boost-spirit 数字解析器并获取所需的合成属性
--编辑--解决了问题:对最后一个旁注的评论会很有帮助。另外,对 phoenix::bind 重载处理的评论也会有所帮助(在我的回答中)。
我正在一个具有严格类型要求的系统上工作,我想确保我正在解析满足 int32_t 和约束的整数int64_t,我不希望解析器将解析的字符串综合并限制为上述类型。
我该怎么办? 文档< /a> 提到 long_long
仅在支持 64 位的平台上可用,但我也需要在 32 位平台上解析 int64_t。
我的解析器的摘录如下:
...
eps(_b == VALUE_INT4) >> qi::long_
[phoenix::bind(&AddEntry, _r1,_a, _1, _pass)] ) //
| ( eps(_b == VALUE_INT8) >> qi::long_long)
...
AddEntry 有一个 int32_t
重载和一个 int64_t
重载,是一个 phoenix::static_cast_ 于 _1
按顺序?如果是这种情况,如何在现代 32 位平台上解析 64 位整数?我假设 BOOST_HAS_LONG_LONG
仅在过时的硬件上未定义,例如 8008 ;)。
<咆哮>
我希望他们坚持 c99 和
中规定的标准,我们大多数人都希望针对干净的抽象进行编程。以这种方式定义数字解析器可能有充分的理由。然而,大计划的使用可以在文档中更好地定义。
旁注:上面的条件 epsilon 样式在性能上是否可以与 case 语句相媲美?
--edit -- Solved the question : a comment on the last sidenote would be helpfull. Also comments on phoenix::bind overload handling would be helpfull (in my answer).
I'm working on a system with strict typing requirements, I want to ensure that I am parsing integers that meet the constraints of int32_t and int64_t, I wan't the parsers to synthesise and constrain the parsed strings to the mentioned types.
How do I go about this ? The document mentions that long_long
is only available on platforms with 64-bit support, but I need to parse int64_t's on 32-bit platforms as well.
An excerpt from my parser is as follows:
...
eps(_b == VALUE_INT4) >> qi::long_
[phoenix::bind(&AddEntry, _r1,_a, _1, _pass)] ) //
| ( eps(_b == VALUE_INT8) >> qi::long_long)
...
AddEntry has a int32_t
overload and a int64_t
overload, is a phoenix::static_cast_ on _1
in order ? And if this is the case how do I parse 64-bit integers on a modern 32-bit platform ? I assume BOOST_HAS_LONG_LONG
is only not-defined on archaic hardware like the 8008 ;) .
<Rant>
I wish they had stuck with the standards set out in c99 and <boost/cstdint.hpp>
, most of us want to program against clean abstractions. There are probably good reasons for the numeric parsers being defined the way they are. however, grand-scheme use could be better defined in the documentation.</Rant>
On a side note: Does the conditional epsilon style above rival a case statement in performance ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
1) Qi 解析器已经检查溢出情况。如果输入不能用组件应该匹配的类型表示,则解析器组件将失败。例如,对于不适合有符号 32 位整数的数字,
int_parser
将失败。仅当定义了
BOOST_HAS_LONG_LONG
时,才可以使用long_long
解析器(即预定义的 64 位整数解析器)。如果您的平台并非如此,您仍然可以通过编写自己的包装器类型来模拟 64 位整数,从而公开 Qi 数字解析器所期望的功能(请参阅 此处 ),例如:并将其用作:
2) 如果不帮助编译器,则无法绑定重载函数,即:
如果要绑定
int32_t
,则需要显式转换函数指针:对旁注的回答:否。替代解析器始终按照指定的相同顺序顺序执行不同的替代方案,当第一个匹配时停止。其总体复杂度为
O(N)
,其中N
是单独替代方案的数量(请参阅 此处)。1) Qi parsers already check for overflow conditions. The parser component will fail if the input is not representable by the type the component is supposed to match. For instance,
int_parser<int32_t, 10>
will fail for numbers not fitting into a signed 32 bit integer.You can use the
long_long
parser (i.e. the predefined 64 bit integer parser) only ifBOOST_HAS_LONG_LONG
is defined. If you have a platform where this is not the case, you can still emulate a 64bit integer by writing your own wrapper type exposing the functionality as expected by Qi numeric parsers (see here), for instance:and use it as:
2) You can't bind overloaded functions without helping the compiler, i.e. given:
you need to cast the function pointer explicitly if you want to bind for an
int32_t
:Answer to sidenote: No. The alternative parser is always sequentially executing the different alternatives in the same sequence as specified, stopping when the first of those matches. Its overall complexity is
O(N)
, whereN
is the number of separate alternatives (see here).这些模板将为您提供您想要的语义。
这些解析器经过了单元测试,并在溢出时产生了期望错误,即分别在
>= 2^31
和>= 2^63
时。phoenix::bind afaik 不会拾取重载(如果我错了,请纠正我),
的宏如下
因此,对于那些感兴趣的人,编译器错误消息 (当 AddEntry是一个模板函数):
我也遇到手写重载错误。
These templatas will get you the semantics you want.
These parsers were unit tested and created expectation errors on overflow --i.e., when
>= 2^31
and>= 2^63
respectively.Overloads aren't picked up by phoenix::bind afaik (correct me if I'm wrong please),
therefore a macro along the lines of
For those interested the compiler error message is as follows (when AddEntry is a template function):
I get errors on hand written overloads as well.