title: Using Spirit qi::success callbacks to set fields after a rule match
body: <p>I am trying to use <code>qi::on_success</code> callback (<a href="https://stackoverflow.com/a/51254774/2987773">here</a>) to set a field when a rule is matched. The code below is slightly adapted from this <a href="https://stackoverflow.com/a/62970956/2987773">code</a> though my slight changes to the rules/ast class has made it no to recognize <code>_rule_name</code>. My intention is commented in the code below. I want to set the field <code>term_type</code> to <code>TermType::literal</code> if the <code>_literal</code> rule is matched or to <code>Term::rule_name</code> if <code>_rule_name</code> rule is matched.</p>
  <pre><code>//#define BOOST_SPIRIT_DEBUG
  #include &lt;boost/spirit/include/qi.hpp&gt;
  #include &lt;boost/fusion/adapted.hpp&gt;
  #include &lt;iomanip&gt;
  
  namespace qi = boost::spirit::qi;
  
  namespace Ast {
      enum class TermType {
          literal,
          rule_name
      };
  
  
      struct Term {
          std::string data;
          TermType term_type;
      };
  
      using List = std::list&lt;Term&gt;;
      using Expression = std::list&lt;List&gt;;
  
      struct Rule {
          Term name; // lhs
          Expression rhs;
      };
  
      using Syntax = std::list&lt;Rule&gt;;
  }
  BOOST_FUSION_ADAPT_STRUCT(Ast::Term, data)
  BOOST_FUSION_ADAPT_STRUCT(Ast::Rule, name, rhs)
  
  namespace Parser {
      template&lt;typename Iterator&gt;
      struct BNF : qi::grammar&lt;Iterator, Ast::Syntax()&gt; {
          BNF() : BNF::base_type(start) {
              using namespace qi;
              _blank = blank;
              _skipper = blank | (eol &gt;&gt; !skip(_blank.alias())[_rule]);
              start = skip(_skipper.alias())[_rule % +eol];
  
              _rule = _rule_name &gt;&gt; &quot;::=&quot; &gt;&gt; _expression;
              _expression = _list % '|';
              _list = +(_literal | _rule_name);
              _literal = '&quot;' &gt;&gt; *(_character - '&quot;') &gt;&gt; '&quot;'
                      | &quot;'&quot; &gt;&gt; *(_character - &quot;'&quot;) &gt;&gt; &quot;'&quot;;
              _character = alnum | char_(&quot;\&quot;'| !#$%&amp;()*+,./:;&gt;=&lt;?@]\\^_`{}~[-&quot;);
              _rule_name = '&lt;' &gt;&gt; (alpha &gt;&gt; *(alnum | char_('-'))) &gt;&gt; '&gt;';
  
              BOOST_SPIRIT_DEBUG_NODES(
                      (_rule)(_expression)(_list)(_literal)
                              (_character)
                              (_rule_name))
          }
  
          /*qi::on_success(_term, setTermTypeHandler());
  
          setTermTypeHandler(){
               if term is literal
                  term.symbol_type = TermType::literal
              else
                  term.term_type = TermType::rule_name
          }
          */
  
      private:
          using Skipper = qi::rule&lt;Iterator&gt;;
          Skipper _skipper, _blank;
  
          qi::rule&lt;Iterator, Ast::Syntax()&gt; start;
          qi::rule&lt;Iterator, Ast::Rule(), Skipper&gt; _rule;
          qi::rule&lt;Iterator, Ast::Expression(), Skipper&gt; _expression;
          qi::rule&lt;Iterator, Ast::List(), Skipper&gt; _list;
          // lexemes
          qi::rule&lt;Iterator, Ast::Term()&gt; _literal;
          qi::rule&lt;Iterator, Ast::Term()&gt; _rule_name;
          //  qi::rule&lt;Iterator, std::string()&gt;     _literal;
          qi::rule&lt;Iterator, char()&gt; _character;
      };
  }
  
  int main() {
      Parser::BNF&lt;std::string::const_iterator&gt; const parser;
  
      std::string const input = R&quot;(&lt;code&gt;   ::=  &lt;letter&gt;&lt;digit&gt; | &lt;letter&gt;&lt;digit&gt;&lt;code&gt;
  &lt;letter&gt; ::= &quot;a&quot; | &quot;b&quot; | &quot;c&quot; | &quot;d&quot; | &quot;e&quot;
             | &quot;f&quot; | &quot;g&quot; | &quot;h&quot; | &quot;i&quot;
  &lt;digit&gt;  ::= &quot;0&quot; | &quot;1&quot; | &quot;2&quot; | &quot;3&quot; |
               &quot;4&quot;
      )&quot;;
  
      auto it = input.begin(), itEnd = input.end();
  
      Ast::Syntax syntax;
      if (parse(it, itEnd, parser, syntax)) {
          for (auto &amp;rule : syntax) {
              std::cout &lt;&lt; rule.name.data &lt;&lt; &quot; ::= &quot;;
              std::string sep;
              for (auto &amp;list : rule.rhs) {
                  std::cout &lt;&lt; sep;
                  for (auto &amp;term: list) { std::cout &lt;&lt; term.data; }
                  sep = &quot; | &quot;;
              };
              std::cout &lt;&lt; &quot;\n&quot;;
          }
      } else {
          std::cout &lt;&lt; &quot;Failed\n&quot;;
      }
  
      if (it != itEnd)
          std::cout &lt;&lt; &quot;Remaining: &quot; &lt;&lt; std::quoted(std::string(it, itEnd)) &lt;&lt; &quot;\n&quot;;
  }
  
  </code></pre>