Syntaxe sommaire du langage Oz

Cette page donne un aperçu rapide de la syntaxe du langage Oz. La syntaxe présentée n'est pas complète, mais elle décrit la partie du langage utilisée dans ce cours.

Conventions

La grammaire décrite sur cette page utilise les notations suivantes. Pour faciliter la lecture, les symboles grammaticaux sont en italique et en gras, tandis que les symboles du langage Oz (mots-clés et opérateurs) sont en style télétype.

Notation Signification
w1 w2 concaténation de w1 avec w2
w1 | w2 choix entre w1 et w2
( w ) groupe d'expressions régulières
[ w ] expression w en option (zéro ou une fois)
{ w } expression w zéro, une ou plusieurs fois
{ w }+ expression w une ou plusieurs fois

Lexique du langage

Le lexique définit les identificateurs et les constantes écrites dans un programme Oz.

Règle Exemples
<variable> ::= <upper-case letter> {<alphanumerical>} X   Ma_variable Agent007
| ` {<character>} ` `ceci est une variable`
<atom> ::= <lower-case letter> {<alphanumerical>} f   mon_Atome agent007
| ' {<character>} ' 'ceci est un atome'
<integer> ::= [~] ( 0 | <non-zero digit> {<digit>} ) 42   ~17
<float> ::= [~] {<digit>}+. {<digit>} [ (e | E) [~] {<digit>}+ ]       3.14   6.67e~11   ~17.
<string> ::= " {<character>} " "ceci est un string"
<oz character> ::= & <character> &a = 97

Voici la liste des mots-clés et des opérateurs. Pour utiliser un mot-clé comme atome, il faut le mettre entre apostrophes, comme 'fun'.

andthen at attr case catch choice class cond declare define dis div do else elsecase elseif end export fail false feat finally for from fun functor if import in local lock meth mod not of or orelse prepare proc prop raise require self skip then thread true try unit ( ) [ ] { } | # : ... = . := ^ [] $ ! _ ~ + - * / @ <- , !! <= == \= < =< > >= =: \=: <: =<: >: >=: :: :::
Soyez prudent avec les mots-clés, ils peuvent avoir un sens différent de celui auquel vous pensez!

Instructions

Voici les définitions principales pour les instructions de base du langage.

<statement> ::= skip
| <statement> <statement>
| <variable> = <expression>
| ( <in statement> )   |   local {<declaration>}+ in <statement> end
| if <expression> then <in statement>
{ elseif <expression> then <in statement> }
[ else <in statement> ]
end
| case <expression>
of <pattern> [ andthen <expression> ] then <in statement>
{ [] <pattern> [ andthen <expression> ] then <in statement> }
[ else <in statement> ]
end
| {<expression>   {<expression>} }
| proc {<variable>   {<pattern>} } <in statement> end
| fun {<variable>   {<pattern>} } <in expression> end
| <exception statement>   |   <stateful statement>   |   <functor statement>
<in statement> ::= [ {<declaration>}+ in ] <statement>
<declaration> ::= <variable>   |   <pattern> = <expression>   |   <statement>

Les instructions compilables dans l'environnement de développement ont la syntaxe suivante:

<interactive statement> ::= <statement>
| declare {<declaration>}+ [in <statement>]

Expressions

Voici les définitions principales pour les expressions de base du langage.

<expression> ::= <variable>   |   _
| <data expression>
| <unary operator> <expression>
| <expression> <binary operator> <expression>
| ( <in expression> )
| local {<declaration>}+ in [<statement>] <expression> end
| if <expression> then <in expression>
{ elseif <expression> then <in expression> }
[ else <in expression> ]
end
| case <expression>
of <pattern> [ andthen <expression> ] then <in expression>
{ [] <pattern> [ andthen <expression> ] then <in expression> }
[ else <in expression> ]
end
| { <expression>   {<expression>} }
| proc {$   {<pattern>} } <in statement> end
| fun {$   {<pattern>} } <in expression> end
| <exception expression>   |   <stateful expression>   |   <functor expression>
<in expression> ::= [ {<declaration>}+ in ] [<statement>] <expression>
<unary operator> ::= ~
<binary operator> ::= . | + | - | * | / | div | mod | == | \= | < | =< | > | >= | andthen | orelse

Les priorités des opérateurs sont spécifiées ci-dessous.

Structures de données et patterns

Les expressions suivantes et les patterns décrivent des structures de données. C'est pour cela qu'ils sont groupés ici.

<data expression> ::= <atom> | <integer> | <float> | <string> | <oz character> | true | false | unit
| <label> ( { [<feature> :] <expression> } )
| <expression>|<expression>   |   <expression> {#<expression>}+   |   [ {<expression>}+ ]
<pattern> ::= <variable>   |   _
| <atom> | <integer> | <float> | <string> | <oz character> | true | false | unit
| <label> ( { [<feature> :] <pattern> }   [...] )
| <pattern>|<pattern>   |   <pattern> {#<pattern>}+   |   [ {<pattern>}+ ]
| ( <pattern> )
<label> ::= <atom> | true | false | unit
<feature> ::= <atom> | <integer> | true | false | unit

Exceptions

<exception statement> ::= try <in statement>
[ catch <pattern> then <in statement>
 { [] <pattern> then <in statement> } ]
[ finally <in statement> ]
end
| raise <in expression> end
<exception expression> ::= try <in expression>
[ catch <pattern> then <in expression>
 { [] <pattern> then <in expression> } ]
[ finally <in statement> ]
end
| raise <in expression> end

L'état et les classes

<stateful statement> ::= <expression> := <expression>   |   <expression>,<expression>
| class <variable>
{ <class descriptor> }
{ <method> }
end
<stateful expression> ::= {NewCell <expression>}   |   @<expression>   |   self
| class [$]
{ <class descriptor> }
{ <method> }
end
<class descriptor> ::= from {<expression>}+   |   attr {<feature>}+
<method> ::= meth <method head> <in statement> end
<method head> ::= <label> ( { [<feature> :] <variable> [<= <expression>] }   [...] )

L'appel de méthode sur un objet est une instruction dont la syntaxe correspond à un appel de procédure. Pour en faire une instruction, il faut remplacer un des champs de la méthode par $. Ainsi, les deux instructions suivantes sont équivalentes.

    {Objet methode(X Y)}

    Y = {Objet methode(X $)}

Foncteurs

<functor statement> ::= functor <variable>
[ import { <variable>   [at <atom>] }+ ]
[ export { [<feature>:] <variable> }+ ]
define {<declaration>}+ [in <statement>]
end
<functor expression> ::= functor [$]
[ import { <variable>   [at <atom>] }+ ]
[ export { [<feature>:] <variable> }+ ]
define {<declaration>}+ [in <statement>]
end

Priorités et associativités des opérateurs

Les différents opérateurs utilisés dans Oz sont repris ci-dessous, dans l'ordre décroissant des priorités. Les priorités indiquent, par exemple, que X.1+2 doit se lire (X.1)+2. La direction de l'associativité permet, quant à elle, de lire 1+2+3 comme (1+2)+3 (grouper par la gauche), et 1|2|3 comme 1|(2|3) (grouper par la droite).

Opérateurs Associativité
@ à gauche
. à gauche
~ à gauche
, à droite
* / div mod à gauche
+ - à gauche
# multifixe
| à droite
== \= < =< > >= aucune
andthen à droite
orelse à droite
:= à droite

Raphaël Collet - 20 septembre 2005