2

私は最初のパーサーをコーディングしています。それは F# にあり、私は 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
4

1 に答える 1

1

"(true and false) or true" のような入力に対して何が起こるかというとpline、それが適用され、pexpression適用しようとしますbetweenParentheses exprParserLogic。これは成功し、「(true and false)」を解析します。したがって、解析が成功したため、2 番目のオプションexprParserLogicを試みることはなく、単純に に戻りますplinepline次に適用さeofれますが、「または真」がまだ入力に残っているため失敗します。

はすでに演算子パーサーの用語パーサーの一部であるためbetweenParentheses exprParserLogic、独自のルールでそれを解析しようとする理由はありません。pline完全に呼び出しexprParserLogicて削除するpexpression(または定義let pexpression = oppLogic.ExpressionParserして削除する)ことができますexprParserLogic。これにより、「(true and false) or true」が正しく解析されます。

于 2016-06-01T19:21:24.100 に答える