Java antlr4-任何文本和关键字

Java antlr4-任何文本和关键字,java,antlr,antlr4,Java,Antlr,Antlr4,我正在尝试分析以下内容: SELECT name-of-key[random text] 这是我试图构建的更大语法的一部分。为了清楚起见,我把它留下了 我提出了以下规则: select : 'select' NAME '[' anything ']' ; anything : (ANYTHING | NAME)+ ; NAME : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_

我正在尝试分析以下内容:

SELECT name-of-key[random text]
这是我试图构建的更大语法的一部分。为了清楚起见,我把它留下了

我提出了以下规则:

select      : 'select' NAME '[' anything ']'
            ;
anything    : (ANYTHING | NAME)+
            ;

NAME        : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_')+
            ;
ANYTHING    : (~(']' | '['))+
            ;
WHITESPACE  : ('\t' | ' ' | '\r' | '\n')+ -> skip
            ;
这似乎不起作用。例如,输入
选择[hello world!]
会出现以下错误:

line 1:0 mismatched input 'SELECT a' expecting 'SELECT'

这是错误的,因为输入的
SELECT a
ANYTHING
识别,而不是
SELECT
。我该如何解决这个问题?我觉得这里缺少了一些概念,但很难开始。

也许您缺少的概念是规则优先级

[1] 匹配最长字符串的Lexer规则具有优先级

正如您所提到的,上面的anywhere标记规则与“select a”匹配,后者比(隐式)标记规则“select”匹配的长度长,因此其优先级较高。非贪婪行为用问号表示

ANYTHING    : (~(']' | '['))+?
不过,仅仅使ANYTHING规则非贪婪并不能完全解决您的问题,因为在正确匹配“select”之后,lexer将为空间生成一个ANYTHING标记,因为

[2] 首先出现的Lexer规则具有优先级

切换lexer规则的空白和任何修复这一点。下面的语法应该分析您的示例

select      : 'select' NAME '[' anything ']'
            ;
anything    : (ANYTHING | NAME)+
            ;

NAME        : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_')+
            ;
WHITESPACE  : ('\t' | ' ' | '\r' | '\n')+ -> skip
            ;
ANYTHING    : (~(']' | '['))+?
            ;
我个人避免使用隐式标记规则,尤其是在语法复杂的情况下,这正是因为标记规则的优先级。因此,我要写这篇文章

SELECT      : 'select' ;
L_BRACKET   : '[';
R_BRACKET   : ']';

NAME        : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_')+ ;
WHITESPACE  : ('\t' | ' ' | '\r' | '\n')+ -> skip ;
ANY         : . ;

select      : SELECT NAME L_BRACKET anything R_BRACKET ;
anything    : (~R_BRACKET)+ ;
还请注意,“hello world”中的空格将被空格规则吞没。要正确管理这一点,您需要ANTLR岛语法


“希望这有帮助

你到底想干什么?非常感谢!我在这里学到了很多。我实际上并没有真正考虑规则的优先性。我换了语法,现在很好用。我在这里进步了很多。非常感谢。顺便说一句我试图对你的答案投赞成票,但我的声望还不够。等我拿到它们以后再做。