2017-08-17 5 views
0

EDIT: änderte die Polinom RegelYacc/flex Syntaxfehler

Ich habe versucht, einen einfachen Compiler zu schreiben, die Polynome zu erkennen, geht und ausdrucken. Obwohl es genau wie beabsichtigt ausgeführt wird, spuckt es nach dem Ausdruck des Polynoms einen Syntaxfehler aus. Was mich an solchen Problemen stört, ist nicht in der Lage herauszufinden, ob es der Lexer oder der Parser ist, der den ganzen Aufwand verursacht.

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); 
       } 

%% 

Der Test Beispiel ist eine Textdatei mit einer Zeile in ihm: <1, -3, 0, -1.3, 6>

+1

Lassen Sie mich raten, dass eine einzelne Zeile in der Datei ein * newline * danach haben? Was passiert nun mit der Regel für 'Program' nach einer Newline? Vielleicht sollten Sie ein Token für "EOF" hinzufügen und das in den Parser-Regeln haben? –

+0

Nur ein Schuss in blau: Es konnte nicht schaden, '\ r' in die Flex-Regel für Leerzeichen zu setzen (d. H.' [\ T] '->' [\ t \ r] '). Das würde zumindest unter Windows helfen und wenn Eingabedatei im Binärmodus geöffnet wird ... – Scheff

+0

Eigentlich nein, ich habe es sowohl mit einem Zeilenumbruch versucht als auch ohne es> der Fehler ist immer noch derselbe. Auch gerade mit '\ r' versucht, kein Erfolg. – monolith937

Antwort

0

Offenbar gedit fügt immer ein Newline-Zeichen \n am Ende seiner Dateien. Scheint, es gibt keine Möglichkeit, das zu verhindern. Das Hinzufügen einer leeren Regel zu Polinom in parser.ypp verhindert dieses Problem, indem es Polinom erlaubt, nur eine neue Zeile zu werden.