c++ - boost::spirit:多维输入的迭代器和解析器

标签 c++ parsing iterator boost-spirit

解析器的输入类似于这个例子:

struct Word{
    Word(std::string txt, int val)
    :text(txt)
    ,value(val)
    {}

    std::string text;
    int value;
};

int main()
{
    std::vector<Word> input;

    input.push_back(Word("This", 10));
    input.push_back(Word("is", 73));
    input.push_back(Word("the", 5));
    input.push_back(Word("input", 32));
}

解析器的语法是为 text 编写的Words 的变量,看起来像这样:

qi::rule<Iterator, int()> word = qi::string("This") | 
                                 qi::string("is") | 
                                 qi::string("the") | 
                                 qi::string("input"); 
qi::rule<Iterator, std::vector<int>()> start = +word;

解析std::vector<Word> input应该产生一个包含相应整数值的 vector ,对于这个例子,它将是

[10,73,5,32]
  1. 这甚至可以通过 boost::spirit 实现,还是我应该采取不同的方法?

如果这是一个合理的解决方案,

  1. 如何实现 Iterator为此,它看起来如何?
  2. 要创建相应的合成属性,语义 Action 应该是什么样的,或者我是否需要一些其他精神“魔法”?

我希望我为此提供了足够的信息,如果没有,请告诉我。


编辑:

看起来我问得不够具体,因为我试图让这个问题尽可能笼统。 Sehe's solution应该适用于我所描述的内容,但我有以下限制:

  1. 一个Word可以多次出现,具有不同的Integer值,Words文本与其Integer值之间没有相关性
  2. 无论如何都需要解析“文本”(在本例中为“This is the input”)以完成另一项任务。我已经为此编写了所有内容,如果我能以某种方式从语义操作内部访问 Integer 值,那么添加我需要的内容真的很容易。

最佳答案

从表面上看,这似乎与词法分析(又名标记化或扫描)更相关。参见 Boost Spirit Lex。

以灵气“法术”,用符:

Live On Coliru

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

struct tokens : qi::symbols<char, int>
{
    tokens() {
        add
            ("This",  10)
            ("is",    73)
            ("the",   5)
            ("input", 32);
    }
};

int main() {
    std::string const input("This is the input");

    std::vector<int> parsed;
    std::string::const_iterator f = input.begin(), l = input.end();
    bool ok = qi::phrase_parse(f, l, qi::no_case[ +tokens() ], qi::space, parsed);

    if (ok)
        std::cout << "Parse success: ";
    else
        std::cout << "Parse failed: ";

    std::copy(parsed.begin(), parsed.end(), std::ostream_iterator<int>(std::cout, " "));

    if (f!=l)
        std::cout << "\nRemaining input: '" << std::string(f,l) << "'\n";
}

打印:

Parse success: 10 73 5 32 

另见 qi::no_case qi::symbols :

When symbols is used for case-insensitive parsing (in a no_case directive), added symbol strings should be in lowercase. Symbol strings containing one or more uppercase characters will not match any input when symbols is used in a no_case directive.

关于c++ - boost::spirit:多维输入的迭代器和解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29125093/

相关文章:

c++ - 常量迭代器的问题

c++ - 新的 C++11 range-for (foreach) 语法 : which compilers support it?

C++ 前向声明混淆

java - Jsoup显示数据到textview

c# - 在 C# 中查找数字字符的数值

c++ - 无法在 C++ 中创建模板<typename T> vector<T>::iterator

java - 为什么 ConcurrentSkipListSet 升序迭代器 'faster' 而不是降序迭代器?

c++ - 使用字符串映射 vector C++ 时可能存在内存泄漏

c++ - 任务管理器的精确度如何?

ios - 使用 JSON 数据在标签上设置文本