我正在尝试构建一个lexer.l和parser.l程序,该程序将扫描以下样本输入并产生样本输出。
为此,我编写了lexer.l和parser.l,如下所示:
lexer.l
%option noyywrap
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.tab.h"
extern FILE *yyin;
extern FILE *yyout;
int lineno = 1; // initialize to 1
void ret_print(char *token_type);
void yyerror();
%}
digit "0"[0-1]
%%
[ \t\r\f]+ {}
{digit} { yylval.int_val = atoi(yytext); return BINARY; }
"\n" { lineno += 1; }
. { yyerror("Unrecognized character"); }
%%
parser.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern FILE *yyin;
extern FILE *yyout;
extern int lineno;
extern int yylex();
void yyerror();
%}
/* YYSTYPE union */
%union{
int int_val;
}
%token<int_val> BINARY
%token<int_val> ADDOP
%start program
%%
program: {printf("started\n");} ;
%%
void yyerror ()
{
fprintf(stderr, "Syntax error at line %d\n", lineno);
exit(1);
}
int main (int argc, char *argv[])
{
int flag;
flag = yyparse();
printf("Parsing finished!\n");
return flag;
}
我的Makefile
no3:parser.y lexer.l
bison -d parser.y
flex lexer.l
gcc -o a.out parser.tab.c lex.yy.c
./a.out
clear:
rm *.txt, *.tab.h
现在,当我试图返回令牌时,它总是抛出错误。
make no3
bison -d parser.y
flex lexer.l
gcc -o a.out parser.tab.c lex.yy.c
./a.out
started
r
Syntax error at line 1
make: *** [Makefile:5: no3] Error 1
请您在这一点上帮助我,我将不胜感激。提前谢谢。
答案 0 :(得分:1)
r
与最后一个后备规则(调用yyerror
)以外的任何词汇规则都不匹配。如果您的yyerror
实现打印出作为第一个参数传递的错误消息,那会更加清楚。
您对yyerror
的定义没有任何参数,因此使用参数调用它实际上是未定义的行为。如果您一致地声明 yytext
,编译器会告诉您:在C语言中,您将不带参数的函数声明为
void yyerror(void);
因为
void yyerror();
声明一个函数时不指定其具有什么参数或多少参数。允许这样做是为了向后兼容,但实际上不应该这样做。
您还应该始终使用-Wall
进行编译(至少),以便编译器有机会就技术上并非错误但可能不是您想要编写的内容警告您。不幸的是,gcc不会警告您有关此特定错误的信息(尽管将来的版本可能会警告您)。参见this answer。