Boost Spirit语法自定义属性
Boost Spirit grammar custom attribute
正在尝试学习 Boost::Spirit 并想处理一个 C 风格标识符的简单示例。下面的语法没有编译声明 'incompatible_start_rule'。此语法的目标是 return 字符串而不是字符串向量,正如默认属性传播规则那样。
template <typename IT>
struct cppIdentifier : qi::grammar<IT, std::string, space_type()>
{
cppIdentifier() : cppIdentifier::base_type(start)
{
start = char_("a-zA-Z_")[boost::phoenix::push_back(_val, _1)]
>> *(char_("a-zA-Z0-9_")[boost::phoenix::push_back(_val, _1)]);
}
qi::rule<IT, std::string, space_type> start;
};
我需要做什么才能实现这一目标?
另请注意,我很清楚对于这个特定问题可能有许多更方便的选择,但我在学术上对如何操作自定义语法的属性类型很感兴趣,所以请离开那些在评论而不是答案中。
首先,您需要使用 function-signature-style 模板参数来指定规则的输出属性类型(以及继承的属性类型,如果有的话)。尝试 qi::grammar<IT, std::string(), space_type>
.
而不是 qi::grammar<IT, std::string, space_type()>
其次,您在这里并不真正需要语义操作 - 但如果您打算使用短语解析器,则需要 lexeme[]
指令:
template <typename IT>
struct cppIdentifier : qi::grammar<IT, std::string(), qi::space_type>
{
cppIdentifier() : cppIdentifier::base_type(start)
{
start = qi::lexeme[char_("a-zA-Z_") >> *(char_("a-zA-Z0-9_"))];
}
qi::rule<IT, std::string(), qi::space_type> start;
};
最后,确保将兼容的船长对象传递给 phrase_parse:
std::string s = "HELLO 123";
cppIdentifier < std::string::const_iterator> id;
std::string ident;
qi::phrase_parse(s.cbegin(), s.cend(), id, qi::space_type(), ident);
// without lexeme[], ident becomes "HELLO123", not "HELLO"
正在尝试学习 Boost::Spirit 并想处理一个 C 风格标识符的简单示例。下面的语法没有编译声明 'incompatible_start_rule'。此语法的目标是 return 字符串而不是字符串向量,正如默认属性传播规则那样。
template <typename IT>
struct cppIdentifier : qi::grammar<IT, std::string, space_type()>
{
cppIdentifier() : cppIdentifier::base_type(start)
{
start = char_("a-zA-Z_")[boost::phoenix::push_back(_val, _1)]
>> *(char_("a-zA-Z0-9_")[boost::phoenix::push_back(_val, _1)]);
}
qi::rule<IT, std::string, space_type> start;
};
我需要做什么才能实现这一目标?
另请注意,我很清楚对于这个特定问题可能有许多更方便的选择,但我在学术上对如何操作自定义语法的属性类型很感兴趣,所以请离开那些在评论而不是答案中。
首先,您需要使用 function-signature-style 模板参数来指定规则的输出属性类型(以及继承的属性类型,如果有的话)。尝试 qi::grammar<IT, std::string(), space_type>
.
qi::grammar<IT, std::string, space_type()>
其次,您在这里并不真正需要语义操作 - 但如果您打算使用短语解析器,则需要 lexeme[]
指令:
template <typename IT>
struct cppIdentifier : qi::grammar<IT, std::string(), qi::space_type>
{
cppIdentifier() : cppIdentifier::base_type(start)
{
start = qi::lexeme[char_("a-zA-Z_") >> *(char_("a-zA-Z0-9_"))];
}
qi::rule<IT, std::string(), qi::space_type> start;
};
最后,确保将兼容的船长对象传递给 phrase_parse:
std::string s = "HELLO 123";
cppIdentifier < std::string::const_iterator> id;
std::string ident;
qi::phrase_parse(s.cbegin(), s.cend(), id, qi::space_type(), ident);
// without lexeme[], ident becomes "HELLO123", not "HELLO"