Re: Horrible compiletimes and memory usage while compiling a parser with X3

Jens Kallup <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
Oh, sorry, I see.
It seems that you use the spirit X3 version, instead of
boost::spirit
I recommend to use boost version.
I can't say, who maintain it, but I had no concerns.
Please download latest bosst version, compile and install it.
Then you can have a look over the code above the mail text.
It doesn't work for my need, but it can be an example, on how
to code with boost::soirit.
If you have ideas, why the source can't parse dynamic text:

"class ttt of ttt endclass"   but:
"class of endclass"

let me know.

Hope this helps

Jens

#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>

#include <string>
#include <iostream>

#define ÙSE_QT
#ifdef  USE_QT
#include <QMessageBox>
#endif

using namespace std;
using namespace boost::spirit;

namespace client
{
      namespace fusion = boost::fusion;
      namespace phoenix = boost::phoenix;

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

      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;

              my_skip = (char_("[ \t\n\r]"))                            |
              ("**" >> *(char_ - eol) >> (eol | eoi | char_("[\n\r]"))) |
              ("&&" >> *(char_ - eol) >> (eol | eoi | char_("[\n\r]"))) |
              ("//" >> *(char_ - eol) >> (eol | eoi | char_("[\n\r]"))) |
              ("/*" >> *(char_ - "*/") >> "*/")
              ;

              BOOST_SPIRIT_DEBUG_NODE((my_skip));
          }
          qi::rule<Iterator> 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)
          {
              using qi::lit;
              using qi::char_;

              using qi::on_error;
              using qi::fail;

              using phoenix::construct;
              using phoenix::val;


              start = run_app.alias();

              run_app = - symbol;

              expression =
                      term.alias()
                      >> *(
                        ('+' >> term )
                      | ('-' >> term ))
                      ;
              term =
                      factor.alias()
                      >> *(
                        ('*' >> factor )
                      | ('/' >> factor ))
                      ;

              factor =
                      ( symbol_digit
                      ///| symbol_alpha
                      )
                      >> *(
                      ('('   >> expression >> ')')
                      | ('-' >> factor     )
                      | ('+' >> factor     ))
                      ;

              symbol =
                  (((symbol_class > //symbol_space >
                     //symbol_alpha > //symbol_space >
                     symbol_of    > //symbol_space >
                     //symbol_alpha > //symbol_space >
                     symbol_endclass >> run_app) |
                    (symbol_class > //symbol_space >
                     //symbol_alpha > //symbol_space >
                     symbol_of    > //symbol_space >
                     //symbol_alpha > //symbol_space >
                     symbol_endclass)
                    )              |
                  ((symbol_alpha  > qi::char_('=') > expression >> 
run_app) |
                   (symbol_alpha  > qi::char_('=') > expression           ))
                  )
                  ;

              symbol_class    = "class";
              symbol_of       = "of";
              symbol_endclass = "endclass";

              symbol_space =
                  +(qi::char_("[ \t\n\r]") | eol | eoi)
                  ;

              symbol_alpha =
                  +(qi::alpha | qi::digit | qi::char_( "_" ))
                  ;

              symbol_digit =
                  +(qi::digit)
                  ;

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


              BOOST_SPIRIT_DEBUG_NODE(start);
              BOOST_SPIRIT_DEBUG_NODE(symbol);
              BOOST_SPIRIT_DEBUG_NODE(symbol_of);
              BOOST_SPIRIT_DEBUG_NODE(symbol_endclass);
              BOOST_SPIRIT_DEBUG_NODE(symbol_class);
              BOOST_SPIRIT_DEBUG_NODE(symbol_space);
              BOOST_SPIRIT_DEBUG_NODE(symbol_alpha);
              BOOST_SPIRIT_DEBUG_NODE(symbol_digit);


              BOOST_SPIRIT_DEBUG_NODE(expression);
              BOOST_SPIRIT_DEBUG_NODE(term);
              BOOST_SPIRIT_DEBUG_NODE(factor);
          }

          qi::rule<Iterator, Skipper>
          symbol,
          symbol_alpha,
          symbol_digit,
          symbol_space,
          symbol_class,
          symbol_endclass,
          symbol_of;

          qi::rule<Iterator, Skipper> expression, term, factor;
      };
}

bool my_parser(std::string const str)
{
      typedef std::string::const_iterator iterator_t;

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

      grammar pg;
      skipper skp;

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

      bool r = phrase_parse(iter, end, pg, skp);
      if (r == true) {
          #ifdef USE_QT
          QMessageBox::information(0,"Parser", "Parsing SUCCESS.");
          #else
          std::cout << "SUCCESS" << std::endl;
          #endif
          return true;
      }

      if (iter != end) {
          std::cout << "Remaining: '" << std::string(iter, end) << 
std::endl;
          #ifdef USE_QT
          QMessageBox::information(0,"Parser", "Parsing ERROR.");
          #else
          std::cout << "ERROR" << std::endl;
          #endif
          return false;
      }   return false;
}

bool parseText(std::string str, int mode)
{
      return my_parser(str);
}

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.