Boost::spirit 无法识别可选表达式
Boost::spirit does not recognize an optional expression
我正在学习如何使用boost::spirit,即使使用非常简单的解析器,我也面临着一些问题。我正在尝试构造一个接受由冒号分隔的数字列表(仅 0 或 1)的解析器。列表可以有 3 位或 4 位数字。因此,0:0:0
和1:0:1:0
是有效的,而例如0:0
或0:0:0:0:0
则无效。
在下面的代码中,您可以看到我如何使用可选运算符来指定第一个数字可能存在或不存在。但是,它不起作用(序列 0:0:0
的解析失败)。代码中有什么问题吗?我会说这是正确的,但同样,我刚刚开始学习精神。
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
void parse_tuple(const std::string& tuple) {
using qi::char_;
auto begin = tuple.begin();
auto end = tuple.end();
bool r = qi::parse(begin, end,
-(char_('0', '1') >> ':') >>
char_('0', '1') >> ':' >>
char_('0', '1') >> ':' >>
char_('0', '1')
);
if (!r || begin != end)
throw std::runtime_error("wrong format");
}
int main() {
parse_tuple("0:0:0"); // It fails for this one
parse_tuple("0:0:0:0");
try { parse_tuple("0:0"); } catch (...) {
std::cout << "expected errorn"; }
try { parse_tuple("0:0:0:0:0"); } catch (...) {
std::cout << "expected errorn"; }
}
这里
bool r = qi::parse(begin, end, -(char_('0', '1') >> ':') >> char_('0', '1') >> ':' >> char_('0', '1') >> ':' >> char_('0', '1') );
可选char_应该是最后一个,而不是第一个。这些规则是按顺序应用的,因此当您解析"0:0:0"时,代码的第一行(可选内容)通过测试,然后您的规则期望后面跟着 3 位数字,而不是两位数字。
在我看来,您应该只使用 % 运算符来匹配列表,稍后检查您是否解析了 3 或 4 个元素。
编辑或者使用 qi::重复以提高可读性。
这将是最直接的解决方案:
bool r = qi::parse(begin, end,
char_("01") > ':' >
char_("01") > ':' >
char_("01") > -(':' > char_("01"))
);
完整样品 http://liveworkspace.org/code/3U0QJW$0:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
void parse_tuple(const std::string& tuple) {
using qi::char_;
auto begin = tuple.begin();
auto end = tuple.end();
bool r = qi::parse(begin, end,
char_("01") > ':' >
char_("01") > ':' >
char_("01") > -(':' > char_("01"))
);
if (!r || begin != end)
throw std::runtime_error("wrong format");
}
int main() {
parse_tuple("0:0:0"); // It fails for this one
parse_tuple("0:0:0:0");
try { parse_tuple("0:0"); } catch (...) {
std::cout << "expected errorn"; }
try { parse_tuple("0:0:0:0:0"); } catch (...) {
std::cout << "expected errorn"; }
}
相关文章:
- (C++)分析树以计算返回错误值的简单算术表达式
- 提升 ASIO 无法识别计时器对象
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 从udp接收帧对于人脸识别来说太慢
- 提升精神:解析布尔表达式并简化为规范范式
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 模板类无法识别友元运算符
- 使用正则表达式regex_search在字符串中查找字符串
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 概念中的cv限定符需要表达式参数列表
- 为什么constexpr的性能比正常表达式差
- 对于结构,表达式必须是可修改的ivalue
- Qt 连接无法识别 lambda 表达式
- Boost::spirit 无法识别可选表达式
- 表达式无法识别函数c++中的指针
- 使用正则表达式识别标记的歧义
- 像cerr, exit, string这样的c++表达式在eclipse c++ IDE窗口中无法识别
- 如何使正则表达式识别html元素中的空白
- 我试图在 C++ 的字符串中找到所有"#"字符并用 "hash" 替换它们,但正则表达式无法识别字符"#"
- AST 访问者函数调用表达式无法正确识别函数调用