Question

J'ai inséré la grammaire libre de contexte donné dans la base de données en utilisant assert (....) Si la grammaire est quelque chose comme

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

Cette grammaire est insérée dans la base de données. Je dois écrire un dcg pour générer des phrases pour CFG dans la base de données. Par exemple, si je définis le dcg de cette façon myDcg ( 'S', str) , 'S' (non terminal) devrait être appelé ou substitués par aSb ou c |. d ou si

Le problème est de savoir comment puis-je appeler / remplacer 'S' par des faits de la base de données chaque fois que survient un terminal non ( 'S') pour générer des phrases.

Espoir vous avez compris ma question, sinon je vais essayer de modifier la question.


Ci-dessous (Exemple de code) est ce que je voulais faire exactement Ce n'est pas DCG.

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

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

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

Chaque fois qu'un terminal est rencontré, il doit être imprimé et quand un terminal non est rencontré il backtrack.

Était-ce utile?

La solution

Dans votre mygrammar/2 prédicat il y a une liste des non-terminaux et terminaux dans le premier argument et une liste de terminaux dans la seconde. Il devrait probablement réussir si le second argument est de la forme de la première. Donc ce que vous avez ici est essentiellement un interpréteur de méta pour DCG. Quelques suggestions:

Votre tokenizer produit actuellement [grammar('S',[a,'S',b]),grammar('S',[....]),..]. Laissez-le produire à la place [grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),..]. De cette manière, il est évident ce qui est un terminal et ce qui est un non-terminal. Et, oh, retirez ça!.

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).

DCG, btw sont un peu plus général que cet interprète.

La classification réelle entre les non-terminaux et terminaux doit être fait par le tokenizer.

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

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

Si vous utilisez (caractères atomes d'un caractère), vous utiliserez char_code(Char, Code) pour convertir entre eux.

Support complet Unicode est encore à ses débuts. Il est très difficile à cause de tous ces cas particuliers pour des personnages comme ? qui est en majuscules, mais ne peut toujours pas faire partie d'un identifiant. Mais voici comment vous pouvez le faire en SWI actuellement.

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).

Mise à jour:. Entre-temps, il y a char_type/2 et code_type/2 à cette fin

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

Autres conseils

Je suppose que vous avez commencé avec Prolog récemment. Oui, vous pouvez affirmer des choses dans la base de données, mais ce n'est pas la chose commune que vous faites en premier lieu. Vous voulez utiliser cette fonctionnalité beaucoup plus tard quand vous vous sentez en sécurité avec la langue de base.

Ce que vous faites en général est d'écrire une grammaire dans un fichier comme myfirstgrammar.pl puis chargez ce fichier dans votre système Prolog.

S'il vous plaît se référer à ce fil récent pour plus de détails concernant la grammaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top