f# - Parsing "x y z" with the precedence of multiply -
i'm trying write parser mathematica language in f# using fparsec.
i have written 1 miniml supports syntax f x y = (f(x))(y)
high precedence function application. need use same syntax mean f*x*y
and, therefore, have same precedence multiply. in particular, x y + 2 = x*y + 2
whereas x y ^ 2 = x * y^2
.
how can accomplished?
as stephan pointed out in comment can split operator parser 2 separate parsers , put own parser in middle space-separated expressions. following code demonstrates this:
#i "../packages/fparsec.1.0.1/lib/net40-client" #r "fparsec" #r "fparseccs" open fparsec open system.numerics type expr = | int of biginteger | add of expr * expr | mul of expr * expr | pow of expr * expr let str s = pstring s >>. spaces let pint : parser<_, unit> = many1satisfy isdigit |>> biginteger.parse .>> spaces let high = operatorprecedenceparser<expr,unit,unit>() let low = operatorprecedenceparser<expr,unit,unit>() let phighexpr = high.expressionparser .>> spaces let plowexpr = low.expressionparser .>> spaces high.termparser <- choice [ pint |>> int between (str "(") (str ")") plowexpr ] low.termparser <- many1 phighexpr |>> (function [f] -> f | fs -> list.reduce (fun f g -> mul(f, g)) fs) .>> spaces low.addoperator(infixoperator("+", spaces, 10, associativity.left, fun f g -> add(f, g))) high.addoperator(infixoperator("^", spaces, 20, associativity.right, fun f g -> pow(f, g))) run (spaces >>. plowexpr .>> eof) "1 2 + 3 4 ^ 5 6"
the output is:
add (mul (int 1,int 2),mul (mul (int 3,pow (int 4,int 5)),int 6))
which represents 1 * 2 + 3 * 4^5 * 6
expected.
Comments
Post a Comment