解析器的输入类似于这个例子:
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]
- 这甚至可以通过 boost::spirit 实现,还是我应该采取不同的方法?
如果这是一个合理的解决方案,
- 如何实现
Iterator
为此,它看起来如何? - 要创建相应的合成属性,语义 Action 应该是什么样的,或者我是否需要一些其他精神“魔法”?
我希望我为此提供了足够的信息,如果没有,请告诉我。
编辑:
看起来我问得不够具体,因为我试图让这个问题尽可能笼统。 Sehe's solution应该适用于我所描述的内容,但我有以下限制:
- 一个Word可以多次出现,具有不同的Integer值,Words文本与其Integer值之间没有相关性
- 无论如何都需要解析“文本”(在本例中为“This is the input”)以完成另一项任务。我已经为此编写了所有内容,如果我能以某种方式从语义操作内部访问 Integer 值,那么添加我需要的内容真的很容易。
最佳答案
从表面上看,这似乎与词法分析(又名标记化或扫描)更相关。参见 Boost Spirit Lex。
以灵气“法术”,用符:
#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 ano_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 ano_case
directive.
关于c++ - boost::spirit:多维输入的迭代器和解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29125093/