2012-02-08 7 views
6

प्रश्न this one के समान है, लेकिन FParsec में OperatorPrecedenceParser का उपयोग करके मैं फ़ंक्शन एप्लिकेशन के साथ एक अभिव्यक्ति को पार्स करना चाहता हूं।ऑपरेटर प्रेसेडेंस पार्सर का उपयोग कर FParsec के साथ पार्सिंग फ़ंक्शन एप्लिकेशन?

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

मेरे समस्या यह है कि समारोह तर्क अभिव्यक्ति भी हैं (वे ऑपरेटरों, चर आदि शामिल कर सकते हैं) और मुझे नहीं पता कि मेरेको कैसे बढ़ाया जाए अभिव्यक्ति की सूची के रूप में तर्क सूची को पार्स करने के लिएपार्सर। मैं एक पार्सर का निर्माण यहीं है, लेकिन मैं कैसे अपने मौजूदा पार्सर के साथ गठबंधन करने के लिए पता नहीं है:

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

और फिर expr

let expr = (number |>> Float) <|> identWithOptArgs 
तरह परिभाषित
संबंधित मुद्दे