如何绕过贪婪的道路
How to get around greedy rd?
我想解析一个可以包含'-'的字符串,但不能以它开头或结尾。
我希望这个解析器可以工作:
auto const parser = alnum >> -(*(alnum | char_('-')) >> alnum);
但是在我的测试输入"某物"中,它只解析"所以",而不会吃掉其余的。
问题是中间位*(alnum | char_('-'))
一直吃到最后(包括最后一个字符,所以整个可选括号都失败了(。
如何以及为什么在这里和这里解释
我想知道的是,我怎样才能绕过它并制作这个解析器?
现场观看:http://coliru.stacked-crooked.com/a/833cc2aac7ba5e27
我个人会"积极"地写它:
auto const rule = raw [ lexeme [
alnum >> *('-' >> alnum | alnum) >> !(alnum|'-')
] ];
这使用
-
lexeme
处理空格意义, -
raw
避免主动匹配要作为输出一部分的每个字符(您只需要所有字符(。 -
'-' >> alnum
积极要求任何破折号后面都有一个alnum。请注意,这也禁止在输入中"--"
。请参阅下面的变体
住在科里鲁
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
#include <algorithm>
namespace x3 = boost::spirit::x3;
namespace parser {
using namespace boost::spirit::x3;
auto const rule = raw [ lexeme [
alnum >> *('-' >> alnum | alnum) >> !(alnum|'-')
] ];
}
int main() {
struct test { std::string input; bool expected; };
for (auto const t : {
test { "some-where", true },
test { " some-where", true },
test { "some-where ", true },
test { "s", true },
test { " s", true },
test { "s ", true },
test { "-", false },
test { " -", false },
test { "- ", false },
test { "some-", false },
test { " some-", false },
test { "some- ", false },
test { "some--where", false },
test { " some--where", false },
test { "some--where ", false },
})
{
std::string output;
bool ok = x3::phrase_parse(t.input.begin(), t.input.end(), parser::rule, x3::space, output);
if (ok != t.expected)
std::cout << "FAILURE: '" << t.input << "'t" << std::boolalpha << ok << "t'" << output << "'n";
}
}
变体
为了也允许some--thing
和类似的输入,我会将'-'
更改为+lit('-')
:
alnum >> *(+lit('-') >> alnum | alnum) >> !(alnum|'-')
住在科里鲁
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
#include <algorithm>
namespace x3 = boost::spirit::x3;
namespace parser {
using namespace boost::spirit::x3;
auto const rule = raw [ lexeme [
alnum >> *(+lit('-') >> alnum | alnum) >> !(alnum|'-')
] ];
}
int main() {
struct test { std::string input; bool expected; };
for (auto const t : {
test { "some-where", true },
test { " some-where", true },
test { "some-where ", true },
test { "s", true },
test { " s", true },
test { "s ", true },
test { "-", false },
test { " -", false },
test { "- ", false },
test { "some-", false },
test { " some-", false },
test { "some- ", false },
test { "some--where", true },
test { " some--where", true },
test { "some--where ", true },
})
{
std::string output;
bool ok = x3::phrase_parse(t.input.begin(), t.input.end(), parser::rule, x3::space, output);
if (ok != t.expected)
std::cout << "FAILURE: '" << t.input << "'t" << std::boolalpha << ok << "t'" << output << "'n";
}
}
我通过告诉贪婪的 kleene 星内的解析器忽略"eoi"(输入结束(来修复它。一个更强大的修复程序也会让它因空格而失败:
所以*(alnum | char_('-'))
变得*((alnum | char_('-')) >> !(eoi | space))
现场观看:http://coliru.stacked-crooked.com/a/79242cdbd2fac947
相关文章:
- 贪婪算法编号列表
- 用给定面值的最小硬币数量计价金额.贪婪的问题
- 贪婪地分配分数以最大化最终结果
- 贪婪算法的实现
- C 中的贪婪算法最小搜索
- Dijkstra与机场和道路
- 增强精神解析器:绕过贪婪的克莱恩*
- 贪婪算法练习无法正常工作
- 他是不是很贪婪
- 如何维护城市道路数据?(我应该使用什么数据结构)
- 硬币兑换的贪婪算法c++
- 如何使预处理器宏贪婪
- 标准库中潜伏着哪些贪婪的初始值设定项列表示例
- 配置 VS2010 用于贪婪投影三角测量
- 贪婪送礼者USACO培训计划中的执行错误
- 通过贪婪算法找到最小移动次数
- 为什么贪婪的方法在这种情况下不起作用?
- 删除字符串贪婪正则表达式在QT
- 助推中的非贪婪匹配.Regex扩展Regex
- 如何绕过贪婪的道路