Предупреждение; в то время как я пытался сократить код до минимума. Я все еще должен был включить совсем немного, чтобы обеспечить наличие необходимой информации.Перевертывание порядка субрулей внутри правила в boost :: spirit grammar приводит к segfault
Этот код компилирует файлы и запускает, что приводит к синтаксической ошибке;
name = simple_name [ qi::_val = qi::_1 ]
| qualified_name [ qi::_val = qi::_1 ]
;
Хотя это;
name = qualified_name [ qi::_val = qi::_1 ]
| simple_name [ qi::_val = qi::_1 ]
;
Результаты в SIGSEGV
, ошибка сегментации;
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 to come ...
Куда;
simple_name = (tok.identifier) [ qi::_val = build_simple_name_(qi::_1) ];
И;
qualified_name = (name >> qi::raw_token(DOT) >> tok.identifier) [ qi::_val = build_qualified_name_(qi::_1, qi::_2) ] ;
Все эти правила, вернуть Ast::name*()
;
qi::rule<Iterator, Ast::name*()> name;
qi::rule<Iterator, Ast::name*()> simple_name;
qi::rule<Iterator, Ast::name*()> qualified_name;
Вспомогательные функции определяются как;
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)
И;
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)
Используемые определения lexer определяются как;
lex::token_def<std::string> identifier = "{JAVA_LETTER}{JAVA_LETTER_OR_DIGIT}*";
И;
('.', DOT)
Там, где образцы {JAVA_LETTER}
и {JAVA_LETTER_OR_DIGIT}
определяются как;
("DIGIT", "[0-9]")
("LATIN1_LETTER", "[A-Z]|[a-z]")
("JAVA_LETTER", "{LATIN1_LETTER}|$|_")
("JAVA_LETTER_OR_DIGIT", "{JAVA_LETTER}|{DIGIT}")
Мой ввод, это простая строка;
package a.D;
Какие лексики для жетонов;
Keywords : package
Identifier : a
Delimiters : .
Identifier : D
Delimiters : ;
Где первый пример (с первым именем simple_name), генерирует синтаксическую ошибку как;
Syntax Error at line 1:
package a.D;
^^
И последний пример просто выбрасывает segfault с ранее отправленной ошибкой.
Очевидно, что второй пример - это то, что я хочу, поскольку он должен попытаться совместить сложное выражение перед простым.
Кто-нибудь видит, почему происходит сбой кода, или как я буду разбираться? - Также должно ли это быть в обзоре кода?
Вы оставили рекурсию, имя зависит от квалифицированного имени, которое зависит от имени и т. Д. – llonesmiz
Это незаконно? - Также, если это так, как я могу получить тот же эффект, вот как я могу его реорганизовать? – Skeen