yacc 生成的解析器的新行被忽略

问题描述

ubuntu 20.04 上的这个解释器有换行问题。

s1.l

%%
(a|b)*  { strcpy(yylval.string,yytext);
      return AB; 
        }
z   return Z;
'\n'    return yytext[0];
.   return yytext[0];
%%

s1.y

%{
#include <stdio.h>
#include <string.h>
#define check(first,two) \
        if (strcmp(first,two)) \
            fprintf(stderr," -------- no word of language S1\n"); \
        else \
            fprintf(stderr," --------  word of language S1\n");
int yylex();
void yyerror();

%}
%union {
    char string[100];
}
%token Z
%token <string> AB

%%
word: AB Z AB '\n' { check($1,$3); }  
    | word AB Z AB '\n' { check($2,$4); } 
    | error '\n'
    ;
%%
#include "lex.yy.c"
void yyerror(char *s)
{
    fprintf(stderr,"no word of language S1\n"); 
}

当我运行解释器时,无法识别换行符。

./s1
aazbb

解决方法

lex 不会将 ' 视为特殊字符(表示单个字符),因此当您有模式 '\n' 时,它会匹配该文字 3 字符序列。改用 "\n"(或仅使用 \n)。

,

您的模式是一个由简单引号包围的新行,然后 lex(或 flex)期望将新行返回给解析器,并且无法识别新行是正常的。您应该简单地删除简单的引号,如下所示:

%%
(a|b)*  { strcpy(yylval.string,yytext);
      return AB; 
        }
z   return Z;
\n    return yytext[0];
.   return yytext[0];
%%