gpt4 book ai didi

java - antlr4 - 任何文本和关键字

转载 作者:行者123 更新时间:2023-12-02 00:59:41 31 4
gpt4 key购买 nike

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

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] Lexer 规则匹配最长的可能字符串具有优先权。

正如您所提到的,上面的 ANYTHING 标记规则匹配“select a”,它比(隐式)标记规则“select”匹配的长度长,因此具有优先级。非贪婪行为用问号表示。

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

仅仅使 ANYTHING 规则非贪婪并不能完全解决你的问题,因为在正确匹配“select”之后,词法分析器将为该空间生成一个 ANYTHING 标记,因为......

[2] Lexer 规则首先出现具有优先权。

切换词法分析器规则 WHITE_SPACE 和 ANYTHING 可以修复此问题。下面的语法应该解析您的示例。

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”中的空格将被 WHITESPACE 规则吞没。为了正确管理这个,您需要 ANTLR岛语法

“希望这有帮助!

关于java - antlr4 - 任何文本和关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28322957/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com