【问题标题】:How to get the AST from YACC?如何从 YACC 获取 AST?
【发布时间】:2011-08-04 05:08:43
【问题描述】:

我知道如何让 YACC 生成一个 AST,但是你是怎么得到它的呢?我的意思是,你如何从 YACC 中获取根节点的值?

【问题讨论】:

  • 你们似乎都不明白我的问题。 我实际上从哪里获得根非终结符的语义值?

标签: c++ c parsing yacc bison


【解决方案1】:

Yacc 一次只给你一个节点,它总是是你在早些时候给 yacc 的东西,即你想从减少的生产中返回的任何东西,或者你想要的任何东西从终端符号返回。 (抱歉,你说你知道,但有些人可能不知道。)

所以,把你想从根或顶级规则返回的任何内容,并以你喜欢的任何方式保存(在你附加的 C 简化代码中)。

【讨论】:

  • 我究竟该如何接受最高规则返回的内容?这就是我的全部问题!
  • 很简单,就像这样:toprule: expression_list { some_global = whatever_you_were_going_to_return }; 换句话说,你只需写 { globalsym = e; } 而不是 { $$ = e; }
  • 嗯,这不是线程安全的。你能想出一个线程安全的解决方案吗? PS:我在野牛中使用push pure parser。
【解决方案2】:

Yacc 为您提供的是解析树,它与 AST 不同。在遍历解析树的每个节点(通过 yacc)时,您需要自己构建 AST。

【讨论】:

  • 这是什么意思,与我的问题有什么关系?
  • AST 与解析树根本不同。解析树仍然包含树中的语法信息,而 AST 没有它们。 Yacc 不给你一个 AST,它只给你一个解析树。您可以从 Wikipedia 中了解它们的不同之处。因此,您的 q 的答案是,您无法从 yacc 获得它。您必须定义自己的 AST 节点并从解析树构造它。
  • 向我解释 yacc 如何在此处生成 AST:pastebin.com/SBfbMXNB
  • 哦,这显然是一个误解,我的错。所以看起来问题实际上是关于与 C++ 中的 yacc 和 lex 接口。对于这种情况,我的头上没有答案,对不起=(。我能做的最好的就是从这里向您展示一些示例(如果您使用的是野牛)en.wikipedia.org/wiki/GNU_bison。还阅读官方手册如:gnu.org/software/bison/manual/….
【解决方案3】:

我就是这样做的:

在 yacc 文件 (your_grammar.y) 中:

%parse-param {AstNode **pproot}
%parse-param {char **errmsg}

在调用程序(your_program.c)中:

res = yyparse(&pAst, &errmsg);

AST 节点在 yyparse() 中被分配和链接为树(你自己做逻辑),根节点的地址在 pAst 指针中传回。

【讨论】:

    【解决方案4】:

    它不像让解析器直接返回一个 AST 那样优雅,但我想出的最好的方法是拥有一个全局数据结构(例如向量或链表),以及线程安全的插入方法如果需要线程安全,并让顶级 yacc 规则将其结果(又名$$)添加到该数据结构。然后您可以在其他功能中访问此结果。当然,如果您只想输出一个 AST,可能只需要一个指向该 AST 的全局指针,而不是一个充满它们的数据结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 2016-10-20
      • 2021-03-20
      相关资源
      最近更新 更多