【问题标题】:lex and yacc : a simple calculator with syntax errorlex 和 yacc : 一个有语法错误的简单计算器
【发布时间】:2014-01-20 04:05:33
【问题描述】:

一个简单的计算器只支持 + - * / 和整数。我使用 GNU/Linux。

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*

为什么以及如何解决它,谢谢!

【问题讨论】:

  • 语法错误意味着输入数据错误,但您没有提供的一件事是输入数据。 '\r' 有可能吗?
  • @davidusrex 我在这篇文章的底部提供了输入数据(在 "runtime-error"... 之后),我使用的是 linux 所以真的有 '\n' 而不是 '\r' ?谢谢。

标签: yacc lex


【解决方案1】:

您忘记在您的 lex 文件中包含您的运算符,并且您应该在成功读取令牌时返回非零值:直观地返回 0 表示 yylex 没有匹配项。删除 lex 文件中处理换行符的行并将其替换为以下内容:

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

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

【讨论】:

  • 我参考了unix编程环境一书,而yylex() 似乎没有(事实上确实如此)处理操作符。现在我知道我的错误在哪里,我应该多学习。谢谢。
  • @Mike 您可能会受益于阅读和查看this page 中列出的 PDF 文件和随附的源代码。我就是这样知道答案的;几天前我才开始看它。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多