我想匹配以下文本: test.define_shared_constant(:testConst,"12",false)
通过这种语法,它可以正确地匹配:
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)*')'
;与这种语法不匹配。它与method_call匹配,这甚至是不正确的。
shared_constant_defioniton
: ID('.' DEF_SHARED_CONSTANT '(' KEY ',' expr ',' (BOOLEAN) ')')
;它将'define_shared_constant‘解释为ID,所以我必须指定ID不应该包含'define_’。但我怎么能做到呢?
发布于 2020-05-02 19:45:19
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_SHARED_CONSTANT都可以匹配输入define_shared_constant。在这种情况下,多个规则可以匹配并产生相同长度的匹配,首先定义的规则将获胜。因此,defined_shared_constant被识别为ID令牌,因为ID是首先定义的。
要获得您想要的行为,您应该在DEF_SHARED_CONSTANT的定义之前移动ID的定义。如果您根本没有为它定义一个命名的lexer规则,而是在解析器规则中直接使用'define_shared_constant',这也有效,因为隐式定义的lexer规则的作用就好像它们是在文件开始时定义的一样。
发布于 2020-05-03 07:25:36
这是根据ANTLR规范工作的。但是,将其作为IntelliJ语言插件运行并没有实现。我使用了一个谓词,最后的解决方案如下所示:
ID: { getText().indexOf("define") == 0}? ('a'..'z'|'A'..'Z'|'!') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'!'|'?')*;https://stackoverflow.com/questions/61556264
复制相似问题