parser.mly:
%{ let env=Hashtbl.create 10 %} %token INT %token SUB %token EOL %token EQUAL %token NAME %left SUB %start main /* the entry point */ %type main %% main: statement_list EOL { $1 } statement_list: {} |statement statement_list {} statement: assign_statement{} |print_statement{} assign_statement: var EQUAL expr {Hashtbl.add env $1 $3} print_statement: var {print_int(Hashtbl.find env $1)} expr: INT { $1} | expr SUB expr { $1 - $3} var:NAME {$1}
lexer.mll:
{ open Parser exception Eof } rule token = parse [' ' '\t'] { token lexbuf } (* skip blanks *) | ['\n' ] { EOL } | ['0'-'9']+ as lxm { INT(int_of_string lxm) } | '-' { SUB } |['a'-'z']+ as name {NAME(name)} |'=' {EQUAL} | eof { raise Eof }
calc.ml:
open Syntax let _ = try let a=open_in "test" in let lexbuf = Lexing.from_channel a in while true do Parser.main Lexer.token lexbuf; done with Lexer.Eof -> exit 0;
build.sh:
ocamllex lexer.mll menhir parser.mly ocamlc -c parser.mli ocamlc -c lexer.ml ocamlc -c parser.ml ocamlc -c calc.ml ocamlc -o calc lexer.cmo parser.cmo calc.cmo
it can work sometimes,it test is:
a=1
there is no error
it test is:
a=1 1=a
got:
Fatal error: exception Parser.MenhirBasics.Error
so the prog can parse more than 1 lines
if test is
a=1 a
the prog will no print 1
if test is
a=1 b
the prog will no report a error(b not defined)
the prog is first written useing stdio,it works fine.but I want use it not using stdio.It seems I am not understand ocamlyacc very well.
so how to fix it?Thanks!
Your code should work once the trivial typos are fixed, but you may want to update your printing code to:
in order to avoid any buffer flushing issues.