簡體   English   中英

讓 Bison 接受替代的 EOF 令牌

[英]Make Bison accept an alternative EOF token

我正在用 flex 和 bison 用 C++ 編寫 ansi-C 解析器; 這很復雜。

我遇到的問題是編譯錯誤。 錯誤如下,這是因為yy_terminate返回YY_NULL定義為(一個 int) 0並且yylex的返回類型為yy::AnsiCParser::symbol_type yy_terminate(); 是由 flex 生成的掃描器中<<EOF>>令牌的自動操作。 顯然,這會導致類型問題。

我的掃描器不會為 EOF 生成任何特殊標記,因為 EOF 在 C 語法中沒有用途。 我可以為<<EOF>>創建一個令牌規則,但是如果我忽略它,那么掃描儀會在YY_STATE_EOF(INITIAL)情況下的yylex無限循環。

編譯錯誤,

ansi-c.yy.cc: In function ‘yy::AnsiCParser::symbol_type yylex(AnsiCDriver&)’:
ansi-c.yy.cc:145:17: error: could not convert ‘0’ from ‘int’ to ‘yy::AnsiCParser::symbol_type {aka yy::AnsiCParser::basic_symbol<yy::AnsiCParser::by_type>}’
ansi-c.yy.cc:938:30: note: in expansion of macro ‘YY_NULL’
ansi-c.yy.cc:1583:2: note: in expansion of macro ‘yyterminate’

此外,Bison 為我的開始規則 (translation_unit) 和 EOF ($end) 生成此規則。

$accept: translation_unit $end

所以yylex必須為 EOF 返回一些東西,否則解析器永遠不會停止等待輸入,但我的語法不能支持 EOF 標記。 有沒有辦法讓 Bison 在不修改我的語法的情況下識別$end條件的0東西?

或者,是否可以從掃描儀中的<<EOF>>令牌返回一些內容以滿足 Bison $end條件?

通常,您不會在詞法分析器中包含顯式 EOF 規則,不是因為它沒有任何用途,而是因為默認值正是您想要做的。 (它的作用是表明輸入是完整的;否則,解析器將接受某些無效程序的有效前綴。)

不幸的是,C++ 接口可能會破壞默認 EOF 操作的簡單便利性,即返回 0(或 NULL)。 我從你的問題描述中假設你已經要求 bison 使用完整的符號生成解析器。 在這種情況下,您不能簡單地從yylex返回 0,因為解析器需要一個完整的符號,這是一個比int更復雜的類型(盡管報告 EOF 的標記通常沒有語義值,但它確實有一個位置,如果您正在使用位置。)對於其他令牌類型,bison 將自動生成一個函數,該函數生成一個令牌,命名為make_FOO_TOKEN ,您將在掃描儀操作中調用FOO_TOKEN

雖然 C bison 解析器會自動定義文件結尾標記(稱為END ),但 C++ 接口似乎沒有。 所以你需要在你的野牛輸入文件的%token聲明中手動定義它:

%token END 0 "end of file"

(這定義了帶有整數值 0 和人類可讀標簽“文件結尾”的令牌類型END 。值 0 是強制性的。)

完成后,您可以在 flex 輸入文件中添加顯式 EOF 規則:

<<EOF>> return make_END();

如果您使用位置,則還必須給make_END一個位置參數。

這是防止編譯器錯誤的另一種方法could not convert 0 from int to ...symbol_type - 將yyterminate宏的重新定義YY_DECL重新定義YY_DECL

// change curLocation to the name of the location object used in yylex
// qualify symbol_type with the bison namespace used
#define yyterminate() return symbol_type(YY_NULL, curLocation)

啟用野牛位置時會出現編譯器錯誤,例如使用%define locations - 這使得野牛向其symbol_type構造函數添加location參數,因此沒有位置的構造函數

symbol_type(int tok)

變成這個位置

symbol_type(int tok, location_type l)

渲染不再可能將int轉換為symbol_type ,這是未啟用野牛位置時 flex 中yyterminate的默認定義能夠執行的操作

#define yyterminate() return YY_NULL

使用此解決方法,如果您不需要,則無需在 flex 中處理EOF如果您不需要,則不需要在野牛中使用多余的END令牌

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM