提升:精神从非终端获得价值
Boost::spirit get value from non-terminal
我有这个,在我的提升中::精神语法;
paren = (qi::token(LEFT_PAREN) >> character >> qi::token(RIGHT_PAREN)) [ build_paren ]
;
character = qi::token(CHARACTER) [ build_character]
;
其中这些定义为:;
qi::rule<Iterator> paren;
qi::rule<Iterator, char> character;
函数build_paren
具有以下原型(通过编译器强制转换错误找到);
void build_paren(boost::fusion::vector2<boost::iterator_range<__gnu_cxx::__normal_iterator<char*, std::basic_string<char>>>, boost::iterator_range<__gnu_cxx::__normal_iterator<char*, std::basic_string<char>>>> v)
这里的向量包含两个字符串,分别是"( "
和") "
,这是我所期望的,但是我如何使char
在字符上匹配呢?
实际上,我想要的build_paran
函数的原型是;
void build_paren(std::string left_paren, char character, std::string right_paren)
或者,相同,但是char
参数是列表中的最后一个参数。
你不必那么努力:)
Spirit具有自动属性传播。事实上,我认为这是它的主要卖点。所以你可以:
char parsed_char;
bool ok = qi::phrase_parse(f,l, '(' >> qi::char_("0-9") >> ')', qi::space, parsed_char);
这将简单地将char_
解析器组件的暴露属性绑定到传递到可变解析API(phrase_parse
)的attribute引用(parsed_char
)。
下面是一个概括的演示,展示了你可以通过多种方式影响曝光的内容。暴露的确切内容用解析器指令进行了记录,例如这里的"%"列表解析器。
对于您的具体问题,您只需简单地:
qi::rule<Iterator, char()> character;
qi::rule<Iterator, char()> parenthesized;
character = qi::char_("0-9a-z_"); // or qi::alnum, qi::graph, qi::alpha etc...
parenthesized = '(' >> character >> ')';
注意重要的是,您需要说
qi::rule<Iterator, char()>
而不是qi::rule<Iterator, char>
!
演示
查看Coliru直播:
#include <boost/spirit/include/qi.hpp>
#include <cassert>
namespace qi = boost::spirit::qi;
template<typename ParseExpr, typename... Attr>
void test(const std::string& input, const ParseExpr& p, Attr&... attrs)
{
auto f = input.begin(),
l = input.end();
bool ok = qi::phrase_parse(f,l, p, qi::space, attrs...);
if (!ok)
std::cerr << "parse failed at: '" << std::string(f,l) << "'n";
if (f!=l)
std::cerr << "trailing unparsed: '" << std::string(f,l) << "'n";
}
int main()
{
char parsed_char1, parsed_char2;
int parsed_int;
std::string parsed_str;
test("( 0 )", // input
'(' >> qi::char_("0-9") >> ')', // parser/grammar
parsed_char1 // output
);
assert(parsed_char1 == '0');
test("( q 123 )",
'(' >> qi::graph >> qi::int_ >> ')',
parsed_char1,
parsed_int);
assert(parsed_char1 == 'q');
assert(parsed_int == 123);
// parsing strings: with the skipper
test("( hello world )",
'(' >> *~qi::char_(")") >> ')',
parsed_str = "");
assert(parsed_str == "helloworld");
// parsing strings: qi::char_ exposes the char
test("( hello world )",
qi::char_('(') >> *~qi::char_(")") >> qi::char_(')'),
parsed_char1, parsed_str = "", parsed_char2);
assert(parsed_char1 == '(');
assert(parsed_str == "helloworld");
assert(parsed_char2 == ')');
// parsing strings: qi::char_ exposes the char, chars get 'combined' into attribute
test("( hello world )",
qi::char_('(') >> *~qi::char_(")") >> qi::char_(')'),
parsed_str = "");
assert(parsed_str == "(helloworld)");
// parsing strings: as a lexeme
test("( hello world )",
'(' >> qi::lexeme [ *~qi::char_(")") ] >> ')',
parsed_str = "");
assert(parsed_str == "hello world ");
// parsing strings: as bigger lexeme
test("( hello world )",
qi::lexeme [ '(' >> *~qi::char_(")") >> ')' ],
parsed_str = "");
assert(parsed_str == " hello world ");
// parsing anything as "raw" - exposes an iterator pair, but still 'converts' to a string!
test("( hello 42 false )",
qi::raw [ '(' >> qi::lexeme[*qi::graph] >> qi::int_ >> qi::bool_ >> ')' ],
parsed_str = "");
assert(parsed_str == "( hello 42 false )");
// note: this would fail to parse, because with the skipper, *qi::graph would eat "42 false )" as well:
std::cout << "next parse should fail:n";
test("( hello 42 false )", qi::raw [ '(' >> *qi::graph >> qi::int_ >> qi::bool_ >> ')' ]);
}
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- 如何在linux终端中同时编译和运行c++代码
- 提升 ASIO 无法识别计时器对象
- 提升精神:解析布尔表达式并简化为规范范式
- 终端不会为C++文件创建.exe文件吗
- 如何克服提升精神AST混乱
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 缓慢提升ASIO
- 我可以把基础班提升为儿童班吗
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- 提升反序列化对象具有 nan 或 -nan 值
- 在 Mac 上的 python 上提升
- 提升 Asio TCP 服务器 处理多个客户端
- 使用提升将数据从 PyObject 复制到浮点数 *
- 用于窗口的 HID 终端
- 是否可以配置提升日志刷新?
- 提升精神 x3 - 懒惰解析器
- 提升:精神从非终端获得价值
- 提升精神:内置终端应该使用什么类型名称