2012-02-08 3 views
6

soru this one benzer, ama OperatorPrecedenceParserFParsec kullanarak fonksiyon uygulaması ile bir ifade ayrıştırmak istiyor.Ayrıştırma işlevi uygulama?

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

Aşağıdaki giriş var: Burada

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

Ve ayrıştırıcı kod şudur: Burada

benim AST burada

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

Benim sorunum fonksiyonu olmasıdır argümanlar (onlar vb operatörleri, değişkenleri içerebilir) yanı ifadelerdir ve benimuzatmak bilmiyorumayrıştırıcı ifade liste olarak argüman listesi ayrıştırmak için. Burada bir ayrıştırıcı inşa, ama benim mevcut ayrıştırıcı ile birleştirmek nasıl bilmiyorum:

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

Şu anda benim ayrıştırıcı aşağıdaki çıkışı:

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

İstediğim etmektir izleyici kitlesi elde:

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

cevap

6

Sen bir tanımlayıcı isteğe bağlı sonek ifadesi olarak argüman listesi ayrıştırmak olabilir

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

ve

let expr = (number |>> Float) <|> identWithOptArgs 
gibi expr tanımlar