next problem: can not handle text string "HTTP/1.1 200 OK"
Jens Kallup <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
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