Productions program = main_class class_decl* ; main_class = class_token id lbrace main_def rbrace ; main_def = public static void main lparen string lbracket rbracket id rparen lbrace statement rbrace ; class_decl = {baseclass} class_token id lbrace var_decl* method_decl* rbrace | {extclass} class_token [classid]:id extends [baseid]:id lbrace var_decl* method_decl* rbrace ; var_decl = type id semi ; method_decl = public type id lparen formal_list rparen method_body ; method_body = lbrace var_decl* statement* return exp semi rbrace ; formal_list = {empty} | {nonempty} type id formal_rest ; formal_rest = {empty} | {nonempty} comma type id formal_rest ; type = {array} int lbracket rbracket | {bool} boolean | {int} int | {class} id ; statement = {ifone} if lparen exp rparen statement | {if} if lparen exp rparen [truepart]:stmt_all_paired else [falsepart]:statement | {while} while lparen exp rparen statement | {simple} simple_stmt ; simple_stmt = {print} println lparen exp rparen semi | {assign} id equal exp semi | {array} id lbracket [index]:exp rbracket equal exp semi | {nested} lbrace statement* rbrace ; stmt_all_paired= {sans_trailer} simple_stmt | {while} while lparen exp rparen stmt_all_paired | {if} if lparen exp rparen [truepart]:stmt_all_paired else [falsepart]:stmt_all_paired ; exp = and_exp ; and_exp = {simple} comparison | {and} [left]:and_exp and [right]:comparison ; comparison = {simple} arith_exp | {compare} [left]:arith_exp less [right]:arith_exp ; arith_exp = {simple} term | {add} [left]:arith_exp plus [right]:term | {subt} [left]:arith_exp minus [right]:term ; term = {simple} bool_exp | {times} [left]:term star [right]:bool_exp ; bool_exp = {simple} factor | {not} bang bool_exp ; factor = {array} factor lbracket [index]:exp rbracket | {length} factor dot length | {call} factor dot id lparen exp_list rparen | {num} number | {true} true | {false} false | {id} id | {this} this | {newarray} new int lbracket exp rbracket | {newobj} new id lparen rparen | {nested} lparen exp rparen ; exp_list = {empty} | {exps} exp exp_rest ; exp_rest = {empty} | {exps} comma exp exp_rest ;