2016-06-01 2 views
1

저는 첫 번째 파서를 코딩하고 있습니다. 그것은 F #에 있고 FParsec와 함께 사용하고 있습니다.FParsec 괄호로 구문 분석

내 파서는 올바른 true and false, (true and false or true), true, (((true and false or true))) 등, 같은 일을 구문 분석합니다.

그러나 (true and false) or true 일 때 파싱되지 않습니다. 텍스트 중간에 괄호가 있으면 실패합니다.

어떻게 해결할 수 있습니까?

샘플 코드 :

"(true 및 false) 또는 true"로 같은 입력에 대해 어떻게됩니까
let private infixOperator (opp: OperatorPrecedenceParser<_,_,_>) op prec map = 
    opp.AddOperator(InfixOperator (op, ws, prec, Associativity.Left, map)) 

let private oppLogic = new OperatorPrecedenceParser<_,_,_>() 

infixOperator oppLogic "is" 1 (fun x y -> Comparison (x, Equal, y)) 
infixOperator oppLogic "isnt" 1 (fun x y -> Comparison (x, NotEqual, y)) 
infixOperator oppLogic "or" 2 (fun x y -> Logic (x, Or, y)) 
infixOperator oppLogic "and" 3 (fun x y -> Logic (x, And, y)) 

let private exprParserLogic = oppLogic.ExpressionParser 

let private betweenParentheses p = 
    between (str "(") (str ")") p 

oppLogic.TermParser <- choice [ 
    betweenParentheses exprParserLogic 
    pboolean 
] 

let pexpression = 
    choice [ 
     attempt <| betweenParentheses exprParserLogic 
     exprParserLogic 
    ] 

let private pline = 
    ws 
    >>. pexpression 
    .>> eof 

답변

1

plinepexpression 시도가 betweenParentheses exprParserLogic을 적용 할 적용한다는 것입니다. 이것은 성공하고 "(참 및 거짓)"을 구문 분석합니다. 따라서 구문 분석이 성공한 후에는 두 번째 옵션 exprParserLogic을 시도하지 않고 단순히 pline으로 돌아갑니다. plineeof을 적용합니다. "또는 true"가 여전히 입력에 남아 있기 때문에 실패합니다.

betweenParentheses exprParserLogic은 이미 운영자 파서의 용어 파서에 포함되어 있기 때문에 자체 규칙에서 파싱을 시도 할 이유가 없습니다. pline을 호출하여 exprParserLogic을 호출하고 pexpression을 모두 제거하거나 let pexpression = oppLogic.ExpressionParser을 정의하고 을 제거 할 수 있습니다. 이렇게하면 "(true 및 false) 또는 true"를 올바르게 구문 분석합니다.

+0

당신은 유쾌하게 맞습니다. – Gabriel