2011-08-24 45 views
5

試圖學習助推精神和文檔中給出的示例讓我有點困惑。加強精神羅馬數字解析器示例

參照此代碼:

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

+lit('M')*lit('M')都是正確的。但前者比後者(語義上)更具可讀性,在我看來,如前所述1000_val如果有one匹配,並重復執行。另一方面,後者難以閱讀,因爲人們可以將其看作爲1000_val即使對於零匹配是錯誤的。 1000沒有被添加到_val零次匹配,但解析器*lit('M')似乎匹配零匹配以及(似乎有點混淆)。

因此+lit('M')是優選的。


好的。我讀了你的評論。 CCLLIX不是有效的羅馬數字。你認爲它的價值是什麼? 309?如果是這樣,那麼CCCIX會有什麼價值?這太309了,它是正確的。你的錯誤。因此解析器在您使用*lit('M')時停止。還要注意,即使您對此錯誤輸入使用了+lit('M'),解析器也會停止。

+0

使用*點亮('M')和CCLLIX。那麼爲什麼結果返回250並停在LIX?就像你說的那樣,它不應該爲零匹配增加1000到_val並且CCLLIX沒有M.因此不應該返回1250而不是250嗎? – Integer

+1

@Integer:我添加了解釋。 'CCLLIX'不是一個有效的數字。 – Nawaz

+0

好的。對於那個很抱歉。但即使我使用CCLIX都使用*和+結果的正確答案爲259。爲什麼不像你說的那樣導致1259? – Integer

2

a || b操作者在裝置靈後aab,但b,如果發生a。在對運營商的指示中,沒有M的情況是隱含的(因爲M的匹配可能存在也可能不存在)。另外,在*lit('M')的情況下,如果存在M,您會說第一個規則是否匹配?無論如何,這將是有效的,並且_val將增加1000.

+0

但是,當沒有M時,_val不會遞增。我嘗試使用輸入CCLIX,並返回了正確的值259,無論我使用+還是* – Integer

+0

那麼,*可能*取決於實現。從規則*可以匹配(因此它可以執行代碼)的意義上來說,語義很清楚,所以最好使用'+',因爲0匹配無論如何都被'||'運算符隱含。 –

0

它是(一個或多個女士)或數百或數十個OR。 (零個或多個小姐)或幾百或幾十或1將匹配沒有MS又名空字符串和無謂增加1000

+0

這是不正確的。我嘗試傳遞一個空字符串,並且在使用Kleene星形解決方案時未添加1000 *點亮('M') – Integer

0

表達式匹配的A || B齊意味着要麼匹配只是A,或者只是BA followed by B。因此,您的情況+lit('M') || hundreds意味着+lit('M')hundreds+lit('M')followed by hundreds。出於這個原因,語法允許匹配任何不以M開頭的羅馬數字。