2010-07-19 22 views
10

I tienen el siguiente analizador simple expresión:números de análisis sintáctico con múltiples dígitos en Prolog

expr(+(T,E))-->term(T),"+",expr(E). 
expr(T)-->term(T). 

term(*(F,T))-->factor(F),"*",term(T). 
term(F)-->factor(F). 

factor(N)-->nat(N). 
factor(E)-->"(",expr(E),")". 

nat(0)-->"0". 
nat(1)-->"1". 
nat(2)-->"2". 
nat(3)-->"3". 
nat(4)-->"4". 
nat(5)-->"5". 
nat(6)-->"6". 
nat(7)-->"7". 
nat(8)-->"8". 
nat(9)-->"9". 

Sin embargo, esto sólo es compatible con números de 1 dígito. ¿Cómo puedo analizar números con múltiples dígitos en este caso?

+0

¿Qué prólogo estás usando? Mine dones no tiene el "->" think iirc. (SWI-Prolog) – InsertNickHere

+0

Estoy usando SWI-Prolog, también ^^ – ubuntudroid

+0

Huh. Shouldent sea: ¿en cambio? * scratchhead * – InsertNickHere

Respuesta

9

Usa las variables del acumulador y transfiere esas en llamadas recursivas. A continuación, A y A1 son el acumulador.

digit(0) --> "0". 
digit(1) --> "1". 
% ... 
digit(9) --> "9". 

nat(N) --> digit(D), nat(D,N). 
nat(N,N) --> []. 
nat(A,N) --> digit(D), { A1 is A*10 + D }, nat(A1,N). 

Tenga en cuenta que la primera cláusula nat inicializa el acumulador por el consumo de un dígito, debido a que no desea para que coincida con la cadena vacía.

+0

@ubuntodroid: Creo que esta es una buena solución si tiene que implementar el número de análisis usted mismo. No sé si hay un predicado para analizar los números naturales por defecto en Prolog. El código también se puede reducir si se puede hacer una aritmética de caracteres que sea "0" -> 0, "1" -> "0" + 1, ... en Prolog. – thequark

+0

@thequark: No sé de ningún predicado. 'atom_char/2' se puede usar, pero no sería bonito. También podría escribir un predicado 'digit_int/2' con el valor ASCII de '0' codificado (yuck). –

-3

¿Puede proporcionarnos una entrada de muestra?

creo que este fuerza de trabajo:

nat(N)-->number(N). 

Si eso no funciona probar:

nat(N)-->number(N),!. 

El! es un corte, detiene la unificación. Puedes leer sobre esto en libros/tutoriales.

+0

Algunos ejemplos de entrada podrían ser expr (E, "2 * 14 + 3", ""). El código que proporcionó conduce a un mensaje de error que me dice que el número/3 es un procedimiento indefinido y que solo se conoce el número/1. Pensé en una cláusula DGC para resolver mi problema, pero no pude conseguir uno funcionando. – ubuntudroid

+0

'number/1' es un predicado ordinario, no un predicado DCG. Además, falla si su entrada no está baja (es una variable). –

-1
nat(0). 
nat(N):-nat(N-1). 

Pero se usa una sintaxis que no conozco (ver mi comentario anterior).

Cuestiones relacionadas