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 能夠正確地生成解析器程式碼。