Domanda

Ho inserito la grammatica libera dato contesto nel database utilizzando assert (....) Se la grammatica è qualcosa come

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

Questa grammatica è inserito nel database. Devo scrivere un DCG per generare frasi per la CFG nel database. Ad esempio se definisco la dcg in questo modo myDcg ( 'S', str) , il 'S' (non terminale) dovrebbe essere chiamato o Sostituito da ASB o c |. d o giù di lì

Il problema è come posso chiamare / sostituto 'S' da fatti dal database ogni volta che si incontra un non terminale ( 'S') per generare frasi.

Spero che hai capito la mia domanda, se non cercherò di modificare la domanda.


Di seguito (Codice di esempio) è quello che volevo fare esattamente Questo non è DCG.

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

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

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

Ogni volta che si incontra un terminale dovrebbe essere stampato e quando si incontra un non terminale sarà marcia indietro.

È stato utile?

Soluzione

Nel vostro mygrammar/2 predicato c'è una lista dei non-terminali e terminali nel primo argomento e una lista di terminali nel secondo. Probabilmente dovrebbe avere successo se il secondo argomento è la forma del primo. Quindi, quello che avete qui in sostanza, è una meta interprete per DCGs. Alcuni suggerimenti:

Il tuo tokenizer produce attualmente [grammar('S',[a,'S',b]),grammar('S',[....]),..]. Let it produrre [grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),..] invece. In questo modo è evidente che cosa è un terminale e quello che è un non terminale. E, oh, rimuovere tale!.

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, btw sono un po 'più generale di questo interprete.

L'effettiva classificazione tra non-terminali e terminali deve essere inserita dal tokenizzatore.

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

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

Se si utilizza caratteri (atomi di un carattere), si utilizzerà char_code(Char, Code) per la conversione tra di loro.

Supporto

completa Unicode è ancora nella sua infanzia. La sua molto difficile a causa di tutti quei casi speciali per i personaggi come ? che è maiuscolo, ma ancora non può essere parte di un identificatore. Ma ecco come si può fare in SWI attualmente.

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

Aggiornamento:. Nel frattempo, c'è char_type/2 e code_type/2 per questo scopo

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

Altri suggerimenti

Suppongo che si è iniziato con Prolog recente. Sì, si può affermare cose nel database, ma questo non è la cosa comune che si fa in primo luogo. Si vuole utilizzare questa funzione molto più tardi, quando ci si sente al sicuro con la lingua di base.

Quello che in genere si fa è quello di scrivere una grammatica in un file come myfirstgrammar.pl e quindi caricare il file nel vostro sistema Prolog.

Si veda questo recente discussione per i dettagli riguardanti la grammatica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top