Beispiel #1
0
CAstStatement* CParser::statSequence(CAstScope *s) {
  //
  // statSequence ::= [ statement { ";" statement } ].
  // FIRST(statement) = {tIF, tWhile, tReturn, tIdent}.
  // FOLLOW(statSequence) = {tEnd, tElse}.
  //

  CAstStatement *head = NULL;
  CAstStatement *tail = NULL;

  EToken tt = _scanner->Peek().GetType();

  switch(tt) {
    case tIf:
    case tWhile:
    case tReturn:
    case tIdent:
      head = tail = statement(s);
      assert(head != NULL);

      // for multiple statements.
      while(1) {
        if(_scanner->Peek().GetType() == tEnd ||
           _scanner->Peek().GetType() == tElse) {
          break;
        }
        else {
          Consume(tSemicolon);

          CAstStatement *st = NULL;
          st = statement(s);
          
          assert(st != NULL);
          
          tail->SetNext(st);
          tail = st;
        }
      }

      break;

    default:
      break;
  }

  return head;
}
Beispiel #2
0
CAstStatement* CParser::statSequence(CAstScope *s)
{
  //
  // stateSequence ::= [ statement { ";" statement } ].
  // statement ::= assignment | subroutineCall
  //             | ifStatement | whileStatement | returnStatement.
  //
  CAstStatement *head = NULL;
  CAstStatement *tail = NULL;

  CToken tt = _scanner->Peek();
  while (!_abort && tt.GetType() != kEnd && tt.GetType() != kElse) {
    CAstStatement *st = NULL;

    // stateSequence -> ... statement ...
    tt = _scanner->Peek();
    switch (tt.GetType()) {
      // statement -> assignment | subroutineCall
      case tIdent:
        {
          const CSymbol *sym = s->GetSymbolTable()->FindSymbol(tt.GetValue(), sLocal);
          if (!sym) sym = s->GetSymbolTable()->FindSymbol(tt.GetValue(), sGlobal);
          if (!sym) SetError(tt, "undeclared variable \"" + tt.GetValue() + "\"");

          ESymbolType stype = sym->GetSymbolType();
          if (stype == stProcedure) st = subroutineCall(s);
          else st = assignment(s);
        }
        break;

      // statement -> ifStatement
      case kIf:
        st = ifStatement(s);
        break;

      // statement -> whileStatement
      case kWhile:
        st = whileStatement(s);
        break;

      // statement -> returnStatement
      case kReturn:
        st = returnStatement(s);
        break;

      default:
        SetError(_scanner->Peek(), "statement expected.");
        break;
    }

    assert(st);

    if (!head) head = st;
    else tail->SetNext(st);

    tail = st;

    tt = _scanner->Peek();
    if (tt.GetType() == kEnd || tt.GetType() == kElse) break;

    // stateSequence -> ... ";" ...
    Consume(tSemicolon);
  }

  return head;
}