			(*****************)
			(**  moslog	**)
			(**  anarais	**)
			(*****************)

		(* analyse syntaxique de la phrase *)

	(* M est le tableau contenant la valeur des mots de la phrase
	nbr_mot est le nombre de mots
	p	est l'index courant dans M
	tipe	est le tableau donnant le type d'un mot
			en fonction de sa valeur
	la phrase la plus compliqu‚e est :
		celui qui v1 n1 v2 n2
	verbe1		valeur du verbe 1
	negav1		negation du verbe 1
	snom		valeur du nom 1
	sadj		valeur de l'adjectif 1
	sarticle	article du nom 1
	sprep		pr‚position entre nom et adjectif (frŠre de paul)
	slog		tout	(tout homme mange)
	snegan		non	(un non fou est ..)
	verbe		valeur du verbe 2
	negav		negation du verbe 2
	pro		verbe 2 pronominal (se v2)
	par		verbe2 au passif (est v2 par)
	nom		valeur du nom 2
	adj		valeur de l'adjectif 2
	article		article du nom 2
	prep		pr‚position entre le nom et l'adjectif
	log		tout, du nom 2
	negan		non, negation du nom 2
	il faut aussi calculer ques =0 : affirmation ou =1 ou 2 : question *)



procedure quezako;
var	i:integer;
begin		(* j'y comprends rien
		*********************)
if (p > 0) and (p <= nbr_mot)	then	write(output,MoT_[M[p]]);
write(output,'  quezako');
writeln(output);
ok := 1;
end;

procedure trans(var v:integer);
begin	(* calcul de la valeur semantique de v *)
if v > 0
then	v := vam[v]
else	begin
	if v < -1
	then	v := -vam[-v];
	end;
end;

procedure anarais;	(* analyse de la phrase *)
procedure anaph;	(* determination du type de la phrase *)
var	a:integer;	q:boolean;

procedure inverse;
begin
slog := log;	snegan := negan;	snom := nom;
sadj := adj;	sprep := prep;		sarticle := article;
log := 0;	negan := 0;  nom := 0;	adj := 0;    article := 0;
end;

procedure anagn;
var	goon:boolean;		(* analyse gn *)
begin				(**************)
log := 0;   negan := 0;	nom := 0;   adj := 0;	article := 0;   prep := 0;
goon := true; aucun:=false;	   ok:=0;
while goon do
	begin		(* p est l'index dans la table des mots *)
	if p > nbr_mot	(* nbr_mot est le nombre de mots de la phrase *)
	then	goon := false	(* fin de la phrase *)
	else	begin
		y := m[p];	(* valeur du peme mot *)
		x := tipe[y];	(* type du peme mot *)
		case x of
			tyaucun:begin	(* logique : aucun *)
				p :=p+1;		aucun:=true;
				end;
			tytout: begin	(* logique : tout *)
				p := p+1;		log := y;
				end;
			tynon:	begin	(* booleen : non *)
				p := p+1;		negan := 1;
				end;
			tynom:	begin	(* un nom *)
				p := p+1;
				if nom = 0 then	nom := y  else	adj := y;
				end;
			tyadjectif: begin	(* un adjectif *)
				p := p+1;
				if adj = 0 then	adj := y  else	nom := y;
				end;
			tyqui,tyquest,tyquel: begin (* pronom *)
				p := p+1;		ques := 1;
				if nom = 0 then	nom := -1  else	adj := -1;
				end;
			tyarticle,typrep: begin (* article,preposition *)
				p := p+1;
				if nom = 0 then	article := y else prep := y;
				end;
			else	goon := false;
			end;
		end;
	end;
if (nom = 0) and (adj = 0)	then	ok := 1;
if nom = 0
then	begin	(* si il n'y a pas de nom, on y met l'adjectif *)
	nom := adj;		adj := 0;
	end;
if (adj = 0) and (negan = 1)
then	begin	(* un non x devient un -x *)
	nom := -nom;	negan := 0;
	end;
end;

procedure anav;
var	goon:	boolean;
begin		(* analyse v    rend ok,verbe,negav
		***********)
ok := 1;
negav := 0;	verbe := 0;  pro := 0;
goon := true;
while goon do
	begin
	y := m[p];
	x := tipe[y];
	if x = tyse
	then	begin	(* ne, se, *)
		if (mot_[m[p]] <> 'ne') and (mot_[m[p]] <> 'n')
		then	pro := y;
		p := p+1;
		end
	else	begin
		if x = tyverbe
		then	begin	(* le verbe *)
			goon := false;
			p := p+1;
			ok := 0;
			verbe := y;
			if code[y] = '?'
			then	begin
				verbe := -1;
				if ques = 0 then ques := 2 else ques := 1;
				end;
			y:=m[p];	x:=tipe[y];
			if (x = typas) or (x = tyaucun)
			then	begin	(* verbe pas  ‚quivalent … verbe aucun*)
				p := p+1;
				negav := 1;
				end;
			end
		else	goon := false;
		end;
	end;
if aucun	then	negav:=1-negav;	(* transformation :
				aucun gn ne v gn' devient  gn ne v pas gn' *)

if (ok = 0) and (code[abs(verbe)] = tyetre)
then	begin	(* forme passive : est verbe par *)
	y := m[p];
	x := tipe[y];
	if x = tyverbe
	then	begin	(* le verbe est au passif *)
		if mot_[m[p+1]] = 'par'
		then	p := p+2
		else	p := p+1;
		verbe := y;
		par := 1;
		end;
	end;
end;






procedure xgnv;		(* x gn v / x gn v gn / x est gn *)
begin			(*********************************)
if code[m[p]] = tyetre
then	begin
	anav;
	anagn;
	if ok <> 0	then	quezako
	else	begin
		snom := -1;	sadj := -1;
		end;
	end
else	begin
	anagn;
	if ok <> 0	then	quezako
	else	begin
		inverse;
		anav;
		if ok <> 0	then	quezako
		else	begin
			if p > nbr_mot
			then	begin
				if snom = 0	then	snom := -1;
				if sadj = 0	then	sadj := -1;
				end
			else	begin
				anagn;
				if ok <> 0
				then	quezako
				else	begin
					if nom = 0  then	nom := -1;
					if adj = 0  then	adj := -1;
					if snom = 0 then	snom := -1;
					if sadj = 0 then	sadj := -1;
					end;
				end;
			end;
		end;
	end;
end;
procedure ovgn;
var	sp:integer;
begin		(* o v gn  / o gn v
sp := p;	******************)
anav;
if ok = 0
then	begin
	ok := 0;
	anagn;
	if ok <> 0	then	quezako;
	end
else	begin
	p := sp;
	anagn;
	if ok <> 0
	then	quezako
	else	begin
		anav;
		if ok <> 0	then	quezako;
		end;
	end;
inverse;
nom := -1;		adj := -1;
end;
procedure ivgn;		(* i v gn *)
begin			(*********)
p := p+1;
anav;
if ok <> 0
then	quezako
else	begin
	if p > nbr_mot
	then	begin
		snom := -1;	sadj := -1;
		end
	else	begin
		anagn;
		if ok <> 0
		then	quezako
		else	begin
			snom := -1;	sadj := -1;
			end;
		end;
	end;
end;

procedure anag;forward;
procedure iestcequi;	(* i (est ce qui) v gn / i est gn *)
begin			(**********************************)
if code[m[p]] <> tyetre
then	begin
	p := p-1;
	ivgn;
	end
else	begin
	verbe := m[p];
	p := p+1;
	if mot_[m[p]] <> 'ce'
	then	begin	(* qui est gn ou qui est v par gn *)
		p:=p-1;
		nom := -1;	adj := -1;
		anag;
		end
	else	begin
		p := p+1;
		if mot_[m[p]] <> 'qui'
		then	quezako
		else	ivgn;
		end;
	end;
end;

procedure estcequegn;	(* est ce que gn v gn *)
begin			(**********************)
if mot_[m[p]] <> 'ce'
then	quezako
else	begin
	p := p+1;
	if mot_[m[p]] <> 'que'
	then	quezako
	else	begin
		ques := 2;
		anaph;
		end;
	end;
end;

procedure qestgn;
begin
anagn;
if ok <> 0
then	quezako
else	begin
	if p > nbr_mot
	then	begin
		inverse;
		nom := -1;
		adj := -1;
		verbe := -1;
		end
	else	begin
		anav;
		if ok <> 0
		then	quezako
		else	begin
			inverse;
			nom := -1;
			adj := -1;
			end;
		end;
	end;
end;

procedure qestcqiv;
begin			(* q est ce qui v (gn)
			*********************)
p := p+1;
anav;
if ok <> 0
then	quezako
else	begin
	if p <= nbr_mot
	then	begin
		anagn;
		if ok <> 0	then	quezako;
		end;
	inverse;
	snom := -1;
	sadj := -1;
	end;
end;

procedure anag;
begin
inverse;
anav;
if ok <> 0
then	quezako
else	begin
	if p <= nbr_mot
	then	begin
		anagn;
		if ok <> 0	then	quezako;
		end;
	end;
end;




procedure qestcequi;
begin	(* q est ce qui v (gn) / q est ce que v gn
	 / q est ce que gn / q est gn
	******************************************)
if code[m[p]] <> tyetre
then	quezako
else	begin
	verbe := m[p];
	p := p+1;
	if mot_[m[p]] <> 'ce'
	then	qestgn
	else	begin
		p := p+1;
		if mot_[m[p]] = 'qui'
		then	qestcqiv
		else	begin
			if (mot_[m[p]] <> 'que') and (mot_[m[p]] <> 'qu')
			then	quezako
			else	begin
				p := p+1;	sp := p;
				anav;
				if ok = 0
				then	begin
					anagn;
					if ok <> 0
					then	quezako
					else	begin
						inverse;
						nom := -1;   adj := -1;
						end;
					end
				else	begin
					p := sp;
					qestgn;
					end;
				end;
			end;
		end;
	end;
end;

procedure gnvgn;	(* gn v gn / gn v *)
begin			(******************)
anagn;
if ok <> 0    then    quezako	else	anag;
end;

procedure parqui;
begin
if (mot_[m[p]] <> 'qui') and (mot_[m[p]] <> 'quoi')
then	quezako
else	begin
	p := p+1;
	if mot_[m[p]] = 'est'
	then	begin
		p := p+1;
		anav;
		if ok <> 0	then	quezako
		else	begin
			anagn;
			if ok <> 0	then	quezako
			else	begin
				snom := -1;	sadj := -1;
				end;
			end;
		end
	else	begin
		anagn;
		if ok <> 0	then	quezako
		else	if mot_[m[p]] <> 'est'
			then	quezako
			else	begin
				p := p+1;
				anav;
				if ok <> 0	then	quezako
				else	begin
					snom := -1;	sadj := -1;
					end;
				end;
		end;
	end;
end;
procedure celuiqui;	(* celui qui v gn v gn *)
begin			(***********************)
if mot_[m[p]] <> 'qui'
then	quezako
else	begin
	p := p+1;
	anav;
	if ok <> 0
	then	quezako
	else	begin
		negav1 := negav;	verbe1 := verbe;
		negav := 0;		verbe := 0;
		gnvgn;
		end;
	end;
end;

procedure spec;
		(* entree de connaissances speciales - relations *)
var	q:boolean;

procedure jesais;
begin
writeln(output,'je le savais deja');
end;
procedure typdif;
begin
writeln(output,'ne melange pas les torchons et les serviettes');
end;
procedure predef;
begin
write(output,'occupe toi de tes oignons et laisse mes mots tranquilles');
end;

procedure zieut;
var	i:integer;
begin	(* mise … jour des phrases stokees *)
for i := 1 to nb_aff do
	begin
	trans(sn1[i]);		trans(sn2[i]);
	trans(sa1[i]);		trans(sa2[i]);
	trans(sverbe[i]);	trans(sp1[i]);
	end;
end;
procedure antonym;		(* gn est l inverse de n *)
var	i,x:integer;		(*************************)
begin
if tipe[snom] <> tipe[adj]
then	typdif
else	if (snom < last_pred) or (adj < last_pred)
	then	predef
	else	if vam[snom] = -vam[adj]
		then	jesais
		else	begin	(* mise … jour du dico *)
			for i := last_pred To nb_mot do
				begin
				x := vam[snom];
				if vam[i]=x then vam[i] := -vam[adj];
				end;
			zieut;
			end;
end;
procedure synonym;		(* n est synonyme de n *)
var	x:integer;		(***********************  *)
begin
if tipe[snom] <> tipe[adj]
then	typdif
else	if (snom < last_pred) or (adj < last_pred)
	then	predef	(* on ne modifie pas les pr‚d‚finis *)
	else	if vam[snom] = vam[adj]
		then	jesais
		else	begin	(* mise … jour du dico *)
			for i := last_pred To nb_mot do
				begin
				x := vam[snom];
				if vam[i]=x then vam[i] := vam[adj];
				end;
			zieut;
			end;
end;
procedure reflexif;	(* n est reflexif *)
begin			(******************)
if snom < last_pred
then	predef	(* on ne modifie pas les predefinis *)
else	if rel[snom] = 1
	then	jesais
	else	rel[snom] := 1;		(* mise … jour du dico *)
end;
procedure symetrique;	(* n est sym‚trique de n *)
begin			(*************************)
if (snom < last_pred) or (adj < last_pred)
then	predef	(* on ne modifie pas les predefinis *)
else	if tipe[snom] <> tipe[adj]
	then	typdif
	else	if pas[snom] = adj	(* gn1 et gn2 : 2 noms ou 2 adj *)
		then	jesais
		else	begin		(* mise … jour du dico *)
			pas[snom] := adj;	pas[adj] := snom;
			end;
end;

begin	(* code de spec *)
snom := m[1];		(* entree de connaissances speciales - relations *)
sadj := 0;		(*************************************************)
q := false;
while not q do
	begin
	q := true;	i := i+1;	adj := ord(code[m[i]]);
	if (adj = ord(tyarticle)) or (adj = ord(typrep))  then	q := false;
	end;
adj := m[i];
if sadj <> 0
then	writeln(output,'pas d''adjectif please')
else	case x of
		tyinverse	:antonym;
		tysyno		:synonym;
		tyreflexif	:reflexif;
		tysymetrique	:symetrique;
		else		quezako;
		end;
end;

procedure aiguiltyp;
begin
case chr(a) of	    (* on s'aiguille selon le type du 1er mot *)
	' '	:begin
		spec;	ok:=2;	(* declarations reflexif, ... *)
		end;
	tycelui	:begin
		p := p+1;
		celuiqui;
		end;
	typar	:begin
		p := p+1;	ques := 1;
		parqui;
		end;
	tyarticle,tynom,tytout,tyaucun,tynon,tyadjectif :gnvgn;
	tyquel:	begin
		p := p+1;	ques := 1;
		xgnv;
		end;
	tyquest,tyu:	begin
		p := p+1;	ques := 1;
		ovgn;
		end;
	tyqui	:begin
		p := p+1;	ques := 1;
		iestcequi;
		end;
	tyqu	:begin
		p := p+1;	ques := 1;
		qestcequi;
		end;
	tyetre	:begin
		p := p+1;	ques := 1;
		estcequegn;
		end;
	tyverbe	:begin
		p := p+1;
		if mot_[m[2]] = 'est'
		then	begin
 			p := 2;		ques := 0;
			nom := m[1];	adj := 0;
			anag;
			end
		else	quezako;
		end;
	else	quezako;
	end;
end;

begin	(* code de anaph *)
	(* determination du type de la phrase *)
if p >= nbr_mot
then	quezako
else	begin
	p := p+1;
	a := 1;
	if nbr_mot > 2
	then	begin	(* ne serait ce pas une d‚claration :
			 reflexif, synonyme, sym‚trique, ... *)
		x := code[m[2]];
		if x = tyetre
		then	begin	(* verbe etre *)
			i := 3;
			q := false;
			while not q do
				begin
				adj := m[i];
				x := code[m[i]];
				if (x = tyarticle) or (x = typrep)
				then	i := i+1
				else	q := true;
				end;
			if (x = tyinverse) or (x = tysyno)
			or (x = tyreflexif) or (x = tysymetrique)
			then	a := 0;	(* c'est ca *)
			end;
		end;
	if a = 1
	then	begin
		x := chr(m[p]);
		a := ord(code[ord(x)]);
		end;
	if a = 0	then	a := ord(' ');
	aiguiltyp;
	end;
if par = 1
then	begin	(* on retourne la phrase passive *)
	j := snom;	 snom := nom;		nom := j;
	j := sadj;	 sadj := adj;		adj := j;
	j := sarticle;	 sarticle := article;	article := j;
	j := sprep;	 sprep := prep;		prep := j;
	j := slog;	 slog := log;		log := j;
	j := snegan;	 snegan := negan;	negan := j;
	end;
(* calcul des valeurs semantique *)
trans(snom);	trans(sadj);	trans(nom);
trans(adj);	trans(verbe);	trans(verbe1);
end;

	(*	analyse de la phrase
	*****************************)
begin	(* code de anarais *)
p := 0;
ok := 0;

verbe1 := 0;  	negav1 := 0;	nom := 0;   	adj := 0;	prep := 0;
negav := 0;	log := 0;	negan := 0;	article := 0; 	par := 0;
verbe := 0;
anaph;
end;
