在Lex中捕获换行符出错

时间:2013-03-27 15:40:46

标签: lex

我已经调试了几天,似乎无法解决这个问题。以下代码是C语言语法的Lex文件。

我有两个我无法发现的问题。

首先是换行检测。它似乎在输出中保留换行符char并且不会增加行var(以跟踪行,列以获得错误反馈)。

我拥有换行符转义序列的所有组合,但似乎无法捕获它。

第二个是检测单个引号后跟换行符,该换行符应生成一个 非法字符错误。

我没看到什么?提前谢谢!

%{
int col = 1;
int line = 1;
int aux_col = 0;
int err = 0; 
%}

%x C_COMMENT

 /* Identifiers */
ids    [a-zA-Z_]([a-zA-Z0-9_])*
 /* Integers    */
inteiros    0|[1-9]([0-9])*

 /* Chars or any Escape Sequence */
chrlit    (\'[^\n\'\\]?\')|(\'\\.\')
 /* Strings */  
strlit    (\"[^\n\"\\]?+\")         

 /* Char Error: Multi Char Constant */
chr_multi    (\'[^\n\']{2,}\')

 /* Char Error: Non-terminated Char Constant */
chr_nonterm    (\'[^\n\']{1,})

 /* String Error: Non-terminated String Constant */
strerr    (\"[^\n\"]?+)



%%

"/*"    {BEGIN(C_COMMENT); if(col==0) {aux_col=3;} else {aux_col=2;}}
<C_COMMENT>"*/"    {col+=aux_col+2; aux_col=0; BEGIN(INITIAL);}
<C_COMMENT><<EOF>>    {printf("Line %d, col %d: unterminated comment\n",line, col); BEGIN(INITIAL);}
<C_COMMENT>.    {aux_col++;}


"do"|"struct"|"auto"|"long"|"switch"|"break"|"enum"|"register"|"typedef"
"case"|"extern"|"union"|"float"|"short"|"unsigned"|"const"|"for"|"signed"       "void"|"continue"|"goto"|"sizeof"|"volatile"|"default"|"static"
{col+=yyleng; printf("RESERVED\n");}

return    {col+=yyleng; printf("RETURN\n");}

while    {col+=yyleng; printf("WHILE\n");}

printf    {col+=yyleng; printf("PRINTF\n");}

atoi    {col+=yyleng; printf("ATOI\n");}

if    {col+=yyleng; printf("IF\n");}

int    {col+=yyleng; printf("INT\n");}

itoa    {col+=yyleng; printf("ITOA\n");}

char    {col+=yyleng; printf("CHAR\n");}

"&&"    {col+=yyleng; printf("AND\n");}

"&"    {col+=yyleng;  printf("AMP\n");}

"="    {col+=yyleng;  printf("ASSIGN\n");}

"*"    {col+=yyleng; printf("AST\n");}

","    {col+=yyleng; printf("COMMA\n");}

"/"    {col+=yyleng; printf("DIV\n");}

"=="    {col+=yyleng; printf("EQ\n");}

">="    {col+=yyleng; printf("GE\n");}

">"    {col+=yyleng; printf("GT\n");}

"{"    {col+=yyleng; printf("LBRACE\n");}

"<="    {col+=yyleng; printf("LE\n");}

"("    {col+=yyleng; printf("LPAR\n");}

"["    {col+=yyleng; printf("LSQ\n");}

"<"    {col+=yyleng; printf("LT\n");}

"-"    {col+=yyleng; printf("MINUS\n");}

"%"    {col+=yyleng; printf("MOD\n");}

"!="    {col+=yyleng; printf("NE\n");}

"!"    {col+=yyleng; printf("NOT\n");}

"+"    {col+=yyleng; printf("PLUS\n");}

"}"    {col+=yyleng; printf("RBRACE\n");}

")"    {col+=yyleng; printf("RPAR\n");}

"]"    {col+=yyleng; printf("RSQ\n");}

";"    {col+=yyleng; printf("SEMI\n");}

\|\|    {col+=yyleng; printf("OR\n");}



{ids}    {col+=yyleng; printf("ID(%s)\n",yytext);}
{inteiros}    {col+=yyleng; printf("INTLIT(%s)\n", yytext);}
{strlit}    {col+=yyleng; printf("STRLIT(%s)\n", yytext);}
{chrlit}    {col+=yyleng; printf("CHRLIT(%s)\n", yytext);}


{chr_multi}    {if(col==0) {col++;err=1;}
            printf("Line %d, col %d: multi-character char constant\n", line, col);
            col+=yyleng;
            if(err == 1) {col--;err=0;}}

{chr_nonterm}    {if(col==0) {col++;err=1;}
            printf("Line %d, col %d: unterminated char constant\n", line, col);
            col+=yyleng;if(err == 1) {col--;err=0;}}

{strerr}    {if(col==0) {col++;err=1;}
            printf("Line %d, col %d: unterminated string constant\n", line,col);
            col+=yyleng;
            if(err == 1) {col--;err=0;}}

" "    {col++;};
'\n'    {col=1;line++;printf("BAR N\n");}
"\\n"    {col=1;line++;printf("BAR N2\n");}
\n    {col=1;line++;printf("BAR N3\n");}

.|\'    {printf("Line %d, col %d: illegal character ('%s')\n", line, col, yytext); col++;}

%%

int main () {
    yylex();
    return 0;
}

int yywrap(){
    return 1;
}

1 个答案:

答案 0 :(得分:1)

您没有在评论中匹配换行符。 .匹配任何字符换行符。

修正规则以匹配关键字(添加几个|并将其全部放在一行上)后,程序 报告单个引号上的非法字符,后跟换行符。所以请给出能给出意想不到的结果的确切输入。

布莱恩同事致以最诚挚的问候。