从匹配的子字符串中停止X3符号 [英] Stop X3 symbols from matching substrings

查看:92
本文介绍了从匹配的子字符串中停止X3符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何防止X3符号解析器匹配部分令牌?在下面的示例中,我要匹配 foo,而不是 foobar。我尝试将符号解析器扔到 lexeme 指令中,就像使用标识符一样,但是没有匹配项。

How does one prevent X3 symbol parsers from matching partial tokens? In the example below, I want to match "foo", but not "foobar". I tried throwing the symbol parser in a lexeme directive as one would for an identifier, but then nothing matches.

#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以前在其存储库中有个区别

Qi used to have distinct in their repository.

X3没有。

为您显示的情况解决该问题的是一个简单的前瞻性断言:

The thing that solves it for the case you showed is a simple lookahead assertion:

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

您也可以轻松地创建独特的助手,例如:

You could make a distinct helper easily too, e.g.:

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

这篇关于从匹配的子字符串中停止X3符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆