我正在为类似于 SQL 的语言开发解析器,但我遇到了创建一些语言规则的问题,例如:expression IS NULL
以及expression IN (expression1, expression2, ...)
逻辑和数学运算符之间的优先级。
我上传了一个 GitHub 测试项目https://github.com/anpv/SpracheTest/但是这个变种不好。
我尝试使用以下规则:
private static readonly Parser<AstNode> InOperator =
from expr in Parse.Ref(() => Expression)
from inKeyword in Parse.IgnoreCase("in").Token()
from values in Parse
.Ref(() => Expression)
.DelimitedBy(Comma)
.Contained(OpenParenthesis, CloseParenthesis)
select new InOperator(expr, values);
private static readonly Parser<AstNode> IsNullOperator =
from expr in Parse.Ref(() => Expression)
from isNullKeyword in Parse
.IgnoreCase("is")
.Then(_ => Parse.WhiteSpace.AtLeastOnce())
.Then(_ => Parse.IgnoreCase("null"))
select new IsNullOperator(expr);
private static readonly Parser<AstNode> Equality =
Parse
.ChainOperator(Eq, IsNullOperator.Or(InOperator).Or(Additive), MakeBinary);
它会抛出ParseException
类似ScriptParser.ParseExpression("1 is null")
or的代码ScriptParser.ParseExpression("1 in (1, 2, 3)"): "Parsing failure: Left recursion in the grammar."
。
我如何预测表达式,或者是否存在其他变体来解决这个问题?