有关Spirit.Qi序列运算符和语义动作的问题 [英] Questions about Spirit.Qi sequence operator and semantic actions

查看:81
本文介绍了有关Spirit.Qi序列运算符和语义动作的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对《 Spirit Qi》中的序列运算符和语义动作有疑问.

I have some questions about the sequence operator and semantic actions in Spirit Qi.

我正在尝试为一个浮点数定义一个语法规则,该浮点数接受度量前缀(u,m,k,M等)以及正常的指数形式.

I'm trying to define a grammar rule for a floating point number that accepts metric prefixes (u, m, k, M, etc.) as well as the normal exponent form.

  rule<Iterator, std::string()> sign = char_("+-") [ _val = _1 ];
  rule<Iterator, std::string()> exp = char_("eE") >> -sign >> +digit;
  rule<Iterator, std::string()> suffix = char_("yzafpnumkKMGTPEZY") [ _val = _1 ];
  rule<Iterator, std::string()> mantissa = ((*digit >> char_('.') >> +digit) | (+digit >> char_('.') >> *digit));
  rule<Iterator, std::string()> unsigned_floating = (mantissa >> -(exp | suffix) | +digit >> (exp | suffix));
  rule<Iterator, std::string()> floating = -sign >> unsigned_floating;

问题1:为什么我必须在上述规则sign上添加语义动作? char不能转换为std::string吗?

Question 1: Why do I have to add a semantic action to the rule sign above? Isn't char convertible to std::string?

问题2:为什么当我尝试合并最后两个规则时,编译会失败:

Question 2: Why does compilation fail when I try to merge the last two rules like this:

  rule<Iterator, std::string()> floating = -sign >> (mantissa >> -(exp | suffix) | +digit >> (exp | suffix));

问题3:假设我想让floating的属性为double并编写语义操作以完成从字符串到双精度的转换.如何从语义动作内部引用规则匹配的整个字符串?

Question 3: Let's say I want to let the attribute of floating be double and write a semantic action to do the conversion from string to double. How can I refer to the entire string matched by the rule from inside the semantic action?

问题4:在问题2的规则floating中,占位符_2指的是什么,其类型是什么?

Question 4: In the rule floating of Question 2, what does the placeholder _2 refer to and what is its type?

我想最后一个问题需要澄清:

I guess the last question needs some clarification:

在以下规则的语义动作中,占位符_2指的是什么?

What does the placeholder _2 refer to in the semantic action of the following rule, and what's its type?

  rule<Iterator, std::string()> floating = (-sign >> (mantissa >> -(exp | suffix) | +digit >> (exp | suffix))) [ _2 ];

谢谢!

推荐答案

首先,逐吹.开箱即用的答案,请参见下文.

First, blow-by-blow. See below for a out-of-the-box answer.

问题1 :为什么我必须在上面的规则符号上添加语义动作? char不能转换为std :: string吗?

Question 1: Why do I have to add a semantic action to the rule sign above? Isn't char convertible to std::string?

Erm,没有char不能转换为字符串.有关其他选项,请参见下文.

Erm, no char is not convertible to string. See below for other options.

问题2 :当我尝试合并最后两个规则时,为什么编译失败 像这样:

Question 2: Why does compilation fail when I try to merge the last two rules like this:

rule<Iterator, std::string()> floating = -sign >> 
              (mantissa >> -(exp | suffix) | +digit >> (exp | suffix));

这是由于原子属性分配规则所致.解析器公开了

This is due to the rules for atomic attribute assignment. The parser exposes something like

vector2<optional<string>, variant<
      vector2<string, optional<string> >,
      vector2<std::vector<char>, optional<string> > >

或类似内容(请参见

or similar (see the documentation for the parsers, I typed this in the browser from memory). This is, obviously, not assignable to string. Use qi::as<> to coerce atomic assignment. For convenience ***there is qi::as_string:

floating = qi::as_string [ -sign >> (mantissa >> -(exp | suffix) | 
                                     +digit >> (exp | suffix)) ] 

问题3 :假设我想让float属性为double, 编写语义操作以完成从字符串到双精度的转换.我怎样才能 从语义内部引用规则匹配的整个字符串 行动吗?

Question 3: Let's say I want to let the attribute of floating be double and write a semantic action to do the conversion from string to double. How can I refer to the entire string matched by the rule from inside the semantic action?

您可以再次使用qi::as_string,但最合适的方法似乎是使用qi::raw:

You could use qi::as_string again, but the most appropriate would seem to be to use qi::raw:

floating = qi::raw [ -sign >> (mantissa >> -(exp | suffix) | 
                               +digit >> (exp | suffix)) ] 
       [ _val = parse_float(_1, _2) ];

此解析器指令公开了一对源迭代器,因此您可以使用它来指代匹配的确切输入序列.

This parser directive exposes a pair of source iterators, so you can use it to refer to the exact input sequence matched.

问题4 :在问题2的规则浮动中,占位符_2是什么 指的是什么?

Question 4: In the rule floating of Question 2, what does the placeholder _2 refer to and what is its type?

通常,要检测属性类型-也就是说,当您对文档感到困惑或要仔细检查对它的理解时-请在此处查看答案:

In general, to detect attribute types - that is, when the documentation has you confused or you want to double check your understanding of it - see the answers here:

您是否看过使用Qi的

Have you looked at using Qi's builtin real_parser<> template, which can be comprehensively customized. It sure looks like you'd want to use that instead of doing custom parsing in your semantic action.

具有策略的real_ parser模板既快速又非常灵活且健壮.另请参阅最新答案是否可以使用输入流读取无穷大或NaN值?.

The real_parser template with policies is both fast and very flexible and robust. See also the recent answer Is it possible to read infinity or NaN values using input streams?.

对于RealPolicies模型,以下表达式必须有效:

For models of RealPolicies the following expressions must be valid:

Expression                 | Semantics 
===========================+=============================================================================
RP::allow_leading_dot      | Allow leading dot. 
RP::allow_trailing_dot     | Allow trailing dot. 
RP::expect_dot             | Require a dot. 
RP::parse_sign(f, l)       | Parse the prefix sign (e.g. '-'). Return true if successful, otherwise false. 
RP::parse_n(f, l, n)       | Parse the integer at the left of the decimal point. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_dot(f, l)        | Parse the decimal point. Return true if successful, otherwise false. 
RP::parse_frac_n(f, l, n)  | Parse the fraction after the decimal point. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_exp(f, l)        | Parse the exponent prefix (e.g. 'e'). Return true if successful, otherwise false. 
RP::parse_exp_n(f, l, n)   | Parse the actual exponent. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_nan(f, l, n)     | Parse a NaN. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_inf(f, l, n)     | Parse an Inf. Return true if successful, otherwise false. If successful, place the result into n

请参见

See the example for a compelling idea of how you'd use it.

这篇关于有关Spirit.Qi序列运算符和语义动作的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆