有关Spirit.Qi序列运算符和语义动作的问题 [英] Questions about Spirit.Qi sequence operator and semantic actions
问题描述
我对《 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:
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屋!