rewritten to use ocamllex and ocamlyacc