[英]Why are multi-line comments in flex/bison so evasive?
我正在嘗試在我的flex(.l)文件中解析C風格的多行注釋:
%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文件中是否存在一些至關重要的內容? 或者我在掃描器規則中做錯了什么傳播到解析器端?
編輯: Per @Rudi的建議,我打開調試,發現:
$ ./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; 它沒有給我任何關於我試圖使用的有狀態規則的警告。
以這種方式解析注釋可能會導致錯誤,因為:
在我的解析器中,我處理這樣的評論。 首先為注釋的開頭定義lex規則,如下所示:
\/\* {
if (!SkipComment())
return(-1);
}
\/\/ {
if (!SkipLine())
return(-1);
}
然后編寫SkipComment和SkipLine函數。 他們需要消耗所有輸入,直到找到注釋的結尾(這是相當古老的代碼,所以請原諒我有些過時的結構):
bool SkipComment (void)
{
int Key;
Key=!EOF;
while (true)
{
if (Key==EOF)
{
/* yyerror("Unexpected EOF within comment."); */
break;
}
switch ((char)Key)
{
case '*' :
Key=input();
if (char)Key=='/') return true;
else continue;
break;
case '\n' :
++LineNr;
break;
}
Key=input();
}
return false;
}
bool SkipLine (void)
{
int Key;
Key=!EOF;
while (true)
{
if (Key==EOF)
return true;
switch ((char)Key)
{
case '\n' :
unput('\n');
return true;
break;
}
Key=input();
}
return false;
}
我認為您需要將ML_COMMENT啟動條件聲明為獨占啟動條件,因此只有ML_COMMENT規則處於活動狀態。 %x ML_COMMENT
而不是%s ML_COMMENT
否則,沒有開始條件的規則也是活動的。
我發現這種C語言語法的描述(實際上只是詞法分析器)非常有用。 我認為它與帕特里克的答案大致相同,但略有不同。
除了%x
vs %s
的問題,你也有問題了.
在[.\\n]
匹配(僅)一個文字.
而不是“除了換行之外的任何其他角色” .
確實。 你想要一個像這樣的規則
<ML_COMMENT>.|"\n" { /* do nothing */ }
代替
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.