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;
}
Beispiel #4
0
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;

    }
  }
}