antlr4 - 任何文本和关键字



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

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
            ;

这似乎行不通。例如,输入SELECT a[hello world!]给出以下错误:

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

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

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

[1] 与最长可能字符串匹配的词法分析器规则具有优先级。

正如您提到的,上面的 ANY 令牌规则与"select a"匹配,这比(隐式)令牌规则"select"匹配的要长,因此具有优先级。非贪婪行为用问号表示。

ANYTHING    : (~(']' | '['))+?

只是让 ANYTHING 规则不贪婪并不能完全解决您的问题,因为在正确匹配"选择"之后,词法分析器将为空间生成一个 ANYTHING 令牌,因为......

[2] 首先出现的词法分析规则具有优先权。

切换词法分析器规则WHITE_SPACE和任何东西都可以解决这个问题。下面的语法应该解析您的示例。

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 岛语法

"希望这有帮助!

相关内容

  • 没有找到相关文章

最新更新