Vous êtes sur la page 1sur 13

Erreur Lexique et syntaxe

1. Introduction

1. Comment dcrire un langage de programmation

2. Lexique

1. Identificateurs et Mots-cls

2. Constantes

3. Symboles spciaux

4. Commentaires

3. Syntaxe

1. Dclarations

2. Accs aux variables

3. Expressions

1. Oprateurs arithmtiques

2. Oprateurs relationnels

3. Oprateurs logiques

4. Priorits

4. Instructions

Introduction

Les deux chapitres prcdents ont prsent les principes de base de la


programmation imprative, savoir les notions de :

actions ;
variables et affectation ;

types abstraits et concrets (numration, tableaux, produits, sommes).

Le but de cette seconde partie du cours est double :

donner les lments ncessaires l'apprentissage d'un nouveau langage de


programmation imprative (ou ventuellement autre) partir de son manuel
de rfrence ;

expliquer plus en dtail certains aspects de la programmation imprative


comme les rgles de porte, l'affectation, le passage de paramtre, les
pointeurs, etc.

Pour cela, nous allons expliquer comment dcrire avec prcision un langage de
programmation.
Comment dcrire un langage de programmation

Lorsque l'on apprend une langue (par exemple l'anglais), on doit matriser :

le vocabulaire : mots du dictionnaire, dclinaisons, conjugaisons, etc. ;

la grammaire : comment composer des phrases correctes du point de vue de


leur forme et de leur structure sinon de leur sens. Par exemple, "le chat
mange la maison" est correct du point de vue grammatical.

le sens des mots et des phrases. Gnralement, cet apprentissage se fait en


mme temps que le vocabulaire et la grammaire : on apprend les mots
corrects et leur sens, et les constructions grammaticales et leur sens.
Cependant, l'exemple ci-dessus montre que l'on peut sparer la correction
grammaticale de la correction du sens (dite correction smantique).

Un langage de programmation (que l'on peut considrer comme une langue


artificielle par rapport aux langues naturelles comme le franais et l'anglais) peut
tre dcrit par les mmes 3 niveaux :

le vocabulaire, appel lexique ;

la grammaire, appele syntaxe ;

le sens, appel smantique.


La diffrence principale entre un langage de programmation et une langue naturelle
est qu'un langage de programmation est beaucoup plus simple et beaucoup plus
strict qu'une langue naturelle.

Une bonne faon de mettre en vidence les trois niveaux ci-dessus est de prendre
des exemples de (morceaux de) programmes errons (ici en Pascal) :
1 program p;
2 var 12x, y : boolean;
3 t : array [1..10] of integer;
4 begin
5 if y <> 0
6 else t[11] := 0;
7 end.

La ligne 2 contient une erreur lexicale : 12x n'est pas un identificateur lgal en
Pascal. La ligne 5/6 contient une erreur syntaxique : la construction if...else n'est
pas lgale en Pascal (il faut une partie then). La ligne 5 contient galement une
erreur smantique : la variable y est dclare boolenne, on ne peut donc la
comparer l'entier 0. Enfin la ligne 6 contient une autre erreur smantique : 11 n'est
pas un indice valide pour le tableau t. Ces deux erreurs smantiques sont de nature
diffrente : la premire peut tre dtecte simplement en regardant le texte du
programme, on dit qu'il s'agit d'une erreur de smantique statique. La seconde ne
peut tre dtecte (dans le cas gnral) que lorsque le programme s'excute, on dit
qu'il s'agit d'une erreur de smantique dynamique. Nous reviendrons sur ces notions
en temps utile.

Les trois niveaux lexique/syntaxe/smantique sont galement la base de la


conception des compilateurs. Un compilateur est un programme qui traduit un
programme crit dans un langage volu (par exemple Pascal) en code machine
excutable directement sur la machine. C'est grce un compilateur que l'on peut
crire et excuter des programmes dans des langages volus. La structure gnrale
d'un compilateur consiste dcouper le programme qu'il traduit en mots (units
lexicales), a structurer ces mots en arbres syntaxiques, puis analyser cet arbre
pour vrifier qu'il est smantiquement correct. Ensuite seulement, la traduction
proprement dite peut commencer : chaque morceau de l'arbre est traduit en langage
machine quivalent, puis ce langage machine est ventuellement optimis. Inutile
de dire qu'un compilateur est un programme particulirement complexe ! Ces
concepts sont approfondis dans le cours de M3 Spcialit Informatique.

Dans la suite de ce chapitre, nous nous intressons aux lments usuels des lexiques
des langages de programmation impratifs et la description de la syntaxe des
langages.

Lexique
Les units lexicales d'un langage dcrivent ses composants de base, les "mots" de
son vocabulaires. La plupart des langages sont fonds sur des vocabulaires trs
proches. Nous allons ici dcrire les principales catgories d'units lexicales et
dtailler le cas du langage Pascal.
Identificateurs et Mots-cls

Les "mots" les plus vidents dans un programme sont les identificateurs et les
mots-cls. Les identificateurs sont utiliss pour dnoter des "objets" du
programme : variables, fonctions, types, etc. Les mots-cls sont utiliss pour
faciliter la reconnaissance de la structure du programme. Par exemple en Pascal, les
mots-cls begin et end dlimitent des blocs d'instructions.

En gnral (en en particulier en Pascal), les identificateurs sont constitus d'au


moins une lettre, suivie de lettres ou de chiffres. Certains caractres (comme le
soulign "_") sont parfois galement autoriss. Le nombre de caractres qui sont
effectivement utiliss pour diffrencier deux identificateurs dpend du langage : 8
dans la version originale de Pascal. Ainsi
12x est illgal mais x12 est lgal
toto_tata_tutu et toto_tata_titi sont identiques

Les mots-cls sont des mots particuliers qui ne peuvent pas tre utiliss comme
identificateurs. En Pascal, la liste des mots-cls est la suivante :
program const var type function procedure begin end
array record set of file
if then else while do repeat until case for to downto
and or not in div mod
goto label nil packed with

Constantes

Les constants sont de mots qui dsignent des valeurs d'un type prdfini du
langage. Typiquement, on trouve les constantes entires, relles, boolennes,
caractres et ventuellement chanes. Ce qui suit concerne le langage Pascal :

Les entiers et les rels s'crivent sous la forme mathmatique habituelle :


10 -50 32767 153648293764234 (illgal car trop grand)
3.14 -0.05 6.02e+23 1.0e-6 1.0 (diffrent de 1)

Les constants boolennes sont les deux mots


true et false

Les constantes caractres sont notes entre simple quotes. Le caractre simple
quote est not en rptant la quote :
'a' '9' ';' ''''

Les constantes chanes de caractres sont galement notes entre simple quotes,
avec rptition des quotes ventuelles :
'Bonjour' 'Commet allez-vous aujourd''hui'

Dans d'autres langages, par exemple C, on utilise des doubles quotes pour les
chanes de caractres, et le caractre '\' ("backslash") pour "protger" les doubles
quotes et indiquer des caractres spciaux :
"Il dit : \"bonjour !\""
"Un deux\ntrois quatre" "\n" indique un retour la ligne
"voici un backslash : \\"

Symboles spciaux

Les langages de programmation utilisent de nombreux symboles spciaux no


alphanumriques. Par exemple, en Pascal il y en a 24 :
+ - * / := . , ; : ' = <> < <= >= > ( ) [ ] { } ^ ..

Certains de ces caractres sont des oprateurs artihmtiques et relationnels :


+ - * / = <> < <= > >=

D'autres correspondent des oprateurs particuliers :


:= affectation
[ ] accs un tableau
^ drfrencer un pointeur

D'autres encore sont utiliss pour sparer des instructions ou grouper des
expressions :
, sparer les lments d'une liste
; sparer des instructions
( ) grouper des sous-expressions
L'espace sert de sparateur, c'est--dire qu'il permet de sparer des units lexicales
adjacentes. Par exemple
typet=array[1..10]ofinteger

est incorrect et doit s'crire avec au moins deux espaces :


type t=array[1..10]of integer
type t = array [1 .. 10] of integer

En Pascal, les fins de ligne et les tabulations sont galement des sparateurs.
Commentaires

Les commentaires sont des parties du programme qui sont ignores du compilateur
et qui ne changent donc rien au sens du programme. Ils sont cependant trs
importants pour documenter le programme, notamment en vue de son utilisation
par quelqu'un d'autre ou de sa modification ultrieure (il est trs rare d'crire un
programme que l'on ne modifie plus jamais et que l'on ne rutilise pas par ailleurs).

En Pascal, les deux formes suivantes sont acceptes :


(* un commentaire *)
{ un autre commentaire }

Syntaxe

La syntaxe d'un langage dcrit les faons correctes d'assembler des units lexicales
pour crire des programmes. Un programme syntaxiquement correct peut encore
tre erron s'il contient des erreurs smantiques.

Pour dcrire la grammaire d'une langue naturelle, on utilise parfois des schmas (et
le plus souvent des rgles). Par exemple, un phrase en franais peut tre compose
d'un groupe sujet, d'un groupe verbal, d'un groupe complment et d'un point final.
Le groupe sujet est constitu d'un article, d'un adjectif ventuel et d'un nom ou d'un
nom et d'un adjectif. Le groupe verbal est compos d'un auxiliaire ventuel et d'un
verbe. Le groupe complment est compos d'un prposition ventuelle et d'un
groupe sujet. Par exemple, les phrases suivantes correspondent cette description :

Le chat mange la souris. Le cadavre exquis boira le vin nouveau. Le partiel aura
lieu dans le grand amphi.
La figure ci-dessous explicite la structure syntaxique de la premire phrase d'aprs
les rgles de grammaire expliques ci-dessus :

Cependant la description ci-dessus est fastidieuse lire et peut tre difficile


comprendre. Une notation un peu plus formelle peut faciliter la lecture et la
comprhension. Il suffit pour cela de donner un nom chaque noeud possible de
l'arbre et de dcrire quels sont les fils possibles de chaque noeud :
<phrase> -> <g_sujet> <g_verbe> <g_complment> .
<g_sujet> -> article [ adjectif ] nom
| article nom adjectif
<g_verbe> -> [ auxiliaire ] verbe
<g_complment> -> [ prposition ] <g_sujet>

Cette notation correspond la description d'une grammaire de production.


Chaque ligne correspond une rgle de production. Les noms entre chevrons
(comme <phrase>) sont appels non-terminaux. Les autres sont les terminaux,
c'est--dire des mots du vocabulaire. Pour construire une phrase grammaticalement
correcte, il faut construire un arbre dont la racine est le non-terminal gauche de la
premire rgles et dont les fils sont les terminaux et non-terminaux de la partie
droite. Chaque feuille de l'arbre qui est un non-terminal doit tre complte en
utilisant une rgle dont le non-terminal est en partie gauche. Il faut noter que dans
cet exemple, on peut produire des phrases "insenses". Dans les rgles de
production ci-dessus, les crochets permettent de mentionner des parties optionnelles
et les barres verticales des alternatives.

Cette notation formelle n'est pas toujours facile lire. On peut utiliser une autre
reprsentation des rgles de production, les diagrammes de
Conway ou diagrammes syntaxiques :
Souvent, on trouve dans les grammaires des structures rptitives. Par exemple, un
texte est une suite de phrases. Ces structures se traduisent par des rgles rcursives
dans les grammaires de production, mais on peut souvent les reprsenter par des
boucles dans les diagrammes syntaxiques :
<texte> -> <phrase>
| <phrase> <texte>

Les langages de programmation ont une structure la fois plus simple et plus stricte
que les langues naturelles. Ils se prtent donc mieux la reprsentation par rgles
de production et diagrammes syntaxiques. Les principales structures syntaxiques
que l'on trouve dans les langages impratifs sont les suivantes :

les dclarations (de constantes, types, variables, fonctions, procdures,


paramtres, etc.) ;

les accs aux variables (notation pointe, accs un tableau, etc.).

les expressions (arithmtiques ou logiques) ;

les instructions (affectation, conditionnelles, boucles, etc.) ;

Dans la suite, nous prsentons ces principales structures syntaxiques en utilisant


tantt des rgles de production, tantt des diagrammes syntaxiques, et en tudiants
particulirement le cas de Pascal. La plupart des manuels de rfrence utilisent des
rgles de production. Les diagrammes syntaxiques sont plus rares.
Dclarations
Un programme impratif est gnralement constitu d'un ensemble de dclarations
et d'un ensemble d'instructions. Pour un programme Pascal, on a :

Les dclarations de constantes, types, variables, fonctions et procdures sont toutes


optionnelles. Elles font rfrence aux dclarations de type dcrites ci-dessous :

Un type simple correspond aux types prdfinis (entier, rel, boolen, caractre),
aux types numrs et aux types intervalles. Les types composs sont les tableaux
et les enregistrements, ainsi que d'autres types que nous n'avons pas tudi
(pointeurs, ensembles, fichiers).

Le dtail de la dclaration des champs d'un enregistrement (non-terminal champs)


n'est pas donn et est laiss titre d'exercice.
Accs aux variables

Pour accder une variable dans un programme, il suffit de mentionner son


identificateur. Cependant, les types composs permettent de dfinir des variables
complexes : ainsi, un tableau contient plusieurs lments, et un enregistrement
contient des champs. Il est possible de combiner ces types, et d'avoir ainsi un
tableau d'enregistrements ou un enregistrement dont certains sont des tableaux, etc.
La syntaxe de l'accs aux variables permet de dcrire comment dnoter les
lments de tableaux (t [i]) et les champs d'enregistrements (c.im) et comment
combiner ces notations. En Pascal, on a la syntaxe (incomplte) suivante :

Par exemple, la dclaration


var m = array [1..10, 1..10] of record re, im : real end;

dfinit m comme un tableau deux dimensions dont les lments sont des nombres
complexes. Pour accder la partie relle de l'lment d'indices 2, 3, il faut crire :
m [2, 3].re

Expressions

Une expression dnote une valeur. Les expressions sont construites partir d'un
ensemble d'oprateurs. On distingue les oprateurs arithmtiques, relationnels et
logiques. La notation est proche de celle utilise en mathmatiques (attention
cependant : le produit doit tre explicitement not *).

Oprateurs arithmtiques
Ce sont les 4 oprations usuelles : +, -, *, /. En Pascal, on a galement les
oprateurs DIV et MOD pour les nombres entiers, qui reprsentent le quotient et le
reste de la division entire. Ainsi, si b != 0 :

a = (a DIV b) * b + a MOD b.

Les oprateurs * et / ont une plus grande priorit que les oprateurs + et -. Ainsi

a + b * c se lit a + (b * c).

En cas d'oprateurs successifs de mme priorit, l'associativit est gauche :

a - b + c est valu (a - b) + c.

Si ncessaire, on utilise des parenthses pour grouper des sous-expressions :

(a + b) * c est diffrent de a + b * c.

Enfin, l'oprateur unaire - est de priorit suprieure tous les autres :

- a + b se lit (- a) + b.

Oprateurs relationnels

Les oprateurs relationnels permettent de comparer des valeurs d'un type simple. Ils
ont pour signature :

entier x entier -> boolen rel x rel -> boolen

En Pascal, les oprateurs sont :


= <> < <= > >=

Ils sont tous de mme priorit. En effet, on ne peut avoir une expression de la forme
:

a<b<c

Celle-ci serait value de la faon suivante, qui provoque une erreur car le terme
entre parenthse est de type boolen mais pas le terme de droite :

(a < b) < c

Oprateurs logiques
Les oprateurs logiques portent sur les boolens. Ce sont le ou logique (OR), le et
logique (AND) et la ngation logique (NOT). Ils ont pour priorits (par ordre
croissant) : OR AND NOT.

Priorits

Les oprateurs arithmtiques sont de priorit suprieure aux oprateurs relationnels,


eux-mme de priorit suprieur aux oprateurs logiques. Ainsi, l'expression

x + y > 10 and x - y < 0

est value dans l'ordre suivant :

((x + y) > 10 ) and ((x - y) < 0)

Les priorits sont donc, par ordre croissant :

OR

AND

NOT

= <> < <= > >=

+-

*/

- unaire

Les facteurs qui constituent les oprandes d'une expression peuvent tre des
constantes, des variables, ou des appels de fonction. Ainsi, si l'on ne tient pas
compte des priorits, la syntaxe des expression peut se dcrire comme suit :
Pour prendre en compte les priorits des oprateurs, il faut dcomposer expression
en plusieurs niveaux, et donner autant de diagrammes correspondants ( faire en
exercice).
Instructions

Les instructions constituent la partie action d'un programme impratif. Dans un


langage impratif, on trouve au moins les instructions suivantes :

affectation et appel de procdure

conditionnelles (if et case en Pascal)

boucles (while, repeat et for en Pascal).

De plus, des instructions peuvent tre groupes dans un bloc (begin-end en Pascal).
Le diagramme syntaxe des instructions Pascal est le suivant :

Les instructions case, repeat et for ne sont pas compltes dans ce diagrammes.
Elles sont laisses titre d'exercice.