using System; using System.Collections; using System.IO; using System.Reflection.Emit; /// /// The parser for the Z# Compiler. /// public class Parser { static Token token; // last recognized token static Token laToken; // lookahead token (not yet recognized) static int la; // shortcut to kind attribute of lookahead token (laToken.kind) // Sets of starting tokens for some productions. static BitArray firstActPars, firstDecl, firstExpr, firstStat; // Sets of follow tokens for some productions. static BitArray followDecl, followStat; // Symbol table object of the currently compiled method static Symbol curMethod; // Reads ahead one symbol. static void Scan () { token = laToken; laToken = Scanner.Next(); la = laToken.kind; } // Verifies symbol and reads ahead. static void Check (int expected) { if (la == expected) { Scan(); } else { Error(Token.names[expected] + " expected"); } } public static void Error (string msg) { Errors.Error(msg, laToken.line, laToken.col); } ////////////////////////////////////////////////////////////////////////// // TODO ////////////////////////////////////////////////////////////////////////// // Starts the analysis. // Output is written to System.out. // Initializes the parser and all its components. public static void Parse () { // init first sets int nTokens = Token.names.Length; firstActPars = new BitArray(nTokens); firstActPars[Token.IDENT] = true; firstActPars[Token.NUMBER] = true; firstActPars[Token.CHARCONST] = true; firstActPars[Token.SUB] = true; firstActPars[Token.LPAR] = true; firstActPars[Token.NEW] = true; firstDecl = new BitArray(nTokens); firstDecl[Token.CONST] = true; firstDecl[Token.IDENT] = true; firstDecl[Token.CLASS] = true; firstExpr = firstActPars; firstStat = new BitArray(nTokens); firstStat[Token.IDENT] = true; firstStat[Token.SEMCOL] = true; firstStat[Token.LBRACE] = true; firstStat[Token.IF] = true; firstStat[Token.WHILE] = true; firstStat[Token.RETURN] = true; firstStat[Token.READ] = true; firstStat[Token.WRITE] = true; // init follow sets followDecl = new BitArray(nTokens); followDecl.Or(firstDecl); followDecl[Token.LBRACE] = true; followDecl[Token.EOF] = true; followStat = new BitArray(nTokens); followStat.Or(firstStat); followStat[Token.RBRACE] = true; followStat[Token.ELSE] = true; followStat[Token.EOF] = true; curMethod = null; token = null; // TODO, Exercise 3, add: Tab.Init(); // avoid crash when 1st symbol has scanner error laToken = new Token(0, 1, 1, 0, ""); // scan first symbol Scan(); // TODO, Exercise 1, start analysis Check(Token.EOF); } }