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)
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
Difficile credere che la linea causi un errore di seg. Hai fflush() l'output o eseguito in gdb? –
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. –