Multiply priority xy z parsing

I am trying to write a parser for Mathematica in F # using FParsec.

I wrote one for MiniML that supports the fxy = (f(x))(y) syntax with high priority for function app. Now I need to use the same syntax to denote f*x*y and therefore have the same priority as multiply. In particular, xy + 2 = x*y + 2 whereas xy ^ 2 = x * y^2 .

How can I do that?

+5
source share
1 answer

As Stefan noted in a comment, you can split the parser into two separate parsers and put your own parser in the middle for spatially separated expressions. The 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 fg -> Mul(f, g)) fs) .>> spaces low.AddOperator(InfixOperator("+", spaces, 10, Associativity.Left, fun fg -> Add(f, g))) high.AddOperator(InfixOperator("^", spaces, 20, Associativity.Right, fun fg -> Pow(f, g))) run (spaces >>. pLowExpr .>> eof) "1 2 + 3 4 ^ 5 6" 

Conclusion:

 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 as expected.

+6
source

Source: https://habr.com/ru/post/1216366/


All Articles