c++ - Boost Spirit Qi Attribute Propagation -


i have issue boost spirit qi grammar emitting undesired type, resulting in compilation error:

error c2664: 'std::basic_string<_elem,_traits,_ax> &std::basic_string<_elem,_traits,_ax>::insert(unsigned int,const std::basic_string<_elem,_traits,_ax> &)' : cannot convert parameter 1 'std::_string_iterator<_elem,_traits,_alloc>' 'unsigned int' 

here grammar causing issue:

    qi::rule<iterator, qi::unused_type()> gr_newline;              // asmast::label() contains identifier struct emitted gr_identifier     qi::rule<iterator, asmast::label(), skipper<iterator> > gr_label;      gr_newline = +( char_('\r')                    |char_('\n')                   ); 

this fails:

gr_label = gr_identifier            >> ':'            > gr_newline; 

but following work:

// parses ok gr_label = gr_identifier            > gr_newline;  // parses ok gr_label = gr_identifier            > ':'            > gr_newline;      // parses ok     // **why work when parenthesized?**     gr_label = gr_identifier            >> (':'                 > skip_grammar.gr_newline               );  // parses ok gr_label = gr_identifier            >> omit[':'                     > gr_newline]; 

i don't understand why removing character literal or omit[]ing "fixes" problem, don't want grammar cluttered that.

according the compound attribute rules >> , > found here, , character parser attributes here, gr_label should emit asmast::label

a: a, b: b --> (a >> b): tuple<a, b> a: a, b: unused --> (a >> b):  <---- 1 here 1 should match far understand a: unused, b: b --> (a >> b): b a: unused, b: unused --> (a >> b): unused    expression attribute  c          unused or if c lazy argument, character type returned invoking it.  

however, somehow polluting intended attribute, , resulting in compiler error.

so questions grammar emits undesired attribute, , how rid of it.

the problem seems because mix , match > , >> here.

though correctly observe documented attribute generation rules, really appears happen unused side more fusion::vector1<qi::unused_type> (instead of qi::unused_type).

side note:
this explains "why work when parenthesized?" -
altering order of expression evaluation (overruling operator precedence)
, getting type.

you can find out whether hunch correct using techniques e.g. detecting parameter types in spirit semantic action.

so, short answer is: how works. whether bug, omission in documentation or feature not constructive discuss on so. refer [spirit-general] mailing list (note have active #irc channel).


the slightly longer answer is: i think there more not showing.

two things:

  1. the error message quite indicates trying insert string iterator* character (or convertible) expected. don't see connection of code posted, though can guess at

    • the use of qi::raw[] somewhere (quite likely)
    • the use of iterator_pair in 1 of ast structs (quite unlikely)
  2. i can compile "problematic" rule specimen fine embedded in "mock-up" grammar built guessing little bits exposed in previous question.

i think maybe should try post question, while showing short self contained correct example exhibits problem really having.

be sure mention compiler version , version of boost used.

fully working sscce example

#define boost_spirit_debug #include <boost/spirit/include/qi.hpp>  namespace qi    = boost::spirit::qi;  namespace asmast {     typedef std::string label; }  template <typename it, typename skipper = qi::blank_type>     struct parser : qi::grammar<it, skipper> {     parser() : parser::base_type(start)     {         using namespace qi;          start = lexeme["func" >> !(alnum | '_')] > function;         function = gr_identifier                     >> "{"                     >> -(                               gr_instruction                             | gr_label                           //| gr_vardecl                           //| gr_paramdecl                         ) % eol                     > "}";          gr_instruction_names.add("mov", unused);         gr_instruction_names.add("push", unused);         gr_instruction_names.add("exit", unused);          gr_instruction = lexeme [ gr_instruction_names >> !(alnum|"_") ] > gr_operands;         gr_operands = -(gr_operand % ',');          gr_identifier = lexeme [ alpha >> *(alnum | '_') ];         gr_operand    = gr_identifier | gr_string;         gr_string     = lexeme [ '"' >> *("\"\"" | ~char_("\"")) >> '"' ];          gr_newline = +( char_('\r')                        |char_('\n')                       );          gr_label = gr_identifier >> ':' > gr_newline;          boost_spirit_debug_nodes((start)(function)(gr_instruction)(gr_operands)(gr_identifier)(gr_operand)(gr_string));     }    private:     qi::symbols<char, qi::unused_type> gr_instruction_names;     qi::rule<it, skipper> start, function, gr_instruction, gr_operands, gr_operand, gr_string;     qi::rule<it, qi::unused_type()> gr_newline;     qi::rule<it, asmast::label(), skipper> gr_label, gr_identifier; };  int main() {     typedef boost::spirit::istream_iterator it;     std::cin.unsetf(std::ios::skipws);     f(std::cin), l;      parser<it, qi::blank_type> p;      try     {         bool ok = qi::phrase_parse(f,l,p,qi::blank);         if (ok)   std::cout << "parse success\n";         else      std::cerr << "parse failed: '" << std::string(f,l) << "'\n";          if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";         return ok;     } catch(const qi::expectation_failure<it>& e)     {         std::string frag(e.first, e.last);         std::cerr << e.what() << "'" << frag << "'\n";     }      return false; } 

Comments

Popular posts from this blog

java - activate/deactivate sonar maven plugin by profile? -

python - TypeError: can only concatenate tuple (not "float") to tuple -

java - What is the difference between String. and String.this. ? -