Move parsers out of Parser.parse
This commit is contained in:
parent
7b9ccd1328
commit
e859d01683
1 changed files with 51 additions and 51 deletions
102
parser.ml
102
parser.ml
|
@ -92,59 +92,59 @@ let (@>) f g seq =
|
||||||
let a, seq = f seq in
|
let a, seq = f seq in
|
||||||
g a seq
|
g a seq
|
||||||
|
|
||||||
|
(* expr := "level" level_inner
|
||||||
|
* | value binop_right
|
||||||
|
*)
|
||||||
|
let rec expr seq =
|
||||||
|
seq |> either
|
||||||
|
(ident "level" @> level_inner)
|
||||||
|
(value @> binop ~-1)
|
||||||
|
|
||||||
|
(* level_inner := "get" | "set" [op] *)
|
||||||
|
and level_inner _ seq =
|
||||||
|
let id, seq = idents (S.of_list ["get"; "set"]) seq in
|
||||||
|
let op, seq = operator seq in
|
||||||
|
if id = "get" then
|
||||||
|
Get_binop_pre op, seq
|
||||||
|
else if id = "set" then
|
||||||
|
let v, seq = value seq in
|
||||||
|
Set_binop_pre (op, v), seq
|
||||||
|
else
|
||||||
|
failwith "Parser.level"
|
||||||
|
|
||||||
|
(* value := int | ( expr ) *)
|
||||||
|
and value seq =
|
||||||
|
match seq () with
|
||||||
|
| Seq.Nil -> raise End_of_tokens
|
||||||
|
| Seq.Cons (x, seq) -> begin match x with
|
||||||
|
| Token.Int n -> Value (Int n), seq
|
||||||
|
| Float n -> Value (Float n), seq
|
||||||
|
| Ident id -> Var id, seq
|
||||||
|
| LParen -> expr seq
|
||||||
|
| _ -> unexpected_token x
|
||||||
|
end
|
||||||
|
|
||||||
|
(* binop := binop op binop *)
|
||||||
|
and binop pre left seq =
|
||||||
|
match seq () with
|
||||||
|
| Seq.Nil -> left, Seq.empty
|
||||||
|
| Seq.Cons (x, seq) -> begin match x with
|
||||||
|
| op when token_is_operator op ->
|
||||||
|
let op = token_to_op op in
|
||||||
|
let o = precedence_of op in
|
||||||
|
(* op has to be calculated first *)
|
||||||
|
if o > pre || (op_is_right_to_left op && o = pre) then
|
||||||
|
let v, seq = value seq in
|
||||||
|
let right, seq = binop o v seq in
|
||||||
|
binop pre (Ast.binop left op right) seq
|
||||||
|
else
|
||||||
|
left, Seq.cons x seq
|
||||||
|
| Token.RParen -> left, seq
|
||||||
|
| _ -> unexpected_token x
|
||||||
|
end
|
||||||
|
|
||||||
(* parse tokens *)
|
(* parse tokens *)
|
||||||
let parse ts =
|
let parse ts =
|
||||||
(* value := int | ( expr ) *)
|
|
||||||
let rec value seq =
|
|
||||||
match seq () with
|
|
||||||
| Seq.Nil -> raise End_of_tokens
|
|
||||||
| Seq.Cons (x, seq) -> begin match x with
|
|
||||||
| Token.Int n -> Value (Int n), seq
|
|
||||||
| Float n -> Value (Float n), seq
|
|
||||||
| Ident id -> Var id, seq
|
|
||||||
| LParen -> expr seq
|
|
||||||
| _ -> unexpected_token x
|
|
||||||
end
|
|
||||||
|
|
||||||
(* binop := binop op binop *)
|
|
||||||
and binop pre left seq =
|
|
||||||
match seq () with
|
|
||||||
| Seq.Nil -> left, Seq.empty
|
|
||||||
| Seq.Cons (x, seq) -> begin match x with
|
|
||||||
| op when token_is_operator op ->
|
|
||||||
let op = token_to_op op in
|
|
||||||
let o = precedence_of op in
|
|
||||||
(* op has to be calculated first *)
|
|
||||||
if o > pre || op_is_right_to_left op && o = pre then
|
|
||||||
let v, seq = value seq in
|
|
||||||
let right, seq = binop o v seq in
|
|
||||||
binop pre (Ast.binop left op right) seq
|
|
||||||
else
|
|
||||||
left, Seq.cons x seq
|
|
||||||
| Token.RParen -> left, seq
|
|
||||||
| _ -> unexpected_token x
|
|
||||||
end
|
|
||||||
|
|
||||||
(* level_inner := "get" | "set" [op] *)
|
|
||||||
and level_inner _ seq =
|
|
||||||
let id, seq = idents (S.of_list ["get"; "set"]) seq in
|
|
||||||
let op, seq = operator seq in
|
|
||||||
if id = "get" then
|
|
||||||
Get_binop_pre op, seq
|
|
||||||
else if id = "set" then
|
|
||||||
let v, seq = value seq in
|
|
||||||
Set_binop_pre (op, v), seq
|
|
||||||
else
|
|
||||||
failwith "Parser.level"
|
|
||||||
|
|
||||||
(* expr := "level" level_inner
|
|
||||||
* | value binop_right
|
|
||||||
*)
|
|
||||||
and expr seq =
|
|
||||||
seq |> either
|
|
||||||
(ident "level" @> level_inner)
|
|
||||||
(value @> binop ~-1)
|
|
||||||
in
|
|
||||||
let ast, rest = expr ts in
|
let ast, rest = expr ts in
|
||||||
if rest () <> Seq.Nil then failwith "Parser.parse";
|
if rest () <> Seq.Nil then failwith "Parser.parse";
|
||||||
ast
|
ast
|
||||||
|
|
Loading…
Add table
Reference in a new issue