【发布时间】:2017-08-17 11:41:22
【问题描述】:
编辑:更改 Polinom 规则
我尝试编写一个简单的编译器来识别多项式并将它们打印出来。尽管它这样做了,但正如预期的那样,它在打印出多项式后会吐出一个语法错误写入。诸如此类问题困扰我的是无法弄清楚是词法分析器还是解析器引起了大惊小怪。
parser.ypp
%{
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <vector>
using namespace std;
extern int yylex();
void yyerror(string s) {
cerr << s << endl;
exit(EXIT_FAILURE);
}
%}
%union {
double d;
vector<double> *niz;
}
%token <d> num_token
%type <niz> NizBrojeva
%%
Program: Program '\n' Polinom
| Polinom
;
Polinom: '<' NizBrojeva '>' {
vector<double>::iterator i;
int k = 0;
for(i = $2->begin(); i != $2->end(); i++, k++) {
if (*i == 0)
continue;
if (k == 0) {
cout << *i;
continue;
}
if (*i > 0)
cout << " + " << abs(*i) << "x";
if (*i < 0)
cout << " - " << abs(*i) << "x";
if (k != 1)
cout << "^" << k;
}
cout << endl;
}
| // <-------------------------------------------- That's all I added
;
NizBrojeva: NizBrojeva ',' num_token { $1->push_back($3); $$ = $1; }
| num_token { $$ = new vector<double>(); $$->push_back($1); }
;
%%
int main() {
yyparse();
return 0;
}
lexer.l
%option noyywrap
%option noinput
%option nounput
%{
#include <iostream>
#include <vector>
using namespace std;
#include "parser.tab.hpp"
%}
DIGIT [0-9]
%%
([+|-])?{DIGIT}+(\.{DIGIT}*)? { yylval.d = atof(yytext); return num_token; }
[<>,\n] { return *yytext; }
[ \t] { }
. { cerr << "Leksicka greska: neprepoznat karakter " << *yytext << endl;
exit(EXIT_FAILURE);
}
%%
测试示例是一个文本文件,其中包含一行:<1, -3, 0, -1.3, 6>
【问题讨论】:
-
让我猜猜,文件中的那一行后面有一个 newline 吗?现在
Program的规则在换行符之后发生了什么?也许您应该为EOF添加一个标记并将其包含在解析器规则中? -
只是一个蓝色的镜头:将
\r放入空格的弹性规则中并没有什么坏处(即[ \t]->[ \t\r])。这至少对 Windows 有帮助,如果输入文件以二进制模式打开... -
实际上,不,我尝试了换行和没有换行>错误仍然是一样的。刚才也试过
\r,没有成功。 -
您确定用于编辑输入文件的编辑器不会自动添加尾随换行符?如果您在控制台中输入,是否有换行符?
-
^ 刚才试过了,没有任何帮助。我在 Ubuntu 中使用 gedit,以前从未遇到过类似的问题。不仅仅是解析器,而是一般情况下。
标签: c++ flex-lexer yacc