当前位置: 首页 > 知识库问答 >
问题:

ANTLR4解析树简化

孔阳平
2023-03-14

有什么方法可以让ANTLR4自动删除生成的解析树中的冗余节点吗?

更具体地说,我一直在试验GLSL的语法,由于自动处理操作符优先级所需的规则转发,您最终会在解析树中看到长的线性“表达式”序列。

大多数生成的树节点都只是简单地“转发到下一个优先级”,所以不要提供任何有用的语法信息--你只需要每个序列中最后一个表达式节点(即规则转发停止的点),或者它成为一个实际的树节点并拥有多个子节点的点(即在源中遇到了一个实际的表达式)……

我希望有一种简单的方法来消除虚拟的中间表达式节点--这种类型的结构在任何具有操作符优先级的语法中都是常见的。

语法的基本结构是一个相当直接的克隆,取自该语言的Khronos规范:

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

共有1个答案

古彦
2023-03-14

如果您使用下面这样的语法(basic math的示例),ANTLRV4能够从处理不同优先级的单个递归规则生成代码

expr : '(' expr ')'
     | '-' expr
     | expr ('*'|'/') expr
     | expr ('+'|'-') expr
     | INT
     ;

ANTLRV3无法这样做,基本上要求您为每个优先级编写一个规则。所以我建议你重写你的语法,以避免这些样板规则。

然后,我认为您混淆了解析树(又名具体语法树)和AST(抽象语法树)。AST就像解析树的简化版本,它只保留您需要的内容。例如,使用上面的expr规则,AST将不包含任何用于括号的节点,因为优先级是在树本身中编码的,您通常不需要知道给定表达式的一部分是否带括号。

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

 类似资料:
  • 我所开发的ANTR4语法。在解析字符串期间 时间;25 10 * * *;' faccalc_minus1_cron.out.'yyyyMMdd。嗯;美国/New_York 我有以下错误 表达式中的字符无效!表达式:;'无效字符:;'无关输入“;”应为{“”,整数,“-”,“/”,“,”},缺少“;”“\uu”处的时区格式不正确:faccalc\u minus1 我不理解为什么,因为正则表达式规则

  • 我有一个语法,当解析在一次传递(整个文件)很好。 现在我希望将解析分解成组件。并在子库上运行解析器。我遇到了一个问题,我假设其他解析子库的人会看到下面的规则: 当上面的规则从一个顶级的开始规则解析到EOF时,一切都很好。当解析为子规则(而不是解析为EOF)时,解析器在没有thing子句时会感到不安,因为它希望看到“,”字符或EOF字符。 第8行:0不匹配的输入“%”应为{,“,”} 当我解析到EO

  • 我试图以C#为目标,使用Antlr4解析一个日期。在我的情况下,有效日期应具有以下内容 采用格式 年份只能有4位数字 月和日只能有2位 我知道类似的问题已经出现了,但它们的解决方案似乎对我不起作用 如何创建将解析日期的antlr4语法 ANTLR:识别日期和数字的最简单方法? 我在某个地方读到过,有一种类似优先级的解析,其中基于语法文件如何编写的顶级规则首先被评估。因此,考虑一下,除了日期,我的语

  • 我试图使用ANTLR4在golang创建一个javascript解析器。我使用的语法是这样的(https://github.com/antlr/grammars-v4/tree/master/javascript/ecmascript),我遵循自述文件https://github.com/antlr/antlr4/blob/master/doc/go-target.md中的说明 因此,我从语法中生

  • 在我刚刚编写的一个测试解析器中,我遇到了一个奇怪的问题,我不太明白。 将其简化为显示问题的最小示例,让我们从以下语法开始: 这是语法的变化: 突然间,相同的测试输入被错误地分解成两个statement_list,每个statement_list都继续到一个带有“missing”;“警告,第一个返回“z=”的不完整的assignment_statement,第二个返回“x+”的不完整的assignm

  • 我正在尝试使用antlr4版本4.4和python2运行时。语法来自antlr4书,第6页,文件:Hello. g4: 我用命令生成lexer和parser 然后生成文件HelloLexer.py、HelloParser.py和HelloListener.py。我做了一个主程序test.py来测试生成的python解析器: 一切似乎都正常,只是我无法打印解析树。 我还没弄明白问题出在哪里。