lexer.l 尝试 return 令牌时程序抛出错误
lexer.l program throwing error while trying to return a token
我正在尝试构建一个 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;
}
我的生成文件
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
现在,当我尝试 return 令牌时,它会不断抛出错误。
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
如果你能在这一点上帮助我,我将不胜感激。提前致谢。
r
不匹配除最后的回退规则之外的任何词法规则,它调用 yyerror
。如果您的 yyerror
实现打印了作为第一个参数传递的错误消息,那会更清楚。
您对 yyerror
的定义不接受任何参数,因此使用参数调用它实际上是未定义的行为。如果您始终如一地 声明 yytext
,您的编译器会告诉您:在 C 中,您将一个没有参数的函数声明为
void yyerror(void);
因为
void yyerror();
声明一个函数但没有指定它有什么参数或有多少参数。为了向后兼容,您可以这样做,但实际上不应该这样做。
您还应该始终使用 -Wall
进行编译(至少),以便您的编译器有机会警告您一些不是技术错误但可能不是您想要编写的内容。不幸的是,gcc 不会就此特定错误警告您(尽管未来的版本可能会)。参见 。
我正在尝试构建一个 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;
}
我的生成文件
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
现在,当我尝试 return 令牌时,它会不断抛出错误。
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
如果你能在这一点上帮助我,我将不胜感激。提前致谢。
r
不匹配除最后的回退规则之外的任何词法规则,它调用 yyerror
。如果您的 yyerror
实现打印了作为第一个参数传递的错误消息,那会更清楚。
您对 yyerror
的定义不接受任何参数,因此使用参数调用它实际上是未定义的行为。如果您始终如一地 声明 yytext
,您的编译器会告诉您:在 C 中,您将一个没有参数的函数声明为
void yyerror(void);
因为
void yyerror();
声明一个函数但没有指定它有什么参数或有多少参数。为了向后兼容,您可以这样做,但实际上不应该这样做。
您还应该始终使用 -Wall
进行编译(至少),以便您的编译器有机会警告您一些不是技术错误但可能不是您想要编写的内容。不幸的是,gcc 不会就此特定错误警告您(尽管未来的版本可能会)。参见