Ich schreibe einen kleinen Compiler nur zum Spaß und ich benutze Boost Spirit Qi, um meine Grammatik zu beschreiben. Jetzt möchte ich eine kleine Änderung in der Grammatik vornehmen, um einige weitere Ergänzungen vorzubereiten. Leider werden diese Änderungen nicht kompiliert und ich würde gerne verstehen, warum das so ist.Boost Spirit Qi: Kompilierfehler bei geringfügiger Regeländerung
Hier ist ein Ausschnitt aus dem Code, den ich ändern möchte. Ich hoffe, dass die bereitgestellten Informationen ausreichen, um die Idee zu verstehen. Der vollständige Code ist ein bisschen groß, aber wenn Sie ihn anschauen oder sogar testen wollen (Makefile und Travis CI wird mitgeliefert), siehe https://github.com/Kruecke/BFGenerator/blob/8f66aa5/bf/compiler.cpp#L433.
typedef boost::variant<
function_call_t,
variable_declaration_t,
variable_assignment_t,
// ...
> instruction_t;
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
grammar() : grammar::base_type(program) {
instruction = function_call
| variable_declaration
| variable_assignment
// | ...
;
function_call = function_name >> '(' > -(variable_name % ',') > ')' > ';';
// ...
}
qi::rule<iterator, instruction::instruction_t(), ascii::space_type> instruction;
qi::rule<iterator, instruction::function_call_t(), ascii::space_type> function_call;
// ...
};
Bis jetzt funktioniert alles nur gut. Jetzt möchte ich das Parsen des abschließenden Semikolons (> ';'
) von der function_call
Regel zur instruction
Regel verschieben. Mein Code sieht nun wie folgt aus:
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
grammar() : grammar::base_type(program) {
instruction = (function_call > ';') // Added trailing semicolon
| variable_declaration
| variable_assignment
// | ...
;
// Removed trailing semicolon here:
function_call = function_name >> '(' > -(variable_name % ',') > ')';
// ...
}
Von meinem Verständnis haben die Regeln nicht wirklich geändert, weil der Charakter-Parser ';'
keine Attribut ergeben und so sollte es keine Rolle, wo diese Parser positioniert ist. Allerdings wird diese Änderung nicht kompilieren:
/usr/include/boost/spirit/home/support/container.hpp:278:13: error: no matching function for call to ‘std::basic_string<char>::insert(std::basic_string<char>::iterator, const bf::instruction::function_call_t&)’
c.insert(c.end(), val);
^
(Dieser Fehler kommt von der instruction = ...
Linie.)
Warum ist diese Änderung Kompilieren nicht? Ich bin eher auf der Suche nach einer Erklärung, um zu verstehen, was vor sich geht, als ein Workaround.
Sie haben absolut Recht! Da ich in 'function_call_t' nur einen' std :: string' hatte, war ich nie so, wie ich es mir vorgestellt habe. Daher bin ich sehr überrascht, dass mein vorheriger Code überhaupt gelaufen ist! Ich habe meiner Struktur einen 'std :: vector variable_names' hinzugefügt, der das Problem sofort behebt. Danke vielmals! –