static int PreAnalise(MMap& map, MMap::iterator it, bool& allsame) { int currentRuleIndex = it->m_pNotTerminal->GetIndex(); int currentRule = it->m_RuleIndex; //Faz todos desta regra (até ela mudar) if (it == map.end()) { return 0; } int sub = 0; allsame = true; while (it->m_pNotTerminal->GetIndex() == currentRuleIndex) { if (currentRule != it->m_RuleIndex) { allsame = false; } sub++; it++; if (it == map.end()) { break; } } //retorna quantos tem destra regra return sub; }
void Print(std::wostream& os, MMap& map, Grammar& g) { for (auto it = map.begin(); it != map.end(); it++) { os << L"[" << it->m_pNotTerminal->GetName() << L", " << it->m_pTerminal->GetName() << L"]"; //Print(os, it->m_pTerminal); os << L" : " ; const Production& production = g.GetProduction(it->m_RuleIndex); Print(os , production); os << std::endl; } }
MMap BuildMTable(const FirstSets& first, const FollowSets& follow, Grammar& g) { MMap M; std::wcout << L"\n Building M table \n"; for (int k = 0; k < g.GetNumOfProductions(); k++) { //Para cada producao da gramatica A = alfa const Production& production = g.GetProduction(k); Print(std::wcout, production); //Aqui o first tem que ser em relacao a "alfa" e não a "A" // pois o A engloba todos os "firsts" e aqui se quer o first especifico // desta producao // Entao o FirstSets& first é o "pior caso" o first de qualquer "A" // No aho novo parece que tem um defeito de escrita e que o first deveria // ser first alfa no dois (esta so no segundo) //Nao testei se o follow teria que ter algo assim std::set<const GrammarSymbol*> f = GetFirstSet(first, g, production); //Regra 1 //auto f = first.Get(production.GetLeftSymbol()); for (auto it = f.begin(); it != f.end(); ++it) { // Para cada terminal a em primeiro(A) const GrammarSymbol* pgs = (*it); if (pgs->IsTerminal() && pgs != g.epsilon()) { //M[A, a] = alfa std::wcout << L"[" << production.GetLeftSymbol()->GetName() << L"," << pgs->GetName() << L"] = " ; Print(std::wcout, production); /*if (M.find(MKey(production.GetLeftSymbol(), pgs)) != M.end()) { std::wcout << L"<-- duplicated" << std::endl; throw std::exception("multiple entries"); }*/ auto MTableIt = M.find(MKey(production.GetLeftSymbol(), pgs, k)); if (MTableIt != M.end()) { if (MTableIt->m_pNotTerminal->GetName() != production.GetLeftSymbol()->GetName()) { //if (MTableIt->) //M.insert(MKey(production.GetLeftSymbol(), pgs, k)); std::string strError; strError = "Multiple entries "; strError += to_utf8_string(production.GetLeftSymbol()->GetName()); strError += " -> "; strError += to_utf8_string(pgs->GetName()); throw std::exception(strError.c_str()); } else { //ja existe a regra igual //std::string strError; //strError = "Multiple entries "; //strError += to_utf8_string(production.GetLeftSymbol()->GetName()); //strError += " -> "; //strError += to_utf8_string(pgs->GetName()); //throw std::exception(strError.c_str()); } } else { //criar a regra std::wcout << std::endl; M.insert(MKey(production.GetLeftSymbol(), pgs, k)); } //M[MKey(production.GetLeftSymbol(), pgs)] = k; } else if (pgs == g.epsilon()) { // Nao existe epsilon o input stream // entao vou fazer para cada follow auto fo = follow.Get(production.GetLeftSymbol()); //se esta em folow for (auto it = fo.begin(); it != fo.end(); ++it) { const GrammarSymbol* b = (*it); if (b->IsTerminal() && b != g.epsilon()) //ou $ que da no mesmo { std::wcout << L"[" << production.GetLeftSymbol()->GetName() << L"," << b->GetName() << L"] = " ; Print(std::wcout, production); auto MTableIt = M.find(MKey(production.GetLeftSymbol(), b, k)); if (MTableIt != M.end()) { if (MTableIt->m_pNotTerminal->GetName() != production.GetLeftSymbol()->GetName()) { std::wcout << L"<-- duplicated" << std::endl; throw std::exception("multiple entries"); } else { //std::wcout << L"<-- duplicated" << std::endl; //throw std::exception("multiple entries"); } } else { std::wcout << std::endl; M.insert(MKey(production.GetLeftSymbol(), b, k)); } //M[MKey(production.GetLeftSymbol(), b)] = k; } } } } } return M; }
void TriMesh::rebuildTopology(Float maxAngle) { typedef std::multimap<Vertex, TopoData, vertex_key_order> MMap; typedef std::pair<Vertex, TopoData> MPair; const Float dpThresh = std::cos(degToRad(maxAngle)); if (m_normals) { delete[] m_normals; m_normals = NULL; } if (m_tangents) { delete[] m_tangents; m_tangents = NULL; } Log(EInfo, "Rebuilding the topology of \"%s\" (" SIZE_T_FMT " triangles, " SIZE_T_FMT " vertices, max. angle = %f)", m_name.c_str(), m_triangleCount, m_vertexCount, maxAngle); ref<Timer> timer = new Timer(); MMap vertexToFace; std::vector<Point> newPositions; std::vector<Point2> newTexcoords; std::vector<Spectrum> newColors; std::vector<Normal> faceNormals(m_triangleCount); Triangle *newTriangles = new Triangle[m_triangleCount]; newPositions.reserve(m_vertexCount); if (m_texcoords != NULL) newTexcoords.reserve(m_vertexCount); if (m_colors != NULL) newColors.reserve(m_vertexCount); /* Create an associative list and precompute a few things */ for (size_t i=0; i<m_triangleCount; ++i) { const Triangle &tri = m_triangles[i]; Vertex v; for (int j=0; j<3; ++j) { v.p = m_positions[tri.idx[j]]; if (m_texcoords) v.uv = m_texcoords[tri.idx[j]]; if (m_colors) v.col = m_colors[tri.idx[j]]; vertexToFace.insert(MPair(v, TopoData(i, false))); } Point v0 = m_positions[tri.idx[0]]; Point v1 = m_positions[tri.idx[1]]; Point v2 = m_positions[tri.idx[2]]; faceNormals[i] = Normal(normalize(cross(v1 - v0, v2 - v0))); for (int j=0; j<3; ++j) newTriangles[i].idx[j] = 0xFFFFFFFFU; } /* Under the reasonable assumption that the vertex degree is bounded by a constant, the following runs in O(n) */ for (MMap::iterator it = vertexToFace.begin(); it != vertexToFace.end();) { MMap::iterator start = vertexToFace.lower_bound(it->first); MMap::iterator end = vertexToFace.upper_bound(it->first); /* Perform a greedy clustering of normals */ for (MMap::iterator it2 = start; it2 != end; it2++) { const Vertex &v = it2->first; const TopoData &t1 = it2->second; Normal n1(faceNormals[t1.idx]); if (t1.clustered) continue; uint32_t vertexIdx = (uint32_t) newPositions.size(); newPositions.push_back(v.p); if (m_texcoords) newTexcoords.push_back(v.uv); if (m_colors) newColors.push_back(v.col); for (MMap::iterator it3 = it2; it3 != end; ++it3) { TopoData &t2 = it3->second; if (t2.clustered) continue; Normal n2(faceNormals[t2.idx]); if (n1 == n2 || dot(n1, n2) > dpThresh) { const Triangle &tri = m_triangles[t2.idx]; Triangle &newTri = newTriangles[t2.idx]; for (int i=0; i<3; ++i) { if (m_positions[tri.idx[i]] == v.p) newTri.idx[i] = vertexIdx; } t2.clustered = true; } } } it = end; } for (size_t i=0; i<m_triangleCount; ++i) for (int j=0; j<3; ++j) Assert(newTriangles[i].idx[j] != 0xFFFFFFFFU); delete[] m_triangles; m_triangles = newTriangles; delete[] m_positions; m_positions = new Point[newPositions.size()]; memcpy(m_positions, &newPositions[0], sizeof(Point) * newPositions.size()); if (m_texcoords) { delete[] m_texcoords; m_texcoords = new Point2[newTexcoords.size()]; memcpy(m_texcoords, &newTexcoords[0], sizeof(Point2) * newTexcoords.size()); } if (m_colors) { delete[] m_colors; m_colors = new Spectrum[newColors.size()]; memcpy(m_colors, &newColors[0], sizeof(Spectrum) * newColors.size()); } m_vertexCount = newPositions.size(); Log(EInfo, "Done after %i ms (mesh now has " SIZE_T_FMT " vertices)", timer->getMilliseconds(), m_vertexCount); computeNormals(); }
static void GenerateDescRec3(std::wostream& os, Grammar& g, MMap& map, const std::wstring& tokenPrefix) { if (map.empty()) { return; } PrintGeneratedFileHeader(os); PrintGeneratedFileLicense(os); os << L"#pragma once\n"; os << L"\n"; os << L"#include <string.h>\n"; os << L"#include \"" << g.GetModuleName() << L"Lex.h\"\n"; os << L"\n"; os << L"\n"; //PrintOutputClass(os, g); PrintFowardDeclarations(os, g, map); int i = 0; int sub = 0; int currentRuleIndex = -1; auto it = map.begin(); for (; it != map.end();) { int currentRuleIndex = it->m_pNotTerminal->GetIndex(); //Faz todos desta regra (até ela mudar) os << TAB_1 << L"int " << GetFunctionName(g, it->m_pNotTerminal->GetName()) << L"( " << g.GetLanguageName() << L"_Context* ctx)\n"; os << TAB_1 << L"{\n"; int sub = 0; bool allsame = false; bool firstPrinted = false; if (PreAnalise(map, it, allsame) == 1) { //se so tem um nao precisa testar pelo token pois sempre haver um teste //a seguir de qualquer forma const Production& production = g.GetProduction(it->m_RuleIndex); os << TAB__2 << L"//"; Print(os, production); os << L"\n"; PrintProduction(os, production, g, tokenPrefix, TAB__2); it++; } else { while (it->m_pNotTerminal->GetIndex() == currentRuleIndex) { //se todos forem iguais nao testa pelo token //e so imprimi o primeiro que eh igual aos outros if (!allsame) { if (sub == 0) { os << TAB__2 << L"if (IsToken(ctx, " << tokenPrefix << it->m_pTerminal->GetName() << L"))\n"; } else { os << TAB__2 << L"else if (IsToken(ctx, " << tokenPrefix << it->m_pTerminal->GetName() << L"))\n"; } } const Production& production = g.GetProduction(it->m_RuleIndex); if (!allsame) { os << TAB__2 << L"{\n"; } if (!allsame || (allsame && !firstPrinted)) { os << (!allsame ? TAB___3 : TAB__2); os << L"/*"; Print(os, production); os << L"*/\n"; PrintProduction(os, production, g, tokenPrefix, !allsame ? TAB___3 : TAB__2); if (!allsame) { os << TAB__2 << L"}\n"; } } sub++; it++; if (it == map.end()) { break; } firstPrinted = true; } } os << TAB_1 << L"}\n\n"; } }
void GenerateDescRecC(std::wostream& os, Grammar& g, MMap& map, const std::wstring& tokenPrefix, const std::wstring& parserFileSuffix) { if (map.empty()) { return; } PrintGeneratedFileHeader(os); PrintGeneratedFileLicense(os); os << L"\n"; os << L"#include \"stdafx.h\"\n"; os << L"#include <assert.h>\n"; os << L"\n"; os << L"#include \"" << g.GetModuleName() << L"Lex.h\"\n"; os << L"#include \"" << g.GetModuleName() << parserFileSuffix << L".h\"\n"; os << L"\n"; os << L"\n"; //os << L"#include \"sstream.h\"\n"; //os << L"#include \"errors.h\"\n"; os << L"\n"; os << L"\n"; PrintActionsNames(os, g, false); //PrintActions(os, g, false); os << L"\n"; PrintFowardDeclarations(os, g, map); std::wstring ws(SourceCode); find_replace(ws, L"{GRAMMAR}", g.GetLanguageName()); find_replace(ws, L"{MODULE}", g.GetLanguageName()); os << ws; int i = 0; int currentRuleIndex = -1; auto it = map.begin(); int rulecount = 0; for (; it != map.end();) { int currentRuleIndex = it->m_pNotTerminal->GetIndex(); //Faz todos desta regra (até ela mudar) os << L"Result " << GetFunctionName(g, it->m_pNotTerminal->GetName()) << L"( " << g.GetLanguageName() + L"_Context* ctx)\n"; os << L"{\n"; os << TAB_1 << L"Result result = RESULT_OK;\n"; os << TAB_1 << L"" << g.GetLanguageName() << L"_Tokens token = ctx->token; \n"; os << L"\n"; int sub = 0; rulecount = 0; while (it->m_pNotTerminal->GetIndex() == currentRuleIndex) { int currentResultIndex = it->m_RuleIndex; //faz todos que resultam na mesma producao int count = 0; while (currentResultIndex == it->m_RuleIndex) { if (count == 0) { os << TAB_1; if (rulecount > 0) { os << L"else "; } os << L"if (token == " << tokenPrefix << it->m_pTerminal->GetName(); } else { os << L" ||\n"; os << TAB_1 << L" token == " << tokenPrefix << it->m_pTerminal->GetName(); } auto itcopy = it; it++; count++; if (it == map.end() || currentResultIndex != it->m_RuleIndex) { os << L")\n"; //fecha if const Production& production = g.GetProduction(itcopy->m_RuleIndex); os << TAB_1 << L"{\n"; os << TAB__2; os << L"/*"; Print(os, production); os << L"*/\n"; PrintProduction(os, production, g, tokenPrefix, TAB__2); os << TAB_1 << L"}\n"; break; } if (it == map.end()) { break; } } /* if (it != map.end()) { it++; } */ if (it == map.end()) { break; } rulecount++; } //regra os << TAB_1 << L"else\n"; os << TAB_1 << L"{\n"; os << TAB__2 << g.GetLanguageName() << L"_OnAction(ctx, " << g.GetLanguageName() << L"_OnError); \n"; os << TAB__2 << L"return RESULT_FAIL;\n"; os << TAB_1 << L"}\n"; os << L"\n"; os << TAB_1 << L"return result;\n"; os << L"}\n\n"; } }