parsing - 如何解析依赖于父节点信息的子节点?

标签 parsing compiler-construction bison yacc

如果我像这样在 Yacc/Bison 中编写语法文件:

Module
    :ModuleName "=" Functions
      { $$ = Builder::concat($1, $2, ","); }

Functions
    :Functions Function
      { $$ = Builder::concat($1, $2, ","); }
    | Function
      { $$ = $1; }

Function
    : DEF ID ARGS BODY
      {
          /** Lacks module name to do name mangling for the function **/
          /** How can I obtain the "parent" node's module name here ?? **/
          module_name = ; //????

          $$ = Builder::def_function(module_name, $ID, $ARGS, $BODY); 
      }

这个解析器应该解析如下代码:

main_module:
    def funA (a,b,c) { ... }

在我的 AST 中,名称“funA”应重命名为 main_module.funA。但是当解析器处理 Function 节点时我无法获取模块的信息!

是否有任何 Yacc/Bison 工具可以帮助我处理这个问题,或者我应该改变我的解析风格以避免这种尴尬的情况?

最佳答案

有一个 bison 功能,但如 manual说,小心使用:

$N with N zero or negative is allowed for reference to tokens and groupings on the stack before those that match the current rule. This is a very risky practice, and to use it reliably you must be certain of the context in which the rule is applied. Here is a case in which you can use this reliably:

 foo:      expr bar '+' expr  { ... }
         | expr bar '-' expr  { ... }
         ;

 bar:      /* empty */
         { previous_expr = $0; }
         ;

As long as bar is used only in the fashion shown here, $0 always refers to the expr which precedes bar in the definition of foo.

更干净地说,您可以使用中间规则操作(在模块中)将模块名称推送到名称堆栈上(这必须是解析上下文的一部分)。然后,您将在规则末尾弹出堆栈。

有关中间规则操作的更多信息和示例,请参阅manual .

关于parsing - 如何解析依赖于父节点信息的子节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13532818/

相关文章:

java - 如何在 Java 源文件中获取给定行号的周围方法

javascript - 我有一个 JSON 响应,但无法解析它。需要帮助。没有 JQUERY 没有原型(prototype)。只是 JavaScript

c - 如何使用libc函数在c中模拟asm代码?

c - 是否有可能将类似 Lisp 的宏构建成命令式语言?

c++ - 我想在 C++ 项目中包含一种脚本语言。 Lua 与 Bison/Yacc

javascript - 如何在格式化文本上使用 .split

java - 从java中的wsdl读取复杂类型

javascript - 使用 Cakefile 编译 CoffeeScript

c - 字符串输入到 flex 词法分析器

parsing - 编写一个可在 8 位嵌入式系统上使用的解析器,例如 Flex/Bison