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