boost::spirit:用于多维输入的迭代器和解析

boost::spirit: iterator and parsing for multidimensional input

本文关键字:迭代器 输入 和解 spirit 用于 boost      更新时间:2023-10-16

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

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));
}

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

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应该会得到一个包含相应整数值的向量,在本例中,它将是

[10,73,5,32]
  1. 这是否有可能:精神上还是应该采取不同的方法

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

  1. 如何实现Iterator,它看起来怎么样
  2. 语义动作应该是什么样子才能创建相应的合成属性,还是我需要一些其他的精神"魔法"

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


编辑:

看起来我问得不够具体,因为我尽量保持这个问题的一般性。Sehe的解决方案应该适用于我所描述的,但我有以下限制:

  1. 一个单词可以用不同的整数值出现多次,单词文本与其整数值之间没有相关性
  2. 无论如何,"文本"(在本例中为"this is The input")都需要进行解析才能完成另一项任务。我已经写了所有这样做的东西,如果我能以某种方式从语义操作内部访问Integer值,那么添加我需要的东西对我来说真的很容易

从表面上看,这似乎更多地与词法分析(也称为标记化或扫描)有关。参见Boost Spirit Lex。

使用灵气"魔法",使用符号:

在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_caseqi::symbols

symbols用于不区分大小写的解析(在no_case指令中)时,添加的符号字符串应为小写。在no_case指令中使用符号时,包含一个或多个大写字符的符号字符串将与任何输入都不匹配