Разобрать процитированные строки с boost :: spirit
Я хотел бы разобрать предложение, в котором некоторые строки могут быть без кавычек, "цитировано"; или "процитировано". Код ниже почти работает - но он не соответствует закрывающим кавычкам. Я предполагаю, что это из-за ссылки на qq. Модификация прокомментирована в коде, модификация повторяется в «цитируемом». или "цитируется" Также анализ и помогает показать оригинальную проблему с заключительной цитатой. Код также описывает точную грамматику.
Чтобы было совершенно ясно: строки без кавычек разбираются. Строка в кавычках, как'hello'
будет разбирать открытую цитату'
все персонажиhello
, но потом не удалось разобрать окончательную цитату'
.
Я сделал еще одну попытку, похожую на начало / конец тега вповысить учебники, но безуспешно.
<code>template <typename Iterator> struct test_parser : qi::grammar<Iterator, dectest::Test(), ascii::space_type> { test_parser() : test_parser::base_type(test, "test") { using qi::fail; using qi::on_error; using qi::lit; using qi::lexeme; using ascii::char_; using qi::repeat; using namespace qi::labels; using boost::phoenix::construct; using boost::phoenix::at_c; using boost::phoenix::push_back; using boost::phoenix::val; using boost::phoenix::ref; using qi::space; char qq; arrow = lit("->"); open_quote = (char_('\'') | char_('"')) [ref(qq) = _1]; // Remember what the opening quote was close_quote = lit(val(qq)); // Close must match the open // close_quote = (char_('\'') | char_('"')); // Enable this line to get code 'almost' working quoted_string = open_quote >> +ascii::alnum >> close_quote; unquoted_string %= +ascii::alnum; any_string %= (quoted_string | unquoted_string); test = unquoted_string [at_c<0>(_val) = _1] > unquoted_string [at_c<1>(_val) = _1] > repeat(1,3)[any_string] [at_c<2>(_val) = _1] > arrow > any_string [at_c<3>(_val) = _1] ; // .. <snip>set rule names on_error<fail>(/* <snip> */); // debug rules } qi::rule<Iterator> arrow; qi::rule<Iterator> open_quote; qi::rule<Iterator> close_quote; qi::rule<Iterator, std::string()> quoted_string; qi::rule<Iterator, std::string()> unquoted_string; qi::rule<Iterator, std::string()> any_string; // A quoted or unquoted string qi::rule<Iterator, dectest::Test(), ascii::space_type> test; }; // main() // This example should fail at the very end // (ie not parse "str3' because of the mismatched quote // However, it fails to parse the closing quote of str1 typedef boost::tuple<string, string, vector<string>, string> DataT; DataT data; std::string str("addx001 add 'str1' \"str2\" -> \"str3'"); std::string::const_iterator iter = str.begin(); const std::string::const_iterator end = str.end(); bool r = phrase_parse(iter, end, grammar, boost::spirit::ascii::space, data); </code>
Для бонусного кредита: решение, которое позволяет избежать локального члена данных (например,char qq
в приведенном выше примере) было бы предпочтительным, но с практической точки зрения я буду использовать все, что работает!