Hmmm :
ident_decl = keyword_table_ > ident;
, - :
struct my_keywords : boost::spirit::qi::symbols<char, int> {
my_keywords() {
add
("void", TYPE_VOID)
("string", TYPE_STRING)
("float", TYPE_FLOAT)
("int", TYPE_INT)
("bool", TYPE_BOOL)
;
}
} keywords_table_;
//...
class ident_decl_node
{
template < typename, int>
friend struct boost::fusion::extension::struct_member;
int type;
std::string ident;
};
BOOST_FUSION_ADAPT_STRUCT(
ident_decl_node,
(int, type)
(std::string, ident)
)
//...
struct MyErrorHandler
{
template <typename, typename, typename, typename>
struct result { typedef void type; };
template <typename Iterator>
void operator()(Iterator first, Iterator last, Iterator error_pos, std::string const& what) const
{
using boost::phoenix::construct;
std::string error_msg = "Error! Expecting ";
error_msg += what;
error_msg += " here: \"";
error_msg += std::string(error_pos, last);
error_msg += "\"";
std::cout << error_msg;
}
};
//...
using boost::spirit::qi::grammar;
using boost::spirit::ascii::space_type;
typedef std::vector<boost::variant<ident_decl_node, some_other_node> ScriptNodes;
template <typename Iterator>
struct NodeGrammar: public grammar<Iterator, ScriptNodes(), space_type>
{
using boost::spirit::arg_names;
NodeGrammar: NodeGrammar::base_type(start)
{
start %= ident_decl | some_other_node_decl >> eps;
ident_decl %= keyword_table > ident;
ident %= raw[lexeme[((alpha | char_('_')) >> *(alnum | char_('_'))) - keywords_table_]];
on_error<fail>(start, error_handler(_1, _2, _3, _4));
}
my_keywords keyword_table_;
boost::spirit::qi::rule<Iterator, ScriptNodes(), ascii::space_type> start;
boost::spirit::qi::rule<Iterator, ident_decl_node(), ascii::space_type> ident_decl;
boost::spirit::qi::rule<Iterator, some_other_node(), ascii::space_type> ident_decl;
boost::spirit::qi::rule<Iterator, std::string(), ascii::space_type> ident;
boost::phoenix::function<MyErrorHandler> error_handler;
};
, , , boost 1.40, ,
% =, ( ). :
ident_decl %= ident;
ident_decl %= ident > eps;
.
, .