使用OperatorPrecedenceParser解析FParsec的函数应用程序?

Ale*_*kin 7 f# parsing fparsec

问题与类似,但我想使用OperatorPrecedenceParserin 解析带有函数应用程序的表达式FParsec.

这是我的AST:

type Expression =
  | Float of float
  | Variable of VarIdentifier
  | BinaryOperation of Operator * Expression * Expression
  | FunctionCall of VarIdentifier (*fun name*) * Expression list (*arguments*)
Run Code Online (Sandbox Code Playgroud)

我有以下输入:

board?create_obstacle(4, 4, 450, 0, fric)
Run Code Online (Sandbox Code Playgroud)

这是解析器代码:

let expr = (number |>> Float) <|> (ident |>> Variable)
let parenexpr = between (str_ws "(") (str_ws ")") expr

let opp = new OperatorPrecedenceParser<_,_,_>()

opp.TermParser <- expr <|> parenexpr

opp.AddOperator(InfixOperator("?", ws, 
  10, Associativity.Right, 
  fun left right -> BinaryOperation(Arrow, left, right)))
Run Code Online (Sandbox Code Playgroud)

我的问题是函数参数也是表达式(它们可以包含运算符,变量等),我不知道如何扩展我的expr解析器来将参数列表解析为表达式列表.我在这里构建了一个解析器,但我不知道如何将它与我现有的解析器结合起来:

let primitive = expr <|> parenexpr
let argList = sepBy primitive (str_ws ",")
let fcall = tuple2 ident (between (str_ws "(") (str_ws ")") argList)
Run Code Online (Sandbox Code Playgroud)

我目前从我的解析器输出以下内容:

Success: Expression (BinaryOperation 
     (Arrow,Variable "board",Variable "create_obstacle"))
Run Code Online (Sandbox Code Playgroud)

我想要的是获得以下内容:

 Success: Expression 
      (BinaryOperation 
            (Arrow,
                Variable "board",
                Function (VarIdentifier "create_obstacle",
                          [Float 4, Float 4, Float 450, Float 0, Variable "fric"]))
Run Code Online (Sandbox Code Playgroud)

Ste*_*orf 6

您可以将参数列表解析为标识符的可选后缀表达式

let argListInParens = between (str_ws "(") (str_ws ")") argList
let identWithOptArgs = 
    pipe2 ident (opt argListInParens) 
          (fun id optArgs -> match optArgs with
                             | Some args -> FunctionCall(id, args)
                             | None -> Variable(id))
Run Code Online (Sandbox Code Playgroud)

然后定义expr喜欢

let expr = (number |>> Float) <|> identWithOptArgs
Run Code Online (Sandbox Code Playgroud)