package parser; import trees.*; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class Parser { Token token; Lexer in; public Parser(Lexer in) { this.in = in; consume(); } // prog : (stat newline)* ; Return a List of ExpressionTrees public List prog() { List statements = new ArrayList(); while ( token.type==Lexer.ID || token.type==Lexer.PRINT ) { ExpressionTree t = stat(); statements.add(t); match(Lexer.NEWLINE); } if ( token.type!=Lexer.EOF ) { throw new IllegalArgumentException("extra junk on end: "+token); } return statements; } // stat : ID '=' expr newline | 'print' expr newline ; public ExpressionTree stat() { ExpressionTree root; switch ( token.type ) { case Lexer.ID : VarNode id = new VarNode(token); match(Lexer.ID); match(Lexer.EQUALS); ExpressionTree e = expr(); root = new AssignTree(); root.left = id; root.right = e; break; case Lexer.PRINT : match(Lexer.PRINT); ExpressionTree v = expr(); root = new PrintTree(); root.left = v; break; default : throw new IllegalArgumentException("expected assign or print: "+token); } return root; } // expr : mexpr ('+' mexpr)* ; public ExpressionTree expr() { ExpressionTree root = mexpr(); while ( token.type==Lexer.PLUS ) { consume(); ExpressionTree right = mexpr(); AddTree newRoot = new AddTree(); newRoot.left = root; newRoot.right = right; root = newRoot; } return root; } // mexpr : primary ('*' primary)* ; public ExpressionTree mexpr() { ExpressionTree root = primary(); while ( token.type==Lexer.MULT ) { consume(); ExpressionTree right = primary(); MultTree newRoot = new MultTree(); newRoot.left = root; newRoot.right = right; root = newRoot; } return root; } // primary : INT | ID; public ExpressionTree primary() { Token t; switch ( token.type ) { case Lexer.INT : t = token; consume(); return new IntNode(t); case Lexer.ID : t = token; consume(); return new VarNode(t); default : throw new IllegalArgumentException("expected ID or INT: "+token); } } public void match(int type) { if ( token.type!=type ) { String expecting = ""; if ( type!=Lexer.EOF ) { expecting = Lexer.tokenNames[type]; } String found = ""; if ( token.type!=Lexer.EOF ) { expecting = Lexer.tokenNames[token.type]; } throw new IllegalArgumentException("expected "+expecting+ " found "+found); } consume(); } public void consume() { try { token = in.nextToken(); } catch (IOException ioe) { System.err.println("io error reaching token"); } } }