What is wrong with the code in the message body? I get many warnings and error messages. Use by spirit::qi
Jens Kallup <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
//#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 <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/phoenix/object/construct.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <exception>
#include <fstream>
#include <string>
#include <vector>
#define USE_QT
#ifdef USE_QT
#include <QMessageBox>
#endif
using namespace std;
using boost::phoenix::function;
using boost::phoenix::ref;
using boost::phoenix::size;
using namespace boost::spirit;
using namespace boost::spirit::qi;
namespace client
{
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
enum byte_code
{
op_neg, // negate the top stack entry
op_add, // add top two stack entries
op_sub, // subtract top two stack entries
op_mul, // multiply top two stack entries
op_div, // divide top two stack entries
op_not, // boolean negate the top stack entry
op_eq, // compare the top two stack entries for ==
op_neq, // compare the top two stack entries for !=
op_lt, // compare the top two stack entries for <
op_lte, // compare the top two stack entries for <=
op_gt, // compare the top two stack entries for >
op_gte, // compare the top two stack entries for >=
op_and, // logical and top two stack entries
op_or, // logical or top two stack entries
op_add_var, // add new variable
op_load, // load a variable
op_store, // store a variable
op_double, // push constant integer into the stack
op_true, // push constant 0 into the stack
op_false, // push constant 1 into the stack
op_jump_if, // jump to an absolute position in the code
if top stack
// evaluates to false
op_jump, // jump to an absolute position in the code
op_stk_adj, // adjust the stack (for args and locals)
op_call, // function call
op_return // return from function
};
class vmachine
{
public:
vmachine(unsigned stackSize = 4096)
: stack(stackSize)
{
}
int execute(
std::vector<int> const& code // the program code
, std::vector<int>::const_iterator pc // program counter
, std::vector<int>::iterator frame_ptr // start of
arguments and locals
);
std::vector<int> stack;
};
struct error_handler_
{
template <typename, typename, typename>
struct result { typedef void type; };
template <typename Iterator>
void operator()(
info const& what
, Iterator err_pos, Iterator last) const
{
std::stringstream ss;
ss << "Error! Expecting "
<< what // what failed?
<< " here: \""
<< std::string(err_pos, last) // iterators to
error-pos, end
<< "\""
<< std::endl
;
std::cout << ss.str();
QMessageBox::information(0,"Parser", ss.str().c_str());
}
};
boost::phoenix::function<client::error_handler_> const
error_handler = client::error_handler_();
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_("äöüÄÖÜß") | char_) - eol) >> (eol | eoi
| char_("[\n\r]"))) |
("&&" >> *((char_("äöüÄÖÜß") | char_) - eol) >> (eol | eoi
| char_("[\n\r]"))) |
("//" >> *((char_("äöüÄÖÜß") | char_) - eol) >> (eol | eoi
| char_("[\n\r]"))) |
("/*" >> *((char_("äöüÄÖÜß") | 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;
};
struct my_ops {
byte_code op_code;
std::string name;
double value;
};
std::vector<struct my_ops> code;
struct compile_op
{
template <typename A, typename B = unused_type, typename C =
unused_type>
struct result { typedef void type; };
compile_op(std::vector<my_ops> _code)
{
code = _code;
}
void operator()(const byte_code &a) const
{
struct my_ops my_pspush;
my_pspush.op_code = a;
my_pspush.name = "";
my_pspush.value = 0.00;
code.push_back(my_pspush);
}
void operator()(const byte_code &a, double &b) const
{
struct my_ops my_pspush;
my_pspush.op_code = a;
my_pspush.name = "";
my_pspush.value = b;
code.push_back(my_pspush);
}
void operator()(const byte_code &a, const std::string &b) const
{
struct my_ops my_pspush;
my_pspush.op_code = a;
my_pspush.name = b;
my_pspush.value = 0.00;
code.push_back(my_pspush);
}
/*
void operator()(byte_code a, byte_code b, byte_code c)
{
code.push_back(a);
code.push_back(b);
code.push_back(c);
}*/
};
struct function_state_reset
{
template <typename>
struct result { typedef void type; };
function_state_reset(
std::vector<int>& code
, symbols<char, int>& vars
, int& nvars)
: code(code)
, vars(vars)
, nvars(nvars)
{
}
void operator()(int address)
{
code[address+1] = nvars;
nvars = 0; // reset
vars.clear(); // reset
}
std::vector<int>& code;
symbols<char, int> vars;
int &nvars;
};
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)
{
//bool has_return;
//int nvars;
//boost::phoenix::function<var_adder> add_var;
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 = * symsbols;
expression = equality_expr;
equality_expr =
relational_expr
>> *( ("==" > relational_expr [op(op_eq)])
| ("!=" > relational_expr [op(op_neq)])
)
;
relational_expr =
logical_expr
>> *( ("<=" > logical_expr [op(op_lte)])
| ('<' > logical_expr [op(op_lt)])
| (">=" > logical_expr [op(op_gte)])
| ('>' > logical_expr [op(op_gt)])
)
;
logical_expr =
additive_expr
>> *( (lit(".and.") > additive_expr [op(op_and)])
| (lit(".or.") > additive_expr [op(op_or)])
)
;
additive_expr =
multiplicative_expr
>> *( ('+' > multiplicative_expr [op(op_add)])
| ('-' > multiplicative_expr [op(op_sub)])
)
;
multiplicative_expr =
unary_expr
>> *( ('*' > unary_expr [op(op_mul)])
| ('/' > unary_expr [op(op_div)])
)
;
unary_expr =
primary_expr
| ('!' > primary_expr [op(op_not)])
| ('-' > primary_expr [op(op_neg)])
| ('+' > primary_expr)
;
primary_expr =
double_ [op(op_double, _1)]
| variable
| lit("true") [op(op_true)]
| lit("false") [op(op_false)]
| '(' > expression > ')'
;
variable = symbol_alpha;
symsbols %=
symbol_def_parameter |
symbol_def_local |
symbol_def_class |
symbol_def_if |
(symbol_alpha > '=' > (expression % qi::char_('=')))
;
symbol_class = lexeme[no_case["class"]];
symbol_of = lexeme[no_case["of"]];
symbol_endclass = lexeme[no_case["endclass"]];
symbol_parameter = lexeme[no_case["parameter"]];
symbol_local = lexeme[no_case["local"]];
symbol_if = lexeme[no_case["if"]];
symbol_else = lexeme[no_case["else"]];
symbol_endif = lexeme[no_case["endif"]];
symbol_def_parameter %=
(symbol_parameter >> (symbol_alpha % ','))
;
symbol_def_local %=
(symbol_local >> (symbol_alpha % ','))
;
symbol_def_class %= symbol_def_class_inner;
symbol_def_class_inner %=
symbol_class
>> symbol_alpha >> -(qi::lit('(') >> symbol_alpha >>
qi::lit(')'))
>> symbol_of
>> symbol_alpha >>
* symbol_def_stmts
>> symbol_endclass;
symbol_def_if %= symbol_def_if_inner;
symbol_def_if_inner %=
symbol_if > '(' > expression > ')' >>
* (symbol_def_stmts | symbol_else)
> symbol_endif;
symbol_def_assign =
symbol_alpha
[
op(op_add_var,
boost::phoenix::construct<std::string>(qi::_1))
]
> (qi::lit('=') > expression
[
op(op_store, qi::_1)
])
;
symbol_def_stmts %=
symbol_def_if |
symbol_def_class |
symbol_def_assign
;
symbol_space =
+(qi::char_(" \t\n\r") | eol | eoi)
;
symbol_alpha %=
qi::char_("a-zA-Z_") >>
*qi::char_("a-zA-Z0-9_")
[
_val =
boost::phoenix::construct<std::string>(qi::_1) +
boost::phoenix::construct<std::string>(qi::_2)
]
;
symbol_digit =
+(qi::digit)
;
qi::on_error<fail>( start, client::error_handler(_4, _3,
_2) );
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(symbol_def_stmts);
BOOST_SPIRIT_DEBUG_NODE(symbol_def_local);
BOOST_SPIRIT_DEBUG_NODE(symbol_def_class);
BOOST_SPIRIT_DEBUG_NODE(symbol_def_class_inner);
BOOST_SPIRIT_DEBUG_NODE(expression);
BOOST_SPIRIT_DEBUG_NODE(term);
BOOST_SPIRIT_DEBUG_NODE(factor);
BOOST_SPIRIT_DEBUG_NODE(symbol_if);
BOOST_SPIRIT_DEBUG_NODE(symbol_else);
BOOST_SPIRIT_DEBUG_NODE(symbol_endif);
BOOST_SPIRIT_DEBUG_NODE(symbol_local);
}
qi::rule<Iterator, Skipper> assignment_rhs;
qi::rule<Iterator, Skipper>
equality_expr, relational_expr
, logical_expr, additive_expr, multiplicative_expr
, unary_expr, primary_expr, variable
;
phoenix::function<compile_op> op;
qi::rule<Iterator, std::string()>
symbol_alpha,
symbol_ident;
qi::rule<Iterator, Skipper>
symsbols,
symbol_local,
symbol_if,
symbol_else,
symbol_endif,
symbol_digit,
symbol_space,
symbol_class,
symbol_endclass,
symbol_of,
symbol_parameter,
symbol_def_assign,
symbol_def_parameter,
symbol_def_if,
symbol_def_if_inner,
symbol_def_stmts,
symbol_def_local,
symbol_def_class_inner,
symbol_def_class;
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::stringstream ss;
ss << "Parsing ERROR" << std::endl
<< "Remaining: '"
<< std::string(iter, end)
<< std::endl;
#ifdef USE_QT
QMessageBox::information(0,"Parser", ss.str().c_str());
#else
std::cout << "ERROR" << std::endl;
#endif
return false;
}
return false;
}
bool parseText(std::string str, int mode)
{
client::code.clear();
client::code.resize(10);
return my_parser(str);
}
------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general