最小语法复制:
grammar GeneralSearchQuery;
id : ID;
ID : ('A'[A-Z0-9]+);
anystring: ANYSTRING;
ANYSTRING: ~[ trn"\'():^]+;
问题与"任何弦"规则。如果我删除任何ID/ID规则,那么奇怪的解析就会消失。
目的是匹配 nything (unicode,non-nicode),除了某些具有含义的字符。
据我了解,这就是它的分解方式:
~ 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
。
关于我可能缺少什么的想法?
在词汇分析阶段,该输入将根据语法中的词汇规则分为令牌。此阶段不受解析器规则中发生的任何事情的影响。也就是说,无论解析器的功能如何,lexer始终将与给定输入相同的令牌序列。
因此,要查看为给定输入生成哪个令牌序列,我们只需要查看您的语法中定义的词汇规则,其中您有两个:
ID : ('A'[A-Z0-9]+);
ANYSTRING: ~[ trn"\'():^]+;
现在,这两个规则显然重叠:ID
可以匹配的任何东西也可以与ANYSTRING
匹配。在这种情况下,最大的蒙克规则适用,其中说:
- 如果多个规则可以产生匹配项,则使用较长匹配的规则
- 如果多个规则产生相同长度的匹配,则使用语法中的第一个规则。
因此,由于这些规则,任何以A
开头的输入,不包含只能由ANYSTRING
匹配的任何字符,都会产生ID
令牌。
如果您希望anystring
规则也匹配有效标识符,则需要将其定义为:
anystring: ID | ANYSTRING;