Frage

Ich schreibe ein C-Parser mit PLY, und vor kurzem lief in ein Problem. Dieser Code:

typedef int my_type;
my_type x;

Stimmt C-Code, weil my_type als Typ definiert ist zuvor wird als solches verwendet. I umgehen, indem eine Art Symboltabelle Füllung in der Parser, der durch die Lexer zu unterscheiden zwischen verschiedenen Arten verwendet wird und einfache Bezeichner.

Während jedoch die Typdeklaration Regel mit SEMI endet (das ‚;‘ token), PLY verschiebt das Token my_type aus der zweiten Zeile, bevor es fertig ist mit dem ersten Entscheidung. Aus diesem Grunde habe ich keine Chance, das Update in der Art Symboltabelle zum Lexer und es passiert sieht als Kennung my_type und nicht eine Art.

Alle Ideen für eine Korrektur?

Der vollständige Code ist unter: http: / /code.google.com/p/pycparser/source/browse/trunk/src/c_parser.py Nicht sicher, wie ich ein kleineres Beispiel aus dieser schaffen.

Edit:

Problem gelöst. Siehe meine Lösung unten.

War es hilfreich?

Lösung 2

Mit etwas Hilfe von Dave Beazley (PLY Schöpfer), mein Problem gelöst wurde.

Die Idee ist, spezielle Unterregeln zu verwenden, und die Aktionen in ihnen zu tun. In meinem Fall spaltete ich die declaration Regel:

def p_decl_body(self, p):
    """ decl_body : declaration_specifiers init_declarator_list_opt
    """
    # <<Handle the declaration here>>        

def p_declaration(self, p):
    """ declaration : decl_body SEMI 
    """
    p[0] = p[1]

decl_body wird immer vor dem Token reduziert nach SEMI in verschoben wird, so dass meine Aktion zur richtigen Zeit ausgeführt wird.

Andere Tipps

Nicht sicher, warum Sie das Niveau der Analyse in Ihrem Lexer tun.

Die lexikalische Analyse sollte wahrscheinlich den Eingangsstrom in lexikalische Token (Nummer, Zeilenwechsel, Stichwort usw.) zu trennen verwendet werden. Es ist die Parsing-Phase, die das Niveau der Analyse tun soll, einschließlich Tabelle Lookups für typedefs und so weiter.

Das ist die Art, wie ich habe immer die Aufgaben zwischen lexx und yacc getrennt, meine Werkzeuge der Wahl.

Ich glaube, Sie müssen die Prüfung für sich bewegen, ob eine ID ist ein TYPEID von c_lexer.py c_parser.py.

Wie Sie gesagt haben, da der Parser der Suche voraus 1 Token, können Sie diese Entscheidung nicht in der Lexer machen.

Stattdessen ändern Sie Ihren Parser zu überprüfen ID, um zu sehen, ob sie TYPEID die in Erklärungen sind, und, wenn sie nicht sind, einen Fehler.

Wie Pax Diablo sagte in seiner ausgezeichneten Antwort, der Lexer / tokenizer Aufgabe ist es nicht, diese Art von Entscheidungen über Tokens zu machen. Das ist die Aufgabe des Parsers.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top