Antlr 错误的AST选择
给定以下ANTLR v3语法:Antlr 错误的AST选择,antlr,antlr3,Antlr,Antlr3,给定以下ANTLR v3语法: tokens { OPTION; UNKNOWN; } statement : my_statement | UNKNOWN_KEYWORD -> ^(UNKNOWN) ; my_statement : FIRST SECOND type = THIRD? -> ^(OPTION $type?); FIRST : 'my'; SECOND : 'keyword'; THIRD: 'best
tokens
{
OPTION;
UNKNOWN;
}
statement : my_statement
| UNKNOWN_KEYWORD -> ^(UNKNOWN)
;
my_statement : FIRST SECOND type = THIRD? -> ^(OPTION $type?);
FIRST : 'my';
SECOND : 'keyword';
THIRD: 'best';
UNKNOWN_KEYWORD : .;
为什么在解析字符串“my keyword this_is_garbage”时,它由my_语句提取,而它本应由UNKNOWN_关键字提取(即返回的AST为^(选项$type?),而它本应为^(未知))?输入
我的关键字this_is_garbage
将标记如下(假设空间是隐藏的):
即,一个第一个
令牌,一个第二个
令牌,然后是15个未知关键字
令牌
如果您现在尝试匹配语句
,则规则my_语句
将乐意使用第一个
和第二个
令牌,将15个未知关键字
令牌留在令牌流中
但是,如果您重复匹配您的语句
规则,如下所示:
parse
: statement+ EOF
;
然后,您将得到以下解析树:
或者这个AST:
如果您想将所有UNKNOWN_关键字
token分组到一个备选方案中,您需要执行以下操作:
statement : my_statement
| UNKNOWN_KEYWORD+ -> ^(UNKNOWN)
;
请注意,不能在lexer中对未知\u关键字进行分组
:
UNKNOWN_KEYWORD : .+ ;
因为这将导致lexer将整个字符流吞噬为一个单独的
未知\u关键字
标记。输入的我的关键字this\u is\u垃圾
将按如下方式标记(假设空格隐藏):
即,一个第一个
令牌,一个第二个
令牌,然后是15个未知关键字
令牌
如果您现在尝试匹配语句
,则规则my_语句
将乐意使用第一个
和第二个
令牌,将15个未知关键字
令牌留在令牌流中
但是,如果您重复匹配您的语句
规则,如下所示:
parse
: statement+ EOF
;
然后,您将得到以下解析树:
或者这个AST:
如果您想将所有UNKNOWN_关键字
token分组到一个备选方案中,您需要执行以下操作:
statement : my_statement
| UNKNOWN_KEYWORD+ -> ^(UNKNOWN)
;
请注意,不能在lexer中对未知\u关键字进行分组
:
UNKNOWN_KEYWORD : .+ ;
因为这将导致lexer将整个字符流吞并为一个单独的
未知\u关键字标记。第三个在解析器规则中是可选的,因此该规则匹配我的关键字
很好,甚至没有前进到这\u是\u垃圾。是的,它不会匹配我的\u关键字,但不会重新搜索rn AST^(未知),这是我们所期望的。如何修复语法,使其返回此AST?您看到的行为正是我从该语法中所期望的:)好吧,假设UNKNOWN\u关键字
是在某个地方定义的(UNKNOWN
是单个字符)my_语句
匹配,因此语句
的第二个分支甚至没有尝试。第三个
在解析器规则中是可选的,因此该规则匹配了my关键字
很好,甚至没有前进到this_is_garbage
。是的,它不会匹配my_关键字,但不会返回AST^(未知),这正是我们所期望的。语法如何被修正以返回此AST?您看到的行为正是我从该语法中所期望的:)好吧,假设UNKNOWN\u关键字
是在某个地方定义的(UNKNOWN
是单个字符)my_语句
匹配,因此,语句
的第二个分支甚至没有尝试过。您还应该在这里添加未知的_关键字应该是一个。*循环,而不仅仅是一个字符,以匹配预期的行为。是的,但您可能指的是+
。是的,加号是正确的。但您对该循环的添加不是:-)UNKNOWN_关键字只会在之前没有其他规则匹配的情况下吃掉所有内容。在语法的末尾有一个全包规则是完全可以的。@MikeLischke,不,我说过你不能有一个只有+
的lexer规则,我不是说你不能有一个lexer规则,它使用(一个)
匹配一个字符。你还应该在这里添加未知的\u关键字应该是一个。*循环,而不仅仅是一个字符,匹配预期行为。是的,但你可能是指+
。没错,加号是正确的。但您对该循环的添加不是:-)UNKNOWN_关键字只会在之前没有其他规则匹配的情况下吃掉所有内容。在语法的末尾有一个通配符规则是完全可以的。@MikeLischke,不,我说你不能有一个只有+
的词法规则,我不是说你不能有一个使用(单个)匹配单个字符的词法规则