Antlr4 ANTLR:Lexer规则不匹配
我想匹配以下文本: 定义共享常数(:testConst,“12”,false) 使用此语法,它将正确匹配:Antlr4 ANTLR:Lexer规则不匹配,antlr4,Antlr4,我想匹配以下文本: 定义共享常数(:testConst,“12”,false) 使用此语法,它将正确匹配: grammar test; statement: shared_constant_defioniton | method_call; KEY: ':' ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'?'|'!'|'|'|'-'|'()')+; expr: STRING; STRING: '"' (~'"')* ('"' | NEWLINE) | '\'' (~'\''
grammar test;
statement: shared_constant_defioniton | method_call;
KEY: ':' ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'?'|'!'|'|'|'-'|'()')+;
expr: STRING;
STRING: '"' (~'"')* ('"' | NEWLINE) | '\'' (~'\'')* ('\'' | NEWLINE);
NEWLINE: '\r'? '\n' | '\r';
BOOLEAN: 'true' | 'false';
ID: ('a'..'z'|'A'..'Z'|'!') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'!'|'?')*;
WS : [ \t\n\r]+ -> channel(HIDDEN);
DEF_SHARED_CONSTANT: 'define_shared_constant';
shared_constant_defioniton
: ID('.define_shared_constant' '(' KEY ',' expr ',' (BOOLEAN) ')')
;
method_call
: ID '.' ID? '('expr*(',' expr)*')'
;
与此语法不匹配。它与甚至不正确的方法_调用相匹配
shared_constant_defioniton
: ID('.' DEF_SHARED_CONSTANT '(' KEY ',' expr ',' (BOOLEAN) ')')
;
它将“define_shared_constant”解释为ID。因此我必须指定ID不应包含“define_”。但是我怎么能做到呢
ID: ('a'..'z'|'A'..'Z'|'!') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'!'|'?')*;
WS : [ \t\n\r]+ -> channel(HIDDEN);
DEF_SHARED_CONSTANT: 'define_shared_constant';
这里,ID
和DEF_共享_常量
都可以匹配输入define_共享_常量
。在这样的情况下,如果多个规则可以匹配并产生相同长度的匹配,则首先定义的规则获胜。因此defined\u shared\u常量
被识别为ID
标记,因为ID
是首先定义的
要获得所需的行为,应将
DEF_SHARED_CONSTANT
的定义移到ID
的定义之前。如果您根本没有为它定义一个命名的lexer规则,而是直接在解析器规则中使用'define\u shared\u constant'
,这也是可行的,因为隐式定义的lexer规则就像是在文件开头定义的一样。这是根据ANTLR规范工作的。但作为IntelliJ语言插件运行它却没有。我使用了谓词,最终的解决方案如下所示:
ID: { getText().indexOf("define") == 0}? ('a'..'z'|'A'..'Z'|'!') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'!'|'?')*;
语法规则中有一个不匹配的单引号,应该是有效的——它不是有效的Antlr。请更正语法。请添加足够的语法,以便其他人可以复制您所描述的内容。如果语法不是几百行,只需添加整个语法。
define\u sharedConstant
无法与任何一个语法一起工作(甚至忽略第一个语法错误),因此我假设您的意思是define\u shared\u constant
。如果我填空的话,你的输入在第二个语法上可以很好地工作。因此,请发布一个正确复制问题的帖子。对不起,第一个语法中不匹配的单引号是一个拼写错误。('.'define_shared_constant'…和('.define_shared_constant'..)都可以工作。只要我将'define_shared_constant'移动到LEXER规则,它就会停止匹配。你可以省略大括号之间的规则,它的行为仍然相同。但是这里有完整的语法:没问题@user39558,谢谢你的更新。