我正在爬Nearley学习曲线,并尝试为搜索查询解析器编写语法。
我想编写一种语法,该语法能够解析包含布尔运算符(例如AND
,OR
,NOT
)的查询字符串。让我们将AND
用作小问题。
例如,语法应将这些示例字符串识别为有效:
我的幼稚尝试看起来像这样:
query ->
statement
| statement "AND" statement
statement -> .:+
上面的语法尝试是模棱两可的,因为.:+
实际上会匹配任何字符串。我真正想要的是第一个条件,以匹配其中不包含AND
的任何字符串。一旦出现“ AND”,我只想输入第二个条件。
如何在没有模棱两可的语法的情况下检测这两种不同的情况?
我担心我缺少基本的东西;我可以想象大量的用例,其中我们希望由已知运算符分割任意文本。
是的,如果您有逃生舱口,实际上可能是任何东西,那么您就会遇到问题。
您将要在某处定义令牌的基本集合是什么,至少要定义\S+
之类的东西,然后定义这些令牌的组成方式。
我通常开始使用解析器的位置试图找出解析器中递归的位置,以及采用哪种解析您依赖的库的方法。
看起来像Nearley是Earley解析器,并且是the wikipedia entry for them notes, they're efficient for left-recursion。
这只是在猜测,但是这样的事情至少会使您结识。
CONJUNCTION -> AND | OR
STATEMENT -> TOKENS | (STATEMENT CONJUNCTION STATEMENT)
TOKENS -> [^()]+
这样的结构应该是明确的,并禁止标记中的括号,除非它们用双引号引起来。