-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathin
202 lines (141 loc) · 5.5 KB
/
in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import sys
from constantes import *
def Appliquer(auto, char):
""" Applique une chaine a un automate et renvoie le dernier etat acceptant (ou -1 s'il n'y en a pas) """
etat = 0
i=0
final = -1
while i<len(char) and etat != -1:
#~ print char[i], etat, auto.delta[etat][ord(char[i])]
etat = auto.delta[etat][ord(char[i])]
if etat in auto.F:
final = i
i+=1
return final
def appliquerAutomates(chaine):
""" Permet d'appliquer la chaine sur tous les automates """
listeEtatsFinaux = [Appliquer(AutNum, chaine), Appliquer(AutCar, chaine), Appliquer(AutSymb, chaine), Appliquer(AutCl, chaine), Appliquer(AutId, chaine)]
#On cherche maintenant le max dans cette liste
max = listeEtatsFinaux[0]
indiceDuMax = 0
for i in range(1, len(listeEtatsFinaux)):
if listeEtatsFinaux[i] > max:
max = listeEtatsFinaux[i]
indiceDuMax = i
return listeEtatsFinaux[indiceDuMax], typeUnLex[indiceDuMax] #On retourne la plus graned valeur que retourne Appliquer pour les automates, et le type de l'automates qui a cette plus grande valeur.
def AnLex(listProg):
retraitCourant = 0
lexUnits = []
j=0
while j < len(listProg): #On parcourt le programme ligne apres ligne
ligne = listProg[j]
i=0
newRetrait = 0
#On compte le retrait
while i<len(ligne) and (ligne[i] == '\t' or ligne[i] == ' '):
if ligne[i] == '\t':
newRetrait += 1
i+=1
if i<len(ligne) and not detecteComments(listProg, j, i): #Si le retrait n'est pas suivi d'un commentaire ou d'un retour a la ligne
if newRetrait - retraitCourant <= 1: #Si on a moins de deux debuts de procedures, c'est bon.
listeLex = debut_fin_procedure(newRetrait - retraitCourant, lexUnits)
retraitCourant = newRetrait
#Ici, on s'est occupe du retrait, donc on peut passer a la suite de la ligne.
while i<len(ligne):
if not detecteComments(listProg, j, i) and not detecteSeparateur(listProg, j, i):
(positionTmp, type) = appliquerAutomates(ligne[i:])
if positionTmp == -1: #Si aucun automate ne reconnait la chaine :
return j,i, MotInvalideError, lexUnits
lex = UnLex(type, ligne[i:i+positionTmp+1])
print "On trouve ("+lex.label+", "+lex.type+") dans :", ligne[i:]
i += positionTmp
lexUnits += [lex]
else:
if ligne[i] == '#':
break
elif not detecteSeparateur(listProg, j, i): #Si on a detecte une chaine multilignes :
if cherch3Quotes(listProg, j, i+3) == False: #Si cette chaine n'est pas fermee.
return j, i, ChaineMultiligneError, lexUnits
else: #On va ajouter la chaine multilignes a la liste des unites lexicales.
(jprime, iprime) = cherch3Quotes(listProg, j, i+3)
chaine = "\""
i+=3
while j<jprime:
chaine += listProg[j][i:]+"\\n"
i=0
j+=1
chaine += listProg[j][i:iprime] + "\""
lexUnits += [UnLex('Car', chaine)]
print "On trouve ("+chaine+", Car). (Chaine multilignes)"
#~ (j, i) = (jprime, iprime)
ligne = listProg[j]
i+=4
i+=1
else: #Si on detecte deux debuts de procedures consecutives, on s'arrete car c'est impossible.
return j, i, IndentationError, lexUnits
else:
if i<len(ligne) and ligne[i] != '#': #Si on rencontre un commentaire multiligne en debut de ligne ou apres un retrait.
if cherch3Quotes(listProg, j, i+3) == False: #Si on ouvre un commentaire multiligne sans le fermer plus tard dans le code :
return j, i, ChaineMultiligneError, lexUnits
else: #Sinon on va a l'endroit ou ce commentaire est ferme.
(j, i) = cherch3Quotes(listProg, j, i+3)
lexUnits += [UnLex('Symb', '\n')]
j+=1
listeLex = debut_fin_procedure(-retraitCourant, lexUnits)
return j,i, True, lexUnits
def debut_fin_procedure(difference, listeLex):
""" Recoit la difference entre le retraitCourant et le retrait lu, et ecrit les debuts ou fin de procedure en consequences """
if difference == 1:
lex = UnLex('Pr', '${')
listeLex += [lex]
elif difference < 0:
i=difference
while i < 0:
lex = UnLex('Pr', '}$')
listeLex += [lex]
i+=1
return listeLex
def detecteComments(liste, j, i):
""" Retourne True si le caractere courant est un commentaire """
return liste[j][i] == '#' or (liste[j][i] == "\"" and (j, i) == cherch3Quotes(liste, j, i))
def detecteSeparateur(liste, j, i):
""" Retourne True si le caractere courant est une tabulation ou un espace """
return liste[j][i] in [' ', '\t']
def cherch3Quotes (liste, j, i):
""" Prend une position dans le code python a analyser et renvoie la position du prochain caractere : \""" """
nbGuillemets = 0 #Sert a compter les guillemets doubles consecutifs.
while j < len(liste):
while i<len(liste[j]):
if liste[j][i] == '"':
nbGuillemets +=1
else:
nbGuillemets = 0
if nbGuillemets == 3:
return (j, i-2) #On retourne la position du premier guillemet du groupe de 3
i+=1
i=0
j+=1
return False
def diviseLignes(prog):
""" Divise une chaine de caracteres par ligne, retourne un tableau ou chaque element est une ligne de prog """
liste = []
ligne = ""
i=0
while i < len(prog):
if prog[i] == '\n': #Si on rencontre un saut de ligne.
#if ligne != "": # Et si cette ligne precedant le saut de lignes n'etait pas vide, on l'ajoute.
liste += [ligne]
ligne = ""
else: #Si on atteit pas un saut de ligne, on continue a lire
ligne += prog[i]
i+=1
if ligne != "":
liste += [ligne]
return liste
"""
sdfsdf_
"""
"""dsfsef """
if ff:
dsf
i = 0