2016-05-26 13 views
2

Ich mag würde die folgende recusive Regel zu analysieren, die einfach hier Vorlage classe Kennung wie foo<bar> foo<bar,baz> foo<bar<baz>> parst ist die einfache Grammatik:Parsing rekursive Regeln mit Geist x3

identifier := A-Z | a-z | _ 
class_identifier = identifier ?("<" identifier|class_identifier 
            ("," identifier|class_identifier)* 
           ">") 

Ich habe versucht, einen Parser mit x3 wie folgt zu schreiben:

auto const identifier = x3::rule<class identifier_id, std::string>{"identifier"} 
          = +x3::char_("A-Za-z"); 

x3::rule<class class_identifier, std::string> class_identifier = "class_identifier"; 

auto const class_identifier_def = identifier //classname 
              >> -(x3::string("<") 
               >> (identifier | class_identifier)           
               >> *(x3::string(",")              
                 >> (identifier | class_identifier)) 
               >> x3::string(">")); 
BOOST_SPIRIT_DEFINE(class_identifier) 

aber dieser Versuch fehlschlägt Sachen wie diese foo<bar<baz>> zu analysieren, aber foo ist in Ordnung. Gibt es einen logischen Fehler in meiner Grammatik oder verwende ich Boost Spirit falsch, da dies eine rekursive Regel ist?

+1

Um Ihnen das Leben leichter zu machen, glaube ich '(identifier | class_identifier) ​​ >> * (x3 :: string ("") > > (identifier | class_identifier)) 'kann durch' (identifier | class_identifier)% x3 :: string (",") 'ersetzt werden. Ich würde mich nicht wundern, wenn das auch zu '% 'vereinfacht werden könnte, zusammen mit anderen Stellen, an denen ein Literal die Überlastung des Operators nicht stören würde. – chris

+1

In der Tat. '% ','' ist in Ordnung, – sehe

+0

auch wenn ich in eine Zeichenfolge analysieren und will das '',' 'in der Zeichenfolge? – Exagon

Antwort

3

Ich habe gefunden, warum dies nicht analysiert werden kann. Ich habe diese (identifier | class_identifier) zu dieser (class_identifier | identifier) ändern, weil es auch die class_identifier Regel beginnt mit einem identifier. das ist, warum es versucht, jedes Mal mit der identifier Regel zu analysieren und schlägt dann fehl am <

+1

Ich denke, dass derzeit der zweite Zweig des alternativen Parsers nie genommen wird. Ich habe es nicht getestet, also kann ich mich irren, aber ich bin ziemlich sicher, dass Sie den alternativen Operator nicht einmal brauchen, solange Sie das optionale in 'class_identifier' haben. Wenn Sie die Attribute in Zukunft ändern (von einer einfachen Zeichenfolge zu einer Art von AST), wäre Ihre aktuelle Definition besser (Entfernen des optionalen). – llonesmiz