2015-04-11 3 views
5

Immer wenn ich yyparse() mit einer gültigen Datei aufrufen, bekomme ich einen Seg Fehler, scheint durch diese Linie (um Linie 1789) verursacht zu werden Code:Parser von GNU erzeugt Bison löst einen Segmentierungsfehler 11 wenn eine nicht leere Datei gegeben wird

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

ich zu diesem Schluss kam mit dem Debug-Druck-Nachrichten vor und nach dieser Codezeile. Die Nachrichten vor dieser Zeile wurden gedruckt, die nach dieser Zeile jedoch nicht.

Eine seltsame Sache ist, dass, wenn ich yyparse() mit einer leeren Datei aufrufen, wird der Fehler nicht ausgelöst, aber es wird ausgelöst, wenn die Datei mindestens ein Zeichen enthält.

Der Parser selbst wurde ohne Fehler kompiliert. Was könnten die Gründe für diesen Segeldruck sein?

Die Parse-Datei: https://gist.github.com/SamTebbs33/bffb72517f174af679ef

Debug Nachrichtencode:

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

Die erste Debug-Meldung 3 mal gedruckt wird, bevor der Fehler ausgelöst wird.

Edit: Der Fehler tatsächlich in der switch-Anweisung ausgelöst wird, wenn die 55-Token innerhalb des yyreduce Etikett angepasst ist:

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; 

Bevor die switch-Anweisung erreicht ist, drucken I den ganzzahligen Wert der Variablen, die geschaltet wird, und ihr Wert ist 55, so sollte der fehlerhafte Code innerhalb des obigen Codes liegen, da "verarbeiteter Token 55" nicht gedruckt wird, sondern "Verarbeitungstoken 55" gedruckt wird. Unten ist der Code für die TIdentifier Konstruktor:

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

Dies bedeutet, dass der Fehler bei (yyvsp[0].string)

+1

Es gibt keinen Grund (kann ich mir vorstellen) Zeigerarithmetik und Vergleiche können einen Segmentierungsfehler verursachen. Vielleicht könntest du das Programm durch 'valgrind' ausführen, um mehr Details darüber zu erhalten, wie es scheitert. – Diego

+1

Kaum zu glauben, dass diese Linie einen Seg-Fehler verursacht. Hast du die Ausgabe fflush() oder in gdb ausgeführt? –

+1

Verwenden Sie 'endl' am Ende jedes' cout'?Wenn nicht, bedenken Sie, dass die Ausgabe, die Sie sehen, wenn Sie den seg-Fehler erhalten, falsch ist, da etwas noch im Puffer ist und darauf wartet, dass es wirklich gedruckt wird, aber dann stürzt das Programm ab und diese Zeilen werden nie gedruckt. Mit anderen Worten: Wenn Sie nicht sicherstellen, dass der Puffer gelöscht wird, stürzt Ihr Programm möglicherweise ** nach der von Ihnen identifizierten Zeile ab. Wie viel später, es ist schwer zu sagen, aber benutze einfach "endl" und du wirst wissen, wo es wirklich abstürzt. –

Antwort

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) dereferencing produziert werden müssen.

Die OP schrieben:

Nach weiteren Debuggen, ich habe erkannt, dass meine flex Grammatik die Strings in der Datei, wie es sollte nicht gefunden spart und versucht, ein nicht existierendes Element in yylval zugreifen und der Parser funktioniert jetzt!

Allerdings wäre es besser gewesen, dass das corect Material in der Frage nach @rici wie erwähnt enthalten war:

Es wäre nützlicher sein (oder zumindest einfacher) Ihren Bison Eingang zu sehen Datei (.y), anstatt den erzeugten Parser.

Verwandte Themen