[似乎我的解释和期望一点都不清楚,所以我在帖子末尾添加了我想如何使用该功能的精确度]
我目前正在使用 boost qi 研究语法。我有一个规则的循环构造,因为我需要从向量的元素构建它。我用简单的类型重写了它,它看起来像:
#include <string>
// using boost 1.43.0
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_eps.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace bqi = boost::spirit::qi;
typedef const char* Iterator;
// function that you can find [here][1]
template<typename P> void test_phrase_parser(char const* input, P const& p, bool full_match = true);
int main()
{
// my working rule type:
bqi::rule<Iterator, std::string()> myLoopBuiltRule;
std::vector<std::string> v;
std::vector<std::string>::const_iterator iv;
v.push_back("abc");
v.push_back("def");
v.push_back("ghi");
v.push_back("jkl");
myLoopBuiltRule = (! bqi::eps);
for(iv = v.begin() ; iv != v.end() ; iv++)
{
myLoopBuiltRule =
myLoopBuiltRule.copy() [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
;
}
debug(myLoopBuiltRule);
char s[] = " abc ";
test_phrase_parser(s, myLoopBuiltRule);
}
(貌似这里不想换成对应的超链接,所以这里是找到函数test_phrase_parser()的地址:http: //www.boost.org/doc/libs/1_43_0/libs/spirit/doc/html/精神/qi/reference/basics.html )
一切都是为了最好的世界……直到我不得不对这条规则提出一个论据。这是新的规则类型:
// my not-anymore-working rule type:
bqi::rule<Iterator, std::string(int*)> myLoopBuiltRule;
'int*' 类型仅用于示例目的,我的真正指针正在处理一个更复杂的类......但仍然只是一个指针。
我相应地改变了我的'for'循环,即:
for(iv = v.begin() ; iv != v.end() ; iv++)
{
myLoopBuiltRule =
myLoopBuiltRule.copy()(bqi::_r1) [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
;
}
我必须添加一条新规则,因为 test_phrase_parser() 无法猜测要为 int 指针赋予哪个值:
bqi::rule<Iterator> myInitialRule;
并更改 for 循环之后的所有内容:
myInitialRule = myLoopBuiltRule((int*)NULL);
debug(myLoopBuiltRule);
char s[] = " abc ";
test_phrase_parser(s, myInitialRule);
然后一切都崩溃了:
/home/sylvain.darras/software/repository/software/external/include/boost/boost_1_43_0/boost/spirit/home/qi/nonterminal/rule.hpp:199: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&)
然后我疯了,尝试:
myLoopBuiltRule =
myLoopBuiltRule.copy(bqi::_r1) [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
-->
error: no matching function for call to ‘boost::spirit::qi::rule<const char*, std::string(int*), boost::fusion::unused_type, boost::fusion::unused_type, boost::fusion::unused_type>::copy(const boost::phoenix::actor<boost::spirit::attribute<1> >&)’
然后我很生气,写道:
myLoopBuiltRule =
myLoopBuiltRule(bqi::_r1) [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
可以编译,因为它在语法上是完全正确的,但是哪个堆栈溢出,因为它愉快地,很好地,递归地调用自己死亡......
然后我失去了理智,输入:
myLoopBuiltRule =
jf jhsgf jshdg fjsdgh fjsg jhsdg jhg sjfg jsgh df
正如您可能期望的那样,它未能编译。
你想象一下,在写上面的小说之前,我在网上查了一下,但没有发现任何与 copy() 和同时传递的参数有关的东西。有没有人已经遇到过这个问题?我错过了什么吗?
请放心,任何帮助都会非常感激。
PS:非常感谢 hkaiser,他在不知不觉中通过 google 回答了我的很多 boost::qi 问题(但这个问题)。
更多信息:
我的解析器的目的是读取用给定语言 L 编写的文件。我的帖子的目的是传播我的“上下文”(即:变量定义,尤其是常量值,因此我可以计算表达式)。
我处理的变量类型的数量很少,但它肯定会增长,所以我将这些类型保存在一个容器类中。我可以循环这些托管类型。
所以,让我们考虑一个我想要实现的伪算法:
LTypeList myTypes;
LTypeList::const_iterator iTypes;
bqi::rule<Iterator, LType(LContext*)> myLoopBuiltRule;
myLoopBuiltRule = (! bqi::eps);
for(iTypes = myTypes.begin() ; iTypes != myTypes.end() ; iTypes++)
{
myLoopBuiltRule =
myLoopBuiltRule.copy()(bqi::_r1) [ bqi::_val = bqi::_1 ]
| iTypes->getRule()(bqi::_r1) [ bqi::_val = bqi::_1 ]
}
这是在初始化期间完成的,然后 myLoopBuiltRule 与不同的 LContext* 一起使用和重用,解析多种类型。而且由于某些 L 类型可以有界限,它们是整数表达式,并且这些整数表达式可以显示常量,我(认为我)需要我的继承属性来获取我的 LContext 并能够计算表达式值。
希望我的意图更清楚。