我有一个由混合变量($(name)
)和变量值对($(name:value)
)组成的简单文法。我有一个手工编码的递归解析器,但有兴趣将它用作学习Spirit的练习,最终(/很快)我将需要它来使用更复杂的语法。使用Boost.Spirit解析混合值和键值对
总之,一套我与(简化从完整的语法)工作可能的形式是:
$(variable) // Uses simple look-up, recursion and inline replace
$(name:value) // Inserts a new variable into the local lookup table
我现在的规则是这样:
typedef std::map<std::string, std::string> dictionary;
template <typename Iterator>
bool parse_vars(Iterator first, Iterator last, dictionary & vars, std::string & output)
{
using qi::phrase_parse;
using qi::_1;
using ascii::char_;
using ascii::string;
using ascii::space;
using phoenix::insert;
dictionary statevars;
typedef qi::rule<Iterator, std::string()> string_rule;
typedef qi::rule<Iterator, std::pair<std::string, std::string>()> pair_rule;
string_rule state = string >> ':' >> string; // Error 3
pair_rule variable =
(
char_('$') >> '(' >>
(
state[insert(phoenix::ref(statevars), _1)] |
string[output += vars[_1]] // Error 1, will eventually need to recurse
) >> ')'
); // Error 2
bool result = phrase_parse
(
first, last,
(
variable % ','
),
space
);
return r;
}
如果:这不是什么很明显,我不知道Spirit是如何工作的,而且文档除了实际的解释之外都有其他的东西,所以这大概需要一个小时的时间。
零件在可变规则我特别问题是领先的char_('$')
,但除去这会导致移位运算错误(编译器解释'$' >> '('
作为右移位)。
编译时,我得到有关状态规则,特别是创造了对错误,并查找:
- 错误C2679:二进制“[”:没有操作员发现这需要右手类型'const boost :: spirit :: _ 1_type'的操作数(或者没有可接受的转换)
- 错误C2512:'boost :: spirit :: qi :: rule :: rule':没有适当的默认构造函数可用
更改查找(vars[_1]
)以简单的+=
给出:
。错误C2665:“的boost ::精神:: char_class ::分类::是”:没有15个重载可以转换所有的参数类型
错误1似乎涉及到的类型(属性?)的_1
占位符,但应该是一个字符串,并且在用于打印或连接到输出字符串时是。 2似乎引起的噪音1.
错误3,向下挖掘模板的误差的叠层,似乎涉及不能够转动状态规则成一对,这似乎奇数,因为它几乎完全匹配其中一条规则从this example。
如何修改变量规则以正确处理两个输入表单?
@peachykeen:我已经修复了我的代码示例(我一直在用我的鼻子阅读,因为我完全错过了'parse_vars' _template function_甚至没有实例化的事实:)现在它运行并且测试对我来说确定。 – sehe 2012-02-05 16:48:15
我打算说,我试过了,它给了类似的错误;将在今天晚些时候再次测试,并让你知道发生了什么。 :) – ssube 2012-02-07 14:23:09
对于子集文法,更新实际上工作得很好。现在我必须补充其余的... – ssube 2012-02-09 00:17:03