Boost::Spirit: Application SUCCESS, crash at: printer(ast) ... why?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Boost::Spirit: Application SUCCESS, crash at: printer(ast) ... why?

Jens Kallup
Hello,

I have the problem, that the visitor does endless
loop, and crash after a while.
The problem is on:

void operator()(expression_ast const& ast) const
{
   boost::apply_visitor(*this, ast.expr);
}

How can this be fixed?

Thanks for helping
Jens

here the run/compileable source:

#include "includes/mainwindow.h"

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/get.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/lexical_cast.hpp>

#include <boost/bind.hpp>
#include <boost/ref.hpp>

#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <utility>

int lineno = 1;


using namespace std;
using namespace boost::spirit;

namespace bs    = boost::spirit;
namespace phx   = boost::phoenix;
namespace ascii = boost::spirit::ascii;

using boost::spirit::ascii::space; // use the ASCII space parser
using boost::spirit::ascii::char_;
using boost::spirit::_val;

using boost::phoenix::val;

struct print_testclass
{
     print_testclass() {}
     print_testclass(std::string str1, std::string str2)
     {
         cout << str1 << " = " << str2 << endl;
     }
};

namespace dBaseParser
{
     // -----------------
     // AST for dBase ...
     // -----------------
     struct binary_op;
     struct unary_op;
     struct nil {};

     struct expression_ast
     {
         typedef
             boost::variant<
                 nil // can't happen!
               , int
               , boost::recursive_wrapper<expression_ast>
               , boost::recursive_wrapper<binary_op>
               , boost::recursive_wrapper<unary_op>
             >
         type;

         expression_ast()
           : expr(nil()) {}

         template <typename Expr>
         expression_ast(Expr const& expr) : expr(expr) {}

         expression_ast& operator+=(expression_ast const& rhs);
         expression_ast& operator-=(expression_ast const& rhs);
         expression_ast& operator*=(expression_ast const& rhs);
         expression_ast& operator/=(expression_ast const& rhs);

         type expr;
     };

     struct binary_op
     {
         binary_op(
             char op
           , expression_ast const& left
           , expression_ast const& right)
         : op(op), left(left), right(right) {}

         char op;
         expression_ast left;
         expression_ast right;
     };

     struct unary_op
     {
         unary_op(
             char op
           , expression_ast const& subject)
         : op(op), subject(subject) {}

         char op;
         expression_ast subject;
     };

     expression_ast& expression_ast::operator+=(expression_ast const& rhs)
     {
         expr = binary_op('+', expr, rhs);
         return *this;
     }

     expression_ast& expression_ast::operator-=(expression_ast const& rhs)
     {
         expr = binary_op('-', expr, rhs);
         return *this;
     }

     expression_ast& expression_ast::operator*=(expression_ast const& rhs)
     {
         expr = binary_op('*', expr, rhs);
         return *this;
     }

     expression_ast& expression_ast::operator/=(expression_ast const& rhs)
     {
         expr = binary_op('/', expr, rhs);
         return *this;
     }

     std::ostream& operator << (std::ostream& os, const expression_ast& as)
     {
         return os
                 << boost::get<binary_op>(as.expr).left
                 //<< " = "
                 //<< boost::get<binary_op>(as.expr).right;
                 << endl;
     }

     // ------------------------------------------------------------
     // We should be using expression_ast::operator-. There's a bug
     // in phoenix type deduction mechanism that prevents us from
     // doing so. Phoenix will be switching to BOOST_TYPEOF. In the
     // meantime, we will use a phoenix::function below:
     // ------------------------------------------------------------
     struct negate_expr
     {
         template <typename T>
         struct result { typedef T type; };

         expression_ast operator()(expression_ast const& expr) const
         {
             return expression_ast(unary_op('-', expr));
         }
     };

     boost::phoenix::function<negate_expr> neg;

     // -----------------------
     // walk throug the AST ...
     // -----------------------
     struct ast_print
     {
         typedef void result_type;

         void operator()(qi::info::nil) const {}
         void operator()(int n) const { std::cout << n; }

         void operator()(expression_ast const& ast) const
         {
             boost::apply_visitor(*this, ast.expr);

             //int i = boost::get<int>(ast.expr);
             //cout << "1 = " << (int)i << endl;
         }

         void operator()(binary_op const& expr) const
         {
             std::cout << "op:" << expr.op << "(";
             boost::apply_visitor(*this, expr.left.expr);
             std::cout << ", ";
             boost::apply_visitor(*this, expr.right.expr);
             std::cout << ')';
         }

         void operator()(unary_op const& expr) const
         {
             std::cout << "op:" << expr.op << "(";
             boost::apply_visitor(*this, expr.subject.expr);
             std::cout << ')';
         }
     };

     template <typename Lexer>
     struct dbase_tokens : lex::lexer<Lexer>
     {
         // ----------------------------
         // tokens with no attributes...
         // ----------------------------
         lex::token_def<lex::omit> whitespace;
         lex::token_def<lex::omit> cpcomment;
         lex::token_def<lex::omit> d_comment;
         lex::token_def<lex::omit> c_comment;

         lex::token_def<lex::omit> kw_class;
         lex::token_def<lex::omit> kw_of;
         lex::token_def<lex::omit> kw_endclass;

         // --------------------------
         // tokens with attributes ...
         // --------------------------
         lex::token_def<char> printLn;

         lex::token_def<int>         number_digit;
         lex::token_def<std::string> identifier;
         lex::token_def<std::string> quoted_string;

         dbase_tokens()
         {
             // ------------
             // keywords ...
             // ------------
             kw_class        = "(?i:class)";
             kw_endclass     = "(?i:endclass)";
             kw_of           = "(?i:of)";

             printLn   = "\\\?";

             // Values.
             number_digit      = "[0-9]+";
             quoted_string     = "\\\"(\\\\.|[^\\\"])*\\\""; //
\"(\\.|[^\"])*\"

             // Identifier.
             identifier        = "[a-zA-Z][a-zA-Z0-9_]*";

             cpcomment = "\\/\\/[^\\n]*\\n";                    //
single line comment
             d_comment = "\\*\\*[^\\n]*\\n";                    //
dBase  line comment
             c_comment = "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"; //
c-style comments

             whitespace = "[ \\t\\n]+";

             this->self += lex::token_def<>
                     ('(') | ')'
                     | '+' | '-'
                     | '*' | '/'
                     | ',' | '.';
             this->self +=
                 printLn
                 ;
             this->self +=
                 kw_class | kw_of | kw_endclass
                 ;
             this->self +=
                   identifier
                 | number_digit
                 | quoted_string
                 ;

             this->self +=
                   whitespace [ lex::_pass = lex::pass_flags::pass_ignore ]
                 | cpcomment
                 | c_comment
                 | d_comment
                 ;
         }
     };

     template <typename Iterator, typename Lexer>
     struct dbase_grammar
     :   public qi::grammar<Iterator>
     {   template <typename TokenDef>

         dbase_grammar(TokenDef const& tok) :
         dbase_grammar::base_type(start, "start")
         {
             using qi::_val;

             start
                 = +symsbols
                 ;

             expression =
                 term                            [_val  = qi::_1]
                 >> *(   ('+' >> term            [_val += qi::_1])
                     |   ('-' >> term            [_val -= qi::_1])
                     )
                 ;

             term =
                 factor                          [_val  = qi::_1]
                 >> *(   ('*' >> factor          [_val *= qi::_1])
                     |   ('/' >> factor          [_val /= qi::_1])
                     )
                 ;

             factor =
                 tok.number_digit                [_val = qi::_1]
                 |  '('   >> expression          [_val = qi::_1] >> ')'
                 |   ('-' >> factor              [_val = neg(qi::_1)])
                 |   ('+' >> factor              [_val = qi::_1])
                 ;

             symsbols
                 = printLn
                 | comments
                 | class_definition
                 | expression
                 ;

             comments
                 = tok.cpcomment
                 | tok.c_comment
                 | tok.d_comment
                 ;

             printLn
                 = tok.printLn >> *comments >> tok.quoted_string
                 | tok.printLn >> tok.quoted_string
                 ;

             class_definition
                 = (tok.kw_class          >> *comments
                     >> tok.identifier    >> *comments
                     >> tok.kw_of         >> *comments
                     >> tok.identifier    >> *comments >> class_body
                     >> tok.kw_endclass)
                     [
                         qi::_val = phx::construct<print_testclass>(
                         phx::construct<std::string>(qi::_1),
                         phx::construct<std::string>(qi::_2))
                     ]
                 ;
             class_body
                 = *comments
                 ;

             start.name("start");
             symsbols.name("symsbols");
             comments.name("comments");
             expression.name("expression");
             term.name("term");
             factor.name("factor");
             printLn.name("printLn");
             class_definition.name("class_definition");
             class_body.name("class_body");

             BOOST_SPIRIT_DEBUG_NODE(start);
             BOOST_SPIRIT_DEBUG_NODE(symsbols);
             BOOST_SPIRIT_DEBUG_NODE(comments);
             BOOST_SPIRIT_DEBUG_NODE(printLn);
             BOOST_SPIRIT_DEBUG_NODE(class_definition);
             BOOST_SPIRIT_DEBUG_NODE(class_body);
             BOOST_SPIRIT_DEBUG_NODE(factor);
             BOOST_SPIRIT_DEBUG_NODE(term);
             BOOST_SPIRIT_DEBUG_NODE(expression);

             using namespace qi::labels;
             qi::on_error<qi::fail>
             (
                 start,
                 std::cout
                     << phx::val("Error! Expecting ")
                     << bs::_4 // what failed?
                     << phx::val(" here: \"")
                     << phx::construct<std::string>(bs::_3, bs::_2)   //
iterators to error-pos, end
                     << phx::val("\"")
                     << std::endl
             );
         }

         typedef qi::unused_type skipper_type;
         typedef qi::rule<Iterator, skipper_type> simple_rule;

         simple_rule start, symsbols, comments, printLn;
         simple_rule class_body;

         qi::rule<Iterator, print_testclass()> class_definition;
         qi::rule<Iterator, expression_ast()> expression, term, factor;
     };
}

bool parseText(QString text)
{
     std::string data(text.toStdString().c_str());
     if (data.size() < 1) {
         QMessageBox::information(0,"Error","No Data for parser.\nABORT.");
         return false;
     }

     using dBaseParser::expression_ast;
     using dBaseParser::ast_print;

     typedef std::string::iterator base_iterator_type;
     typedef lex::lexertl::token<
         base_iterator_type, boost::mpl::vector<char, int, std::size_t,
std::string>
     > token_type;
     typedef lex::lexertl::actor_lexer<token_type> lexer_type;

     typedef dBaseParser::dbase_tokens<lexer_type> dbase_tokens;
     typedef dbase_tokens::iterator_type iterator_type;
     typedef dBaseParser::dbase_grammar<iterator_type,
dbase_tokens::lexer_def> dbase_grammar;

     dbase_tokens  tokens;
     dbase_grammar dbase(tokens);

     base_iterator_type it = data.begin();
     iterator_type iter    = tokens.begin(it, data.end());
     iterator_type end     = tokens.end();

     dBaseParser::expression_ast ast;
     dBaseParser::ast_print  printer;

     bool r = qi::parse(iter, end, dbase, ast);

     if (r && iter == end) {
         QMessageBox::information(w,"text parser","SUCCESS");
printer(ast); } else
         QMessageBox::information(w,"text parser","ERROR");

     return 0;
}


------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Boost::Spirit: Application SUCCESS, crash at: printer(ast) ... why?

Philipp Schwaha-2
Hi Jens,

On 07/15/2016 01:56 AM, Jens Kallup wrote:

> Hello,
>
> I have the problem, that the visitor does endless
> loop, and crash after a while.
> The problem is on:
>
> void operator()(expression_ast const& ast) const
> {
>    boost::apply_visitor(*this, ast.expr);
> }
>
> How can this be fixed?
I noticed that you define a 'nil' type, but use qi::info::nil in the
visitor. Is there a particular reason for this?
I modified the code so it compiles for me (with both g++ and clang++ in
c++11 mode). The visitor will not crash in this form.
Did you have a look at
http://www.boost.org/doc/libs/1_61_0/libs/spirit/doc/html/spirit/support/utree.html 
for representing the ast?

Best regards
        Philipp


>
> Thanks for helping
> Jens
>
> here the run/compileable source:
>
> #include "includes/mainwindow.h"
>
> #define BOOST_SPIRIT_USE_PHOENIX_V3
> #include <boost/config/warning_disable.hpp>
> #include <boost/spirit/include/lex_lexertl.hpp>
> #include <boost/spirit/include/qi.hpp>
> #include <boost/spirit/include/lex_lexertl.hpp>
> #include <boost/spirit/include/phoenix.hpp>
> #include <boost/spirit/include/phoenix_operator.hpp>
> #include <boost/spirit/include/phoenix_container.hpp>
> #include <boost/spirit/include/phoenix_function.hpp>
> #include <boost/spirit/include/karma.hpp>
> #include <boost/fusion/include/adapt_struct.hpp>
> #include <boost/fusion/include/std_pair.hpp>
> #include <boost/variant/recursive_variant.hpp>
> #include <boost/variant/apply_visitor.hpp>
> #include <boost/variant/get.hpp>
>
> #include <boost/algorithm/string.hpp>
> #include <boost/shared_ptr.hpp>
> #include <boost/make_shared.hpp>
> #include <boost/lexical_cast.hpp>
>
> #include <boost/bind.hpp>
> #include <boost/ref.hpp>
>
> #include <iostream>
> #include <fstream>
> #include <string>
> #include <set>
> #include <utility>
>
> int lineno = 1;
>
>
> using namespace std;
> using namespace boost::spirit;
>
> namespace bs    = boost::spirit;
> namespace phx   = boost::phoenix;
> namespace ascii = boost::spirit::ascii;
>
> using boost::spirit::ascii::space; // use the ASCII space parser
> using boost::spirit::ascii::char_;
> using boost::spirit::_val;
>
> using boost::phoenix::val;
>
> struct print_testclass
> {
>      print_testclass() {}
>      print_testclass(std::string str1, std::string str2)
>      {
>          cout << str1 << " = " << str2 << endl;
>      }
> };
>
> namespace dBaseParser
> {
>      // -----------------
>      // AST for dBase ...
>      // -----------------
>      struct binary_op;
>      struct unary_op;
>      struct nil {};
>
>      struct expression_ast
>      {
>          typedef
>              boost::variant<
>                  nil // can't happen!
>                , int
>                , boost::recursive_wrapper<expression_ast>
>                , boost::recursive_wrapper<binary_op>
>                , boost::recursive_wrapper<unary_op>
>              >
>          type;
>
>          expression_ast()
>            : expr(nil()) {}
>
>          template <typename Expr>
>          expression_ast(Expr const& expr) : expr(expr) {}
>
>          expression_ast& operator+=(expression_ast const& rhs);
>          expression_ast& operator-=(expression_ast const& rhs);
>          expression_ast& operator*=(expression_ast const& rhs);
>          expression_ast& operator/=(expression_ast const& rhs);
>
>          type expr;
>      };
>
>      struct binary_op
>      {
>          binary_op(
>              char op
>            , expression_ast const& left
>            , expression_ast const& right)
>          : op(op), left(left), right(right) {}
>
>          char op;
>          expression_ast left;
>          expression_ast right;
>      };
>
>      struct unary_op
>      {
>          unary_op(
>              char op
>            , expression_ast const& subject)
>          : op(op), subject(subject) {}
>
>          char op;
>          expression_ast subject;
>      };
>
>      expression_ast& expression_ast::operator+=(expression_ast const& rhs)
>      {
>          expr = binary_op('+', expr, rhs);
>          return *this;
>      }
>
>      expression_ast& expression_ast::operator-=(expression_ast const& rhs)
>      {
>          expr = binary_op('-', expr, rhs);
>          return *this;
>      }
>
>      expression_ast& expression_ast::operator*=(expression_ast const& rhs)
>      {
>          expr = binary_op('*', expr, rhs);
>          return *this;
>      }
>
>      expression_ast& expression_ast::operator/=(expression_ast const& rhs)
>      {
>          expr = binary_op('/', expr, rhs);
>          return *this;
>      }
>
>      std::ostream& operator << (std::ostream& os, const expression_ast& as)
>      {
>          return os
>                  << boost::get<binary_op>(as.expr).left
>                  //<< " = "
>                  //<< boost::get<binary_op>(as.expr).right;
>                  << endl;
>      }
>
>      // ------------------------------------------------------------
>      // We should be using expression_ast::operator-. There's a bug
>      // in phoenix type deduction mechanism that prevents us from
>      // doing so. Phoenix will be switching to BOOST_TYPEOF. In the
>      // meantime, we will use a phoenix::function below:
>      // ------------------------------------------------------------
>      struct negate_expr
>      {
>          template <typename T>
>          struct result { typedef T type; };
>
>          expression_ast operator()(expression_ast const& expr) const
>          {
>              return expression_ast(unary_op('-', expr));
>          }
>      };
>
>      boost::phoenix::function<negate_expr> neg;
>
>      // -----------------------
>      // walk throug the AST ...
>      // -----------------------
>      struct ast_print
>      {
>          typedef void result_type;
>
>          void operator()(qi::info::nil) const {}
>          void operator()(int n) const { std::cout << n; }
>
>          void operator()(expression_ast const& ast) const
>          {
>              boost::apply_visitor(*this, ast.expr);
>
>              //int i = boost::get<int>(ast.expr);
>              //cout << "1 = " << (int)i << endl;
>          }
>
>          void operator()(binary_op const& expr) const
>          {
>              std::cout << "op:" << expr.op << "(";
>              boost::apply_visitor(*this, expr.left.expr);
>              std::cout << ", ";
>              boost::apply_visitor(*this, expr.right.expr);
>              std::cout << ')';
>          }
>
>          void operator()(unary_op const& expr) const
>          {
>              std::cout << "op:" << expr.op << "(";
>              boost::apply_visitor(*this, expr.subject.expr);
>              std::cout << ')';
>          }
>      };
>
>      template <typename Lexer>
>      struct dbase_tokens : lex::lexer<Lexer>
>      {
>          // ----------------------------
>          // tokens with no attributes...
>          // ----------------------------
>          lex::token_def<lex::omit> whitespace;
>          lex::token_def<lex::omit> cpcomment;
>          lex::token_def<lex::omit> d_comment;
>          lex::token_def<lex::omit> c_comment;
>
>          lex::token_def<lex::omit> kw_class;
>          lex::token_def<lex::omit> kw_of;
>          lex::token_def<lex::omit> kw_endclass;
>
>          // --------------------------
>          // tokens with attributes ...
>          // --------------------------
>          lex::token_def<char> printLn;
>
>          lex::token_def<int>         number_digit;
>          lex::token_def<std::string> identifier;
>          lex::token_def<std::string> quoted_string;
>
>          dbase_tokens()
>          {
>              // ------------
>              // keywords ...
>              // ------------
>              kw_class        = "(?i:class)";
>              kw_endclass     = "(?i:endclass)";
>              kw_of           = "(?i:of)";
>
>              printLn   = "\\\?";
>
>              // Values.
>              number_digit      = "[0-9]+";
>              quoted_string     = "\\\"(\\\\.|[^\\\"])*\\\""; //
> \"(\\.|[^\"])*\"
>
>              // Identifier.
>              identifier        = "[a-zA-Z][a-zA-Z0-9_]*";
>
>              cpcomment = "\\/\\/[^\\n]*\\n";                    //
> single line comment
>              d_comment = "\\*\\*[^\\n]*\\n";                    //
> dBase  line comment
>              c_comment = "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"; //
> c-style comments
>
>              whitespace = "[ \\t\\n]+";
>
>              this->self += lex::token_def<>
>                      ('(') | ')'
>                      | '+' | '-'
>                      | '*' | '/'
>                      | ',' | '.';
>              this->self +=
>                  printLn
>                  ;
>              this->self +=
>                  kw_class | kw_of | kw_endclass
>                  ;
>              this->self +=
>                    identifier
>                  | number_digit
>                  | quoted_string
>                  ;
>
>              this->self +=
>                    whitespace [ lex::_pass = lex::pass_flags::pass_ignore ]
>                  | cpcomment
>                  | c_comment
>                  | d_comment
>                  ;
>          }
>      };
>
>      template <typename Iterator, typename Lexer>
>      struct dbase_grammar
>      :   public qi::grammar<Iterator>
>      {   template <typename TokenDef>
>
>          dbase_grammar(TokenDef const& tok) :
>          dbase_grammar::base_type(start, "start")
>          {
>              using qi::_val;
>
>              start
>                  = +symsbols
>                  ;
>
>              expression =
>                  term                            [_val  = qi::_1]
>                  >> *(   ('+' >> term            [_val += qi::_1])
>                      |   ('-' >> term            [_val -= qi::_1])
>                      )
>                  ;
>
>              term =
>                  factor                          [_val  = qi::_1]
>                  >> *(   ('*' >> factor          [_val *= qi::_1])
>                      |   ('/' >> factor          [_val /= qi::_1])
>                      )
>                  ;
>
>              factor =
>                  tok.number_digit                [_val = qi::_1]
>                  |  '('   >> expression          [_val = qi::_1] >> ')'
>                  |   ('-' >> factor              [_val = neg(qi::_1)])
>                  |   ('+' >> factor              [_val = qi::_1])
>                  ;
>
>              symsbols
>                  = printLn
>                  | comments
>                  | class_definition
>                  | expression
>                  ;
>
>              comments
>                  = tok.cpcomment
>                  | tok.c_comment
>                  | tok.d_comment
>                  ;
>
>              printLn
>                  = tok.printLn >> *comments >> tok.quoted_string
>                  | tok.printLn >> tok.quoted_string
>                  ;
>
>              class_definition
>                  = (tok.kw_class          >> *comments
>                      >> tok.identifier    >> *comments
>                      >> tok.kw_of         >> *comments
>                      >> tok.identifier    >> *comments >> class_body
>                      >> tok.kw_endclass)
>                      [
>                          qi::_val = phx::construct<print_testclass>(
>                          phx::construct<std::string>(qi::_1),
>                          phx::construct<std::string>(qi::_2))
>                      ]
>                  ;
>              class_body
>                  = *comments
>                  ;
>
>              start.name("start");
>              symsbols.name("symsbols");
>              comments.name("comments");
>              expression.name("expression");
>              term.name("term");
>              factor.name("factor");
>              printLn.name("printLn");
>              class_definition.name("class_definition");
>              class_body.name("class_body");
>
>              BOOST_SPIRIT_DEBUG_NODE(start);
>              BOOST_SPIRIT_DEBUG_NODE(symsbols);
>              BOOST_SPIRIT_DEBUG_NODE(comments);
>              BOOST_SPIRIT_DEBUG_NODE(printLn);
>              BOOST_SPIRIT_DEBUG_NODE(class_definition);
>              BOOST_SPIRIT_DEBUG_NODE(class_body);
>              BOOST_SPIRIT_DEBUG_NODE(factor);
>              BOOST_SPIRIT_DEBUG_NODE(term);
>              BOOST_SPIRIT_DEBUG_NODE(expression);
>
>              using namespace qi::labels;
>              qi::on_error<qi::fail>
>              (
>                  start,
>                  std::cout
>                      << phx::val("Error! Expecting ")
>                      << bs::_4 // what failed?
>                      << phx::val(" here: \"")
>                      << phx::construct<std::string>(bs::_3, bs::_2)   //
> iterators to error-pos, end
>                      << phx::val("\"")
>                      << std::endl
>              );
>          }
>
>          typedef qi::unused_type skipper_type;
>          typedef qi::rule<Iterator, skipper_type> simple_rule;
>
>          simple_rule start, symsbols, comments, printLn;
>          simple_rule class_body;
>
>          qi::rule<Iterator, print_testclass()> class_definition;
>          qi::rule<Iterator, expression_ast()> expression, term, factor;
>      };
> }
>
> bool parseText(QString text)
> {
>      std::string data(text.toStdString().c_str());
>      if (data.size() < 1) {
>          QMessageBox::information(0,"Error","No Data for parser.\nABORT.");
>          return false;
>      }
>
>      using dBaseParser::expression_ast;
>      using dBaseParser::ast_print;
>
>      typedef std::string::iterator base_iterator_type;
>      typedef lex::lexertl::token<
>          base_iterator_type, boost::mpl::vector<char, int, std::size_t,
> std::string>
>      > token_type;
>      typedef lex::lexertl::actor_lexer<token_type> lexer_type;
>
>      typedef dBaseParser::dbase_tokens<lexer_type> dbase_tokens;
>      typedef dbase_tokens::iterator_type iterator_type;
>      typedef dBaseParser::dbase_grammar<iterator_type,
> dbase_tokens::lexer_def> dbase_grammar;
>
>      dbase_tokens  tokens;
>      dbase_grammar dbase(tokens);
>
>      base_iterator_type it = data.begin();
>      iterator_type iter    = tokens.begin(it, data.end());
>      iterator_type end     = tokens.end();
>
>      dBaseParser::expression_ast ast;
>      dBaseParser::ast_print  printer;
>
>      bool r = qi::parse(iter, end, dbase, ast);
>
>      if (r && iter == end) {
>          QMessageBox::information(w,"text parser","SUCCESS");
> printer(ast); } else
>          QMessageBox::information(w,"text parser","ERROR");
>
>      return 0;
> }
>
>
> ------------------------------------------------------------------------------
> What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
> patterns at an interface-level. Reveals which users, apps, and protocols are
> consuming the most bandwidth. Provides multi-vendor support for NetFlow,
> J-Flow, sFlow and other flows. Make informed decisions using capacity planning
> reports.http://sdm.link/zohodev2dev
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
>

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

test.cpp (13K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Boost::Spirit: Application SUCCESS, crash at: printer(ast) ... why?

Philipp Schwaha-2
Hi Jens,

looking at this again I see that you only build a partial tree.
What I mean is that not all of the rules in the grammar (as well as the
grammar itself) do not have attributes to expose the collected results.

Take a look at a further modified version of the code you provided. I
added qi::debug statements and provided operater<< for expression_ast,
binary_op and unary_op. Running it on the input "2+3" give the following:

<start>
   <try>[2][+][3]</try>
   <symsbols>
     <try>[2][+][3]</try>
     <expression>
       <try>[2][+][3]</try>
       <term>
         <try>[2][+][3]</try>
         <factor>
           <try>[2][+][3]</try>
           <success>[+][3]</success>
           <attributes>[expression_ast int value: 2]</attributes>
         </factor>
         <success>[+][3]</success>
         <attributes>[expression_ast int value: 2]</attributes>
       </term>
       <term>
         <try>[3]</try>
         <factor>
           <try>[3]</try>
           <success></success>
           <attributes>[expression_ast int value: 3]</attributes>
         </factor>
         <success></success>
         <attributes>[expression_ast int value: 3]</attributes>
       </term>
       <success></success>
       <attributes>[expression_ast op:+(int value: 2, int value:
3)]</attributes>
     </expression>
     <success></success>
     <attributes>[]</attributes>
   </symsbols>
   <symsbols>
     <try></try>
     <expression>
       <try></try>
       <term>
         <try></try>
         <factor>
           <try></try>
           <fail/>
         </factor>
         <fail/>
       </term>
       <fail/>
     </expression>
     <fail/>
   </symsbols>
   <success></success>
   <attributes>[]</attributes>
</start>

So you can see that the values are put into attributes, but the
'symbols' and 'start' rules do not have attributes. So there is no place
to accumulate this information.

I think 'start' should have an attribute of std::vector<X> to
accommodate the parse results, if 'symbols' has attribute type X.
Have a look at
http://www.boost.org/doc/libs/1_61_0/libs/spirit/doc/html/spirit/qi/quick_reference/qi_parsers/operator.html 
the attributes due to operators.
The 'symbol' attribute is currently empty and apparently the
'expression_ast' is not sufficient at this point, since it collides with
the 'class_definition' attribute 'print_testclass'.

So this is a point where the value of the attribute stops propagating
leading to the default constructed attribute you get on parsing success.

Hope this is helpful.

Cheers
        Philipp



On 07/17/2016 05:55 PM, Philipp Schwaha wrote:

> Hi Jens,
>
> On 07/15/2016 01:56 AM, Jens Kallup wrote:
>> Hello,
>>
>> I have the problem, that the visitor does endless
>> loop, and crash after a while.
>> The problem is on:
>>
>> void operator()(expression_ast const& ast) const
>> {
>>    boost::apply_visitor(*this, ast.expr);
>> }
>>
>> How can this be fixed?
>
> I noticed that you define a 'nil' type, but use qi::info::nil in the
> visitor. Is there a particular reason for this?
> I modified the code so it compiles for me (with both g++ and clang++ in
> c++11 mode). The visitor will not crash in this form.
> Did you have a look at
> http://www.boost.org/doc/libs/1_61_0/libs/spirit/doc/html/spirit/support/utree.html
> for representing the ast?
>
> Best regards
>     Philipp
>
>
>>
>> Thanks for helping
>> Jens
>>
>> here the run/compileable source:
>>
>> #include "includes/mainwindow.h"
>>
>> #define BOOST_SPIRIT_USE_PHOENIX_V3
>> #include <boost/config/warning_disable.hpp>
>> #include <boost/spirit/include/lex_lexertl.hpp>
>> #include <boost/spirit/include/qi.hpp>
>> #include <boost/spirit/include/lex_lexertl.hpp>
>> #include <boost/spirit/include/phoenix.hpp>
>> #include <boost/spirit/include/phoenix_operator.hpp>
>> #include <boost/spirit/include/phoenix_container.hpp>
>> #include <boost/spirit/include/phoenix_function.hpp>
>> #include <boost/spirit/include/karma.hpp>
>> #include <boost/fusion/include/adapt_struct.hpp>
>> #include <boost/fusion/include/std_pair.hpp>
>> #include <boost/variant/recursive_variant.hpp>
>> #include <boost/variant/apply_visitor.hpp>
>> #include <boost/variant/get.hpp>
>>
>> #include <boost/algorithm/string.hpp>
>> #include <boost/shared_ptr.hpp>
>> #include <boost/make_shared.hpp>
>> #include <boost/lexical_cast.hpp>
>>
>> #include <boost/bind.hpp>
>> #include <boost/ref.hpp>
>>
>> #include <iostream>
>> #include <fstream>
>> #include <string>
>> #include <set>
>> #include <utility>
>>
>> int lineno = 1;
>>
>>
>> using namespace std;
>> using namespace boost::spirit;
>>
>> namespace bs    = boost::spirit;
>> namespace phx   = boost::phoenix;
>> namespace ascii = boost::spirit::ascii;
>>
>> using boost::spirit::ascii::space; // use the ASCII space parser
>> using boost::spirit::ascii::char_;
>> using boost::spirit::_val;
>>
>> using boost::phoenix::val;
>>
>> struct print_testclass
>> {
>>      print_testclass() {}
>>      print_testclass(std::string str1, std::string str2)
>>      {
>>          cout << str1 << " = " << str2 << endl;
>>      }
>> };
>>
>> namespace dBaseParser
>> {
>>      // -----------------
>>      // AST for dBase ...
>>      // -----------------
>>      struct binary_op;
>>      struct unary_op;
>>      struct nil {};
>>
>>      struct expression_ast
>>      {
>>          typedef
>>              boost::variant<
>>                  nil // can't happen!
>>                , int
>>                , boost::recursive_wrapper<expression_ast>
>>                , boost::recursive_wrapper<binary_op>
>>                , boost::recursive_wrapper<unary_op>
>>              >
>>          type;
>>
>>          expression_ast()
>>            : expr(nil()) {}
>>
>>          template <typename Expr>
>>          expression_ast(Expr const& expr) : expr(expr) {}
>>
>>          expression_ast& operator+=(expression_ast const& rhs);
>>          expression_ast& operator-=(expression_ast const& rhs);
>>          expression_ast& operator*=(expression_ast const& rhs);
>>          expression_ast& operator/=(expression_ast const& rhs);
>>
>>          type expr;
>>      };
>>
>>      struct binary_op
>>      {
>>          binary_op(
>>              char op
>>            , expression_ast const& left
>>            , expression_ast const& right)
>>          : op(op), left(left), right(right) {}
>>
>>          char op;
>>          expression_ast left;
>>          expression_ast right;
>>      };
>>
>>      struct unary_op
>>      {
>>          unary_op(
>>              char op
>>            , expression_ast const& subject)
>>          : op(op), subject(subject) {}
>>
>>          char op;
>>          expression_ast subject;
>>      };
>>
>>      expression_ast& expression_ast::operator+=(expression_ast const&
>> rhs)
>>      {
>>          expr = binary_op('+', expr, rhs);
>>          return *this;
>>      }
>>
>>      expression_ast& expression_ast::operator-=(expression_ast const&
>> rhs)
>>      {
>>          expr = binary_op('-', expr, rhs);
>>          return *this;
>>      }
>>
>>      expression_ast& expression_ast::operator*=(expression_ast const&
>> rhs)
>>      {
>>          expr = binary_op('*', expr, rhs);
>>          return *this;
>>      }
>>
>>      expression_ast& expression_ast::operator/=(expression_ast const&
>> rhs)
>>      {
>>          expr = binary_op('/', expr, rhs);
>>          return *this;
>>      }
>>
>>      std::ostream& operator << (std::ostream& os, const
>> expression_ast& as)
>>      {
>>          return os
>>                  << boost::get<binary_op>(as.expr).left
>>                  //<< " = "
>>                  //<< boost::get<binary_op>(as.expr).right;
>>                  << endl;
>>      }
>>
>>      // ------------------------------------------------------------
>>      // We should be using expression_ast::operator-. There's a bug
>>      // in phoenix type deduction mechanism that prevents us from
>>      // doing so. Phoenix will be switching to BOOST_TYPEOF. In the
>>      // meantime, we will use a phoenix::function below:
>>      // ------------------------------------------------------------
>>      struct negate_expr
>>      {
>>          template <typename T>
>>          struct result { typedef T type; };
>>
>>          expression_ast operator()(expression_ast const& expr) const
>>          {
>>              return expression_ast(unary_op('-', expr));
>>          }
>>      };
>>
>>      boost::phoenix::function<negate_expr> neg;
>>
>>      // -----------------------
>>      // walk throug the AST ...
>>      // -----------------------
>>      struct ast_print
>>      {
>>          typedef void result_type;
>>
>>          void operator()(qi::info::nil) const {}
>>          void operator()(int n) const { std::cout << n; }
>>
>>          void operator()(expression_ast const& ast) const
>>          {
>>              boost::apply_visitor(*this, ast.expr);
>>
>>              //int i = boost::get<int>(ast.expr);
>>              //cout << "1 = " << (int)i << endl;
>>          }
>>
>>          void operator()(binary_op const& expr) const
>>          {
>>              std::cout << "op:" << expr.op << "(";
>>              boost::apply_visitor(*this, expr.left.expr);
>>              std::cout << ", ";
>>              boost::apply_visitor(*this, expr.right.expr);
>>              std::cout << ')';
>>          }
>>
>>          void operator()(unary_op const& expr) const
>>          {
>>              std::cout << "op:" << expr.op << "(";
>>              boost::apply_visitor(*this, expr.subject.expr);
>>              std::cout << ')';
>>          }
>>      };
>>
>>      template <typename Lexer>
>>      struct dbase_tokens : lex::lexer<Lexer>
>>      {
>>          // ----------------------------
>>          // tokens with no attributes...
>>          // ----------------------------
>>          lex::token_def<lex::omit> whitespace;
>>          lex::token_def<lex::omit> cpcomment;
>>          lex::token_def<lex::omit> d_comment;
>>          lex::token_def<lex::omit> c_comment;
>>
>>          lex::token_def<lex::omit> kw_class;
>>          lex::token_def<lex::omit> kw_of;
>>          lex::token_def<lex::omit> kw_endclass;
>>
>>          // --------------------------
>>          // tokens with attributes ...
>>          // --------------------------
>>          lex::token_def<char> printLn;
>>
>>          lex::token_def<int>         number_digit;
>>          lex::token_def<std::string> identifier;
>>          lex::token_def<std::string> quoted_string;
>>
>>          dbase_tokens()
>>          {
>>              // ------------
>>              // keywords ...
>>              // ------------
>>              kw_class        = "(?i:class)";
>>              kw_endclass     = "(?i:endclass)";
>>              kw_of           = "(?i:of)";
>>
>>              printLn   = "\\\?";
>>
>>              // Values.
>>              number_digit      = "[0-9]+";
>>              quoted_string     = "\\\"(\\\\.|[^\\\"])*\\\""; //
>> \"(\\.|[^\"])*\"
>>
>>              // Identifier.
>>              identifier        = "[a-zA-Z][a-zA-Z0-9_]*";
>>
>>              cpcomment = "\\/\\/[^\\n]*\\n";                    //
>> single line comment
>>              d_comment = "\\*\\*[^\\n]*\\n";                    //
>> dBase  line comment
>>              c_comment = "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"; //
>> c-style comments
>>
>>              whitespace = "[ \\t\\n]+";
>>
>>              this->self += lex::token_def<>
>>                      ('(') | ')'
>>                      | '+' | '-'
>>                      | '*' | '/'
>>                      | ',' | '.';
>>              this->self +=
>>                  printLn
>>                  ;
>>              this->self +=
>>                  kw_class | kw_of | kw_endclass
>>                  ;
>>              this->self +=
>>                    identifier
>>                  | number_digit
>>                  | quoted_string
>>                  ;
>>
>>              this->self +=
>>                    whitespace [ lex::_pass =
>> lex::pass_flags::pass_ignore ]
>>                  | cpcomment
>>                  | c_comment
>>                  | d_comment
>>                  ;
>>          }
>>      };
>>
>>      template <typename Iterator, typename Lexer>
>>      struct dbase_grammar
>>      :   public qi::grammar<Iterator>
>>      {   template <typename TokenDef>
>>
>>          dbase_grammar(TokenDef const& tok) :
>>          dbase_grammar::base_type(start, "start")
>>          {
>>              using qi::_val;
>>
>>              start
>>                  = +symsbols
>>                  ;
>>
>>              expression =
>>                  term                            [_val  = qi::_1]
>>                  >> *(   ('+' >> term            [_val += qi::_1])
>>                      |   ('-' >> term            [_val -= qi::_1])
>>                      )
>>                  ;
>>
>>              term =
>>                  factor                          [_val  = qi::_1]
>>                  >> *(   ('*' >> factor          [_val *= qi::_1])
>>                      |   ('/' >> factor          [_val /= qi::_1])
>>                      )
>>                  ;
>>
>>              factor =
>>                  tok.number_digit                [_val = qi::_1]
>>                  |  '('   >> expression          [_val = qi::_1] >> ')'
>>                  |   ('-' >> factor              [_val = neg(qi::_1)])
>>                  |   ('+' >> factor              [_val = qi::_1])
>>                  ;
>>
>>              symsbols
>>                  = printLn
>>                  | comments
>>                  | class_definition
>>                  | expression
>>                  ;
>>
>>              comments
>>                  = tok.cpcomment
>>                  | tok.c_comment
>>                  | tok.d_comment
>>                  ;
>>
>>              printLn
>>                  = tok.printLn >> *comments >> tok.quoted_string
>>                  | tok.printLn >> tok.quoted_string
>>                  ;
>>
>>              class_definition
>>                  = (tok.kw_class          >> *comments
>>                      >> tok.identifier    >> *comments
>>                      >> tok.kw_of         >> *comments
>>                      >> tok.identifier    >> *comments >> class_body
>>                      >> tok.kw_endclass)
>>                      [
>>                          qi::_val = phx::construct<print_testclass>(
>>                          phx::construct<std::string>(qi::_1),
>>                          phx::construct<std::string>(qi::_2))
>>                      ]
>>                  ;
>>              class_body
>>                  = *comments
>>                  ;
>>
>>              start.name("start");
>>              symsbols.name("symsbols");
>>              comments.name("comments");
>>              expression.name("expression");
>>              term.name("term");
>>              factor.name("factor");
>>              printLn.name("printLn");
>>              class_definition.name("class_definition");
>>              class_body.name("class_body");
>>
>>              BOOST_SPIRIT_DEBUG_NODE(start);
>>              BOOST_SPIRIT_DEBUG_NODE(symsbols);
>>              BOOST_SPIRIT_DEBUG_NODE(comments);
>>              BOOST_SPIRIT_DEBUG_NODE(printLn);
>>              BOOST_SPIRIT_DEBUG_NODE(class_definition);
>>              BOOST_SPIRIT_DEBUG_NODE(class_body);
>>              BOOST_SPIRIT_DEBUG_NODE(factor);
>>              BOOST_SPIRIT_DEBUG_NODE(term);
>>              BOOST_SPIRIT_DEBUG_NODE(expression);
>>
>>              using namespace qi::labels;
>>              qi::on_error<qi::fail>
>>              (
>>                  start,
>>                  std::cout
>>                      << phx::val("Error! Expecting ")
>>                      << bs::_4 // what failed?
>>                      << phx::val(" here: \"")
>>                      << phx::construct<std::string>(bs::_3, bs::_2)   //
>> iterators to error-pos, end
>>                      << phx::val("\"")
>>                      << std::endl
>>              );
>>          }
>>
>>          typedef qi::unused_type skipper_type;
>>          typedef qi::rule<Iterator, skipper_type> simple_rule;
>>
>>          simple_rule start, symsbols, comments, printLn;
>>          simple_rule class_body;
>>
>>          qi::rule<Iterator, print_testclass()> class_definition;
>>          qi::rule<Iterator, expression_ast()> expression, term, factor;
>>      };
>> }
>>
>> bool parseText(QString text)
>> {
>>      std::string data(text.toStdString().c_str());
>>      if (data.size() < 1) {
>>          QMessageBox::information(0,"Error","No Data for
>> parser.\nABORT.");
>>          return false;
>>      }
>>
>>      using dBaseParser::expression_ast;
>>      using dBaseParser::ast_print;
>>
>>      typedef std::string::iterator base_iterator_type;
>>      typedef lex::lexertl::token<
>>          base_iterator_type, boost::mpl::vector<char, int, std::size_t,
>> std::string>
>>      > token_type;
>>      typedef lex::lexertl::actor_lexer<token_type> lexer_type;
>>
>>      typedef dBaseParser::dbase_tokens<lexer_type> dbase_tokens;
>>      typedef dbase_tokens::iterator_type iterator_type;
>>      typedef dBaseParser::dbase_grammar<iterator_type,
>> dbase_tokens::lexer_def> dbase_grammar;
>>
>>      dbase_tokens  tokens;
>>      dbase_grammar dbase(tokens);
>>
>>      base_iterator_type it = data.begin();
>>      iterator_type iter    = tokens.begin(it, data.end());
>>      iterator_type end     = tokens.end();
>>
>>      dBaseParser::expression_ast ast;
>>      dBaseParser::ast_print  printer;
>>
>>      bool r = qi::parse(iter, end, dbase, ast);
>>
>>      if (r && iter == end) {
>>          QMessageBox::information(w,"text parser","SUCCESS");
>> printer(ast); } else
>>          QMessageBox::information(w,"text parser","ERROR");
>>
>>      return 0;
>> }
>>
>>
>> ------------------------------------------------------------------------------
>>
>> What NetFlow Analyzer can do for you? Monitors network bandwidth and
>> traffic
>> patterns at an interface-level. Reveals which users, apps, and
>> protocols are
>> consuming the most bandwidth. Provides multi-vendor support for NetFlow,
>> J-Flow, sFlow and other flows. Make informed decisions using capacity
>> planning
>> reports.http://sdm.link/zohodev2dev
>> _______________________________________________
>> Spirit-general mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/spirit-general
>>
>
>
> ------------------------------------------------------------------------------
> What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
> patterns at an interface-level. Reveals which users, apps, and protocols are
> consuming the most bandwidth. Provides multi-vendor support for NetFlow,
> J-Flow, sFlow and other flows. Make informed decisions using capacity planning
> reports.http://sdm.link/zohodev2dev
>
>
>
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
>

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

test.cpp (14K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Boost::Spirit: Application SUCCESS, crash at: printer(ast) ... why?

Jens Kallup
In reply to this post by Philipp Schwaha-2
Hello Philipp,

Thank You for the fast posting.
Now, the programm code will be compile, and the infinit loop
disappears.

"empty"
is the Output.

An other problem was, that I have miss a visitor member.
Thanks for

Jens

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

index_is_out_of_bounds problem?

Jens Kallup
Hello,

I habe the following spirit grammar snippet:
I don't know, why the error message index_out_of_bounds appears.

Can You Help
Jens

             rfc_header
                 = tok.kw_http >> '/' >> double_
                               >> ' ' >> int_
                               >> ' ' >> tok.identifier
                       [
                       qi::_val = phx::construct<expression_ast>(
                            std::string("header1")
                           , qi::_3
                           , qi::_5
                           , qi::_7
                           , qi::_val)
                       ]
                 ;

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: index_is_out_of_bounds problem?

Philipp Schwaha-2
Hi Jens,

On 07/19/2016 08:09 PM, Jens Kallup wrote:
> Hello,
>
> I habe the following spirit grammar snippet:
> I don't know, why the error message index_out_of_bounds appears.
>
the count is off since you should not count the intervening character
literals, which do not have an attribute (see
http://www.boost.org/doc/libs/1_61_0/libs/spirit/doc/html/spirit/qi/reference/char/char.html)

> Can You Help
> Jens
>
>              rfc_header
>                  = tok.kw_http >> '/' >> double_
>                                >> ' ' >> int_
>                                >> ' ' >> tok.identifier
>                        [
>                        qi::_val = phx::construct<expression_ast>(
>                             std::string("header1")
>                            , qi::_3
>                            , qi::_5
>                            , qi::_7
these should be:
                             , qi::_2
                             , qi::_3
                             , qi::_4

>                            , qi::_val)

_val will not be set to the value you expect. It will hold the value due
to the default constructor.

Have a look at the simple test program in the attachment. If you change
[ std::cout <<  _1 << " " << _2 << " " << _val << "\n" ]
to
[ std::cout <<  _1 << " " << _3 << " " << _val << "\n" ]
it will fail to compile.

Also examine that the the output due to '_val' is in a default
constructed state (0 0).
With the semantic actions attached you can turn on attribute propagation
by using the '%=' operator instead just '=' in the rule assignment (also
see the small demo program if you change it to '=' again).

Cheers
        Philipp

>                        ]
>                  ;
>
> ------------------------------------------------------------------------------
> What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
> patterns at an interface-level. Reveals which users, apps, and protocols are
> consuming the most bandwidth. Provides multi-vendor support for NetFlow,
> J-Flow, sFlow and other flows. Make informed decisions using capacity planning
> reports.http://sdm.link/zohodev2dev
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
>

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

indices.cpp (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

next problem: can not handle text string "HTTP/1.1 200 OK"

Jens Kallup
In reply to this post by Jens Kallup
Hello,

I dont find the error/bug, which cause me a ERROR <----
Please have a look.

TIA
Jens


#include "../../../prech.h"

#include "includes/mainwindow.h"

#define BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_eoi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/get.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/lexical_cast.hpp>

#include <boost/bind.hpp>
#include <boost/ref.hpp>

#include <boost/phoenix/bind/bind_member_function.hpp>

#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <utility>

using namespace std;
using namespace boost::spirit;

namespace bs    = boost::spirit;
namespace phx   = boost::phoenix;
namespace ascii = boost::spirit::ascii;

using boost::spirit::ascii::space; // use the ASCII space parser
using boost::spirit::ascii::char_;
using boost::spirit::_val;
using boost::spirit::qi::eoi;

using boost::phoenix::val;

namespace RFCupdateParser
{
     // --------------------------
     // AST for dBase updater ...
     // --------------------------
     struct binary_op;
     struct unary_op;
     struct nil { };
     struct header_1struct;

     struct expression_ast
     {
         typedef
             boost::variant<
                   nil
                 , int
                 , float
                 , std::string
                 , boost::recursive_wrapper<expression_ast>
                 , boost::recursive_wrapper<binary_op>
                 , boost::recursive_wrapper<unary_op>
                 , boost::recursive_wrapper<header_1struct>
             >
         type;
         type expr;

         expression_ast() : expr(nil()) {}
         expression_ast(
                   std::string const& name
                 , float version
                 , int status_code
                 , std::string const& status_text, expression_ast const&
rhs);

         template <typename Expr>
             expression_ast(Expr const& expr)
             : expr(expr) {}

         expression_ast& operator += (expression_ast const& rhs);
         expression_ast& operator -= (expression_ast const& rhs);
         expression_ast& operator *= (expression_ast const& rhs);
         expression_ast& operator /= (expression_ast const& rhs);
     };

     struct binary_op
     {
         binary_op(
               char op
             , expression_ast const& left
             , expression_ast const& right)
             : op(op)
             , left(left)
             , right(right) {}

         char op;
         expression_ast left;
         expression_ast right;
     };

     struct unary_op
     {
         unary_op(
             char op
           , expression_ast const& subject)
         : op(op), subject(subject) {}

         char op;
         expression_ast subject;
     };


     expression_ast dast;

     struct header_1struct
     {
         header_1struct(
               std::string name
             , float       version
             , int         status_code
             , std::string status_text
             , expression_ast const& left
             , expression_ast const& right)
             : name(name)
             , version(version)
             , status_code(status_code)
             , status_text(status_text)
             , left(left)
             , right(right) { }

         std::string name;
         std::string status_text;
         int         status_code;
         float version;

         expression_ast left;
         expression_ast right;
     };

     expression_ast::expression_ast(string const &name
             , float version
             , int status_code
             , string const& status_text
             , expression_ast const& rhs)
     {
         expr = header_1struct(
                       name
                     , version
                     , status_code
                     , status_text
                     , expr
                     , rhs
                );
         dast = expr;
     }

     expression_ast& expression_ast::operator += (expression_ast const& rhs)
     {
         expr = binary_op('+', expr, rhs);
         dast = *this;
         return  dast;
     }

     expression_ast& expression_ast::operator -= (expression_ast const& rhs)
     {
         expr = binary_op('-', expr, rhs);
         dast = *this;
         return  dast;
     }

     expression_ast& expression_ast::operator *= (expression_ast const& rhs)
     {
         expr = binary_op('*', expr, rhs);
         dast = *this;
         return  dast;
     }

     expression_ast& expression_ast::operator /= (expression_ast const& rhs)
     {
         expr = binary_op('/', expr, rhs);
         dast = *this;
         return  dast;
     }

     // We should be using expression_ast::operator-. There's a bug
     // in phoenix type deduction mechanism that prevents us from
     // doing so. Phoenix will be switching to BOOST_TYPEOF. In the
     // meantime, we will use a phoenix::function below:
     struct negate_expr
     {
         template <typename T>
         struct result { typedef T type; };

         expression_ast operator()(expression_ast const& expr) const
         {
             return expression_ast(unary_op('-', expr));
         }
     };

     boost::phoenix::function<negate_expr> neg;

     // -----------------------
     // walk throug the AST ...
     // -----------------------
     struct ast_print
     {
         typedef void result_type;

         void operator()(nil) const   {
             cout << "empty" << endl;
         }
         void operator()(int n) const { std::cout << n; }

         void operator()(expression_ast const& ast) const
         {
             cout << "-> "
                  << ast.expr.type().name()
                  << " : "
                  << endl;

             boost::apply_visitor(*this, ast.expr);
         }

         void operator()(binary_op const& expr) const
         {
             std::cout << "op:" << expr.op << "(";
             boost::apply_visitor(*this, expr.left.expr);
             std::cout << ", ";
             boost::apply_visitor(*this, expr.right.expr);
             std::cout << ')';
         }

         void operator()(unary_op const& expr) const
         {
             std::cout << "op:" << expr.op << "(";
             boost::apply_visitor(*this, expr.subject.expr);
             std::cout << ')';
         }

         void operator()(header_1struct const& expr) const
         {
             std::cout << "header:"
                       << expr.status_text
                       << std::endl;
             boost::apply_visitor(*this, expr.left.expr);
             std::cout << "header2:"
                       << expr.status_text
                       << std::endl;
         }
     };

     template <typename Lexer>
     struct rfcupdate_tokens : lex::lexer<Lexer>
     {
         // ----------------------------
         // tokens with no attributes...
         // ----------------------------
         lex::token_def<lex::omit> whitespace;
         lex::token_def<lex::omit> cpcomment;
         lex::token_def<lex::omit> d_comment;
         lex::token_def<lex::omit> c_comment;

         lex::token_def<lex::omit> kw_http;
         lex::token_def<lex::omit> kw_ok;


         lex::token_def<std::string> identifier;
         lex::token_def<std::string> quoted_string;

         rfcupdate_tokens()
         {
             // ----------------------------
             // keywords ...
             // ----------------------------
             kw_http   = "(?i:http)";
             kw_ok     = "(?i:ok)";

             quoted_string  = "\\\"(\\\\.|[^\\\"])*\\\""; //
\"(\\.|[^\"])*\"

             // Identifier.
             identifier        = "[a-zA-Z][a-zA-Z0-9_]*";

             cpcomment = "\\/\\/[^\\n]*\\n";                    //
single line comment
             d_comment = "\\*\\*[^\\n]*\\n";                    //
dBase  line comment
             c_comment = "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"; //
c-style comments

             whitespace = "[ \\t\\n]+";

             this->self += lex::token_def<>
                     ('(') | ')'
                     | '+' | '-'
                     | '*' | ',' | '.' | '/'
                     ;

             this->self +=
                 kw_http | kw_ok
                 ;

             this->self +=
                   identifier
                 | quoted_string
                 ;

             this->self +=
                   whitespace [ lex::_pass = lex::pass_flags::pass_ignore ]
                 | cpcomment
                 | c_comment
                 | d_comment
                 ;
         }
     };

     template <typename Iterator, typename Lexer>
     struct rfcupdate_grammar
     :   public qi::grammar<Iterator>
     {   template <typename TokenDef>

         rfcupdate_grammar(TokenDef const& tok) :
         rfcupdate_grammar::base_type(start, "start")
         {
             using qi::_val;

             start
                 = +symsbols
                 ;

             symsbols
                 = comments
                 | rfc_header
                 ;

             comments
                 = tok.whitespace
                 | tok.cpcomment
                 | tok.c_comment
                 | tok.d_comment
                 ;

             rfc_header
                 = (tok.kw_http >> char_('/')
                                >> float_ >> *comments
                                >> int_   >> *comments
                                >> tok.identifier
                                >> qi::eol )
                       [
                     printf("----xxxxx-----\n"),
                         qi::_val = phx::construct<expression_ast>(
phx::construct<std::string>("HTTP")
                           , phx::construct<float>(qi::_2)
                           , phx::construct<int >(qi::_3)
                           , phx::construct<std::string>(qi::_4)
                           , qi::_val),
                     printf("----ok----\n")
                       ]
                 ;

             start.name("start");
             symsbols.name("symsbols");
             comments.name("comments");
             rfc_header.name("rfc_header");
         }

         typedef qi::unused_type skipper_type;
         typedef qi::rule<Iterator, skipper_type> simple_rule;

         simple_rule start, symsbols, comments;

         qi::rule<Iterator, expression_ast()>
               rfc_header;
     };
}

bool InitParseTextRFC(QString text)
{
     QMessageBox::information(w,"info",text);

     std::string data(text.toStdString().c_str());
     if (data.size() < 1) {
         QMessageBox::information(0,"Error","No Data for parser.\nABORT.");
         return false;
     }

     using RFCupdateParser::expression_ast;
     using RFCupdateParser::ast_print;

     typedef std::string::iterator base_iterator_type;
     typedef lex::lexertl::token<
         base_iterator_type, boost::mpl::vector<char, int, float,
std::size_t, std::string>
     > token_type;
     typedef lex::lexertl::actor_lexer<token_type> lexer_type;

     typedef RFCupdateParser::rfcupdate_tokens<lexer_type> rfcupdate_tokens;
     typedef rfcupdate_tokens::iterator_type iterator_type;
     typedef RFCupdateParser::rfcupdate_grammar<iterator_type,
rfcupdate_tokens::lexer_def> rfcupdate_grammar;

     rfcupdate_tokens  tokens;
     rfcupdate_grammar rfcupdate(tokens);

     base_iterator_type it = data.begin();
     iterator_type iter    = tokens.begin(it, data.end());
     iterator_type end     = tokens.end();

     RFCupdateParser::expression_ast ast;
     return qi::parse(iter, end, rfcupdate, ast);
}

bool parseRFC_dBaseUpdate(QString text)
{
     RFCupdateParser::ast_print  printer; bool r =
     InitParseTextRFC(QString("HTTP/1.1 200 OK"));
     if (r == true) {
         QMessageBox::information(w,"text parser","SUCCESS");
         printer(RFCupdateParser::dast);
     } else {
         QMessageBox::information(w,"text parser","ERROR <-----");
     }

     return true;
}


------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: next problem: can not handle text string "HTTP/1.1 200 OK"

Philipp Schwaha-2
Hello Jens,

you are mixing tokens from the lexer, which does not have a definition
for float_, and the spirit grammar constructs.
What I mean is: tok.kw_http >> char_('/') >> float_ ...

If this is tokenized, there is no token for float_ since the lexer does
not understand it as far as I can see.
Either you extend the lexer to include float_ tokens or you parse
without the lexer.

Cheers
        Philipp

On 07/20/2016 01:31 AM, Jens Kallup wrote:

> Hello,
>
> I dont find the error/bug, which cause me a ERROR <----
> Please have a look.
>
> TIA
> Jens
>
>
> #include "../../../prech.h"
>
> #include "includes/mainwindow.h"
>
> #define BOOST_SPIRIT_USE_PHOENIX_V3
> #define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
>
> #include <boost/config/warning_disable.hpp>
> #include <boost/spirit/include/lex_lexertl.hpp>
> #include <boost/spirit/include/qi.hpp>
> #include <boost/spirit/include/qi_eoi.hpp>
> #include <boost/spirit/include/lex_lexertl.hpp>
> #include <boost/spirit/include/phoenix.hpp>
> #include <boost/spirit/include/phoenix_operator.hpp>
> #include <boost/spirit/include/phoenix_container.hpp>
> #include <boost/spirit/include/phoenix_function.hpp>
> #include <boost/spirit/include/karma.hpp>
> #include <boost/fusion/include/adapt_struct.hpp>
> #include <boost/fusion/include/std_pair.hpp>
> #include <boost/variant/recursive_variant.hpp>
> #include <boost/variant/apply_visitor.hpp>
> #include <boost/variant/get.hpp>
>
> #include <boost/algorithm/string.hpp>
> #include <boost/shared_ptr.hpp>
> #include <boost/make_shared.hpp>
> #include <boost/lexical_cast.hpp>
>
> #include <boost/bind.hpp>
> #include <boost/ref.hpp>
>
> #include <boost/phoenix/bind/bind_member_function.hpp>
>
> #include <iostream>
> #include <fstream>
> #include <string>
> #include <set>
> #include <utility>
>
> using namespace std;
> using namespace boost::spirit;
>
> namespace bs    = boost::spirit;
> namespace phx   = boost::phoenix;
> namespace ascii = boost::spirit::ascii;
>
> using boost::spirit::ascii::space; // use the ASCII space parser
> using boost::spirit::ascii::char_;
> using boost::spirit::_val;
> using boost::spirit::qi::eoi;
>
> using boost::phoenix::val;
>
> namespace RFCupdateParser
> {
>      // --------------------------
>      // AST for dBase updater ...
>      // --------------------------
>      struct binary_op;
>      struct unary_op;
>      struct nil { };
>      struct header_1struct;
>
>      struct expression_ast
>      {
>          typedef
>              boost::variant<
>                    nil
>                  , int
>                  , float
>                  , std::string
>                  , boost::recursive_wrapper<expression_ast>
>                  , boost::recursive_wrapper<binary_op>
>                  , boost::recursive_wrapper<unary_op>
>                  , boost::recursive_wrapper<header_1struct>
>              >
>          type;
>          type expr;
>
>          expression_ast() : expr(nil()) {}
>          expression_ast(
>                    std::string const& name
>                  , float version
>                  , int status_code
>                  , std::string const& status_text, expression_ast const&
> rhs);
>
>          template <typename Expr>
>              expression_ast(Expr const& expr)
>              : expr(expr) {}
>
>          expression_ast& operator += (expression_ast const& rhs);
>          expression_ast& operator -= (expression_ast const& rhs);
>          expression_ast& operator *= (expression_ast const& rhs);
>          expression_ast& operator /= (expression_ast const& rhs);
>      };
>
>      struct binary_op
>      {
>          binary_op(
>                char op
>              , expression_ast const& left
>              , expression_ast const& right)
>              : op(op)
>              , left(left)
>              , right(right) {}
>
>          char op;
>          expression_ast left;
>          expression_ast right;
>      };
>
>      struct unary_op
>      {
>          unary_op(
>              char op
>            , expression_ast const& subject)
>          : op(op), subject(subject) {}
>
>          char op;
>          expression_ast subject;
>      };
>
>
>      expression_ast dast;
>
>      struct header_1struct
>      {
>          header_1struct(
>                std::string name
>              , float       version
>              , int         status_code
>              , std::string status_text
>              , expression_ast const& left
>              , expression_ast const& right)
>              : name(name)
>              , version(version)
>              , status_code(status_code)
>              , status_text(status_text)
>              , left(left)
>              , right(right) { }
>
>          std::string name;
>          std::string status_text;
>          int         status_code;
>          float version;
>
>          expression_ast left;
>          expression_ast right;
>      };
>
>      expression_ast::expression_ast(string const &name
>              , float version
>              , int status_code
>              , string const& status_text
>              , expression_ast const& rhs)
>      {
>          expr = header_1struct(
>                        name
>                      , version
>                      , status_code
>                      , status_text
>                      , expr
>                      , rhs
>                 );
>          dast = expr;
>      }
>
>      expression_ast& expression_ast::operator += (expression_ast const& rhs)
>      {
>          expr = binary_op('+', expr, rhs);
>          dast = *this;
>          return  dast;
>      }
>
>      expression_ast& expression_ast::operator -= (expression_ast const& rhs)
>      {
>          expr = binary_op('-', expr, rhs);
>          dast = *this;
>          return  dast;
>      }
>
>      expression_ast& expression_ast::operator *= (expression_ast const& rhs)
>      {
>          expr = binary_op('*', expr, rhs);
>          dast = *this;
>          return  dast;
>      }
>
>      expression_ast& expression_ast::operator /= (expression_ast const& rhs)
>      {
>          expr = binary_op('/', expr, rhs);
>          dast = *this;
>          return  dast;
>      }
>
>      // We should be using expression_ast::operator-. There's a bug
>      // in phoenix type deduction mechanism that prevents us from
>      // doing so. Phoenix will be switching to BOOST_TYPEOF. In the
>      // meantime, we will use a phoenix::function below:
>      struct negate_expr
>      {
>          template <typename T>
>          struct result { typedef T type; };
>
>          expression_ast operator()(expression_ast const& expr) const
>          {
>              return expression_ast(unary_op('-', expr));
>          }
>      };
>
>      boost::phoenix::function<negate_expr> neg;
>
>      // -----------------------
>      // walk throug the AST ...
>      // -----------------------
>      struct ast_print
>      {
>          typedef void result_type;
>
>          void operator()(nil) const   {
>              cout << "empty" << endl;
>          }
>          void operator()(int n) const { std::cout << n; }
>
>          void operator()(expression_ast const& ast) const
>          {
>              cout << "-> "
>                   << ast.expr.type().name()
>                   << " : "
>                   << endl;
>
>              boost::apply_visitor(*this, ast.expr);
>          }
>
>          void operator()(binary_op const& expr) const
>          {
>              std::cout << "op:" << expr.op << "(";
>              boost::apply_visitor(*this, expr.left.expr);
>              std::cout << ", ";
>              boost::apply_visitor(*this, expr.right.expr);
>              std::cout << ')';
>          }
>
>          void operator()(unary_op const& expr) const
>          {
>              std::cout << "op:" << expr.op << "(";
>              boost::apply_visitor(*this, expr.subject.expr);
>              std::cout << ')';
>          }
>
>          void operator()(header_1struct const& expr) const
>          {
>              std::cout << "header:"
>                        << expr.status_text
>                        << std::endl;
>              boost::apply_visitor(*this, expr.left.expr);
>              std::cout << "header2:"
>                        << expr.status_text
>                        << std::endl;
>          }
>      };
>
>      template <typename Lexer>
>      struct rfcupdate_tokens : lex::lexer<Lexer>
>      {
>          // ----------------------------
>          // tokens with no attributes...
>          // ----------------------------
>          lex::token_def<lex::omit> whitespace;
>          lex::token_def<lex::omit> cpcomment;
>          lex::token_def<lex::omit> d_comment;
>          lex::token_def<lex::omit> c_comment;
>
>          lex::token_def<lex::omit> kw_http;
>          lex::token_def<lex::omit> kw_ok;
>
>
>          lex::token_def<std::string> identifier;
>          lex::token_def<std::string> quoted_string;
>
>          rfcupdate_tokens()
>          {
>              // ----------------------------
>              // keywords ...
>              // ----------------------------
>              kw_http   = "(?i:http)";
>              kw_ok     = "(?i:ok)";
>
>              quoted_string  = "\\\"(\\\\.|[^\\\"])*\\\""; //
> \"(\\.|[^\"])*\"
>
>              // Identifier.
>              identifier        = "[a-zA-Z][a-zA-Z0-9_]*";
>
>              cpcomment = "\\/\\/[^\\n]*\\n";                    //
> single line comment
>              d_comment = "\\*\\*[^\\n]*\\n";                    //
> dBase  line comment
>              c_comment = "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"; //
> c-style comments
>
>              whitespace = "[ \\t\\n]+";
>
>              this->self += lex::token_def<>
>                      ('(') | ')'
>                      | '+' | '-'
>                      | '*' | ',' | '.' | '/'
>                      ;
>
>              this->self +=
>                  kw_http | kw_ok
>                  ;
>
>              this->self +=
>                    identifier
>                  | quoted_string
>                  ;
>
>              this->self +=
>                    whitespace [ lex::_pass = lex::pass_flags::pass_ignore ]
>                  | cpcomment
>                  | c_comment
>                  | d_comment
>                  ;
>          }
>      };
>
>      template <typename Iterator, typename Lexer>
>      struct rfcupdate_grammar
>      :   public qi::grammar<Iterator>
>      {   template <typename TokenDef>
>
>          rfcupdate_grammar(TokenDef const& tok) :
>          rfcupdate_grammar::base_type(start, "start")
>          {
>              using qi::_val;
>
>              start
>                  = +symsbols
>                  ;
>
>              symsbols
>                  = comments
>                  | rfc_header
>                  ;
>
>              comments
>                  = tok.whitespace
>                  | tok.cpcomment
>                  | tok.c_comment
>                  | tok.d_comment
>                  ;
>
>              rfc_header
>                  = (tok.kw_http >> char_('/')
>                                 >> float_ >> *comments
>                                 >> int_   >> *comments
>                                 >> tok.identifier
>                                 >> qi::eol )
>                        [
>                      printf("----xxxxx-----\n"),
>                          qi::_val = phx::construct<expression_ast>(
> phx::construct<std::string>("HTTP")
>                            , phx::construct<float>(qi::_2)
>                            , phx::construct<int >(qi::_3)
>                            , phx::construct<std::string>(qi::_4)
>                            , qi::_val),
>                      printf("----ok----\n")
>                        ]
>                  ;
>
>              start.name("start");
>              symsbols.name("symsbols");
>              comments.name("comments");
>              rfc_header.name("rfc_header");
>          }
>
>          typedef qi::unused_type skipper_type;
>          typedef qi::rule<Iterator, skipper_type> simple_rule;
>
>          simple_rule start, symsbols, comments;
>
>          qi::rule<Iterator, expression_ast()>
>                rfc_header;
>      };
> }
>
> bool InitParseTextRFC(QString text)
> {
>      QMessageBox::information(w,"info",text);
>
>      std::string data(text.toStdString().c_str());
>      if (data.size() < 1) {
>          QMessageBox::information(0,"Error","No Data for parser.\nABORT.");
>          return false;
>      }
>
>      using RFCupdateParser::expression_ast;
>      using RFCupdateParser::ast_print;
>
>      typedef std::string::iterator base_iterator_type;
>      typedef lex::lexertl::token<
>          base_iterator_type, boost::mpl::vector<char, int, float,
> std::size_t, std::string>
>      > token_type;
>      typedef lex::lexertl::actor_lexer<token_type> lexer_type;
>
>      typedef RFCupdateParser::rfcupdate_tokens<lexer_type> rfcupdate_tokens;
>      typedef rfcupdate_tokens::iterator_type iterator_type;
>      typedef RFCupdateParser::rfcupdate_grammar<iterator_type,
> rfcupdate_tokens::lexer_def> rfcupdate_grammar;
>
>      rfcupdate_tokens  tokens;
>      rfcupdate_grammar rfcupdate(tokens);
>
>      base_iterator_type it = data.begin();
>      iterator_type iter    = tokens.begin(it, data.end());
>      iterator_type end     = tokens.end();
>
>      RFCupdateParser::expression_ast ast;
>      return qi::parse(iter, end, rfcupdate, ast);
> }
>
> bool parseRFC_dBaseUpdate(QString text)
> {
>      RFCupdateParser::ast_print  printer; bool r =
>      InitParseTextRFC(QString("HTTP/1.1 200 OK"));
>      if (r == true) {
>          QMessageBox::information(w,"text parser","SUCCESS");
>          printer(RFCupdateParser::dast);
>      } else {
>          QMessageBox::information(w,"text parser","ERROR <-----");
>      }
>
>      return true;
> }
>
>
> ------------------------------------------------------------------------------
> What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
> patterns at an interface-level. Reveals which users, apps, and protocols are
> consuming the most bandwidth. Provides multi-vendor support for NetFlow,
> J-Flow, sFlow and other flows. Make informed decisions using capacity planning
> reports.http://sdm.link/zohodev2dev
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
>

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general