2015-04-11 11 views
5

Ogni volta che io chiamo yyparse() con un file valido, ottengo un guasto seg che sembra essere causato da questa linea (attorno alla riga 1789) del codice:Parser generato da GNU Bison getta un errore di segmentazione 11 quando somministrato un file non vuoto

if (yyss + yystacksize - 1 <= yyssp){ 

Sono arrivato a questa conclusione stampando i messaggi di debug prima e dopo questa riga di codice. I messaggi prima di questa linea sono stati stampati, ma quelli dopo questa linea no.

Una cosa strana è che se chiamo yyparse() con un file vuoto, l'errore non viene generato ma viene generato se il file contiene almeno un carattere.

Lo stesso parser è stato compilato senza errori. Quale potrebbe essere la ragione/i di questo errore seg?

Il file parse: https://gist.github.com/SamTebbs33/bffb72517f174af679ef

debug di codice un messaggio:

cout << "before if" << endl; 
if (yyss + yystacksize - 1 <= yyssp){ 
    cout << "after if" << endl; 
    cout.flush(); 

Il primo messaggio di debug viene stampato 3 volte prima è gettato l'errore.

Edit: L'errore è effettivamente gettato nella dichiarazione switch quando il 55 token viene abbinato all'interno del yyreduce etichetta:

case 55: 
    #line 219 "grammar/grammar.y" /* yacc.c:1661 */ 
    { 
    cout << "processing token 55" << endl; 
    (yyval.id) = new TIdentifier(*(yyvsp[0].string)); 
    cout << "processed token 55" << endl; 
    } 
    #line 2228 "grammar/parser.cpp" /* yacc.c:1661 */ 
    break; 

prima di raggiungere l'istruzione switch, ho stampare il valore intero della variabile che viene commutata e il suo valore è 55, quindi il codice errato dovrebbe essere compreso nel codice precedente, poiché "token 55 elaborati" non viene stampato ma viene stampato "token di elaborazione 55". Sotto è il codice per il costruttoreTIdentifier:

TIdentifier(std::string name) : name(name) { 
} 

Ciò significa che l'errore deve essere prodotto quando dereferencing (yyvsp[0].string)

+1

Non c'è motivo (mi viene in mente) l'aritmetica del puntatore e il confronto può causare un errore di segmentazione. Forse potresti eseguire il programma tramite 'valgrind' per ottenere maggiori dettagli su come sta fallendo. – Diego

+1

Difficile credere che la linea causi un errore di seg. Hai fflush() l'output o eseguito in gdb? –

+1

Usi 'endl' alla fine di ogni' cout'?In caso contrario, si consideri che l'output che si vede quando si ottiene l'errore seg potrebbe essere sbagliato, poiché qualcosa è ancora nel buffer, in attesa di essere stampato per davvero, ma poi il programma si blocca e quelle linee non vengono mai stampate. In altre parole: se non si è sicuri di svuotare il buffer, potrebbe accadere che il programma si blocchi * dopo ** la linea identificata. Quanto dopo, è difficile da dire, ma usa 'endl' e saprai dove si blocca veramente. –

risposta

0

(Answered by the OP in a question edit. Converted to a community wiki answer, which is more appropriate to the Q&A format of StackOverflow).

Il PO ha scritto:

Dopo ulteriore debug, ho capito che la mia grammatica flex non stava salvando le stringhe trovate nel file come dovrebbe e stava tentando di accedere ad un elemento non esistente in yylval e il parser ora funziona!

Tuttavia, sarebbe stato meglio che il materiale corect è stato incluso nella questione come notato da @rici:

sarebbe più utile (o almeno più facile) per vedere il vostro input bisonti file (.y), piuttosto che il parser prodotto.

Problemi correlati