40 lines
1.3 KiB
Plaintext
40 lines
1.3 KiB
Plaintext
type expression =
|
|
| Const of float
|
|
| Sum of expression * expression (* e1 + e2 *)
|
|
| Diff of expression * expression (* e1 - e2 *)
|
|
| Prod of expression * expression (* e1 * e2 *)
|
|
| Quot of expression * expression (* e1 / e2 *)
|
|
|
|
let rec eval = function
|
|
| Const c -> c
|
|
| Sum (f, g) -> eval f +. eval g
|
|
| Diff(f, g) -> eval f -. eval g
|
|
| Prod(f, g) -> eval f *. eval g
|
|
| Quot(f, g) -> eval f /. eval g
|
|
|
|
open Genlex
|
|
|
|
let lexer = make_lexer ["("; ")"; "+"; "-"; "*"; "/"]
|
|
|
|
let rec parse_expr = parser
|
|
[< e1 = parse_mult; e = parse_more_adds e1 >] -> e
|
|
and parse_more_adds e1 = parser
|
|
[< 'Kwd "+"; e2 = parse_mult; e = parse_more_adds (Sum(e1, e2)) >] -> e
|
|
| [< 'Kwd "-"; e2 = parse_mult; e = parse_more_adds (Diff(e1, e2)) >] -> e
|
|
| [< >] -> e1
|
|
and parse_mult = parser
|
|
[< e1 = parse_simple; e = parse_more_mults e1 >] -> e
|
|
and parse_more_mults e1 = parser
|
|
[< 'Kwd "*"; e2 = parse_simple; e = parse_more_mults (Prod(e1, e2)) >] -> e
|
|
| [< 'Kwd "/"; e2 = parse_simple; e = parse_more_mults (Quot(e1, e2)) >] -> e
|
|
| [< >] -> e1
|
|
and parse_simple = parser
|
|
| [< 'Int i >] -> Const(float i)
|
|
| [< 'Float f >] -> Const f
|
|
| [< 'Kwd "("; e = parse_expr; 'Kwd ")" >] -> e
|
|
|
|
|
|
let parse_expression = parser [< e = parse_expr; _ = Stream.empty >] -> e
|
|
|
|
let read_expression s = parse_expression(lexer(Stream.of_string s))
|