gpt4 book ai didi

parsing - ANTLR AST 规则因 RewriteEmptyStreamException 而失败

转载 作者:行者123 更新时间:2023-12-04 05:27:25 26 4
gpt4 key购买 nike

我有一个简单的语法:

grammar sample;
options { output = AST; }
assignment
: IDENT ':=' expr ';'
;
expr
: factor ('*' factor)*
;
factor
: primary ('+' primary)*
;
primary
: NUM
| '(' expr ')'
;
IDENT : ('a'..'z')+ ;
NUM : ('0'..'9')+ ;
WS : (' '|'\n'|'\t'|'\r')+ {$channel=HIDDEN;} ;

现在我想添加一些重写规则来生成 AST。根据我在网上和语言模式书中的阅读,我应该能够像这样修改语法:
assignment
: IDENT ':=' expr ';' -> ^(':=' IDENT expr)
;
expr
: factor ('*' factor)* -> ^('*' factor+)
;
factor
: primary ('+' primary)* -> ^('+' primary+)
;
primary
: NUM
| '(' expr ')' -> ^(expr)
;

但它不起作用。虽然它编译得很好,但当我运行解析器时,我收到了 RewriteEmptyStreamException 错误。这就是事情变得奇怪的地方。

如果我定义伪标记 ADD 和 MULT 并使用它们而不是树节点文字,则它可以正常工作。
tokens { ADD; MULT; }

expr
: factor ('*' factor)* -> ^(MULT factor+)
;
factor
: primary ('+' primary)* -> ^(ADD primary+)
;

或者,如果我使用节点后缀表示法,它似乎也能正常工作:
expr    
: factor ('*'^ factor)*
;
factor
: primary ('+'^ primary)*
;

这种行为差异是错误吗?

最佳答案

不,不是错误,AFAIK。带上您的 expr规则例如:

expr    
: factor ('*' factor)* -> ^('*' factor+)
;

*可能不存在,它也不应该出现在您的 AST 重写规则中。所以,以上是不正确的,ANTLR 提示它是正确的。

现在,如果您插入一个假想的标记,如 MULT反而:
expr    
: factor ('*' factor)* -> ^(MULT factor+)
;

一切正常,因为您的规则总是会产生一个或多个 factor的。

你可能想要做的是这样的:
expr    
: (factor -> factor) ('*' f=factor -> ^('*' $expr $f))*
;

另请参阅第 7 章:来自 The Definitive ANTLR Reference 的树构建.特别是段落 重写子规则中的规则 (第 173 页)和 在重写规则中引用以前的规则 AST (第 174/175 页)。

关于parsing - ANTLR AST 规则因 RewriteEmptyStreamException 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2710528/

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