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