尝试学习提升精神,文档中给出的例子让我有些困惑。
参考此代码:
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]
)
有人可以向我解释为什么它是+亮('M')而不是*亮('M')。因为毕竟不能有零个或多个M与一个或多个M?
答案 0 :(得分:2)
Spirit中的a || b
运算符表示a
或b
,b
表示a
,a
表示M
。在运算符的meaing中,没有M
的情况是隐式的(因为*lit('M')
的匹配可能存在,也可能不存在)。另外,在M
的情况下,如果有否 _val
,您是否会说匹配第一条规则?无论如何它都是有效的,{{1}}将增加1000。
答案 1 :(得分:0)
+lit('M')
和*lit('M')
都是正确的。但是在我看来,前者比后者(语义上)更具可读性,因为如果1000
匹配,前者说添加 _val
到one
,并反复做。另一方面,后者难以阅读,因为人们可以将其视为添加 1000
到_val
,即使对于错误的零匹配也是如此。 1000
未添加_val
以进行零次匹配,但解析器*lit('M')
似乎也匹配零匹配(似乎有点令人困惑)。
所以+lit('M')
更可取。
好的。我看了你的评论。 CCLLIX
不是有效的罗马数字。你认为它的价值是什么? 309
?如果是这样,那么CCCIX
会有什么价值?它太309了,它是正确的。你错了。因此,当您使用*lit('M')
时,解析器会停止。另请注意,即使您使用+lit('M')
进行此错误输入,解析器也会停止。
答案 2 :(得分:0)
它是(一个或多个Ms)或数百或数十个OR。 (零个或多个Ms)或数百个或数十个OR将匹配没有Ms aka空字符串并毫无意义地添加1000。
答案 3 :(得分:0)
在Qi中匹配表达式A || B
意味着只匹配A
,或仅匹配B
或A followed by B
。因此,在您的情况下,+lit('M') || hundreds
表示+lit('M')
,或hundreds
或+lit('M')followed by hundreds
。因此,语法允许匹配任何甚至不以M
开头的罗马数字。