设为首页 加入收藏

TOP

秘笈18 解析简单的输入(2)
2014-05-12 09:45:01 来源: 作者: 【 】 浏览:165
Tags:秘笈 解析 简单 输入

秘笈18 解析简单的输入(2)

工作原理

这是一个非常简单的实现,它不检查数值的数字个数。解析发生在boost::spirit::qi:: parse函数。我们把它简化一点,消除成功解析后的行动:

first 参数指向待解析数据的开始点,它必须是一个能够修改(非恒定)的变量,因为parse函数将用它来显示解析得出的序列的结束。end参数指向最后一个元素以外的元素。first和end应当是迭代器。

函数的第三个参数是解析规则。它正是用EBNF规则编写的:

只将空格替换为>>操作符。

若执行成功,parse函数返回true。如果想要确保整个字符串都被成功解析,需要检查解析器的返回值并与输入迭代器相等。

现在,需要处理成功解析后的动作,而这个秘笈将结束。Boost.Spirit的语义动作写在[]里面,并且它们可以使用函数指针、函数对象、boost::bind、std::bind(或其他bind()的实现)或C++11 lambda函数编写。

所以,也可以使用C++11的lambda编写 YYYY (年份)的规则:

现在,我们仔细看看在月份上的语义动作:

对于那些从头读了这本书的读者,这将使你回忆起boost::bind和占位符。ref(res.month) 意味着将 res.month作为可修改的引用传递,而_1表示第一个输入参数,其将是一个数值(ushort_ parsing的结果)。

还有更多

现在,修改解析器,以便它可以处理数字的计数。为了这个目的,将采用unit_parser模板类,并仅设置正确的参数:

 

如果觉得这些例子有些复杂,不要担心。第一次我也被Boost.Spirit吓坏了,但现在它真正简化了我的工作。如果这个代码没能吓到你,你是非常勇敢的。

如果你想避免代码膨胀,尝试在源文件中而不是在头文件中编写解析器。也注意传递到 boost::spirit::parse函数的迭代器类型,使用的迭代器的不同类型越少,得到的二进制文件大小就越小。在源文件编写解析器还有一个好处:它不会降低项目编译速度(你可能会注意到,Spirit 解析器编译缓慢,所以最好是在源文件编译一次,而不是在头文件中定义它们并在整个项目中使用此文件)。

如果你现在认为使用STL手工实现解析日期更简单,你是对的!但仅是现在。我们看下一个秘笈,它会给你提供更多的Boost.Spirit用途的例子并扩展这个例子的情况,那时手工编写解析器比使用Boost.Spirit更难。

Boost.Spirit库不属于C++11,并且据我所知,它也未被建议纳入最近即将发布的C++标准中。

参见

参考秘笈8。

参考秘笈9。

Boost.Spirit是一个巨大的只有头文件的库。关于它的使用可以写成一本单独的书,所以请放心地使用其文档http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/index.html。你可能还会找到如何直接在C++11使用Boost的代码编写词法分析器和代码生成器的信息。
 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇秘笈18 解析简单的输入(1) 下一篇秘笈19 解析输入

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)
·Redis配置中`require (2025-12-26 03:18:58)
·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)