module calcgrammar. accum_sig lambdayacc. accumulate lambdayacc. % Grammar for online calculator example type lparen, rparen, plust, minust, timest, dividet, expt, quitt gs. type ae int -> gs. % arithmetic expression %%% tokenizer declarations: printname _ "(" lparen. printname _ ")" rparen. printname _ "+" plust. printname _ "-" minust. printname _ "*" timest. printname _ "/" dividet. printname _ "^" expt. printname _ "quit" quitt. % iconst and id are universal terminal_list [minust,dividet,plust,expt,timest,lparen,rparen,quitt,(iconst V)]. nonterm_list [(ary1 ae)]. comment_list ["%"]. start_symbol (ae X). cfg % really ambiguous gammar w/precedence declarations [ rule ((ae R) ==> [iconst R2]) (R is R2), rule ((ae R3) ==> [lparen,(ae R1),rparen]) (R3 is R1), rule ((ae R4) ==> [(ae A4),plust,(ae B4)]) (R4 is (A4 + B4)), rule ((ae R5) ==> [(ae A5),minust,(ae B5)]) (R5 is (A5 - B5)), rule ((ae R6) ==> [(ae A6),timest,(ae B6)]) (R6 is (A6 * B6)), rule ((ae R7) ==> [(ae A7),dividet,(ae B7)]) (R7 is (A7 div B7)), rule ((ae R8) ==> [(ae A8),expt,(ae B8)]) (power A8 A8 B8 R8), rule ((ae R9) ==> [quitt]) failure ]. % precedence and associatvity. needed to resovle shift-reduce conflicts: binaryop plust (ae X) (ae Y) "left" 3. binaryop minust (ae X) (ae Y) "left" 3. binaryop timest (ae X) (ae Y) "left" 2. binaryop dividet (ae X) (ae Y) "left" 2. binaryop expt (ae X) (ae Y) "right" 1. % freshcopy clauses: (needed because of an implementation characteristic) %%%%%%%%%%%%% Semantic action clauses: type power int -> int -> int -> int -> o. type failure o. power X AX 0 1. power X AX 1 AX. power X AX E N :- E > 1, AX2 is (X * AX), E2 is (E - 1), power X AX2 E2 N. failure :- !, fail. % online calculator program: calculator :- parseline (ae X) (ae X), print "Value = ", printterm std_out X, print "\n", calculator. % repeat until quit entered.