将逻辑与其他中缀运算符区分开 [英] Differentiating logical from other infix operators

查看:84
本文介绍了将逻辑与其他中缀运算符区分开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解析SQL搜索条件,并且无法使解析器将逻辑(ANDOR)与其他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.

完整的代码在要点上.

推荐答案

我认为最终您会发现需要将andor视为具有优先级规则的中缀运算符,因为这正是它们的本质包括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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆