2012-02-08 4 views
6

質問はthis oneに似ていますが、FParsecOperatorPrecedenceParserを使用して関数アプリケーションで式を解析したいと思います。ここでOperatorPrecedenceParserを使用してFParsecでアプリケーション関数を解析する?

は私のASTです:

type Expression = 
    | Float of float 
    | Variable of VarIdentifier 
    | BinaryOperation of Operator * Expression * Expression 
    | FunctionCall of VarIdentifier (*fun name*) * Expression list (*arguments*) 

私は、次の入力があります。

board→create_obstacle(4, 4, 450, 0, fric) 

そして、ここでは、パーサコードです:

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))) 

をここに私の問題は、関数ということです引数は式でもあり(演算子や変数なども含むことができます)、私の拡張方法はわかりませんexpr parserを使用して、引数リストを式のリストとして解析します。私はここで、パーサーを構築しましたが、私は私の既存のパーサーとそれを結合する方法がわからない:

let primitive = expr <|> parenexpr 
let argList = sepBy primitive (str_ws ",") 
let fcall = tuple2 ident (between (str_ws "(") (str_ws ")") argList) 

私は現在、私のパーサからの次の出力を持っている:私が欲しいもの

Success: Expression (BinaryOperation 
    (Arrow,Variable "board",Variable "create_obstacle")) 

がにあります次を得る:

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

答えて

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)) 

、その後

let expr = (number |>> Float) <|> identWithOptArgs 
よう exprを定義します