2017-07-11 8 views
2

Ich habe eine Frage zu semantischen Aktionen auf Boost-Geist mit dem „>“ Operatorsemantische Aktionen mit „>“ Operator

Ich habe diese Regel, die perfekt funktioniert ..

   ifelse = (iter_pos >> 
         nocaselit(L"if") >> expression >> nocaselit(L"then") >> 
          block_statements_eol >> -ifelse_ifelse >> nocaselit(L"end") >> nocaselit(L"if") >> 
         iter_pos) 
       [_val = construct<common_node>(type_cmd_ifelse,LOCATION(_1,_5), key_cond, _2, key_seq, _3, key_else, phoenix::bind(&makeOptNode, _4))]; 

einig hinzufügen Fehlerbehandlung Ich füge auch den on_error stuff zu meinem Parser hinzu. Soweit ich das verstanden habe, muss ich auch "Erwartungspunkte" für Boost hinzufügen, um den Fehler korrekt auszugeben

Also ändere ich die Grammatik in diese (ersetze das >> mit>), um Informationen über Stop-Backtracking und Fehlerberichte zu geben.

   ifelse = (iter_pos >> 
         nocaselit(L"if") > expression > nocaselit(L"then") >> 
          block_statements_eol > -ifelse_ifelse > nocaselit(L"end") > nocaselit(L"if") >> 
         iter_pos) 
       [_val = construct<common_node>(type_cmd_ifelse,LOCATION(_1,_5), key_cond, _2, key_seq, _3, key_else, phoenix::bind(&makeOptNode, _4))]; 

An dieser Stelle ich den C++ Compiler-Fehler ungültiger Index erhalten für _3 und _4 .. so scheint es, dass die semantische Aktion geändert in irgendeiner Weise werden muss, aber ich habe keine Ahnung, wie.

Antwort

1

Die Operatorpriorität ändert die Struktur des synthetisierten Attributs.

Zum Beispiel synthetisieren beide int_ >> int_ >> int_ und int_ > int_ > int_ eine tuple<int, int, int>, aber wenn Sie die Operatoren unterschiedlicher Präzedenz mischen, erhalten Sie z.B. tuple<int, tuple<int, int> > oder tuple<tuple<int, int>, int>/

Nun würde dies für viele automatische Attributausbreitungsszenarien nicht schaden. Bei semantischen Aktionen wird jedoch die Syntax geändert, um das Attribut zu analysieren (siehe fusion::at_c<> und phoenix::at_c<>).

Es gibt eine Chance, dass die unter dokumentierte

#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT 

in bestimmten Umständen helfen könnte, aber ansonsten einfach damit umgehen.

Im Allgemeinen ist die Vermeidung semantischer Aktionen eine gute Richtlinie (Boost Spirit: "Semantic actions are evil"?).