Arrêtez les symboles X3 de faire correspondre les sous-chaînes

Comment empêcher les parsingurs syntaxiques de symboles X3 de faire correspondre des jetons partiels? Dans l’exemple ci-dessous, je veux faire correspondre “foo”, mais pas “foobar”. J’ai essayé de lancer l’parsingur de symboles dans une directive lexeme comme on le ferait pour un identifiant, mais rien ne correspond.

Merci pour toutes les idées!

 #include  #include  #include  #include  int main() { boost::spirit::x3::symbols sym; sym.add("foo", 1); for (std::ssortingng const input : { "foo", "foobar", "barfoo" }) { using namespace boost::spirit::x3; std::cout << "\nParsing " << std::left << std::setw(20) << ("'" + input + "':"); int v; auto iter = input.begin(); auto end = input.end(); bool ok; { // what's right rule?? // this matches nothing // auto r = lexeme[sym - alnum]; // this matchs prefix strings auto r = sym; ok = phrase_parse(iter, end, r, space, v); } if (ok) { std::cout << v << " Remaining: " << std::string(iter, end); } else { std::cout << "Parse failed"; } } } 

Qi avait l’habitude d’avoir distinct dans leur référentiel.

X3 non.

La chose qui résout le problème que vous avez présenté est une simple affirmation anticipée:

 auto r = lexeme [ sym >> !alnum ]; 

Vous pouvez facilement créer un assistant distinct , par exemple:

 auto kw = [](auto p) { return lexeme [ p >> !(alnum | '_') ]; }; 

Maintenant, vous pouvez simplement parsingr kw(sym) .

Live On Coliru

 #include  #include  int main() { boost::spirit::x3::symbols sym; sym.add("foo", 1); for (std::ssortingng const input : { "foo", "foobar", "barfoo" }) { std::cout << "\nParsing '" << input << "': "; auto iter = input.begin(); auto const end = input.end(); int v = -1; bool ok; { using namespace boost::spirit::x3; auto kw = [](auto p) { return lexeme [ p >> !(alnum | '_') ]; }; ok = phrase_parse(iter, end, kw(sym), space, v); } if (ok) { std::cout << v << " Remaining: '" << std::string(iter, end) << "'\n"; } else { std::cout << "Parse failed"; } } } 

Impressions

 Parsing 'foo': 1 Remaining: '' Parsing 'foobar': Parse failed Parsing 'barfoo': Parse failed