将逻辑与其他中缀运算符区分开 [英] Differentiating logical from other infix operators
问题描述
我正在尝试解析SQL搜索条件,并且无法使解析器将逻辑(AND
,OR
)与其他infix运算符区分开.我将它们解析为不同的节点(也许很难做到),但是简化了评估阶段.这是相关的代码段(如有必要,我可以添加更多内容).
I'm trying to parse SQL search conditions and having trouble getting the parser to differentiate logical (AND
, OR
) from other infix operators. I'm parsing them as different nodes (perhaps that's difficult to do), but simplifies the evaluation phase. Here's the relevant code snippet (I can include more if necessary).
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))
但是一旦我尝试使用逻辑运算符(例如"1 = 1 or 2 = 2"
)将两个比较合并在一起,它将无法解析
but once I try to join two comparisons with a logical operator, e.g., "1 = 1 or 2 = 2"
, it fails to parse with
Ln错误:1个列:7
1 = 1或2 = 2
^
预期:输入结束或中缀运算符
:7
Error in Ln: 1 Col: 7
1 = 1 or 2 = 2
^
Expecting: end of input or infix operator
: 7
我希望它将错误之前的1
解析为标量表达式,并在击中or
回溯时,意识到它不是中缀运算符,将1
作为完整的标量返回,并意识到它正在解析左侧的-逻辑运算符or
连接的条件的手侧.
I expected it to parse the 1
before the error as a scalar expression and upon hitting or
backtrack, realizing it's not an infix operator, return 1
as the complete scalar, and recognize it's parsing the left-hand side of a condition joined by logical operator or
.
相反,它似乎继续假设1
开始一个更复杂的标量表达式,可能涉及一个infix运算符.
Instead, it seems to continue assuming 1
begins a more complex scalar expression, possibly involving an infix operator.
代码是否有问题,或者将int运算符解析为AND
/OR
的解决方案(使用相同的OperatorPrecedenceParser
)?我宁愿不走那条路,所以我希望我在某个地方犯了一个简单的错误.
Is there a problem with the code, or is the solution to parse AND
/OR
as infix operators (using the same OperatorPrecedenceParser
)? I'd rather not go that route, so I'm hoping I've made a simple mistake somewhere.
完整的代码在要点上.
推荐答案
我认为最终您会发现需要将and
和or
视为具有优先级规则的中缀运算符,因为这正是它们的本质包括fparsec和fsyacc在内的大多数解析器都具有处理它们的特殊功能的原因(即通过优先级和关联性规则解决歧义).
I think ultimately you'll find you need to treat and
and or
as infix operators with precedence rules because that is exactly what they are and is the reason why most parsers including fparsec and fsyacc have special features to handle them (i.e. resolve ambiguity through precedence and associativity rules).
您发现一个案例突出了这一点,但请考虑另一个案例:
You've found one case highlighting this, but consider another:
1 = 1 or 2 = 2 and 3 =3
该解析为(1 = 1 or 2 = 2) and 3 = 3
还是1 = 1 or (2 = 2 and 3 = 3)
?
这篇关于将逻辑与其他中缀运算符区分开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!