spirit with application crash

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

spirit with application crash

Jens Kallup
Hello,

I have following code. The Compiler+Linker makes an executable.
But if run the Parser Part, the application crashes:


dbase: /usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:201:
boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&
boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const
boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&) [with Iterator =
__gnu_cxx::__normal_iterator<const char*,
std::__cxx11::basic_string<char> >; T1 =
client::dbase_skipper<__gnu_cxx::__normal_iterator<const char*,
std::__cxx11::basic_string<char> > >; T2 = boost::spirit::unused_type;
T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]:
Zusicherung »rhs.f && "Did you mean rhs.alias() instead of rhs?"« nicht
erfüllt.



what can i do?

#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_USE_PHOENIX_V3

#include <boost/config/warning_disable.hpp>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/repository/include/qi_confix.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>

#include <string>
#include <iostream>

#include <QString>
#include <QMessageBox>

namespace client
{
     namespace qi = boost::spirit::qi;
     namespace ascii = boost::spirit::ascii;

     struct binary_op;
     struct unary_op;
     struct nil {};

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

         expression_ast()
             : m_expr(nil()) {}

         template <typename Expr>
             expression_ast(Expr const& expr)
             : m_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 m_expr;
     };

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

         char m_op;
         expression_ast m_left;
         expression_ast m_right;
     };

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

         char m_op;
         expression_ast m_subject;
     };

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

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

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

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


     struct ast_print
     {
         typedef std::string result_type;

         std::string operator()(nil()) const
         {
             return "";
         }
         std::string operator()(std::string const& str) const
         {
             return str;
         }
         std::string operator()(double d) const
         {
             std::ostringstream oss;
             oss << d;
             return oss.str();
         }

         std::string operator()(expression_ast const& ast) const
         {
             return boost::apply_visitor(*this, ast.m_expr);
         }

         std::string operator()(binary_op const& expr) const
         {
             std::ostringstream oss;
             oss << "op:" << expr.m_op << "(";
             oss << boost::apply_visitor(*this, expr.m_left.m_expr);
             oss << ", ";
             oss << boost::apply_visitor(*this, expr.m_right.m_expr);
             oss << ')';
             return oss.str();
         }

         std::string operator()(unary_op const& expr) const
         {
             std::ostringstream oss;
             oss << "op:" << expr.m_op << "(";
             oss << boost::apply_visitor(*this, expr.m_subject.m_expr);
             oss << ')';
             return oss.str();
         }
     };

     std::ostream& operator << (std::ostream& stream, const
expression_ast& expr)
     {
         ast_print printer;
         stream << printer(expr) << std::endl;
         return stream;
     }

     template <typename Iterator>
     struct dbase_skipper : public qi::grammar<Iterator>
     {
         dbase_skipper() : dbase_skipper::base_type(my_skip, "dBase")
         {
             using qi::ascii::char_;
             using qi::ascii::space;
             using qi::eol;
             using qi::eoi;

             skip = my_skip.alias();
             my_skip =
             *(ascii::space) |
             *("**" >> *(char_ - eol) >> (eol | eoi)) |
             *("&&" >> *(char_ - eol) >> (eol | eoi)) |
             *("//" >> *(char_ - eol) >> (eol | eoi)) |
             *("/*" >> *(char_ - "*/") >> "*/")
             ;
         }
         qi::rule<Iterator> skip, my_skip;
     };

     template <typename Iterator, typename Skipper =
dbase_skipper<Iterator>>
     struct dbase_grammar : public qi::grammar<Iterator, Skipper>
     {
         qi::rule<Iterator, Skipper> start, run_app;
         qi::rule<Iterator, Skipper> block;
         qi::rule<Iterator, Skipper> statement;

         dbase_grammar() : dbase_grammar::base_type(start)
         {
             start = run_app.alias();

             run_app = symbol;

             symbol %=
                 (symbol_raw)
                 ;

             symbol_raw %=
                 +(qi::alpha | qi::char_( "_" ))
                 ;

             BOOST_SPIRIT_DEBUG_NODE(start);
             BOOST_SPIRIT_DEBUG_NODE(symbol);
             BOOST_SPIRIT_DEBUG_NODE(symbol_raw);
         }

         qi::rule<Iterator, Skipper>
         symbol, symbol_raw;
     };
}

bool parseText(QString text, int mode)
{
     typedef std::string::const_iterator iterator_t;

     typedef client::dbase_grammar <iterator_t> grammar;
     typedef client::dbase_skipper <iterator_t> skipper;

     grammar pg;  // our grammar
     skipper ws;  // (my) custom skipper

     std::string str = text.toStdString();

     bool r;

     iterator_t iter = str.begin();
     iterator_t end  = str.end();

     r = phrase_parse(iter, end, pg, ws);
     if (r == true) {
         QMessageBox::information(0,"Parser","Parsing SUCCESS.");
         return true;
     }

     if (iter != end)
         std::cout << "Remaining: '" << std::string(iter, end) << std::endl;

     QMessageBox::information(0,"Parser","Parsing ERROR.");
     return false;
}

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: spirit with application crash

sehe
On 14-10-16 01:33, Jens Kallup wrote:

> Hello,
>
> I have following code. The Compiler+Linker makes an executable.
> But if run the Parser Part, the application crashes:
>
>
> dbase: /usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:201:
> boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&
> boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const
> boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&) [with Iterator =
> __gnu_cxx::__normal_iterator<const char*,
> std::__cxx11::basic_string<char> >; T1 =
> client::dbase_skipper<__gnu_cxx::__normal_iterator<const char*,
> std::__cxx11::basic_string<char> > >; T2 = boost::spirit::unused_type;
> T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]:
> Zusicherung »rhs.f && "Did you mean rhs.alias() instead of rhs?"« nicht
> erfüllt.
>
Firstly, make your sample minimal and self contained. Nobody needs to
install Qt just to compile your sample just so they can see a silly
message in a popup dialog.

Secondly, eliminate (better: build the grammar incrementally, so you see
when it breaks).

For some reason you did already know to put .alias() on the start rule
definition, but not on the symbol rule definition. It is required there
too (because you're copy-assigning rules).

As a hint: make your skipper accept only non-empty sequences. In fact,
you don't need to tell it how to accept repeats of the same thing, since
Skippers get applied until they don't match anyways. As written, your
parser will never finish.

I don't see why "skip" needs to alias "myskip" either; it's not even used.

             my_skip =

                 ascii::space |

                 ("**" >> *(char_ - eol) >> (eol | eoi)) |

                 ("&&" >> *(char_ - eol) >> (eol | eoi)) |

                 ("//" >> *(char_ - eol) >> (eol | eoi)) |

                 ("/*" >> *(char_ - "*/") >> "*/")

             ;

Lastly, on recent boost (1.59+ at least AFAIR) you don't need to #define
BOOST_SPIRIT_USE_PHOENIX_V3

See it live http://coliru.stacked-crooked.com/a/8eef1244cec09387

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: spirit with application crash

Jens Kallup
Hello Seth,

I can compile the source and link to executable.
The "Hello" string is success.
But the comments in the skipper will not expect.
or in other words: the skipper don't work.

** comment
// comment

these 2 lines above produce "ERROR" message.
Same to ascii::space (single or more whitespaces)

Have I missed something??

Jens

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general