2014-01-20 59 views
2

一个简单的计算器只支持+ - * /和整数。我使用GNU/Linux。lex和yacc:一个带语法错误的简单计算器

hoc1.l:

%{ 
#include "y.tab.h" 
extern int yylval; 
%} 

%% 
[ \t] { ; } 
[0-9]+ { sscanf(yytext, "%d", &yylval); printf("\nget %d\n", yylval); return NUMBER; } 
\n {return 0;} 
%% 

int yywrap(void) { 
    return 1; 
} 

hoc1.y

%{ 
#include<stdio.h> 
#define YYSTYPE int 
%} 
%token NUMBER 
%left '+' '-' 
%left '*' '/' 
%% 
list: 
    | list '\n' 
    | list expr '\n' {printf("\t%d\n",$2);} 
    ; 
expr: NUMBER  { $$ = $1; } 
    | expr '+' expr {$$ = $1+$3;} 
    | expr '-' expr {$$ = $1-$3;} 
    | expr '*' expr {$$ = $1*$3;} 
    | expr '/' expr {$$ = $1/$3;} 
    ; 
%% 

int main(void) 
{ 
    yyparse(); 
    return 0; 
} 

int yyerror(char *s) { 
    fprintf(stderr, "*%s*\n", s); 
    return 0; 
} 

运行时错误:

% ./hoc 
8+9 

get 8 
+ 
get 9 
*syntax error* 

为什么和如何来解答它,THX!

+0

语法错误意味着错误的输入数据,但您没有提供的是输入数据。 '\ r'是否可能? –

+0

@davidusrex我在这篇文章的底部提供了输入数据(在“runtime-error”之后......)并且我使用了linux,所以真的有'\ n'而不是'\ r'?谢谢。 – songhir

回答

3

您忘记将您的操作符包含在您的lex文件中,并且您应该在成功读取记号时返回非零值:直观返回0意味着yylex没有匹配。删除处理换行符的lex文件中的行并将其替换为以下内容:

[-+*/\n] { return *yytext; } 
. { yyerror("unrecognized character"); return 0; } 

现在它应该可以工作。返回*yytext允许您的yacc语法成功解析表达式,例如如果你得到一个'+',返回它让语法正确解析。

+0

我指的是* unix编程环境*,yylex()*似乎没有*(它实际上)对操作符的处理。现在我知道我的错误在哪里,我应该多学习一下。谢谢。 – songhir

+1

@Mike阅读并查看PDF文件和[本页](http://www.epaperpress.com/lexandyacc/index.html)中列出的源代码可能会使您受益匪浅。我就是这样知道答案的;几天前我刚开始看。 –