我想在我的Flex解析C風格的多行註釋(.L)文件:爲什麼flex/bison中的多行註釋如此迴避?
%s ML_COMMENT
%%
...
<INITIAL>"/*" BEGIN(ML_COMMENT);
<ML_COMMENT>"*/" BEGIN(INITIAL);
<ML_COMMENT>[.\n]+ { }
我不返回任何令牌和我的語法(.Y)沒有解決意見以任何方式。
當我運行我的可執行文件,我得到一個解析錯誤:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
(我的yyerror函數做一個printf(「解析錯誤:%s \ n」),這是其中的第一個半多餘的錯誤信息來自)。
我可以看到爲什麼第二個示例失敗,因爲整個輸入是註釋,並且由於語法忽略了註釋,所以沒有語句。因此輸入不是一個有效的程序。但是,第一部分在我完成評論之前拋出了一個解析錯誤。
另外混亂:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
在這種情況下,註釋之前實際有效的輸入(其沒有評論,解析就好)關閉。在解析「a」之後實際發生失敗,而不是在嘗試解析賦值「a = b;」之後發生。如果我自己輸入「a」,它仍然會報錯。
鑑於錯誤消息是一個解析器錯誤,而不是掃描儀錯誤,是否有什麼關鍵我在我的.y文件中缺少?或者我在掃描器規則中做錯了什麼,傳播到解析器端?
編輯:每@魯迪的建議下,我打開調試,發現:
$ ./a.out
Starting parse
Entering state 0
Reading a token: /*
foo
Next token is 44 (IDENTIFER)
Shifting token 44 (IDENTIFER), Entering state 4
Reducing via rule 5 (line 130), IDENTIFER -> identifier
state stack now 0
Entering state 5
我關掉調試,發現確實/* foo */ = bar;
解析一樣foo = bar;
。我使用的是flex 2.5.4;它並沒有給我任何關於我試圖使用的有狀態規則的警告。
我重新標記彎曲以GNU-FLEX。您的掃描儀規則看起來沒問題。解析錯誤指示解析器的無效令牌輸入。你可能想發佈一些相應的Bison規則。此外,它可能是一個好主意,把printf()的報表您的野牛規則裏面,這樣你可以看到什麼樣的規則令牌的掃描過程中解析器嘗試。 – Kizaru 2010-11-10 14:40:24
爲您的掃描儀創建單獨的測試工具也是一個好主意。這樣您就可以將掃描儀缺陷與解析器缺陷隔離開來。任何掃描分析器系統是複雜的,以至於當你添加了'--debug'標誌的野牛,你不需要通過執行集成測試,當你真正想要的是要進行單元測試...... – bstpierre 2010-11-10 15:11:51
注入額外的複雜性調用並設置'YYDEBUG = 1'的'yyparse()'呼叫之前,則解析器發出調試信息爲每一個令牌從詞法分析器看到。 – Rudi 2010-11-10 15:14:41