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; }
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; }