停止匹配子字符串中的X3符号

Stop X3 symbols from matching substrings

本文关键字:X3 符号 字符串      更新时间:2023-10-16

如何防止X3符号解析器匹配部分令牌?在下面的示例中,我希望匹配"foo",但不匹配"foobar"。我尝试在lexeme指令中抛出符号解析器,就像对标识符一样,但没有匹配的东西。

感谢您的真知灼见!

#include <string>
#include <iostream>
#include <iomanip>
#include <boost/spirit/home/x3.hpp>

int main() {
  boost::spirit::x3::symbols<int> sym;
  sym.add("foo", 1);
  for (std::string 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的存储库中曾经有distinct

X3没有。

解决您展示的案例的方法是一个简单的前瞻性断言:

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

你也可以很容易地制作distinct助手,例如:

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

现在您可以解析kw(sym)

在Coliru上直播

#include <iostream>
#include <boost/spirit/home/x3.hpp>
int main() {
    boost::spirit::x3::symbols<int> sym;
    sym.add("foo", 1);
    for (std::string 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";
        }
    }
}

打印

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