【问题标题】:Stop X3 symbols from matching substrings从匹配的子字符串中停止 X3 符号
【发布时间】:2015-11-15 21:49:48
【问题描述】:

如何防止 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";
      }
    }
}

【问题讨论】:

    标签: c++ c++11 boost-spirit boost-spirit-x3


    【解决方案1】:

    Qi 曾经在他们的存储库中有distinct

    X3 没有。

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

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

    你也可以轻松地创建一个distinct 助手,例如:

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

    现在你可以解析kw(sym)

    Live On 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
    

    【讨论】:

    • 非常感谢。我是如此接近 - '-' 解析器在解析字符时工作。需要重新阅读(有限的)文档以获取前瞻解析器。 lambda 帮助功能的奖励!
    猜你喜欢
    • 2021-08-25
    • 1970-01-01
    • 2011-03-20
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2011-11-08
    相关资源
    最近更新 更多