【发布时间】:2010-08-17 12:52:49
【问题描述】:
我试图在 Boost.Spirit (2.3) 中创建一个自定义 Parser 类,但没有成功。代码是:
template <class Iter>
class crule : public boost::spirit::qi::parser<crule<Iter> >
{
rule<Iter> r_;
public:
crule(const rule<Iter>& r) : r_(r) {}
template <class T>
crule(const T& t) : r_(t) {}
template<class Ctx, class Skip>
bool parse(Iter& f, const Iter& l, Ctx& context, Skip& skip, typename rule<Iter>::template attribute<Ctx, Iter>::type& attr) const {
return r_.parse(f, l, context, skip, attr);
}
template <class Ctx>
boost::spirit::info what(Ctx& context) const {
return r_.what(context);
}
template <class Context, class It>
struct attribute {
typedef typename rule<Iter>::template attribute<Context, It>::type type;
};
};
虽然我已经(至少我认为我已经)满足了所有 requirements,但当我尝试在解析表达式中使用此类时出现错误:
shell_grammar.h:134: error: no match for 'operator!' in '!shell_grammar<Iter>::token(boost::spirit::qi::rule<Iter, boost::fusion::unused_type, boost::fusion::unused_type, boost::fusion::unused_type>) [with Iter = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >](boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::fusion::unused_type, boost::fusion::unused_type, boost::fusion::unused_type>(((const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::fusion::unused_type, boost::fusion::unused_type, boost::fusion::unused_type>&)((const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::fusion::unused_type, boost::fusion::unused_type, boost::fusion::unused_type>*)(&((shell_grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*)this)->shell_grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::reserved_words)))))'
shell_grammar.h:134: note: candidates are: operator!(bool) <built-in>
我试图查看其他解析器的实现(例如not_predicate),但无法弄清楚它的工作原理是什么。
动机
我这样做的原因与this question有关。我想解析具有特殊词汇规则的 POSIX shell 语言。特别是,即使在词位中也必须应用“skipper parser”,但它必须不同于“phrase level”skipper parser。这是lexeme 指令不能做的,skip 不会预先跳过(AFAIK),这也是我需要的。所以我想创建一个函数
something token(std::string);
这将返回与令牌匹配的规则。一种方法是创建我自己的rule 包装器作为终端(因为单独的rule 不能用于其引用语义),另一种方法是创建一个新的解析器(这将是proto 中的非终端),并在其中实现shell的token解析。
【问题讨论】:
-
哇!!!!第一个错误行超过 550 个字符...哇...哇...
-
@Stephane Rolland:实际上,这并不是什么特别的事情。我经常得到更长的行,这可以解释为“运算符!不能应用于
crule”,关键是,它可以应用于精神规则和解析器,我不知道它们是怎么做的它(他们没有实现operator!,但使用了一些 Boost.Proto 魔法)。 -
您是否尝试过仅在满月和新月时编译和链接?
-
遗憾的是,该错误行与您从 Spirit 规范中非常简单的错误中得到的结果完全不同。正如我在下面提到的,如果您对这些事情(或更糟)感到不舒服,那么您可能不应该使用 Spirit。经过几个项目后,我决定我属于那个类别。
标签: c++ boost-spirit-qi