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