Problème
. (Extrait du CNC2013)
Analyseur
lexical d’un langage
Présentation. Avant son
exécution, tout code source d’un programme informatique doit être traduit en un
autre code appelé code machine. Cette traduction est réalisée par un
compilateur dont le rôle est de transformer le code source en une suite
d’instructions élémentaires directement exécutables par le processeur.
Ainsi le rôle de l’analyseur lexical est
d’identifier puis supprimer les caractères superflus du code source
(commentaires, espaces, ..) et de reconnaître les mots clés, les
identificateurs, les opérateurs qui sont définis par un ensemble de règles.
En plus, l’analyseur lexical signale les éventuelles
erreurs de syntaxe et associe à chaque erreur le numéro de ligne dans laquelle
elle intervient.
Dans ce problème, on se propose de mettre en œuvre
un analyseur lexical. Il s’agit d’implémenter des fonctions en langage PYTHON pour
un analyseur lexical d’un langage imaginaire qu’on appellera LIM.
Rappel. Les fonctions
et méthodes prédéfinies qui peuvent être utilisées dans ce problème :
-
La fonction len(seq) : renvoie le nombre
d’éléments de la séquence seq.
-
La fonction range(deb,fin,pas) : renvoie …
avec le pas
-
La méthode append(elem) ajoute l’élément elem à
la fin d’une liste.
-
La méthode values( ) renvoie toutes les valeurs
d’un dictionnaire.
-
La méthode items( ) renvoie tous les objets
d’un dictionnaire.
-
La fonction print(msg) affiche le message msg.
Gestion des
commentaires.
Un commentaire est une instruction qui n’est pas traduite par le compilateur.
Pour notre langage LIM, un commentaire est une chaîne de caractères qui doit
commencer obligatoirement par le caractère # (dièse).
Exemple. La chaîne de
caractères com1=’# du texte’ est un commentaire. La chaîne de caractères
com2=’ceci est commentaire !’ n’est pas un commentaire.
Question 1.
Ecrire une
fonction comment(com) qui retourne True si la chaîne de caractères com
est un commentaire du langage LIM et False sinon.
Gestion des
espaces multiples. Dans une
instruction, on a tendance à supprimer les espaces multiples qui se succèdent
et de ne conserver qu’un seul espace.
Exemple. La chaîne de caractères inst= ’ x
= 21 ’ ne doit pas être traitée par le
processeur avant de supprimer les espaces superflus. On doit avoir le résultat
suivant : inst= ’x = 21’.
Question 2.
Ecrire une fonction suppEspaces(inst) qui
supprime les espaces multiples consécutifs (qui se suivent) entre les
caractères de la chaîne inst en paramètre. S’il y’a
plusieurs espaces au début ou à la fin, on ne conserve aucun.(vous pouvez
écrire plusieurs fonctions suppEspacesdebut(inst),
suppEspacesfin(inst), puis suppEspaces(inst)
Reconnaissance des mots clés. Tout langage de programmation
définit un ensemble de mots clés qui sont des chaînes de caractères ayant des
significations et des utilisations spécifiques pour ce langage.
Pour
notre langage LIM, on suppose avoir défini :
-
MotsCles : un tuple qui contient les
chaînes de caractères qui représentent les mots clés du langage LIM. Pour le
moment le tuple est : MotsCles = ('si','sinon','tantque','pour','definir').
On veut réaliser
une fonction qui vérifie si une chaîne de caractères en paramètre est un mot
clé du langage LIM ou non. Ça sera un mot clé si cet un élément du tuple
MotCles.
Exemple. Pour une chaîne
de caractères mot1=’si’ la fonction renvoie True, et pour mot2=’entier’ la
fonction renvoie False.
Question 3.
Ecrire une fonction motCle(mot) qui retourne
True si mot (le paramètre de la fonction) est un mot clé de LIM et
False sinon.
Validité d’un
identificateur. Un
identificateur est une chaîne de caractères qui permet de définir et
d’identifier les éléments d’un programme (les variables, les fonctions, ..). Il
doit respecter un ensemble de règles particulières pour chaque langage.
Un identificateur du langage LIM est valide s’il
respecte les 4 conditions suivantes :
-
Sa longueur est strictement inférieure à 80.
-
Ne contient aucun espace.
-
Ne commence pas par un chiffre
(’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’).
-
Ne doit pas être un mot clé du langage LIM.
Question 4.
Ecrire une fonction identificateur(iden) qui
retourne True si son paramètre (la chaîne de caractères iden) est un
identificateur valide de LIM et False sinon.
Analyse d’une instruction. Une instruction du langage LIM
est correcte si elle vérifie l’une des conditions suivante :
-
L’instruction est un commentaire du langage LIM.
-
L’instruction commence par un identificateur valide
suivi d’un espace suivi d’une chaîne de caractères. On doit supprimer les
espaces superflus.
-
L’instruction commence par un mot clé du langage LIM
suivi par un espace, suivi d’une chaîne de caractères et se termine par le
caractère ’:’ (deux points).
Exemple. La chaîne de
caractères inst1=’si x<y :’ est une instruction valide.
L’instruction
inst2=’5=7’ n’est pas une instruction valide.
L’instruction
inst3=’alpha = 5.55’ est une instruction valide.
Question 5.
Ecrire une fonction analyserInstruction(inst)
qui retourne True si la chaîne de caractères inst en paramètre
correspond à une instruction correcte de LIM et False sinon.
Analyse d’un code source. On suppose maintenant que les
instructions d’un fichier source sont mises dans une liste. On définit ainsi
une liste ListeInst :
-
ListeInst = ['x =5','y =7','si x<y:','5
= 7','sinon :','y est petit']
Qui
sera l’équivalent d’un fichier source illustré à coté.
Au
lieu de compiler et d’analyser le fichier, on va analyser la liste ListeInst.
Question 6.
( Ecrire une fonction analyserSource(L)
qui analyse toutes les instructions la liste L en paramètre. Cette
fonction affiche sur l’écran les indices de tous les éléments de la liste L
qui correspondent à des instructions incorrectes. Elle affiche « succes de
compilation » dans le cas où toutes les instructions sont correctes.
Exemple. Après l’appel
de la fonction : analyserSource(ListeInst) on aura sur l’écran l’affichage du numéro 3 qui est
l’indice de l’instruction ’5 = 7’ qui n’est pas correcte.
Problème . (Extrait
du CNC2013)
Détermination des itinéraires
Présentation. Dans le monde actuel, il est très utile
de pouvoir localiser géographiquement des personnes ou des objets aussi bien
pour des besoins privés que professionnels.
Au niveau professionnel, la géo-localisation est
très utilisée notamment pour la navigation routière mais aussi dans plusieurs
autres domaines (Transport, logistique, énérgie, ..) favorisant ainsi un gain
de productivité et une sécurité accrue.
Des systèmes de géo-localisation – tels que GPS –
permettent le repérage de la position géographique exacte de leurs usagers,
ainsi que le calcul d’itinéraires.
C’est dans cette optique que s’inscrit le problème
suivant concernant des algorithmes de détermination de chemins et d’itinéraires
entre les points d’un plan.
Notations.Soit P un plan, on notera P(x, y), un point de
coordonnées x et y dance ce plan représenté par un tuple (x, y).
-
Soit N une variable de type int
strictement positive à laquelle on donnera la valeur 10 (N = 10) dans tout le
problème. On notera P (N),
l’ensemble des points du plan P ayant des coordonnées x et y
entières positives telles que (0<=x<
N) et (0<=y< N).
-
Soient A et B deux points distincts de P (N). on appelle chemin de A vers B, une liste C, non vide et ordonnée de points
distincts (tous différents) de P (N) tel que :
C
= [(xA, yA), (x1,
y1), .., (xi, yi), .., (xB, yB)]
Chaque point P(x, y) de ce chemin est relié au point
suivant P(s,t) par l’une des 4
relations suivantes :
a.
Gauche :
P(s, t) est à gauche de P(x, y).
c'est-à-dire : s == x – 1 et t == y
b.
Droite :
P(s, t) est à droite de P(x, y).
c'est-à-dire : s == x + 1 et t == y
c.
Haut :
P(s, t) est au dessus de P(x, y).
c'est-à-dire : s == x et t == y + 1
d.
Bas : P(s, t) est en
dessous de P(x, y). c'est-à-dire : s
== x et t == y – 1
python_fichiers/image003.gif)
Exemples de
chemins.
Soient A (2, 3) et B (5, 5) deux points de P (10) :
C1 = [(2, 3), (3, 3), (4, 3), (4, 4), (4, 5), (5, 5)]
C2 = [(2, 3), (2, 4), (3, 4), (3, 5), (4, 5), (5,
5)]
Les listes C1 et C2 représentent 2 chemins
différents de A vers B.
Construction de chemins.
-
Soit Max une variable de type int
strictement positive qui contient le nombre maximal de points que peut contenir
un chemin entre 2 points quelconques.
Question 1.
Ecrire une fonction initChemin( ) qui
initialise une liste de tuples par les valeurs (-1, -1) et la retourne comme résultat. Les
points P (-1, -1) n’appartient
pas à P (N) mais permettent juste
d’initialiser la liste.
Chemin horizontal
puis vertical. Soient
A et B deux points de P (N). On appelle CheminHV de A vers B le
chemin construit de telle sorte à se déplacer à partir de A horizontalement
(soit à gauche, soit à droite) jusqu’à arriver au point ayant la même abscisse
que B, puis se déplacer verticalement (soit en haut, soit en bas) jusqu’à
arriver au point B.
Exemple. N = 10. Soient
A= (1, 6) et B= (4, 2) de P (10), alors CheminHV de A vers B
est :
C = [(1, 6), (2,
6), (3, 6), (4, 6), (4, 5), (4, 4), (4, 3), (4, 2)]
python_fichiers/image005.jpg)
Question 2.
Ecrire une fonction cheminHV(A, B) qui crée
et retourne la liste HVAB de tuples représentant le
cheminHV de A vers B. Dans ce cas HVAB[0] contiendra le tuple (xA, yA). HVAB[-1]
contiendra le tuple (xB, yB).
Distance d’un chemin et chemin minimal. Soit C un
chemin reliant deux points A et B. on appelle distance du chemin C, le nombre
de points du chemin C différents du point A.
Exemple. Soient A= (2,
6) et B= (4, 3) deux points et C = [(2, 6), (2, 5), (2, 4), (2, 3), (3, 3), (4,
3)] un chemin de A vers B. La distance de C est de 5.
On considère maintenant plusieurs chemins différents
et tous menant de A vers B. On représente ces chemins par un dictionnaire DictChemins
où les clés seront des chaînes de caractères : C1, C2,
.. CN et les valeurs sont les listes représentant ces chemins.
Exemple. Pour les deux
points A= (2,6) et B= (4, 3), DictChemins aura la représentation
suivante :
DictChemins = { 'C1' : [(2, 6), (3, 6), (4, 6), (4, 5), (4, 4), (4, 3)] ,
'C2' : [(2, 6), (2,
5), (2, 4), (2, 3), (2, 2), (3, 2), (3, 3), (4,3)] ,
'C3' : [(2, 6), (2,
5), (2, 4), (3, 4), (3, 3), (4, 3)] ,
'C4'
: [(2, 6), (1, 6), (0, 6), (0, 5), (0, 4), (0, 3), (1, 3), (2, 3), (3, 3), (4,
3)] , }
Avec C1 et C3 de distance 5, C3 de distance 7 et C4
de distance 9.
D’autre part la distance minimale reliant les 2
points A et B (du dictionnare DictChemins) est 5.
Le chemin minimal est donc C1 = [2, 6), (3, 6), (4,
6), (4, 5), (4, 4), (4, 3)].
Si on a plusieurs chemins minimaux, on prend le
premier chemin minimal trouvé pendant le parcours du dictionnaire.
Question 3.
Ecrire une fonction distanceChemin(cle) qui
retourne la distance d’un chemin identifié par sa clé passée en paramètre.
Question 4.
Ecrire une fonction distanceMinimale(DictChm)
qui retourne la distance minimale de plusieurs chemins du dictionnaire DictChm
passé en paramètre.
Question 5.
Ecrire une fonction cheminMinimal(DictChm)
qui retourne le chemin minimal des chemins du dictionnaire DictChm passé en
paramètre.
Question 6.
Ecrire une fonction cheminRetour(C) qui
retourne le chemin de retour qui est le chemin inverse de C. Si C est un chemin
de A vers B, la fonction retourne le chemin de B vers A.
def comment(com):
if (com[0]=='#'):
return True
else:
return False
def supprim_espaces_debut(inst):
inst1=""
i=0
while(inst[i]==' '):
i+=1
inst1=inst1+inst[i:len(inst)]
return inst1
def supprim_espaces_fin(inst):
inst1=""
i=len(inst)-1
while(inst[i]==' '):
i-=1
inst1=inst1+inst[0:i+1]
return inst1
def supprim_espaces_mult(inst):
i=0
inst1=""
while (i<len(inst)):
while (i<len(inst)-1) and ((inst[i]==' ')and (inst[i+1]==' ')) :
i+=1
inst1+=inst[i]
i+=1
return inst1
#pp
print(supprim_espaces_debut(" aabb"))
print(supprim_espaces_fin(" aabb "))
print(supprim_espaces_mult("aa ccc bb"))