I've been using this library to parse a language that I'm making, and I've come into an issue with parsing expressions that have spaces before the operator. Take the expression 10 * 10 - running my parser on it, I get this error:
10 * 10
------------------------------
Error in line 1, column 4:
10 * 10
^
Expecting "::"
For some reason, it fails and expects the last operator in the highest precedence operator list:
...
[ [ expr_infix
"::"
(fun l r -> combine l r, Ast.Bop (l, Ast.Cons, r))
~assoc:Assoc_right
]
...
If I condense the input like this, it does work - even with a space after the operator:
10* 10
------------------------------
(* 10 10)
Note that it does work if I use the suggested operator:
10 :: 10
------------------------------
(:: 10 10)
Is this intentional? Is there a way to structure the code so that this isn't an issue? I'll put the code that has been failing below.
(* expression parsing *)
let expr_infix ?(assoc = Assoc_left) op cons = Infix (optional space >> string op >> optional space >> return cons, assoc)
let expr_prefix op cons = Prefix (string op >> cons)
let operators : (Ast.located_expr, unit) operator list list =
let combine (l, _) (r, _) = Location.combine l r in
[ [ expr_infix
"::"
(fun l r -> combine l r, Ast.Bop (l, Ast.Cons, r))
~assoc:Assoc_right
]
; [ expr_infix "*" (fun l r -> combine l r, Ast.Bop (l, Ast.IMul, r))
; expr_infix "*." (fun l r -> combine l r, Ast.Bop (l, Ast.FMul, r))
; expr_infix "/" (fun l r -> combine l r, Ast.Bop (l, Ast.IDiv, r))
; expr_infix "/." (fun l r -> combine l r, Ast.Bop (l, Ast.FDiv, r))
]
; [ expr_infix "+" (fun l r -> combine l r, Ast.Bop (l, Ast.IAdd, r))
; expr_infix "+." (fun l r -> combine l r, Ast.Bop (l, Ast.FAdd, r))
; expr_infix "-" (fun l r -> combine l r, Ast.Bop (l, Ast.ISub, r))
; expr_infix "-." (fun l r -> combine l r, Ast.Bop (l, Ast.FSub, r))
]
; [ expr_infix "<" (fun l r -> combine l r, Ast.Bop (l, Ast.Less, r))
; expr_infix "<=" (fun l r -> combine l r, Ast.Bop (l, Ast.LessE, r))
; expr_infix ">" (fun l r -> combine l r, Ast.Bop (l, Ast.Greater, r))
; expr_infix ">=" (fun l r -> combine l r, Ast.Bop (l, Ast.GreaterE, r))
]
; [ expr_infix "&&" (fun l r -> combine l r, Ast.Bop (l, Ast.And, r))
; expr_infix "||" (fun l r -> combine l r, Ast.Bop (l, Ast.Or, r))
]
; [ expr_infix "/=" (fun l r -> combine l r, Ast.Bop (l, Ast.NotEq, r))
; expr_infix "=" (fun l r -> combine l r, Ast.Bop (l, Ast.Equal, r))
]
; [ expr_infix "->" (fun l r -> combine l r, Ast.Pi (l, r)) ~assoc:Assoc_right ]
]
;;
let list_expr expr' =
char '[' >> optional space >>
let+ e = sep_by expr' (char ';') in
optional space >> char ']' >> return (Ast.List e)
;;
let rec nud s =
(with_pos
(let@ c = const in
Ast.Const c)
<|> with_pos (list_expr expr)
<|> parens expr)
s
and expr s = expression operators nud s
I've been using this library to parse a language that I'm making, and I've come into an issue with parsing expressions that have spaces before the operator. Take the expression
10 * 10- running my parser on it, I get this error:For some reason, it fails and expects the last operator in the highest precedence operator list:
... [ [ expr_infix "::" (fun l r -> combine l r, Ast.Bop (l, Ast.Cons, r)) ~assoc:Assoc_right ] ...If I condense the input like this, it does work - even with a space after the operator:
Note that it does work if I use the suggested operator:
Is this intentional? Is there a way to structure the code so that this isn't an issue? I'll put the code that has been failing below.