我正在研究在lex和c中创建一个布尔表达式求值程序,但是我在代码中找到错误时遇到了问题。
当我运行代码时,parser.c文件会抛出error("expected end-of-file")
。这意味着程序没有读取文件结尾字符,我找不到这出错的地方。
我在下面附上了有问题的代码。如果,要解决这个问题,你需要看一些代码,请告诉我,我也很乐意发布它们。几个星期以来我一直坚持这个问题,不会有任何帮助。
Lexer.h
#ifndef ____lexer__
#define ____lexer__
#include <stdio.h>
#define AND 258
#define OR 259
#define NOT 260
#define TRUE 261
#define FALSE 262
#define DONE 300
#define NONE (-1)
int lexan();
extern int value;
extern int lineNo;
extern char lexbuf[];
extern FILE *fileSource;
#endif /* defined(____lexer__) */
lexer.lex
%{
#include <ctype.h>
#include <unistd.h>
#include "lexer.h"
#include "error.h"
int value;
int lineNo;
%}
%option noyywrap
%%
['''\t']* {}
['\n']* { lineNo++; }
<<EOF>> {
return DONE;
}
"True" {return (TRUE);}
"False" {return (FALSE);}
"or" {return (OR);}
"and" {return (AND);}
"not" {return (NOT);}
.|\n {
value = NONE;
int temp = (int)(yytext[0]);
return (temp);
}
%%
int lexan()
{
yyin = fileSource;
int result = yylex();
return result;
}
parser.c
#include <stdlib.h>
#include "parser.h"
#include "lexer.h"
#include "error.h"
#include "interpreter.h"
static int lookahead;
static void stmts();
static void stmt();
static void assign();
static void expr();
static void match();
void parse()
{
lookahead = lexan();
stmts();
lookahead = lexan();
if(lookahead != DONE)
error("expected end-of-file");
}
static void stmts()
{
while (lookahead != DONE)
{
if(lookahead == AND || lookahead == OR || lookahead == NOT || lookahead == TRUE || lookahead == FALSE)
{
stmt();
}
else
break;
}
}
static void stmt()
{
switch (lookahead)
{
case AND:
emit(AND);
match(AND);
break;
case OR:
emit(OR);
match(OR);
break;
case NOT:
emit(NOT);
match(NOT);
break;
default:
assign();
}
}
static void assign()
{
switch (lookahead)
{
case TRUE:
emit(TRUE);
match(TRUE);
break;
case FALSE:
emit(FALSE);
match(FALSE);
default:
error("syntax error");
}
}
void match(int t)
{
if (lookahead == t)
{
lookahead = lexan();
}
else
error("syntax error");
}
答案 0 :(得分:0)
如果stmts()
成功返回,则您的直接问题是yylex
已经lookahead
。在点击EOF之后再次调用stmts()
是未定义的行为,但是你真的不想进行调用,因为逻辑不正确; stmts
返回时stmt
尚未匹配,因此调用者应尝试匹配它,而不是用新令牌覆盖它。
但是,解决这个问题是最不重要的。 <<EOF>>
和yylex
的逻辑也是错误的;你需要重读你用来编写递归下降解析器的任何指南/文本。
顺便说一下,如果您没有{{1}}规则,{{1}}会在输入结束时返回0。您应该考虑使用此行为,而不是生成自定义返回代码。