2013-02-05 147 views
0

追趕評論我與想寫一個規則,將捕獲各種意見,甚至是「unended」註釋錯誤掙扎。與萊克斯

這是基於帕斯卡的語言。註釋可以是下列形式:

(* ...with any characters within... *)

(* 
* separated onto multiple lines 
*) 

​​

,但我需要捕捉任何評論錯誤,如:

(* this comment has no closing r-parenthesis *(* this comment is missing an asterisk)

我有這個到目前爲止:

{% 
int yylval; 
vector<string> string_table; 
int string_table_index = 0; 
int yyline = 1, yycolumn = 1; 
%} 

delim [ \t\n] 
ws  {delim}+ 
letter [a-zA-Z] 
digit [0-9] 
id  {letter}({letter}|{digit})* 
number {digit}+ 
float {digit}+(\.{digit}+)?(E[+\-]?{digit}+)? 


%% 
{ws}  {yycolumn += yyleng;} 
"(*" { 
    int c; 
    yycolumn += yyleng; 
    while ((c = yyinput()) != '*' && c != EOF) { 
     c = yyinput(); /* read additional text */ 
     if (c == '*') { 
      while ((c = yyinput()) == '*') { 
       c = yyinput(); 
       if (c == ')') { 
        break; /* found the end */ 
       } else if (c == EOF) { 
        cout << "EOF in comment\n"; 
        break; 
       } else { 
        cout << "unended comment, line = " 
        << yyline << ", column = " 
        << yycolumn-yyleng << "\n"; 
       } 
      } 
     } 
    } 
} 
  1. 它沒有能趕上最後括號(始終打印出來RPARENtoken!)
  2. 它沒有忽略註釋中的所有字符(即:打印MINUStoken爲「 - 」)
  3. 它不能在多行上發表評論。
  4. 我不知道它是正確捕捉unended註釋錯誤。

    我想我已經接近...誰能看到我錯在哪裏?

回答

4

考慮使用start conditions以避免寫在(*模式的所有額外的代碼。我在下面寫了一個簡短的例子。

%x COMMENT 
%% 
"(*" { BEGIN(COMMENT); } 
<COMMENT>{ 
    "*)" { BEGIN(INITIAL); } 
    <<EOF>> { printf("EOF in comment\n"); } 
    . {} 
} 

基本上當詞法分析器找到一個註釋的開始,它進入COMMENT狀態,並且將只檢查<COMMENT>塊內的規則。當它找到*)時,它將返回到初始狀態。請注意,如果您計劃使用多個狀態,這很可能是更好的使用yy_push_state(COMMENT)yy_pop_state(COMMENT)而不是BEGIN(STATENAME)

我不完全知道什麼您的評論誤差標準是(例如,它是如何從遇到在評論一個EOF不同),但是這可能可以擴展到處理這些案件。