Boost Spirit 罗马数字解析器示例
尝试学习 boost Spirit 和文档中给出的示例让我有点困惑。
参考此代码:
http://www. boost.org/doc/libs/1_46_1/libs/spirit/example/qi/roman.cpp
特别是这一段语法:
start = eps [_val = 0] >>
(
+lit('M') [_val += 1000]
|| hundreds [_val += _1]
|| tens [_val += _1]
|| ones [_val += _1]
)
有人可以向我解释一下为什么它是 +lit('M') 而不是*点燃('M')。因为毕竟不能有零个或多个 M 与一个或多个 M 相对吗?
Trying to learn boost spirit and the example given in the docs have me a little confused.
Referring to this code:
http://www.boost.org/doc/libs/1_46_1/libs/spirit/example/qi/roman.cpp
Particularly this segment of grammar:
start = eps [_val = 0] >>
(
+lit('M') [_val += 1000]
|| hundreds [_val += _1]
|| tens [_val += _1]
|| ones [_val += _1]
)
Could someone explain to me why it is +lit('M') and not *lit('M'). Because after all can't there be zero or more M's versus one or more M's?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
a || Spirit 中的 b
运算符表示a
或b
,但b
在a
之后,如果出现
。在运算符的含义中,不存在M
的情况是隐式的(因为M
的匹配可能存在也可能不存在)。另外,在*lit('M')
的情况下,如果NOM
,你会说第一条规则匹配吗?无论如何它都是有效的,并且_val
将增加 1000。The
a || b
operator in Spirit meansa
orb
, butb
aftera
, ifa
occurs. In the meaing of the operator, the case that there is noM
is implicit (because the match forM
may or may not be present). Also, in the case of*lit('M')
, would you say that the first rule is matched if there is NOM
? It would be valid anyway, and_val
would be incremented by 1000.+lit('M')
和*lit('M')
都是正确的。但在我看来,前者比后者更具可读性(语义上),因为前者表示 add1000
到_val
如果有 < code>one 匹配,并重复执行。另一方面,后者很难阅读,因为即使对于零匹配,也可以将其读作 add1000
到_val
错误的。1000
未添加到_val
中进行零次匹配,但解析器*lit('M')
似乎匹配零次匹配以及(似乎有点令人困惑)。所以
+lit('M')
是更好的选择。好吧。我读了你的评论。
CCLLIX
不是有效的罗马数字。你认为它的价值是什么?309
?如果是这样,那么 CCCIX 的价值是多少?太309了,而且是正确的。你的是错的。因此,当您使用*lit('M')
时,解析器会停止。另请注意,即使您使用 +lit('M') 来处理此错误输入,解析器也会停止。Both
+lit('M')
and*lit('M')
are correct. But the former is more readable than the latter (semantically), in my opinion, as the former says add1000
to_val
if there isone
match, and do it repeatedly. On the other hand, the latter is difficult to read, as one could read it as add1000
to_val
even for zero-match which is wrong.1000
is not added to_val
for zero-times match, yet the parser*lit('M')
seems to match for zero-match as well (seems kind of confusing).So
+lit('M')
is preferable.Alright. I read your comment.
CCLLIX
is not a valid roman number. What do you think its value is?309
? If that is so, then what value would be forCCCIX
? It's too 309, and its correct. Yours is wrong. Hence the parser stops when you use*lit('M')
. Note also that the parser would also stop even if you use+lit('M')
for this wrong input.它是(一个或多个女士)或数百或数十或几个。 (零个或多个 Ms)OR 数百个或数十个 OR 个将匹配没有 Ms 又名空字符串并毫无意义地添加 1000。
It's (One or more Ms) OR hundreds OR tens OR ones. (Zero or more Ms) OR hundreds OR tens OR ones would match no Ms aka the empty string and meaninglessly add 1000.
匹配表达式
A || Qi 中的 B
表示仅匹配A
,或者仅匹配B
或A 后跟 B
。因此,在您的情况下+lit('M') ||数百
表示+lit('M')
,或数百
或+lit('M')后跟数百
。因此,语法允许匹配任何不以M
开头的罗马数字。Matching the expression
A || B
in Qi means either matching justA
, or justB
orA followed by B
. Therefore, in your case+lit('M') || hundreds
means+lit('M')
, orhundreds
or+lit('M')followed by hundreds
. For this reason the grammar allows to match any roman numbers not even starting with anM
.