1

--edit -- 解决了这个问题:对最后一个旁注的评论会很有帮助。对 phoenix::bind 重载处理的评论也会有所帮助(在我的回答中)。

我正在开发一个具有严格类型要求的系统,我想确保我正在解析满足 int32_t 和 int64_t 约束的整数,我不希望解析器合成并将解析的字符串限制为提到的类型。

我该怎么做?该文档提到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_ on _1order 吗?如果是这种情况,我如何在现代 32 位平台上解析 64 位整数?我假设仅在8008BOOST_HAS_LONG_LONG等过时的硬件上未定义;)。

<Rant> 我希望他们坚持 c99 中规定的标准,并且<boost/cstdint.hpp>我们大多数人都希望针对干净的抽象进行编程。以它们的方式定义数字解析器可能有充分的理由。但是,可以在文档中更好地定义宏计划的使用。 </Rant>

附带说明:上面的条件 epsilon 样式是否在性能上与 case 语句相媲美?

4

2 回答 2

1

1) Qi 解析器已经检查溢出条件。如果输入不能由组件应该匹配的类型表示,则解析器组件将失败。例如,int_parser<int32_t, 10>对于不适合有符号 32 位整数的数字将失败。

long_long只有定义了才可以使用解析器(即预定义的 64 位整数解析器) BOOST_HAS_LONG_LONG。如果您的平台不是这种情况,您仍然可以通过编写自己的包装器类型来模拟 64 位整数,从而公开 Qi 数字解析器所期望的功能(参见此处),例如:

struct my_64bit_int {
    //...
};
typedef int_parser<my_64bit_int, 10> my_64bit_int_parser_type;
my_64bit_int_parser_type const my_64bit_int_parser;

并将其用作:

my_64bit_int bigint;
parse(b, e, my_64bit_int_parser, bigint);

2)你不能在不帮助编译器的情况下绑定重载函数,即给定:

void AddEntry(int32_t);
void AddEntry(int64_t);

如果要绑定 a ,则需要显式转换函数指针int32_t

phoenix::bind((void(*)(int32_t))&AddEntry, _1);

对旁注的回答:不。替代解析器总是按照指定的相同顺序依次执行不同的替代方案,当第一个匹配时停止。它的总体复杂性是O(N),其中N是单独替代方案的数量(请参见此处)。

于 2011-04-06T19:22:48.570 回答
0

这些模板将为您提供所需的语义。

qi::int_parser< int32_t,  10, 1,10>  p_int32_t;
qi::int_parser< int64_t, 10, 1, 19> p_int64_t;

这些解析器经过单元测试,并在溢出时产生预期错误——即,何时>= 2^31>= 2^63分别。

phoenix::bind afaik 没有发现重载(如果我错了请纠正我),

因此,沿着线的宏

#define  ADD_ENTRY(TP,prefix)                                           \
    void AddEntry_##prefix( value_variant_vector & v, uint32_t ordinal, \
                            TP entry, bool & ok_)                       \

对于那些感兴趣的编译器错误消息如下(当 AddEntry 是模板函数时):

/opt/dev_64_swat/dsl/src/parser/RowAndTable.cc:43: error: no matching function 
for call to ‘bind(<unresolved overloaded function type>, const
boost::phoenix::actor<boost::spirit::attribute<1> >&, const 
boost::phoenix::actor<boost::spirit::local_variable<0> >&, const 
boost::phoenix::actor<boost::spirit::argument<0> >&, const   
boost::phoenix::actor<boost::phoenix::argument<2> >&)’

我也收到手写重载的错误。

于 2011-04-06T13:40:44.210 回答