Re: Hello, How to parse lists?
Jens Kallup <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
Here is the Syntax:
parameter = alpha.input("parameter") > def_param
def_param = alpha.input(alpha) |
(alpha.input(alpha) > ',' > def_param)
alpha = [a-zA-Z_][a-zA-Z0-9_]
------------------------------------------
source example:
parameter ccc, ccc, ccd
Problem:
parameter ccxc ffff fff
Here is the source code:
#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 USE_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;
using qi::on_error;
using qi::fail;
using phoenix::val;
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_ - "*/") >> "*/")
;
on_error<fail>
(
my_skip
, std::cout
<< val("Error! Expecting comment")
<< std::endl
);
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;
dbase_grammar() : dbase_grammar::base_type(start)
{
using boost::spirit::ascii::no_case;
using qi::lit;
using qi::char_;
using qi::lexeme;
using qi::on_error;
using qi::fail;
using phoenix::construct;
using phoenix::val;
start = run_app.alias();
run_app = - symsbols;
expression =
term.alias()
>> *(
('+' >> term )
| ('-' >> term ))
;
term =
factor.alias()
>> *(
('*' >> factor )
| ('/' >> factor ))
;
factor =
( symbol_digit
///| symbol_alpha
)
>> *(
('(' >> expression >> ')')
| ('-' >> factor )
| ('+' >> factor ))
;
symsbols =
(symbol_def_parameter)
|
(((symbol_class > symbol_alpha >
symbol_of > symbol_alpha > symbol_endclass >>
run_app) |
(symbol_class > symbol_alpha >
symbol_of > symbol_alpha > symbol_endclass)
) |
((symbol_alpha > qi::char_('=') > expression >>
run_app) |
(symbol_alpha > qi::char_('=') > expression ))
)
;
symbol_class = no_case["class"];
symbol_of = no_case["of"];
symbol_endclass = no_case["endclass"];
symbol_parameter = no_case["parameter"];
symbol_def_parameter =
(symbol_parameter > (symbol_alpha % qi::char_(',')))
;
symbol_space =
+(qi::char_(" \t\n\r") | eol | eoi)
;
symbol_alpha =
qi::char_("a-zA-Z_") >>
*qi::char_("a-zA-Z0-9_")
;
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(symsbols);
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(symbol_ident);
BOOST_SPIRIT_DEBUG_NODE(symbol_parameter);
BOOST_SPIRIT_DEBUG_NODE(symbol_def_parameter);
BOOST_SPIRIT_DEBUG_NODE(expression);
BOOST_SPIRIT_DEBUG_NODE(term);
BOOST_SPIRIT_DEBUG_NODE(factor);
}
qi::rule<Iterator, std::string()>
symbol_alpha,
symbol_ident;
qi::rule<Iterator, Skipper>
symsbols,
symbol_digit,
symbol_space,
symbol_class,
symbol_endclass,
symbol_of,
symbol_parameter,
symbol_def_parameter,
symbol_def_parameter2;
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);
}
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik