2016-06-01 4 views
1

私は最初のパーサーをコーディングしています。それはF#であり、FParsecで使用しています。FParsec括弧付きの解析式

私のパーサが正しいtrue and false(true and false or true)true(((true and false or true)))など、のようなものを解析します。

ただし、(true and false) or 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

「(真と偽)または真」のような入力のために何が起こるのplinebetweenParentheses exprParserLogicを適用しようとしているpexpression、適用されることです。これが成功し、 "真と偽"を解析します。したがって、解析が成功したので、第2のオプションexprParserLogicを試みることはなく、単にplineに戻ります。 plineeofを適用しますが、これは "true"が入力に残っているため失敗します。

betweenParentheses exprParserLogicはすでに演算子パーサーのタームパーサーに含まれているため、独自のルールで解析する必要はありません。 plineを呼び出してexprParserLogicを呼び出し、pexpressionを完全に削除する(またはlet pexpression = oppLogic.ExpressionParserを定義してexprParserLogicを削除する)ことができます。これは "(真と偽)か真"を正しく解析するでしょう。

+0

あなたはうってつけです。 – Gabriel