Flex aruncă „intrarea în scanerul flex a eșuat” după analizarea întregului fișier? (Programare, Bison, Flex Lexer)

udiboy1209 a intrebat.

Încerc să fac un parser în C++ folosind Flex și Bison. Am văzut „input in flex scanner failed” online doar în postări care oferă un fișier prost pentru parsare. Dar primesc această eroare după ce întregul meu fișier este analizat corect. Există vreun bug în care Flex nu poate detecta EOF corect? Acestea sunt definițiile relevante:

Bison –

%union {
    char node;
    char gate;
    int index;
}

%token END;
%token <node> NODE;
%token <gate> GATE;
%token <index> INDEX;

%%

atpg:
    body END { cout << "Reading last line." << endl; };
body:
    assignments;
assignments:
    assignments assignment { cout << "Token: assignments - rec." << endl; }
    | assignment         { cout << "Token: assignments - first." << endl; };
assignment:
    outnode gatedec '(' nodelist ')'  {
        cout << "Token: assignment" << endl;
        g_gatelist[last_gate].setOutput(&g_nodelist[out_node]);
        for(int i : t_nodelist)
            g_gatelist[last_gate].addInput(&g_nodelist[i]);
        t_nodelist.clear();
        };
outnode:
    nodedec '='  {
        cout << "Token: outnode" << endl;
        out_node = last_node;
        };
nodedec:
    NODE INDEX  {
        num_nodes ++;
        if ($1 == 'i') input_nodes ++;
        if ($1 == 'o') output_nodes ++;

        new(&g_nodelist[$2]) Node($1, $2);
        last_node = $2;

        cout << g_nodelist[$2] << endl;
        };
gatedec:
    GATE INDEX  {
        num_gates ++;

        createGateFromName(&g_gatelist[$2], $1, $2);
        last_gate = $2;

        cout << "Gate: " << $1 << "-" << $2 << endl; 
        };
nodelist:
    nodedec nodelist { 
        cout << "Token: nodelist - rec" << endl;
        t_nodelist.push_back(last_node);
        }
    | nodedec {
        cout << "Token: nodelist - first" << endl;
        t_nodelist.push_back(last_node);
        };

Flex –

%{
#include "gatelist.tab.h"
#define YY_DECL extern "C" int yylex()
%}

INDEX    [0-9]+
GATE     and|or|not
NODE     n|i|o

%%

{GATE}      { yylval.gate = yytext[0]; return GATE; }

{NODE}      { yylval.node = yytext[0]; return NODE; }

{INDEX}     { yylval.index = atoi(yytext); return INDEX; }

[()=]     { return yytext[0]; }

end         { return END; }

.|
 ;/* ignore */
%%
;

Input –

n3 = and1 ( i0 i1 i2 )
n4 = or2 ( i1 i2 )
n5 = not3 ( n4 )
n6 = and4 ( n5 n4 )
end

Ieșire –

Node(n-3 = 0)
Token: outnode
Gate: a-1
Node(i-0 = 0)
Node(i-1 = 0)
Node(i-2 = 0)
Token: nodelist - first
Token: nodelist - rec
Token: nodelist - rec
Token: assignment
Token: assignments - first.
Node(n-4 = 0)
Token: outnode
Gate: o-2
Node(i-1 = 0)
Node(i-2 = 0)
Token: nodelist - first
Token: nodelist - rec
Token: assignment
Token: assignments - rec.
Node(n-5 = 0)
Token: outnode
Gate: n-3
Node(n-4 = 0)
Token: nodelist - first
Token: assignment
Token: assignments - rec.
Node(n-6 = 0)
Token: outnode
Gate: a-4
Node(n-5 = 0)
Node(n-4 = 0)
Token: nodelist - first
Token: nodelist - rec
Token: assignment
Token: assignments - rec.
Reading last line.
input in flex scanner failed

Comentarii

  • Am făcut tot ce am putut, dar vă rog să citiți despre cum să pregătiți un exemplu minim reproductibil. Este imposibil să vă testați codul deoarece (1) acțiunile depind de funcții externe și (2) driverul și Makefile sau procedura de construire nu sunt incluse. NU adăugați doar definițiile funcțiilor necesare, deoarece acest lucru ar face ca un exemplu care nu este minimal să fie și mai lung. În schimb, pregătiți o versiune fără acțiuni (inutile) (În cazul dumneavoastră, toate acțiunile sunt inutile) și includeți toate celelalte definiții utilizate (yywrap și yyerror, de exemplu, deși eu prefer întotdeauna %option noyywrap în fișierul flex pentru a evita necesitatea). –  > Por rici.
1 răspunsuri
rici

Bison mărește întotdeauna gramatica furnizată prin adăugarea unei reguli de scop care se potrivește cu regula de start furnizată de tine, urmată de un indicator de sfârșit de fișier (token numărul 0), astfel încât intrarea este forțată să se potrivească cu un fișier complet. Dacă doriți să folosiți propriul marker de sfârșit și să încheiați analiza când a fost recunoscută, trebuie să utilizați opțiunea YYACCEPT în acțiunea asociată pentru a determina finalizarea cu succes a analizei fără a citi alte semne.

Eroarea pe care o obțineți apare atunci când un scaner flex primește o eroare de citire atunci când încearcă să citească date. Sfârșitul fișierului este not o eroare, iar erorile de I/O sunt destul de puțin frecvente. În mod normal, această eroare indică faptul că s-a încercat continuarea citirii datelor de intrare după ce a fost raportat un sfârșit de fișier și yyin închis (sau setat la o valoare invalidă). În general, ar trebui să evitați să citiți jetoane după ce a fost raportat un sfârșit de fișier; deși funcționează adesea, nu este pe deplin acceptat și, cu anumite opțiuni de scanare, va produce rezultate neașteptate.


Ca o chestiune secundară, veți constata de obicei că este mai ușor să utilizați funcția încorporată de bison de urmărire decât să împrăștiați printf-uri în tot codul dumneavoastră. Veți ajunge să adăugați și să eliminați printf-uri, ceea ce este o pacoste, iar acestea nu vă vor oferi niciodată o imagine la fel de completă a ceea ce se întâmplă ca o urmărire bison.

Comentarii

  • Am adăugat YYACCEPT și am rezolvat problema. Totuși, nu reușesc să fac să funcționeze trace-ul, am adăugat atât YYDEBUG și --debug flag –  > Por udiboy1209.
  • @udiboy1209: aveți nevoie doar de --debug OR #define YYDEBUG dar aveți nevoie și de yydebug = 1;. O expresie uzuală este de a pune #if YYDEBUG yydebug = 1; #endif în main (în cazul în care incluziunile parserului sunt vizibile în main). –  > Por rici.
  • Probabil că acest paragraf ar trebui să fie mai aproape de partea de sus a paginii de documentație. „După ce ați compilat programul cu facilități de urmărire, modul de a solicita o urmărire este de a stoca o valoare diferită de zero în variabila yydebug. ” Se pare că oamenilor le scapă adesea acest lucru. Presupunerea că programatorii vor citi cu adevărat o pagină întreagă de documentație pare să fie de domeniul trecutului, dacă a fost vreodată cazul. –  > Por rici.