SQL検索条件を解析しようとしていますが、パーサーが論理(AND
、OR
)を他の中置演算子と区別するのに問題があります。私はそれらを異なるノードとして解析しています(おそらくそれを行うのは難しいです)が、評価フェーズを単純化します。関連するコードスニペットは次のとおりです(必要に応じてさらに含めることができます)。
let opp = OperatorPrecedenceParser<_,_,_>()
let scalarExpr = opp.ExpressionParser
opp.TermParser <- constant <|> id <|> between lparen rparen scalarExpr <|> scalarExpr
//infix operators added here
let comparison = //(e.g., 1 < 2)
let compareExpr = pipe3 scalarExpr compareOp scalarExpr (fun l op r -> Comparison(op, l, r))
between lparen rparen compareExpr <|> compareExpr
let andTerm = pstringCI "and" .>> ws
let orTerm = pstringCI "or" .>> ws
let searchCondition, searchConditionRef = createParserForwardedToRef()
searchConditionRef :=
[ comparison
pipe3 searchCondition andTerm searchCondition (fun l _ r -> And(l, r))
pipe3 searchCondition orTerm searchCondition (fun l _ r -> Or(l, r))
between lparen rparen searchCondition ]
|> choice
let filter : Parser<_,unit> = ws >>. searchCondition .>> eof
"1 = 1"
正しく解析しますComparison (Eq,Constant (Int32 1),Constant (Int32 1))
しかし、論理演算子を使用して2つの比較を結合しようとすると、たとえば、次"1 = 1 or 2 = 2"
のように解析できません。
Lnのエラー:1列:7
1=1または2=2
^
期待:入力の終わりまたは中置演算子
:7
1
エラーの前をスカラー式として解析し、or
バックトラックを押すと、中置演算子ではないこと1
を認識し、完全なスカラーとして戻り、論理演算子で結合された条件の左側を解析していることを認識しますor
。
1
代わりに、おそらく中置演算子を含む、より複雑なスカラー式が始まると仮定し続けるようです。
コードに問題がありますか、または(同じを使用して)中置演算子としてAND
/を解析するための解決策はありますか?私はそのルートに行きたくないので、どこかで単純な間違いを犯したことを望んでいます。OR
OperatorPrecedenceParser
完全なコードは要点です。