Pregunta

He insertado la gramática gratuita de contexto dado en la base de datos utilizando afirmar(....)Si la gramática es algo como

S-->a,S,b
S-->c

Esta gramática se inserta en la base de datos. Tengo que escribir un DCG para generar oraciones para el CFG en la base de datos. Por ejemplo, si defino el DCG de esta manera mydcg ('s', str), la 'S'(no terminal) debe llamarse o sustituido por asb o C | D más o menos.

El problema es cómo puedo llamar/sustituir 'S' por hechos de la base de datos cada vez que se encuentra un no terminal ('s') para generar oraciones.

Espero que hayas entendido mi pregunta, si no, intentaré editar la pregunta.


A continuación (código de muestra) es lo que quería hacer exactamente esto no es DCG.

myGrammar([], []):-!.

myGrammar([T|Rest], [T|Sentence]):-
          myGrammar(Rest, Sentence).

myGrammar([NT|Rest], Sentence):-
          grammar(NT, Rest1),
          append(Rest1,Rest, NewRest),
          myGrammar(NewRest, Sentence). 

Cada vez que se encuentra un terminal, debe imprimirse y cuando se encuentre un no terminal, retrocederá.

¿Fue útil?

Solución

En tu predicado mygrammar/2 Hay una lista de no terminales y terminales en el primer argumento y una lista de terminales en el segundo. Probablemente debería tener éxito si el segundo argumento es de la forma del primero. Entonces, lo que tienes aquí esencialmente es un meta intérprete para DCG. Algunas sugerencias:

Su tokenizador produce actualmente [grammar('S',[a,'S',b]),grammar('S',[....]),..]. Déjalo producir [grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),..] en cambio. De esta manera, es evidente lo que es un terminal y qué no es un terminal. Y, ¡oh, quítate!

myGrammar([], []).
myGrammar([t(T)|Rest], [T|Sentence]):-
   myGrammar(Rest, Sentence).
myGrammar([nt(NT)|Rest], Sentence):-
   grammar(NT, Rest1),
   append(Rest1,Rest, NewRest),
   myGrammar(NewRest, Sentence).

DCGS, por cierto, son un poco más generales que este intérprete.

La clasificación real entre los no terminales y los terminales debe ser realizada por el tokenizador.

uppercasecode(C) :-
   between(0'A,0'Z,C).

lowercasecode(C) :-
   between(0'a,0'z,C).

Si está utilizando chars (átomos de un personaje), usará char_code(Char, Code) para convertir entre ellos.

El soporte completo de Unicode todavía está en su infancia. Es muy complicado debido a todos esos casos especiales para personajes como ⓐ, que es superior, pero aún no puede ser parte de un identificador. Pero así es como puedes hacerlo en SWI actualmente.

uppercasecode(C) :-
   '$code_class'(C,upper),
   '$code_class'(C,id_start).

lowercasecode(C) :-
   '$code_class'(C,id_start),
   '$code_class'(C,id_continue),
   \+ '$code_class'(C,upper).

Actualización: mientras tanto, hay char_type/2 y code_type/2 para este propósito.

uppercasecode(C) :-
   code_class(C, upper),
   code_class(C, prolog_var_start).

Otros consejos

Supongo que recientemente comenzaste con Prolog. Sí, puede afirmar las cosas en la base de datos, pero esto no es lo común que hace en primer lugar. Querrá usar esa función mucho más tarde cuando se sienta seguro con el lenguaje base.

Lo que normalmente haces es escribir una gramática en un archivo como myfirstgrammar.pl y luego cargue ese archivo en su sistema Prolog.

Por favor refiérase a Este hilo reciente Para más detalles sobre la gramática.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top