2011-08-24 7 views
5

Tratar de aprender impulso y el ejemplo dado en los documentos me tienen un poco confundido.Boost Spirit Analizador de números romanos Ejemplo

En relación con este código:

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

Particularmente este segmento de la gramática:

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

Podría alguien explicarme por qué se + encendido ('M') y no * iluminado ('METRO'). Porque, después de todo, ¿no puede haber cero o más M en comparación con uno o más M?

Respuesta

0

Ambos +lit('M') y *lit('M') son correctos. Pero el primero es más legible que el segundo (semánticamente), en mi opinión, ya que el primero dice agrega1000 a _val si hay coincidencia one, y hazlo repetidamente. Por otro lado, este último es difícil de leer, ya que uno podría leerlo como agregar1000 a _val incluso para la concordancia cero, que es incorrecta. 1000 no se ha agregado a _val para concordancia de cero-tiempos, sin embargo, el analizador *lit('M') parece coincidir con la concordancia cero también (parece un poco confuso).

Entonces +lit('M') es preferible.


Alright. Leí tu comentario. CCLLIX no es un número romano válido. ¿Cuál crees que es su valor? 309? Si eso es así, ¿qué valor sería para CCCIX? Es demasiado 309, y es correcto. El tuyo está mal. Por lo tanto, el analizador se detiene cuando usa *lit('M'). Tenga en cuenta también que el analizador también se detendrá incluso si utiliza +lit('M') para esta entrada incorrecta.

+0

Usando * lit ('M') y CCLLIX. Entonces, ¿por qué el resultado devuelve 250 y se detiene en LIX? Como dijiste, ¿no debería agregar 1000 a _val para cero coincidencias y CCLLIX no tiene una M. Entonces, ¿no debería devolver 1250, no 250? – Integer

+1

@Integer: agregué la explicación. 'CCLLIX' NO es un número válido. – Nawaz

+0

Buena captura. Lo siento por eso. Pero incluso si uso CCLIX tanto usando * como +, obtengo la respuesta correcta de 259.¿Por qué * no resulta en 1259 como dices? – Integer

2

El operador a || b en Espíritu significa a o b, pero b después a, si ocurre a. En el caso del operador, el caso de que no haya M es implícito (porque la coincidencia para M puede estar presente o no). Además, en el caso de *lit('M'), ¿podría decir que la primera regla se corresponde si hay NOM? Sería válido de todos modos, y _val se incrementaría en 1000.

+0

Pero el _val no consigue incrementa cuando no hay M. He intentado utilizar CCLIX de entrada y devuelve el valor correcto de 259 si yo uso + o * – Integer

+0

Bueno, que * puede * ser dependiente de la implementación. La semántica es claro en el sentido de que la regla * * podría ser igualado (por lo que podría ejecutar el código), por lo que es mejor usar el '' +, debido a las 0 partidos se implica por el operador '' || todos modos. –

0

Es (una o más Ms) O cientos O decenas O unos. (Cero o más Ms) o cientos o decenas o unos se correspondería con ninguna Ms aka la cadena vacía y sin sentido agregar 1000.

+0

Esto no es verdad. Intenté pasar una secuencia vacía y no agregó 1000 cuando usé la solución estrella Kleene * lit ('M') – Integer

0

coincida con la expresión A || B en Qi significa ya sea coincidente simplemente A, o simplemente B o A followed by B. Por lo tanto, en su caso +lit('M') || hundreds significa +lit('M'), o hundreds o +lit('M')followed by hundreds. Por esta razón, la gramática permite hacer coincidir cualquier número romano que no empiece con M.

Cuestiones relacionadas