Yacc
# OCamlYacc
Simple calculator with unique binary operator `+`.
~~~
###########################
#### calc0.mly ####
###########################
%{
open Printf
%}
%token NUM
%token PLUS
%token NEWLINE
%left PLUS
%start input
%type input
%%
input: { }
| input line { }
;
line: NEWLINE { }
| expr NEWLINE { printf "\t%.10g\n" $1; flush stdout }
;
expr: NUM { $1 }
| expr PLUS expr { $1 +. $3 }
;
%%
###########################
#### lexer.mll ####
###########################
{
open Calc0
}
let digit = ['0'-'9']
rule token = parse
| [' ' '\t'] { token lexbuf }
| '\n' { NEWLINE }
| digit+ (* '+' ∈ RegExp *)
| "." digit+
| digit+ "." digit* as num { NUM (float_of_string num) }
| '+' { PLUS }
| _ { token lexbuf }
| eof { raise End_of_file }
#########################
#### main.ml ####
#########################
let parse_error s = print_endline s; flush stdout
let main () =
try
let lexbuf = Lexing.from_channel stdin in
while true do
Calc0.input Lexer.token lexbuf
done
with
End_of_file -> exit 0
| Parsing.Parse_error -> parse_error "Parse error"
let _ = Printexc.print main ()
##########################
#### Makefile ####
##########################
all:
ocamlyacc *.mly
ocamlc -c *.mli
ocamllex lexer.mll
ocamlc -c *.ml
ocamlc -o calc *.cmo
clean:
rm -rf *.mli *.cmo *.cmi calc lexer.ml calc0.ml
~~~
# Yacc