Example #1
0
CAstModule* CParser::module() {
  //
  // module ::= "module" ident ";" varDeclaration { subroutineDecl }
  //            "begin" statSequence "end" ident ".".
  //
  
  CToken module_name;
  CToken module_name_check;
  CAstStatement *statseq = NULL;
  
  Consume(tModule);
  Consume(tIdent, &module_name);
  Consume(tSemicolon);

  CAstModule *m = new CAstModule(module_name, module_name.GetValue());

  InitSymbolTable(m->GetSymbolTable());

  // varDeclaration
  if(_scanner->Peek().GetType() == tVar) {
    Consume(tVar);
    varDecl(m);
    Consume(tSemicolon);

    while(1) {
      if(_scanner->Peek().GetType() == tIdent) {
        varDecl(m);
        Consume(tSemicolon);
      }
      else break;
    }
  }

  // subroutineDecl
  while(_scanner->Peek().GetType() == tProcedure || _scanner->Peek().GetType() == tFunction) {
    subroutineDecl(m);
  }

  Consume(tBegin);

  // statSequence
  statseq = statSequence(m);
  m->SetStatementSequence(statseq);

  Consume(tEnd);
  Consume(tIdent, &module_name_check);
  
  // Check module names are equal.
  if(module_name.GetValue() != module_name_check.GetValue()) {
    SetError(module_name_check, "module identifier mismatch ('" + module_name.GetValue() + "' != '" + module_name_check.GetValue() + "').");
  }

  Consume(tDot);

  return m;
}
Example #2
0
CAstModule* CParser::module(void)
{
  //
  // module ::= "module" ident ";" varDeclaration { subroutineDecl }
  //            "begin" stateSequence "end" ident ".".
  //
  CToken t;

  // module -> "module" ident ";" ...
  Consume(kModule, &t);
  CToken tModuleIdent = _scanner->Get();
  if (tModuleIdent.GetType() != tIdent)
    SetError(tModuleIdent, "module identifier expected");
  Consume(tSemicolon);

  CAstModule *m = new CAstModule(t, tModuleIdent.GetValue());
  InitSymbolTable(m->GetSymbolTable());

  // module -> ... varDeclaration ...
  varDeclaration(m);

  // module -> ... { subroutineDecl } ...
  CAstProcedure *sub = NULL;
  EToken tt = _scanner->Peek().GetType();
  while (tt != kBegin) {
    switch (tt) {
      // subroutineDecl -> procedureDecl ...
      case kProc:
        sub = procedureDecl(m);
        break;

      // subroutineDecl -> functionDecl ...
      case kFunc:
        sub = functionDecl(m);
        break;

      default:
        SetError(_scanner->Peek(), "invalid subroutine declaration");
        break;
    }

    // subroutineDecl -> ... subroutineBody ...
    subroutineBody(sub);

    // subroutineDecl -> ... ident ";".
    CToken t = _scanner->Peek();
    if (t.GetType() != tIdent || t.GetValue() != sub->GetName()) {
      string msg = "subroutine identifier mismatched (\"" + sub->GetName()
                    + "\" != \"" + t.GetValue() + "\")";
      SetError(t, msg);
    }
    Consume(tIdent);
    Consume(tSemicolon);

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

  // module -> ... "begin" statSequence "end" ...
  Consume(kBegin);
  CAstStatement *statseq = statSequence(m);
  m->SetStatementSequence(statseq);
  Consume(kEnd);

  // module -> ... ident "."
  CToken tModuleIdentClose = _scanner->Get();
  if (tModuleIdent.GetValue() != tModuleIdentClose.GetValue()) {
    string msg = "module identifier not matched (\"" + tModuleIdent.GetValue()
                + "\" != \"" + tModuleIdentClose.GetValue() + "\")";
    SetError(tModuleIdentClose, msg);
  }
  Consume(tDot);

  return m;
}