我已经调试了几天,似乎无法修复此错误。以下代码是 C 语言语法的 Lex 文件。
我有两个问题我还没有发现。
首先是换行检测。它似乎将换行符留在输出中,并且不会增加行 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;
}