ANTLR4解析树简化

sol*_*xel 2 antlr antlr4

有没有办法让ANTLR4自动删除生成的解析树中的冗余节点?

更具体地说,我一直在试验GLSL的语法,并且由于规则转发需要自动处理运算符优先级,因此在解析树中最终会出现长线性的"表达式"序列.

大多数生成的树节点只是"转发到下一级优先级",因此不提供任何有用的语法信息 - 您只需要每个序列中的最后一个表达式节点(即规则转发停止的点)或者它成为具有多个子节点的实际树节点的点(即在源中遇到实际表达式)...

我希望有一种简单的方法来消除虚拟中间表达式节点 - 这种类型的结构必须在具有运算符优先级的任何语法中都是通用的.

语法的基本结构是从Khronos语言规范中获得的相当直接的克隆:

https://www.khronos.org/registry/gles/specs/3.1/es_spec_3.1.pdf

Luc*_*ski 6

如果您使用这样的语法(基本数学示例),ANTLR v4能够从处理不同优先级的单个递归规则生成代码:

expr : '(' expr ')'
     | '-' expr
     | expr ('*'|'/') expr
     | expr ('+'|'-') expr
     | INT
     ;
Run Code Online (Sandbox Code Playgroud)

ANTLR v3无法执行此操作,并且基本上要求您按优先级编写一个规则.所以我建议你重写你的语法以避免这些样板规则.

然后,我认为你把解析树(也就是具体的语法树)AST(抽象语法树)混淆了.AST就像解析树的简化版本,只保留了您的目的所需的内容.例如,根据上述expr规则,AST不包含括号的任何节点,因为优先级在树本身中编码,并且您通常不需要知道给定表达式的一部分是否带括号.

你的程序应该从解析树构建一个AST,然后从那里开始.不要直接处理解析树,即使它看起来很方便,因为该工具会为您生成它们.它会很快变得麻烦.构建您自己的树结构(AST),为手头的任务量身定制.