// // A barebones parser for the simple grammar from Session 11 // that produces an abstract syntax tree in Session 14: // statement := repeat statement until expression // | print identifier // | identifier <- expression // expression := identifier = expression // | zero? expression // | number // public class Parser { private Scanner scanner; public Parser( Scanner s ) { scanner = s; } public Statement parse() throws Exception { return statement(); } public Statement statement() throws Exception { Token next = scanner.peek(); if ( next.equals(Token.repeat) ) { match(Token.repeat); Statement s = statement(); match(Token.until); Expression e = expression(); return new RepeatStatement( s, e ); } else if ( next.equals(Token.print) ) { match(Token.print); Token t = match(Token.identifier); return new PrintStatement( new Identifier(t) ); } else if ( next.equals(Token.identifier) ) { Token t = match(Token.identifier); match(Token.assign); Expression e = expression(); return new AssignmentStatement( new Identifier(t), e ); } else throw new Exception( "statement failed" ); } public Expression expression() throws Exception { Token next = scanner.peek(); if ( next.equals(Token.identifier) ) { Token t = match(Token.identifier); match(Token.equals); Expression e = expression(); return new EqualsTest( new Identifier(t), e ); } else if ( next.equals(Token.zeroPredicate) ) { match(Token.zeroPredicate); Expression e = expression(); return new ZeroTest( e ); } else if ( next.equals(Token.number) ) { Token t = match(Token.number); return new NumberExp( t ); } else throw new Exception( "expression failed" ); } public Token match( Token expected ) throws Exception { Token next = scanner.next(); if ( expected == next ) return next; else { System.err.println( "Parser expected " + expected + " but saw " + next + "." ); throw new Exception( "token match failed" ); } } }