void Grammar::dump(const Production &prod, MarginFile *f) const { fprintf(f, _T("%s -> "), getSymbol(prod.m_leftSide).m_name.cstr()); for(int i = 0; i < prod.getLength(); i++) { fprintf(f, _T("%s "), getSymbol(prod.m_rightSide[i]).m_name.cstr()); } fprintf(f, _T("prec %d"), prod.m_precedence); }
bool Grammar::canTerminate(const Production &prod) const { const int length = prod.getLength(); for(int s = 0; s < length; s++) { if(!getSymbol(prod.m_rightSide[s]).m_terminate) { return false; } } return true; }
bool Grammar::deriveEpsilon(const Production &prod) const { const int length = prod.getLength(); for(int s = 0; s < length; s++) { if(!getSymbol(prod.m_rightSide[s]).m_deriveEpsilon) { return false; } } return true; }
Node* Parser::makeNode(State* pState, UINT nEnd, Node* pV, NodeDict& ndV) { UINT nDot = pState->getDot() + 1; Production* pProd = pState->getProd(); UINT nLen = pProd->getLength(); if (nDot == 1 && nLen >= 2) return pV; INT iNtB = pState->getNt(); UINT nStart = pState->getStart(); Node* pW = pState->getNode(); Production* pProdLabel = pProd; if (nDot >= nLen) { // Completed production: label by nonterminal only nDot = 0; pProdLabel = NULL; } Label label(iNtB, nDot, pProdLabel, nStart, nEnd); Node* pY = ndV.lookupOrAdd(label); pY->addFamily(pProd, pW, pV); // pW may be NULL return pY; }
void GrammarParser::parseActionBody(const SourcePosition &sourcePos, CompactShortArray &usedDollar, const Production &prod) { for(;;) { switch(m_token) { case LCURL: next(); parseActionBody(sourcePos, usedDollar, prod); if(m_token != RCURL) { m_lex.error(_T("Expected '}'.")); } else { next(); } break; case RCURL: return; case EOI: m_lex.error(sourcePos, _T("This codeblock has no end.")); return; case DOLLARDOLLAR: { SourceText tmp; m_lex.getCollected(tmp); m_lex.collectEnd(); next(); m_actionBody += tmp.m_sourceText + _T("m_leftSide "); m_lex.collectBegin(); } break; case DOLLAR: { SourceText tmp; m_lex.getCollected(tmp); m_lex.collectEnd(); next(); if(m_token != NUMBER) { m_lex.error(_T("Expected number.")); m_actionBody += _T("$ "); } else { const int prodLength = prod.getLength(); const int symbolIndex = (int)m_lex.getNumber(); const int fromTop = prodLength - symbolIndex; if(symbolIndex < 1 || symbolIndex > prodLength) { m_lex.warning(m_lex.getSourcePos(), _T("$%d is not in range [1..%d]."), symbolIndex, prodLength); m_grammar.m_warningCount++; } else { if(m_grammar.isTerminal(prod.m_rightSide[symbolIndex-1])) { m_lex.warning(m_lex.getSourcePos(), _T("$%d is a terminal."), symbolIndex); m_grammar.m_warningCount++; } } next(); m_actionBody += tmp.m_sourceText + format(_T("getStackTop(%d)"), fromTop); } m_lex.collectBegin(); } break; default: next(); break; } } }