jke*_*ian 3 c++ boost-spirit boost-spirit-qi
通过boost :: spirit :: qi :: symbols文档的开头段落,我假设从语义动作向qi :: symbols添加符号并不太难.不幸的是,它似乎并不像我想象的那么简单.
以下测试代码表明了问题:
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
namespace qi = boost::spirit::qi;
typedef qi::symbols<char, unsigned int> constants_dictionary;
template <typename Iter> struct parser : public qi::grammar<Iter, qi::space_type> {
parser(constants_dictionary &dict) : parser::base_type(start) {
start = qi::lit("@") >> ((+qi::char_) >> qi::uint_)[dict.add(qi::_1, qi::_2)];
}
qi::rule<Iter> start;
};
int main() {
constants_dictionary dict;
parser<std::string::const_iterator> prsr(dict);
std::string test = "@foo 3";
parse(test.begin(), test.end(), prsr, qi::space);
}
Run Code Online (Sandbox Code Playgroud)
从VS2010中提供与qi :: _ 2相关的类型错误:
C:\Users\k\Coding\dashCompiler\spirit_test.cpp(12) : error C2664: 'const boost::
spirit::qi::symbols<Char,T>::adder &boost::spirit::qi::symbols<Char,T>::adder::o
perator ()<boost::spirit::_1_type>(const Str &,const T &) const' : cannot conver
t parameter 2 from 'const boost::spirit::_2_type' to 'const unsigned int &'
with
[
Char=char,
T=unsigned int,
Str=boost::spirit::_1_type
]
Reason: cannot convert from 'const boost::spirit::_2_type' to 'const uns
igned int'
No user-defined-conversion operator available that can perform this conv
ersion, or the operator cannot be called
C:\Users\k\Coding\dashCompiler\spirit_test.cpp(10) : while compiling cla
ss template member function 'parser<Iter>::parser(constants_dictionary &)'
with
[
Iter=std::_String_const_iterator<char,std::char_traits<char>,std::al
locator<char>>
]
C:\Users\k\Coding\dashCompiler\spirit_test.cpp(21) : see reference to cl
ass template instantiation 'parser<Iter>' being compiled
with
[
Iter=std::_String_const_iterator<char,std::char_traits<char>,std::al
locator<char>>
]
Run Code Online (Sandbox Code Playgroud)
(为令人讨厌的VS2010错误风格道歉)
我应该使用什么语法来添加(以及稍后删除)此表中的符号?
此问题之前已得到解答.但是,您发布的代码存在相当多的问题,因此我将逐一修复它们,以免您不必要地盯着错误消息页面.
工作代码(加上输出验证)在liveworkspace.org上.
笔记:
语义动作必须是凤凰演员,即你需要
boost::bind,phoenix::bind,std::bindphoenix::lambda<> 要么 phoenix::function<>函数指针或多态可调用对象(根据文档)
我建议phoenix::bind(在这个特殊情况下),我在下面显示
qi::char_吃掉所有人物.结合船长,这导致解析失败,因为(显然)值中的数字也被吃掉了+qi::char_.我向您展示了许多解决方案之一qi::lexeme[+qi::graph]qi::lexeme以"旁路"船长(即,防止+气::图形跨越空白切因为船长,井,跳过它)qi::parse不带船长; 使用qi::phrase_parse该(它的原因出现的工作是,任何尾随"可变参数"参数被结合到解析器的暴露属性,在这种情况下是未指定的,因此qi::unused_type).test.begin()和test.end()直接
qi::phrase_parse,你需要说清楚,你想常量迭代器.比较典型的解决办法是明确地引入类型变量(first和last,如)#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef qi::symbols<char, unsigned int> constants_dictionary;
template <typename Iter> struct parser : qi::grammar<Iter, qi::space_type>
{
parser(constants_dictionary &dict) : parser::base_type(start)
{
start = qi::lit("@") >> (qi::lexeme [+qi::graph] >> qi::uint_)
[ phx::bind(dict.add, qi::_1, qi::_2) ]
;
}
qi::rule<Iter, qi::space_type> start;
};
int main() {
constants_dictionary dict;
parser<std::string::const_iterator> prsr(dict);
const std::string test = "@foo 3";
if (qi::phrase_parse(test.begin(), test.end(), prsr, qi::space))
{
std::cout << "check: " << dict.at("foo") << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1750 次 |
| 最近记录: |