我有一个由混合变量 ( $(name)
) 和变量值对 ( $(name:value)
) 组成的简单语法。我有一个手动编码的递归解析器,但有兴趣将它用作学习 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]
) 更改为简单的+=
给出:
3 . 错误 C2665:'boost::spirit::char_class::classify::is':15 个重载中没有一个可以转换所有参数类型
错误 1 似乎与_1
占位符的类型(属性?)有关,但这应该是一个字符串,并且用于打印或连接到输出字符串。2 似乎是由 1 引起的噪音。
错误 3,挖掘模板错误堆栈,似乎与无法将状态规则变成一对有关,这似乎很奇怪,因为它几乎完全匹配此示例中的一条规则。
如何修改变量规则以正确处理两种输入形式?