segmentation fault - Flipping the order of subrules inside a rule in a boost::spirit grammar results in segfault -


warning; while tried shorten code down, minimum. still had include quite bit, ensure required information present.

this code, compiles files, , runs resulting in syntax error;

name = simple_name      [ qi::_val = qi::_1 ]      | qualified_name   [ qi::_val = qi::_1 ]      ; 

while this;

name = qualified_name   [ qi::_val = qi::_1 ]      | simple_name      [ qi::_val = qi::_1 ]      ; 

results in sigsegv, segmentation fault;

boost::detail::function::function_obj_invoker4<boost::spirit::qi::detail::parser_binder<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::action<boost::spirit::qi::reference<boost::spirit::qi::rule<boost::spirit::lex::lexertl::iterator<boost::spirit::lex::lexertl::functor<boost::spirit::lex::lexertl::token<__gnu_cxx::__normal_iterator<char*, std::string>, boost::mpl::vector<std::string, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, mpl_::bool_<false>, unsigned long>, boost::spirit::lex::lexertl::detail::data, __gnu_cxx::__normal_iterator<char*, std::string>, mpl_::bool_<true>, mpl_::bool_<false> > >, ast::name* (), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> const>, boost::phoenix::actor<boost::proto::exprns_::expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >,0l>,boost::phoenix::actor<boost::spirit::argument<0> > >, 2l> > >,boost::fusion::cons<boost::spirit::qi::action<boost::spirit::qi::reference<boost::spirit::qi::rule<boost::spirit::lex::lexertl::iterator<boost::spirit::lex::lexertl::functor<boost::spirit::lex::lexertl::token<__gnu_cxx::__normal_iterator<char*, std::string>,boost::mpl::vector<std::string, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, mpl_::bool_<false>,unsigned long>, boost::spirit::lex::lexertl::detail::data, __gnu_cxx::__normal_iterator<char*,std::string>, mpl_::bool_<true>, mpl_::bool_<false> > >, ast::name* (), ... more come ... 

where;

simple_name = (tok.identifier) [ qi::_val = build_simple_name_(qi::_1) ]; 

and;

qualified_name = (name >> qi::raw_token(dot) >> tok.identifier) [ qi::_val = build_qualified_name_(qi::_1, qi::_2) ] ; 

all of these rules, return ast::name*();

qi::rule<iterator, ast::name*()> name; qi::rule<iterator, ast::name*()> simple_name; qi::rule<iterator, ast::name*()> qualified_name; 

the helper functions defined as;

ast::name* build_simple_name(std::string str) {     return (new ast::name_simple(ast::identifier(str))); } boost_phoenix_adapt_function(ast::name*, build_simple_name_, build_simple_name, 1) 

and;

ast::name* build_qualified_name(ast::name* name, std::string str) {     std::list<ast::identifier> qualified_name = ast::name_to_identifier_list(name);     qualified_name.push_back(ast::identifier(str));      return (new ast::name_qualified(qualified_name)); } boost_phoenix_adapt_function(ast::name*, build_qualified_name_, build_qualified_name, 2) 

the lexer definitions used defined as;

lex::token_def<std::string> identifier = "{java_letter}{java_letter_or_digit}*"; 

and;

('.', dot) 

where patterns {java_letter} , {java_letter_or_digit} defined as;

("digit",           "[0-9]") ("latin1_letter",   "[a-z]|[a-z]") ("java_letter",     "{latin1_letter}|$|_") ("java_letter_or_digit", "{java_letter}|{digit}") 

my input, simple string;

package a.d; 

which lexes tokens;

keywords : package identifier : delimiters : . identifier : d delimiters : ; 

where first example (with simple_name first), throws syntax error as;

syntax error @ line 1: package a.d;           ^^ 

and last example throws segfault, error posted previously.

clearly second example want, should try match complex expression, before simple one.

does see why code crashes, or how go figuring out? - should @ code review?

the problem have left recursive grammar , cannot used boost.spirit. have basically:

name = identifier | name >> dot >> identifier; 

as can see here, in order remove left recursion when have like:

a = >> alpha | beta; 

you need create 2 new "rules":

a = beta >> a_tail; a_tail = eps | alpha >> a_tail; 

in case:

a := name alpha := dot >> identifier beta := identifier 

so "rules" be:

name = identifier >> name_tail; name_tail = eps | dot >> identifier >> a_tail; 

if closely @ name_tail can see literally means: either nothing or dot >> identifier followed either nothing or dot >> identifier , on. means name_tail is:

name_tail = *(dot >> identifier); 

so name rule be:

name = identifier >> *(dot >> identifier); 

all of correct, there chance not work attributes.


Comments

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -