2016-10-09 9 views
3

Ich versuche derzeit in eine x3::variant zu analysieren, mit Boost Geist x3. die Variante sieht so aus:Probleme Parsing in rekursive Variante mit Boost Geist x3

typedef x3::variant< 
    nil, 
    x3::forward_ast<LambdaType>, 
    x3::forward_ast<ClassType> 
> Type 

wo LambdaType und Classtype suchen wie:

struct LambdaType { 
     std::vector<Type> parameters_; 
     Type return_type_; 
    }; 

struct ClassType{ 
    std::vector<std::string> name_; 
    std::vector<Type> template_args_; 
}; 

wenn ich versuche, in eine Art zu analysieren, oder einer dieser structs, ich einen Compiler-Fehler erhalten, Das sagt mir, ich kann nicht const boost::spirit::x3::char_class zu Type, zuweisen Ich bin davon verwirrt, da ich nie eine const boost::spirit::x3::char_class zuweisen möchte. Ich habe ein Live-Beispiel here, die einen Parser hat und zeigt das Problem und den Fehler, wenn Sie versuchen, es zu kompilieren. Ich versuche dieses Problem für einen ganzen Tag zu lösen und ich bin jetzt an einem Punkt, wo ich keine Ahnung habe, warum das nicht funktioniert. Für jede Hilfe dabei wäre ich mehr als dankbar.

Antwort

3

Sie übergeben x3::space als letztes Argument an x3::parse, so wird es an das Attribut für den Parser gebunden.

Natürlich wollten Sie das nicht.

Verwenden Sie x3::phrase_parse, wenn Sie einen Skipper übergeben möchten.

PS Als Ihr Parser geschrieben hat ein zusätzliches Problem: es in Art/lambdaType links Rekursion hat. Ich rechne damit, das ist, weil Sie Bezeichner Parsen stubbed out (x3::string("foo")) so hier, wenn Sie die Eingabe beheben (foo, foo) => foo sein:

Live On Coliru

#define BOOST_SPIRIT_X3_DEBUG 
#include <iostream> 
#include <boost/spirit/home/x3.hpp> 
#include <boost/spirit/home/x3/support/ast/variant.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 

namespace x3 = boost::spirit::x3; 

namespace ast{ 
    struct LambdaType; 
    struct ClassType; 
    struct nil{}; 

    typedef x3::variant< 
     nil, 
     x3::forward_ast<LambdaType>, 
     x3::forward_ast<ClassType> 
    > Type; 

    struct LambdaType { 
     std::vector<Type> parameters_; 
     Type return_type_; 
    }; 

    struct ClassType{ 
     std::vector<std::string> name_; 
     std::vector<Type> template_args_; 
    }; 

} 

BOOST_FUSION_ADAPT_STRUCT(ast::LambdaType, parameters_, return_type_) 
BOOST_FUSION_ADAPT_STRUCT(ast::ClassType, name_, template_args_) 

namespace parser{ 
    typedef x3::rule<struct lambda_type_class, ast::LambdaType> lambda_type_type; 
    typedef x3::rule<struct class_type_class, ast::ClassType> class_type_type; 
    typedef x3::rule<struct type_class,  ast::Type>  type_type; 

    const class_type_type class_type = "class_type"; 
    const lambda_type_type lambda_type = "lambda_type"; 
    const type_type  type_p  = "type"; 

    auto const type_p_def = class_type | lambda_type; 

    auto const lambda_type_def = 
     ("(" >> -(type_p%",") >> ")" >> "=>" >> type_p) 
     | (x3::repeat(1)[type_p%","] >> "=>" >> type_p) 
      ; 

    auto const class_type_def = 
      (x3::string("foo")%"::") >> -("<" >> type_p%"," >> ">") 
      ; 

    BOOST_SPIRIT_DEFINE(
      lambda_type, 
      class_type, 
      type_p 
    ) 
} 

int main() 
{ 
    std::string input = "(foo, foo) => foo"; 
    x3::phrase_parse(input.begin(), input.end(), parser::type_p, x3::space); 
} 

Mit Debug-Ausgabe

<type> 
    <try>(foo, foo) => foo</try> 
    <class_type> 
    <try>(foo, foo) => foo</try> 
    <fail/> 
    </class_type> 
    <lambda_type> 
    <try>(foo, foo) => foo</try> 
    <type> 
     <try>foo, foo) => foo</try> 
     <class_type> 
     <try>foo, foo) => foo</try> 
     <success>, foo) => foo</success> 
     <attributes>[[[f, o, o]], []]</attributes> 
     </class_type> 
     <success>, foo) => foo</success> 
     <attributes></attributes> 
    </type> 
    <type> 
     <try> foo) => foo</try> 
     <class_type> 
     <try> foo) => foo</try> 
     <success>) => foo</success> 
     <attributes>[[[f, o, o]], []]</attributes> 
     </class_type> 
     <success>) => foo</success> 
     <attributes></attributes> 
    </type> 
    <type> 
     <try> foo</try> 
     <class_type> 
     <try> foo</try> 
     <success></success> 
     </class_type> 
     <success></success> 
    </type> 
    <success></success> 
    </lambda_type> 
    <success></success> 
</type> 
+0

Added noch ein paar Hinweise und ein [Live-Probe] (http://coliru.stacked-crooked.com/a/b6563a54ddc9048e) – sehe

+0

das ist ein Witz ist es nicht: (Ich fühle mich jetzt so blöd, ich habe die letzten 3 Stunden ohne Erfolg debuggt. Vielen Dank fürs Öffnen meiner Augen – Exagon

+0

Ich erkannte auch die linke Rekursion, [hier] (http://stackoverflow.com/questions/39949480/boost-spirit-failing-to-parse-recursive-rule) ist meine Frage darüber habe ich mich nie zuvor mit diesem Problem befasst und ich kämpfe darum, die linke Rekursion zu vermeiden – Exagon

Verwandte Themen