在 Bison 中创建 AST
AST creation in Bison
我正在尝试使用 Bison 和 C 创建脚本语言,我想知道我是否以正确的方式构建 AST。这是我要创建的树:
+
└─ Steps
└─ Step 1
└─ Step 2
...
└─ Step n
如果不清楚,我想要一个包含 n 个步骤的节点。我现在的语法如下所示:
Steps: { $$ = create_steps(); }
| Steps Step
;
Step:
IDENTIFIER StepBody { $$ = create_step(); }
其中 StepBody 被解析为一个节点,就像我期望的那样。在我的代码中,我正在为 create_steps();
中要进入的步骤创建一个链接列表,但这似乎不是执行此操作的最佳方法。
我想我应该有一个 create_steps(node *inner_node);
函数,它获取所有 Step
处理函数的输出并将它们添加到数组中,但我不明白如何实现这一点.
最初,我在 Bison 中 Steps
设置如下:
Steps:
| Steps Step { $$ = create_steps($Step); }
;
当然,每次发现 Step
时都会调用 create_steps
,这不是我想要的。另外,我收到了 "empty rule for typed nonterminal, and no action" 的警告,这可能不太好。
去掉Steps
中的空产生式(ε):
Steps: Step { $$ = create_steps(); }
| Steps Step { $$ = create_steps(); }
;
.. 然后 Step
被附加到你正在生长的树上。您甚至可以通过这种方式传递正在生长的树:
Steps: Step { $$ = create_steps(NIL, ); }
| Steps Step { $$ = create_steps(, ); }
;
这在编译(做列表)中很常见,它出现在大多数语法中。
我正在尝试使用 Bison 和 C 创建脚本语言,我想知道我是否以正确的方式构建 AST。这是我要创建的树:
+
└─ Steps
└─ Step 1
└─ Step 2
...
└─ Step n
如果不清楚,我想要一个包含 n 个步骤的节点。我现在的语法如下所示:
Steps: { $$ = create_steps(); }
| Steps Step
;
Step:
IDENTIFIER StepBody { $$ = create_step(); }
其中 StepBody 被解析为一个节点,就像我期望的那样。在我的代码中,我正在为 create_steps();
中要进入的步骤创建一个链接列表,但这似乎不是执行此操作的最佳方法。
我想我应该有一个 create_steps(node *inner_node);
函数,它获取所有 Step
处理函数的输出并将它们添加到数组中,但我不明白如何实现这一点.
最初,我在 Bison 中 Steps
设置如下:
Steps:
| Steps Step { $$ = create_steps($Step); }
;
当然,每次发现 Step
时都会调用 create_steps
,这不是我想要的。另外,我收到了 "empty rule for typed nonterminal, and no action" 的警告,这可能不太好。
去掉Steps
中的空产生式(ε):
Steps: Step { $$ = create_steps(); }
| Steps Step { $$ = create_steps(); }
;
.. 然后 Step
被附加到你正在生长的树上。您甚至可以通过这种方式传递正在生长的树:
Steps: Step { $$ = create_steps(NIL, ); }
| Steps Step { $$ = create_steps(, ); }
;
这在编译(做列表)中很常见,它出现在大多数语法中。