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.