2011-08-24 3 views
5

Cercando di imparare lo spirito spinta e l'esempio dato nella documentazione farmi un po 'confuso.spinta dello Spirito Parser in numeri romani Esempio

Facendo riferimento a questo codice:

http://www.boost.org/doc/libs/1_46_1/libs/spirit/example/qi/roman.cpp

In particolare questo segmento della grammatica:

 start = eps    [_val = 0] >> 
      (
       +lit('M')  [_val += 1000] 
       || hundreds [_val += _1] 
       || tens  [_val += _1] 
       || ones  [_val += _1] 
      ) 

Qualcuno potrebbe spiegarmi perché è + acceso ('M') e non * illuminato ('M'). Perché dopo tutto non possono esserci zero o più M contro una o più M?

risposta

0

Sia +lit('M') e *lit('M') sono corretti. Ma il primo è più leggibile di quest'ultimo (semanticamente), secondo me, come il primo dice aggiungi1000 a _val se c'è corrispondenza one, e fallo ripetutamente. D'altra parte, quest'ultimo è difficile da leggere, in quanto si potrebbe leggere come aggiungere1000 a _val anche per lo zero-match che è sbagliato. 1000 non viene aggiunto a _val per la corrispondenza a zero-tempi, ma il parser *lit('M') sembra corrispondere anche per lo zero-match (sembra un po 'di confusione).

Quindi è preferibile +lit('M').


Va bene. Ho letto il tuo commento CCLLIX non è un numero romano valido. Quale pensi che sia il suo valore? 309? Se è così, allora quale valore sarebbe per CCCIX? È troppo 309 ed è corretto. La tua è sbagliata. Quindi il parser si interrompe quando si utilizza *lit('M'). Si noti inoltre che il parser si arresterebbe anche se si utilizza +lit('M') per questo input errato.

+0

Utilizzo di * lit ('M') e CCLLIX. Allora perché restituisce il risultato 250 e si ferma a LIX? Come hai detto, non dovrebbe aggiungere 1000 a _val per zero match e CCLLIX non ha un M. Quindi non dovrebbe restituire 1250 non 250? – Integer

+1

@Intero: ho aggiunto la spiegazione. 'CCLLIX' NON è un numero valido. – Nawaz

+0

Buona cattura. Mi dispiace per quello Ma anche se uso CCLIX entrambi usando i risultati * e + nella risposta corretta di 259.Perché * non risulta in 1259 come dici tu? – Integer

2

Il a || b operatore in spirito significa a o b, ma b dopo a, se si verifica a. Nella composizione dell'operatore, il caso in cui non ci sia M è implicito (perché la corrispondenza per M potrebbe essere o non essere presente). Inoltre, nel caso di *lit('M'), diresti che la prima regola corrisponde se c'è NOM? Sarebbe valido in ogni caso, e _val sarebbe incrementato di 1000.

+0

Ma _val non viene incrementato quando non c'è M. Ho provato a usare l'input CCLIX e ha restituito il valore corretto di 259 sia che io usi + o * – Integer

+0

Bene, che * potrebbe * essere dipendente dall'implementazione. La semantica è chiara nel senso che la regola * potrebbe * essere abbinata (in modo che possa eseguire il codice), quindi è meglio usare il '+', perché le corrispondenze 0 sono implicite dall'operatore '||'. –

0

E '(una o più Ms) O centinaia O O OR. (Zero o più Ms) o centinaia o decine o quelli sarebbe partita senza Ms alias la stringa vuota e senza significato aggiungere 1000.

+0

Questo non è vero. Ho provato a passare una stringa vuota e non ha aggiunto 1000 quando si utilizza la soluzione stella Kleene * illuminata ('M') – Integer

0

corrispondenza l'espressione A || B in Qi significa sia corrispondenza solo A, o semplicemente B o A followed by B. Pertanto, nel tuo caso +lit('M') || hundreds significa +lit('M') o hundreds o +lit('M')followed by hundreds. Per questo motivo la grammatica consente di abbinare qualsiasi numero romano nemmeno a partire da M.