C ++ boost :: spirit lexer regex

Я делаю простой лексер / парсер с boost :: spirit.

Это лексер:

template <typename Lexer>
struct word_count_tokens : lex::lexer<Lexer>
{
word_count_tokens()
{
this->self.add_pattern
("WORD", "[a-z]+")
("NAME_CONTENT", "[a-z]+")
;

word = "{WORD}";
name = ".name";
name_content = "{NAME_CONTENT}";

this->self.add
(word)
(name)
(name_content)
('\n')
(' ')
('"')
(".", IDANY)
;
}
lex::token_def<std::string> word;
lex::token_def<std::string> name;
lex::token_def<std::string> name_content;
};

Я определил два одинаковых шаблона: WORD и NAME_CONTENT.

Это грамматика:

template <typename Iterator>
struct word_count_grammar : qi::grammar<Iterator>
{
template <typename TokenDef>
word_count_grammar(TokenDef const& tok)
: word_count_grammar::base_type(start)
{
using boost::phoenix::ref;
using boost::phoenix::size;

start = tok.name >> lit(' ') >> lit('"')  >> tok.word >> lit('"');
}

qi::rule<Iterator> start;
};

Этот код работает с tok.word в грамматике, но если я заменю tok.word на tok.name_content, он не будет работать. Но tok.word == tok.name_content.

В чем проблема с этим кодом?

PS: что я хочу разобрать это что-то вроде: .name "this is my name"

0

Решение

Обновить Кстати, проблема в том, что у вас может быть только одно совпадение токенов — они совпадают по порядку. Вы / можете / обойти это, используя лексеры. Но я не рекомендую это больше, чем использовать lexer здесь, в первую очередь


Мое предложение будет использовать Ци напрямую:

    qi::lexeme[".name"] >> qi::lexeme['"' >> *~qi::char_('"') >> '"']

Мое воспоминание о шаблонах токенов Lexer — одно из чрезвычайно запутанных требований побега.

Я мог бы попытаться выяснить это позже — только из любопытства

Жить на Колиру

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

int main() {
std::string const input(".name \"this is my name\"");

auto f(input.begin()), l(input.end());std::string parsed_name;
if (qi::phrase_parse(f,l,
qi::lexeme[".name"] >> qi::lexeme['"' >> *~qi::char_('"') >> '"'],
qi::space,
parsed_name))
{
std::cout << "Parsed: '" << parsed_name << "'\n";
}
else
{
std::cout << "Parsed failed\n";
}

if (f!=l)
std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n";
}

Печать

Parsed: 'this is my name'
3

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector