Parsing einer Grammatik mit Boost Spirit

Ich versuche zu analysieren, eine C-Funktion wie Baum Ausdrücke wie den folgenden (mit Hilfe der Spirit-Parser-Framework):

F( A() , B( GREAT( SOME , NOT ) ) , C( YES ) )

Dafür bin ich zu versuchen, die drei Regeln auf der folgenden Grammatik:

template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> {

    InputGrammar() : InputGrammar::base_type( ) {
       tag = ( qi::char_("a-zA-Z_")  >> *qi::char_("a-zA-Z_0-9") )[ push_back( at_c<0>(qi::_val) , qi::_1 ) ];
       command =  tag [ at_c<0>(qi::_val) = at_c<0>(qi::_1) ] >> "(" >> (*instruction >> ",")
                                        [ push_back( at_c<1>(qi::_val) , qi::_1 ) ]  >> ")";
       instruction = ( command | tag ) [qi::_val = qi::_1];
    }
    qi::rule< Iterator , ExpressionAST() , space_type > tag;
    qi::rule< Iterator , ExpressionAST() , space_type > command;
    qi::rule< Iterator , ExpressionAST() , space_type > instruction;
};

Feststellen, dass mein-tag-Regel nur zu erfassen versucht die Bezeichner verwendet, die in die Ausdrücke (die 'Funktion' Namen). Beachten Sie auch, dass die Unterschrift von der tag-Regel gibt einen ExpressionAST statt einer std::string, wie in den meisten Beispielen. Der Grund ich will es so machen ist eigentlich ziemlich einfach: ich hasse es mit Varianten, und ich werde Sie vermeiden, wenn möglich. Es wäre toll, halten den Kuchen und ihn auch Essen, denke ich.

Ein-Befehl sollte mit einem start-tag (der name des aktuellen Knotens, erste string-Feld der AST-Knoten) und eine variable Anzahl von Argumenten in Klammern eingeschlossen, und jedes der Argumente kann ein tag sein, sich selbst oder einen anderen Befehl.

In diesem Beispiel jedoch überhaupt nicht funktioniert. Es kompiliert und alles, aber zur Laufzeit scheitert es zu analysieren, alle meine test-strings. Und die Sache, die wirklich mich ärgert ist, dass ich kann nicht herausfinden, wie es zu beheben, da kann ich nicht wirklich Debuggen der oben genannten code, zumindest in der traditionellen Bedeutung des Wortes. Im Grunde die einzige Möglichkeit, die ich sehe, kann ich beheben, der obige code ist von dem wissen, was ich falsch mache.

So, die Frage ist, dass ich nicht weiß, was falsch ist mit dem obigen code. Wie definieren Sie die obige Grammatik?

Den ExpressionAST Typ, den ich verwende, ist:

struct MockExpressionNode {
    std::string name;
    std::vector< MockExpressionNode > operands;

    typedef std::vector< MockExpressionNode >::iterator iterator;
    typedef std::vector< MockExpressionNode >::const_iterator const_iterator;

    iterator begin() { return operands.begin(); }
    const_iterator begin() const { return operands.begin(); }
    iterator end() { return operands.end(); }
    const_iterator end() const { return operands.end(); }

    bool is_leaf() const {
        return ( operands.begin() == operands.end() );
    }
};

BOOST_FUSION_ADAPT_STRUCT(
    MockExpressionNode,
    (std::string, name)
    (std::vector<MockExpressionNode>, operands)
)
  • Etwas, das ich herausgefunden vor kurzem, dass C-und C++ - Bezeichner kann '$' Zeichen im Namen. So dass a-z, A-Z, 0-9 (außer für das erste Zeichen), _ und $ gültig sind, in ein C/C++ - Bezeichner.
  • MSVC erlaubt Sonderzeichen in Bezeichnern. Bedeutet nicht, es ist standard-konform.
  • Noch wichtiger ist, was ist der Punkt, den Sie versuchen zu machen @Cthutu? Ist es ein Mangel in IDS? Hat dein compiler keine Unterstützung für namespaces, richtig?
InformationsquelleAutor lurscher | 2010-06-20
Schreibe einen Kommentar