Re: First-class citizens with only one member causing trouble.
Frank Hein <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
Hi Florian, this reminds me of http://stackoverflow.com/questions/19823413/spirit-qi-attribute-propagation-issue-with-single-member-struct. I don't have an answer though. Regarding your compiler implementation did you examine the mini-c example provided with qi? Inspiring. Regards, Frank Von meinem iPhone gesendet > Am 31.07.2016 um 19:10 schrieb Florian Klemme <[email protected]>: > > I found another workaround I just don't understand. This works perfectly: > > // Instructions > instruction = ( // Semicolon terminated instructions > ( function_call > | variable_declaration > | variable_assignment > | print_variable > | print_text > | scan_variable > ) > ';') > // Non-semicolon terminated instructions > | if_else > | while_loop > | for_loop > | instruction_block; > > but this doesn't even compile: > > // Instructions > instruction = (function_call > ';') > | (variable_declaration > ';') > | (variable_assignment > ';') > | (print_variable > ';') > | (print_text > ';') > | (scan_variable > ';') > | if_else > | while_loop > | for_loop > | instruction_block; > >> On 29.07.2016 18:30, Florian Klemme wrote: >> Hi, >> >> I have a little compiler project in which Spirit Qi works just fine. But there is one little change I'd like to accomplish that causes quite some (compilation) trouble. Have a look at this code snippet. >> >> // Instructions >> instruction = (function_call > ';') >> | (variable_declaration > ';') >> | (variable_assignment > ';') >> | print_variable // Implicit semicolon TODO!!!? >> | print_text // Implicit semicolon >> | scan_variable // Implicit semicolon >> | if_else >> | while_loop >> | for_loop >> | instruction_block; >> >> function_call = function_name >> '(' > -(variable_name % ',') > ')'; >> variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u})); >> variable_assignment = variable_name >> '=' > expression; >> print_variable = qi::lexeme["print"] >> variable_name > ';'; >> print_text = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';'; >> scan_variable = qi::lexeme["scan"] > variable_name > ';'; >> >> Don't look to deep into what these rules are composed of, the only thing that matters is that the first three rules have their trailing ';' defined in the instruction rule and the others have their ';' in the rule itself. >> >> I want to move all tailing ';' to the instruction rule as shown in the first few lines. For the first three rules this hasn't been a problem. The literal parser ';' doesn't affect the attribute of the rule so the position shouldn't matter. >> >> But in fact, appending any literal parser before any "// Implicit semicolon" comment causes a compilation error. It took me some time to figure out why this is not a problem with the other rules. It turns out the problem is that the attribute of the problematic three rules are first-class citizens with only one member (which happens to be a string, not sure if this is relevant). >> >> So the following ugly workaround actually leads to a compiling (and working) solution. By just adding a second member to the attribute of the rule. >> diff --git a/bf/compiler.cpp b/bf/compiler.cpp >> index 6f83c00..7cea53a 100644 >> --- a/bf/compiler.cpp >> +++ b/bf/compiler.cpp >> @@ -103,6 +103,7 @@ namespace instruction { >> >> struct print_variable_t { >> std::string variable_name; >> + int dummy; >> }; >> >> struct print_text_t { >> @@ -253,7 +254,8 @@ BOOST_FUSION_ADAPT_STRUCT( >> >> BOOST_FUSION_ADAPT_STRUCT( >> bf::instruction::print_variable_t, >> - (std::string, variable_name)) >> + (std::string, variable_name) >> + (int, dummy)) >> >> BOOST_FUSION_ADAPT_STRUCT( >> bf::instruction::print_text_t, >> @@ -451,7 +453,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> { >> instruction = (function_call > ';') >> | (variable_declaration > ';') >> | (variable_assignment > ';') >> - | print_variable // Implicit semicolon TODO!!!? >> + | (print_variable > ';') // TODO!!!? >> | print_text // Implicit semicolon >> | scan_variable // Implicit semicolon >> | if_else >> @@ -462,7 +464,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> { >> function_call = function_name >> '(' > -(variable_name % ',') > ')'; >> variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u})); >> variable_assignment = variable_name >> '=' > expression; >> - print_variable = qi::lexeme["print"] >> variable_name > ';'; >> + print_variable = qi::lexeme["print"] >> variable_name > qi::attr(0); >> print_text = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';'; >> scan_variable = qi::lexeme["scan"] > variable_name > ';'; >> if_else = qi::lexeme["if"] > '(' > expression > ')' > instruction > -(qi::lexeme["else"] > instruction); >> Have a look at https://github.com/Kruecke/BFGenerator if you want to check out the whole code. The critical section is this one: https://github.com/Kruecke/BFGenerator/blob/master/bf/compiler.cpp#L454. The workaround is committed in a branch as well: https://github.com/Kruecke/BFGenerator/compare/semicolon_workaround. If you want to run the code, make sure to run "make test" as the other rules don't compile this piece of code at the moment. >> Please let me know if you have any idea how to fix this problem or what mistake I might have made. I am thankful for any ideas. Or is there a chance that this is a bug in Spirit Qi? >> >> I tested this with different versions of Boost as well as different versions of gcc and msvc. C++14 support is required. >> Florian >> >> >> ------------------------------------------------------------------------------ >> >> >> _______________________________________________ >> Spirit-general mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/spirit-general > ------------------------------------------------------------------------------ _______________________________________________ Spirit-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/spirit-general
smime.p7s
(application/pkcs7-signature, 5.1 KB) - not displayed