boost-spirit数值解析器并获得所需的合成属性

--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_在
_1
in命令?如果是这种情况,我如何在现代32位平台上解析64位整数?我假设
BOOST_HAS_LONG_LONG
仅在8008上的古老硬件上没有定义;)。
<Rant>
我希望他们坚持使用c99和ѭ7中规定的标准,我们大多数人都希望针对干净的抽象进行编程。可能有很好的理由按照它们的方式定义数字解析器。但是,可以在文档中更好地定义宏计划使用。
</Rant>
在旁注:上面的条件epsilon风格是否与性能中的案例陈述相媲美?     
已邀请:
1)Qi解析器已经检查溢出条件。如果输入不能由组件应匹配的类型表示,则解析器组件将失败。例如,对于不符合有符号32位整数的数字,
int_parser<int32_t, 10>
将失败。 只有定义了
BOOST_HAS_LONG_LONG
,才能使用
long_long
解析器(即预定义的64位整数解析器)。如果您的平台不是这种情况,您仍然可以通过编写自己的包装类型来模拟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);
如果要绑定
int32_t
,则需要显式转换函数指针:
phoenix::bind((void(*)(int32_t))&AddEntry, _1);
对旁注的回答:否。备用解析器总是按照指定的顺序依次执行不同的备选,在第一个匹配时停止。它的整体复杂性为
O(N)
,其中
N
是单独备选方案的数量(见此处)。     
这些templatas将为您提供您想要的语义。
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> >&)’
我手写的重载也会出错。     

要回复问题请先登录注册