要重现的最小语法:
grammar GeneralSearchQuery;
id : ID;
ID : ('A'[A-Z0-9]+);
anystring: ANYSTRING;
ANYSTRING: ~[ \t\r\n"\\'():^]+;
问题出在“ anystring”规则上。如果我删除任何ID / ID规则,那么奇怪的解析就会消失。
目的是匹配任何(unicode,非unicode),但某些具有含义的字符除外。
据我了解,这就是它的分解方式:
~ Negate the following pattern
[ Start of a matching group
Match a literal space
\t Tab character
\r Newline character
\n Newline character
" Double quote character
\\ backslash character
' Single quote character
( Left parenthesis
) Right parenthesis
: Colon character
^ Caret character
] End of a matching group
+ Match the preceeding one or more times
A - match
AA - no match (BAD!)
ASDF - no match (BAD!)
SDF - match
Asdf - match
如此看来,任何以大写字母A开头并以任何其他大写字母开头的字符串都无法解析。似乎正在将规则更改为NOT match id
。
关于我可能会缺少的任何想法吗?
答案 0 :(得分:1)
在词法分析阶段,将根据语法中的词法规则将输入拆分为标记。此阶段不受解析器规则中发生的任何事情影响。也就是说,无论解析器执行什么操作或所需的令牌类型如何,词法分析器对于给定的输入将始终使用相同的令牌序列。
因此,要查看为给定输入生成的标记顺序,我们只需要查看语法中定义的词汇规则,其中就有两个:
ID : ('A'[A-Z0-9]+);
ANYSTRING: ~[ \t\r\n"\\'():^]+;
现在,这两个规则明显重叠:ID
可以匹配的任何内容,ANYSTRING
也可以匹配的任何内容。在这种情况下,将适用最大限制规则,即:
因此,根据这些规则,任何以A
开头且不包含只能由ANYSTRING
匹配的字符的输入都将产生ID
令牌。
如果您还希望anystring
规则也匹配有效的标识符,则需要将其定义为:
anystring: ID | ANYSTRING;