Bison中百分号的作用
文件开头
在 Bison 中,百分号 %
是用于声明和指示 Bison 解析器行为的符号。你提到的代码片段中的 %code requires
和 %{ %}
是 Bison 特定的语法标记,用来包含 C++ 代码或指示特定的行为。
1. %code requires {}
- 作用:用于声明在解析器生成前必须包含的代码,通常是头文件的引用或前置声明。这部分代码会被放置在 Bison 自动生成的头文件中,确保其他文件或模块在包含这个头文件时也能获得这些定义。
- 你代码中的例子:
这部分代码将被放入到生成的头文件中,以便在解析器生成和编译时可以直接访问%code requires { #include <memory> #include <string> #include "BaseAST.hpp" }
std::string
、std::unique_ptr
以及你定义的BaseAST
类。
2. %{ %}
(C 代码块)
- 作用:用于包含需要嵌入在生成的解析器中的 C/C++ 代码。这部分代码通常被插入到生成的
.c
或.cpp
文件的最前面,常见用途是定义辅助函数、声明全局变量、引入所需的头文件等。 - 你代码中的例子:
这部分代码将被直接插入到生成的解析器的%{ #include <iostream> #include <memory> #include <string> #include <vector> #include "BaseAST.hpp" // 声明 lexer 函数和错误处理函数 int yylex(); void yyerror(std::unique_ptr<BaseAST> &ast, const char *s); using namespace std; %}
.cpp
文件中,确保解析器可以访问这些库和函数(如yylex
和yyerror
)。
3. 其他常见的 Bison 百分号指令
%token
:用于声明终结符。%type
:声明非终结符的类型。%start
:指定起始规则。%union
:声明用于存储语法树节点值的联合体。
总结
%code requires {}
:指定必须包含的代码,会被放入生成的头文件中。%{ %}
:包含的 C/C++ 代码,直接插入到生成的解析器实现文件中。
这些指令有助于管理代码的分工,让 Bison 的自动生成代码与手写代码合理地结合起来。
在 Bison 中,%%
也是一种特殊符号,用于划分Bison 文件中的不同部分。具体来说,Bison 文件由声明部分、规则部分和辅助代码部分组成,而 %%
用来将这些部分清晰地分隔开。
文件总览和主体
Bison 文件结构及 %%
的作用
1. 文件的基本结构
Bison 文件通常由三大部分组成:
- 声明部分:
在这一部分,我们定义终结符、非终结符及它们的数据类型。 - 规则部分:
定义语法规则,描述如何将输入转换为目标语法结构。 - 辅助代码部分:
包含 C/C++ 的实现代码,如错误处理函数等。
结构如下:
/* 声明部分 */
%{
// C/C++ 头文件和全局声明
%}
/* 定义终结符、非终结符和起始符 */
%token INTEGER
%start program
/* 规则部分 */
%%
program:
expr { std::cout << "Result: " << $1 << std::endl; }
;
expr:
INTEGER { $$ = $1; }
| expr '+' expr { $$ = $1 + $3; }
;
/* 辅助代码部分 */
%%
int yylex() {
// 词法分析器实现
}
void yyerror(const char *s) {
std::cerr << "Error: " << s << std::endl;
}
2. %%
的具体作用
-
第一个
%%
:
将声明部分与规则部分分隔开。声明部分通常包含%token
等定义语句,以及引入的 C/C++ 头文件。 -
第二个
%%
:
将规则部分与辅助代码部分分隔开。规则部分定义语法规则,辅助代码部分则包含辅助函数的实现,例如词法分析函数yylex
和错误处理函数yyerror
。
3. 你代码中的 %%
的作用
-
%%
前面的部分:这是语法规则的定义部分。你在这里定义了如何通过语法规则将输入解析为抽象语法树(AST)或其他结构。 -
%%
后面的部分:这是辅助代码部分,你在这里实现了函数,如yylex()
和yyerror()
。具体到你的例子,你可能在这个部分实现了 Bison 调用的错误处理函数:
void yyerror(std::unique_ptr<BaseAST> &ast, const char *s) {
std::cerr << "Error: " << s << std::endl;
}
yyerror
函数:这是 Bison 的标准错误处理接口。当解析过程中遇到语法错误时,Bison 会调用这个函数,并传入错误信息字符串s
。
4. 小结
%%
是 Bison 文件的分隔符,用于分割声明部分、规则部分和辅助代码部分。yyerror
是一个错误处理函数,用于报告解析过程中遇到的错误。- 你的代码结构大致如下:
- 声明部分(引入头文件、声明函数)。
- 规则部分(定义语法规则)。
- 辅助代码部分(定义
yyerror
和其他辅助函数)。
这些分隔符确保你的代码逻辑清晰,并让 Bison 能够正确地生成解析器代码。
标签:百分号,头文件,%%,声明,代码,Bison,部分,作用 From: https://www.cnblogs.com/smartljy/p/18506830