Cours gratuits » Cours informatique » Cours programmation » Cours Oberon » Le langage de programmation Oberon gratuitement

Le langage de programmation Oberon gratuitement

Problème à signaler:

Télécharger



★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Le langage de programmation Oberon [Eng]

1. Introduction

Oberon est un langage de programmation généraliste qui a évolué à partir de Modula-2. Sa principale nouveauté est le concept d'extension de type. Il permet la construction de nouveaux types de données sur la base des types existants et de les relier.

Ce rapport n'est pas destiné à être un didacticiel de programmeur. Il est intentionnellement gardé concis. Sa fonction est de servir de référence pour les programmeurs, les implémenteurs et les rédacteurs manuels. Ce qui reste non-dit est la plupart du temps laissé intentionnelle

ment, soit parce qu'il est dérivé des règles énoncées de la langue, soit parce que cela restreindrait inutilement la liberté des implémenteurs.

Ce document décrit la langue définie en 1988/90 telle que révisée en 2007/11.

  1. Syntaxe

Un langage est un ensemble infini de phrases, à savoir les phrases bien formées selon sa syntaxe. Dans Oberon, ces phrases sont appelées unités de compilation. Chaque unité est une séquence finie de symboles issus d'un vocabulaire fini. Le vocabulaire d'Oberon se compose d'identifiants, de nombres, de chaînes, d'opérateurs, de délimiteurs et de commentaires. Ils sont appelés symboles lexicaux et sont composés de séquences de caractères. (Notez la distinction entre les symboles et les caractères.)

Pour décrire la syntaxe, un formalisme étendu de Backus-Naur appelé EBNF est utilisé. Les parenthèses [et] indiquent l'optionalité de la forme de phrase jointe, et les accolades {et} indiquent sa répétition (probablement 0 fois). Les entités syntaxiques (symboles non terminaux) sont désignées par des mots anglais exprimant leur signification intuitive. Les symboles du vocabulaire de la langue (symboles terminaux) sont indiqués par des chaînes entre guillemets ou par des mots en majuscules.

  1. Vocabulaire

Les règles lexicales suivantes doivent être respectées lors de la composition de symboles. Les espaces et les sauts de ligne ne doivent pas apparaître dans les symboles (sauf dans les commentaires et les espaces dans les chaînes). Ils sont ignorés à moins qu'ils ne soient essentiels pour séparer deux symboles consécutifs. Les majuscules et minuscules sont considérées comme distinctes.

Les identifiants sont des séquences de lettres et de chiffres. Le premier caractère doit être une lettre. ident = lettre {lettre | chiffre}.

Exemples:

x scanner première lettre Oberon GetSymbol

Les nombres sont des entiers (non signés) ou des nombres réels. Les entiers sont des suites de chiffres et peuvent être suivis d'une lettre de suffixe. Si aucun suffixe n'est spécifié, la représentation est décimale. Le suffixe H indique une représentation hexadécimale.

Un nombre réel contient toujours un point décimal. En option, il peut également contenir un facteur d'échelle décimale. La lettre E est prononcée comme "dix fois au pouvoir de". Un nombre réel est de type REAL, sauf s'il contient un facteur d'échelle avec la lettre D, auquel cas il est de type LONGREAL.

nombre = entier | réal.

nombre entier = chiffre {chiffre} | digit {hexDigit} "H". real = digit {digit} "." {digit} [ScaleFactor]. ScaleFactor = ("E" | "D") ["+" | "à ¢ â,¬â € œ"] chiffre {chiffre}. hexDigit = chiffre | "A" | "B" | "C" | "D" | "E" | "F".

digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9".

Exemples:

1987

100H = 256

12,3

4,567E8 = 456700000

Les chaînes sont des suites de caractères entre guillemets (") .Une chaîne ne peut pas contenir la marque de citation délimitante.En variante, une chaîne d'un seul caractère peut être spécifiée par le nombre ordinal du caractère en notation hexadécimale suivi d'un" X ". nombre de caractères dans une chaîne est appelée la longueur de la chaîne.

string = "" "{character}" "" | digit {hexdigit} "X". Exemples:

"OBERON" "Ne t'inquiète pas!" 22X

Les opérateurs et les délimiteurs sont les caractères spéciaux, les paires de caractères ou les mots réservés répertoriés ci-dessous. Ces mots réservés sont constitués exclusivement de lettres majuscules et ne peuvent pas être utilisés dans le rôle d'identificateurs.

+: = ARRAY IMPORT ALORS

- ^ COMMENCER À

* = BY EST VRAI

/ # CAS MOD MODÈLE

~ <MODULE CONST JUSQU'À

&> DIV NIL VAR

. <= FAIRE DE TOUT

,

; > = .. SINON

ELSIF OU

AIGUILLE

| : PROCÉDURE DE FIN

() FAUX ENREGISTREMENT

[] POUR REPRISE

{} SI RETOUR

Les commentaires peuvent être insérés entre deux symboles quelconques dans un programme. Ce sont des séquences de caractères arbitraires ouvertes par le crochet (* et fermées par *). Les commentaires n'affectent pas la signification d'un programme. Ils peuvent être imbriqués.

  1. Déclarations et règles de portée

Tout identifiant apparaissant dans un programme doit être introduit par une déclaration, sauf s'il s'agit d'un identifiant prédéfini. Les déclarations servent également à spécifier certaines propriétés permanentes d'un objet, comme s'il s'agit d'une constante, d'un type, d'une variable ou d'une procédure.

L'identifiant est ensuite utilisé pour faire référence à l'objet associé. Ceci n'est possible que dans les parties d'un programme qui sont dans le champ de la déclaration. Aucun identificateur ne peut désigner plus d'un objet dans une portée donnée. La portée s'étend textuellement du point de la déclaration à la fin du bloc (procédure ou module) auquel appartient la déclaration et donc à laquelle l'objet est local. La règle de portée a les modifications suivantes:

  1. Si un type T est défini comme POINTER TO T1 (voir 6.4), l'identificateur T1 peut être déclaré textuellement après la déclaration de T, mais il doit se situer dans la même portée.
  2. Les identifiants de champ d'une déclaration d'enregistrement (voir 6.3) ne sont valables que dans les indicatifs de champ.

Dans sa déclaration, un identifiant dans la portée globale peut être suivi d'une marque d'exportation (*) pour indiquer qu'il est exporté depuis son module déclarant. Dans ce cas, l'identifiant peut être utilisé dans d'autres modules, s'ils importent le module déclarant. L'identifiant est alors préfixé par l'identifiant désignant son module (voir chapitre 11). Le préfixe et l'identifiant sont séparés par une période et sont appelés ensemble un identifiant qualifié.

qualident = [ident "."] ident. identdef = ident ["*"].

Les identifiants suivants sont prédéfinis; leur signification est définie à la section 6.1 (types) ou 10.2 (procédures):

ABS ASR ASSERT BOOLEAN CHAR

CHR COPY DEC EXCL FLOOR

FLT INC INCL INTÉGRAL LEN

LSL LONG LONGREAL NOUVEAU ODD

ORD PACK REAL ROR SET

UNPK COURT

  1. Déclarations constantes

Une déclaration constante associe un identifiant à une valeur constante.

ConstantDeclaration = identdef "=" ConstExpression. ConstExpression = expression.

Une expression constante peut être évaluée par un simple balayage textuel sans réellement exécuter le programme. Ses opérandes sont des constantes (voir chapitre 8). Des exemples de déclarations constantes sont:

N = 100

limite = 2 * N -1

all = {0 .. WordSize-1}

nom = "Oberon"

  1. Déclarations de type

Un type de données détermine l'ensemble de valeurs que peuvent prendre les variables de ce type et les opérateurs applicables. Une déclaration de type est utilisée pour associer un identifiant à un type. Les types définissent la structure des variables de ce type et, implicitement, les opérateurs applicables aux composants. Il existe deux structures différentes, à savoir les tableaux et les enregistrements, avec différents sélecteurs de composants.

TypeDeclaration = identdef "=" StrucType.

StrucType = ArrayType | RecordType | PointerType | ProcedureType.

 type = qualident | StrucType.

ARRAY N DE VRAI POINTEUR AU Nœud

Touche RECORD: INTEGER; à gauche, à droite: Tree END

ENREGISTREMENT (Noeud)

Nom: ARRAY 32 OF CHAR; sous-noeud: Arbre

FIN

PROCÉDURE (x: INTEGER): INTEGER

6.1. Types de base

Les types de base suivants sont désignés par des identifiants prédéfinis. Les opérateurs associés sont définis en 8.2, et les procédures de fonction déclarées en 10.2. Les valeurs d'un type de base donné sont les suivantes:

BOOLEAN les valeurs de vérité VRAI et FAUX

CHAR les caractères d'un jeu de caractères standard

INTEGER les entiers

REAL nombres réels

LONGREAL nombres réels

SET les ensembles d'entiers entre 0 et 31

Le type LONGREAL est destiné à représenter des nombres réels avec un plus grand nombre de chiffres que REAL. Cependant, les deux types peuvent être identiques.

6.2. Types de tableaux

Un tableau est une structure composée d'un nombre fixe d'éléments qui sont tous du même type, appelé le type d'élément. Le nombre d'éléments d'un tableau est appelé sa longueur. Les éléments du tableau sont désignés par des indices, qui sont des entiers compris entre 0 et la longueur moins 1.

ArrayType = ARRAY length {"," longueur} OF type. length = ConstExpression.

Une déclaration du formulaire

RÉSEAU N0, N1, ..., Nk DE T

est entendu comme une abréviation de la déclaration

RÉSEAU N0 DE

RÉSEAU N1 DE

...

ARRAY Nk DE T

Exemples de types de tableaux:

ARRAY N DE TABLEAU INTEGER 10, 20 DE REAL

6.3. Types d'enregistrements

Un type d'enregistrement est une structure constituée d'un nombre fixe d'éléments de types éventuellement différents. La déclaration de type d'enregistrement spécifie pour chaque élément, appelé champ, son type et un identifiant qui dénote le champ. La portée de ces identificateurs de champ est la définition d'enregistrement elle-même, mais elle est également visible dans les indicateurs de champ (voir 8.1) se référant aux éléments des variables d'enregistrement.

RecordType = RECORD ["(" BaseType ")"] [FieldListSequence] END.

BaseType = qualident

FieldListSequence = FieldList {";" Liste de champ}.

FieldList = IdentList ":" type.

IdentList = identdef {"," identdef}.

Si un type d'enregistrement est exporté, les identificateurs de champ qui doivent être visibles en dehors du module de déclaration doivent être marqués. Ils sont appelés champs publics; les champs non marqués sont appelés champs privés.

Les types d'enregistrement sont extensibles, c'est-à-dire qu'un type d'enregistrement peut être défini comme une extension d'un autre type d'enregistrement. Dans les exemples ci-dessus, CenterNode (directement) étend Node, qui est le type de base (direct) de CenterNode. Plus précisément, CenterNode étend le nœud avec le nom et le sous-noeud des champs.

Définition: Un type T étend un type T0, s'il est égal à T0, ou s'il étend directement une extension de T0. Inversement, un type T0 est un type de base de T, s'il est égal à T, ou s'il s'agit du type de base direct d'un type de base de T.

Exemples de types d'enregistrements:

RECORD jour, mois, année: INTEGER END

RECORD

nom, prénom: ARRAY 32 OF CHAR;

âge: INTEGER;

salaire: REAL

FIN

6.4. Types de pointeurs

Les variables d'un type de pointeur P supposent comme pointeurs de valeurs des variables de type T. Il doit s'agir d'un type d'enregistrement. Le type de pointeur P est dit être lié à T, et T est le type de base de pointeur de P. Les types de pointeurs héritent de la relation d'extension de leurs types de base, s'il y en a. Si un type T est une extension de T0 et que P est un type de pointeur lié à T, alors P est aussi une extension de PO, le type de pointeur lié à T0.

PointerType = POINTER à taper.

Si p est une variable de type P = POINTER TO T, alors un appel de la procédure prédéfinie NEW (p) a l'effet suivant (voir 10.2): Une variable de type T est allouée en stockage libre, et un pointeur vers elle est affecté à p. Ce pointeur p est de type P et la variable référencée p ^ est de type T. L'échec d'allocation conduit à p obtenant la valeur NIL. Toute variable pointeur peut avoir la valeur NIL, qui ne pointe sur aucune variable.

6.5. Types de procédure

Les variables d'un type de procédure T ont une procédure (ou NIL) en tant que valeur. Si une procédure P est affectée à une variable de procédure de type T, les (types des) paramètres formels de P doivent être les mêmes que ceux indiqués dans les paramètres formels de T. Il en va de même pour le type de résultat dans le cas d'un procédure de fonction (voir 10.1). P ne doit pas être déclaré local à une autre procédure, et il ne peut pas non plus être une procédure standard.

ProcedureType = PROCEDURE [FormalParameters]. 7. Déclarations de variables

Les déclarations de variables servent à introduire des variables et à les associer à des identificateurs qui doivent être uniques dans la portée donnée. Ils servent également à associer des types de données fixes aux variables.

 VariableDeclaration = Type ":" IdentList.

Les variables dont les identifiants apparaissent dans la même liste sont toutes du même type. Exemples de déclarations de variables (se reporter aux exemples du chapitre 6):

i, j, k: INTEGER

x, y: REAL

p, q: BOOLÉEN

s: SET

f: Fonction

a: ARRAY 100 DE REAL

w: ARRAY 16 OF

RECORD ch: CHAR; compter: INTEGER END

t: Arbre

  1. Expressions

Les expressions sont des constructions désignant des règles de calcul où les constantes et les valeurs courantes des variables sont combinées pour dériver d'autres valeurs par l'application d'opérateurs et de procédures de fonction. Les expressions sont constituées d'opérandes et d'opérateurs. Les parenthèses peuvent être utilisées pour exprimer des associations spécifiques d'opérateurs et d'opérandes.

8.1. Opérandes

À l'exception des ensembles et des constantes littérales, c'est-à-dire des nombres et des chaînes, les opérandes sont désignés par des indicateurs. Un indicateur est constitué d'un identificateur se référant à la constante, à la variable ou à la procédure à désigner. Cet identifiant peut éventuellement être qualifié par des identifiants de module (voir chapitres 4 et 11), et il peut être suivi par des sélecteurs, si l'objet désigné est un élément d'une structure.

Si A désigne un tableau, alors A [E] désigne cet élément de A dont l'index est la valeur courante de l'expression E. Le type de E doit être de type INTEGER. Un désignateur de la forme A [E1, E2, ..., En] représente A [E1] [E2] ... [En]. Si p désigne une variable pointeur, p ^ désigne la variable référencée par p. Si r désigne un enregistrement, alors r.f désigne le champ f de r. Si p désigne un pointeur, p.f désigne le champ f de l'enregistrement p ^, c'est-à-dire que le point implique un déréférencement et p.f représente p ^ .f.

Le contrôle de type v (T0) affirme que v est de type TO, c'est-à-dire qu'il interrompt l'exécution du programme s'il n'est pas de type T0. Le garde est applicable, si

  1. T0 est une extension du type déclaré T de v, et si
  2. v est un paramètre variable du type d'enregistrement, ou v est un pointeur.

désignateur = qualident {sélecteur}.

selector = "." ident | "[" ExpList "]" | "^" | "(" qualident ")". ExpList = expression {"," expression}.

Si l'objet désigné est une variable, le désignateur fait référence à la valeur actuelle de la variable. Si l'objet est une procédure, un désignateur sans liste de paramètres fait référence à cette procédure. S'il est suivi d'une liste de paramètres (éventuellement vides), le désignateur implique une activation de la procédure et représente la valeur résultant de son exécution. Les (types des) paramètres réels doivent correspondre aux paramètres formels spécifiés dans la déclaration de la procédure (voir chapitre 10).

Exemples de désignateurs (voir les exemples dans le chapitre 7):

je (ENTIER)

un [i] (REEL)

w [3] .ch (CHAR)

t.key (INTEGER)

t.left.right (Arbre)

 t (CenterNode) .subnode (arborescence)

8.2. Les opérateurs

La syntaxe des expressions distingue quatre classes d'opérateurs avec des priorités différentes (forces de liaison). L'opérateur ~ a la priorité la plus élevée, suivi des opérateurs de multiplication, des opérateurs d'addition et des relations. Les opérateurs de même préséance s'associent de gauche à droite. Par exemple, xï ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ stands

expression = SimpleExpression [relation SimpleExpression].

relation = "=" | "#" | "<" | "<=" | ">" | "> =" | IN | EST.

SimpleExpression = ["+" | "" ïâ ""] terme {terme AddOperator}. AddOperator = "+" | "¯â,¬" | OU.

term = facteur {facteur MulOperator}.

MulOperator = "*" | "/" | DIV | MOD | "&".

facteur = nombre | chaîne | NIL | VRAI | FAUX |

définir | indicatif [ActualParameters] | "(" expression ")" | "~" facteur.

set = "{" [element {"," element}] "}".

element = expression [".." expression].

ActualParameters = "(" [ExpList] ")".

Les opérateurs disponibles sont répertoriés dans les tableaux suivants. Dans certains cas, plusieurs opérations différentes sont désignées par le même symbole d'opérateur. Dans ces cas, l'opération réelle est identifiée par le type des opérandes.

8.2.1. Opérateurs logiques

résultat du symbole

OU disjonction logique

& conjonction logique

~ négation

Ces opérateurs s'appliquent aux opérandes BOOLEAN et donnent un résultat BOOLEAN.

p OU q signifie "si p alors VRAI, sinon q"

p & q signifie "si p alors q, sinon FAUX"

~ p signifie "pas p"

8.2.2. Opérateurs arithmétiques

résultat du symbole

+ somme

Ça différence

* produit

/ quotient

Quotient entier DIV

MOD module

Les opérateurs +, ïâ,¬, *, et / s'appliquent aux opérandes de types numériques. Les deux opérandes doivent être du même type, ce qui est également le type du résultat. Lorsqu'ils sont utilisés comme opérateurs unaires, Ãâ désigne l'inversion de signe et + désigne l'opération d'identité.

Les opérateurs DIV et MOD s'appliquent uniquement aux opérandes entiers. Soit q = x DIV y, et r = x MOD y. Alors le quotient q et le reste r sont définis par l'équation

x = q * y + r 0 ¯ ¤ r <y

8.2.3. Définir les opérateurs

 résultat du symbole

+ union

-              différence

* intersection

/ différence de réglage symétrique

Lorsqu'il est utilisé avec un seul opérande de type SET, le signe moins indique le complément défini.

8.2.4. Rapports

relation de symbole

= égal

# inégale

<moins

<= moins ou égal

> plus grand

> = plus grand ou égal

IN set d'adhésion

Test de type IS

Les relations sont booléennes. Les relations d'ordre <, <=,>,> = s'appliquent aux types numériques, CHAR et tableaux de caractères. Les relations = et # s'appliquent également aux types BOOLEAN et SET, et aux types pointeur et procédure. Les relations <= et> = dénotent une inclusion lorsqu'elles sont appliquées à des ensembles.

x IN s signifie "x est un élément de s". x doit être de type INTEGER et s de type SET. v IS T signifie "v est de type T" et s'appelle un test de type. C'est applicable, si

  1. T est une extension du type déclaré T0 de v, et si
  2. v est un paramètre variable du type d'enregistrement ou v est un pointeur.

En supposant, par exemple, que T est une extension de T0 et que v soit un désignateur déclaré de type T0, alors le test v IS T détermine si la variable effectivement désignée est (non seulement un T0, mais aussi) un T. La valeur de NIL IS T est indéfini.

Exemples d'expressions (voir les exemples dans le chapitre 7):

1987 (ENTIER)

i DIV 3 (INTEGER)

~ p OU q (BOOLEAN)

(i + j) * (i-j) (INTEGER)

s - {8, 9, 13} (SET)

a [i + j] * a [i-j] (REEL)

(0 <= i) & (i <100) (BOOLÉEN)

t.key = 0 (BOOLEAN)

k IN {i .. j-1} (BOOLÉEN)

t IS CenterNode (BOOLEAN)

  1. Déclarations

Les déclarations dénotent des actions. Il y a des énoncés élémentaires et structurés. Les instructions élémentaires ne sont pas composées de parties qui sont elles-mêmes des instructions. Ils sont l'appel et l'appel de procédure. Les instructions structurées sont composées de parties qui sont elles-mêmes des instructions. Ils sont utilisés pour exprimer le séquençage et l'exécution conditionnelle, sélective et répétitive. Une déclaration peut également être vide, auquel cas elle ne dénote aucune action. L'instruction vide est incluse afin d'assouplir les règles de ponctuation dans les séquences d'instructions.

statement = [affectation | ProcedureCall | IfStatement | CaseStatement | WhileStatement | RepeatStatement | ForStatement].


177