用Lex捕捉评论

时间:2013-02-05 16:02:45

标签: regex lex

我正在努力编写一条能够捕捉各种评论甚至“未发表评论”错误的规则。

这是基于Pascal的语言。评论可以是以下形式:

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

(*
 * separated onto multiple lines
 *)

(* they can contain "any" symbol, so -, +, :, ; , etc. should be ignored *)

但我需要发现任何评论错误,例如:

(* 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. 我不确定它是否正确捕捉未发表的评论错误。

    我想我很亲密......谁能看到我哪里出错?

1 个答案:

答案 0 :(得分: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的方式有何不同),但这可能会扩展到处理这些情况。