编辑:更改了波利诺姆规则
我尝试编写一个简单的编译器,它可以识别多项式并打印出来。尽管它这样做了,但正如预期的那样,它在打印出多项式后吐出语法错误。困扰我的是无法弄清楚是词法分析器还是解析器导致了所有的大惊小怪。
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>
显然,gedit 总是在其文件末尾添加一个换行符n
。似乎没有办法阻止这种情况。在parser.ypp中向Polinom添加一个空规则,通过允许Polinom只换行符来回避这个问题。