2012-02-08 3 views
6

질문은 this one과 비슷하지만 FParsecOperatorPrecedenceParser을 사용하여 함수 응용 프로그램으로 표현식을 파싱하고 싶습니다.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) 

그리고 파서 코드 : 여기

내 AST 여기

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 구문 분석기로 인수 목록을 표현식 목록으로 구문 분석합니다. 여기 파서를 내장,하지만 난 내 기존 파서와 결합하는 방법을 모른다 :

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을 정의