Il s'agit de la grammaire développée initialement, réécrite pour l'analyseur présenté dans cette annexe.
Le lexique est le même.
Le prédicat lex
permettant l'analyse lexicale est donc :
lex(lex(MOT,CAT,[]))-->[MOT],{mot(MOT,T),categorie(T,CAT)}.
Les étapes de calcul sont mémorisées différemment : on utilise une liste en paramètre du symbôle lex
.
Ainsi, pour afficher ces étapes, il suffit d'appeler le prédicat suivant :
afficher_calculs([A,B,CA,CB,CAB|S]):- !, writef("%t . %t : %t . %t => %t\n",[A,B,CA,CB,CAB]), afficher_calculs(S). afficher_calculs([]).
Les deux règles de grammaires s'écrivent alors naturellement :
lex([A,B],X,CAB):=lex(A,X/Y,CA),lex(B,Y,CB), {append(CA,CB,TMP), append(TMP,[A,B,X/Y,Y,X],CAB)}. lex([A,B],X,CAB):=lex(A,Y,CA),lex(B,X\Y,CB), {append(CA,CB,TMP), append(TMP,[A,B,Y,X\Y,X],CAB)}.
CA
, CB
, CAB
représentent les listes utilisées pour mémoriser les calculs.
Pour analyser une phrase, on veut obtenir la catégorie s dans le deuxième argument de lex
:
analyser(PH):- parse(lex(_,s,CALC),PH), afficher_calculs(CALC).
Il se trouve que cet analyseur est plus rapide que celui de la première version de cette grammaire. Cela est du à l'optimisation d'application des règles juste après un décalage. Ce qui n'existait pas dans la première version. On notera aussi que l'écriture de la grammaire avec cet analyseur est plus intuitive. Le cas de la grammaire de Lambek-Gentzen le montre bien.