La syntaxe

par Tom
le 31/01/2020

Préambule

Cet article est un bref résumé de la syntaxe formelle du Java, du C, et plus généralement de la plupart des langages de la famille du C.

Dans un langage de programmation typique, on trouve plusieurs catégories d'éléments constitutifs :

  • les blocs (ex: if, for, do, while, fonctions, structures, classes, ...)
  • les instructions (ex: System.out.println("bonjour");)
  • les expressions (ex: 2 + x, acos(0.5) * sqrt(rand()))

Ainsi, un programme typique en C ressemble à ça :

// directives de préprocesseur éventuelles

déclaration (globale)

déclaration (fonction)

déclaration (fonction)

déclaration (fonction)

Le fait de définir formellement le langage permet de mieux comprendre les programmes, car cela aide à les lire "comme" le fait le compilateur.

Définitions

Note : un terme écrit

  • [ entre crochets ] est optionnel.
  • en gras italique est "fixe", c'est-à-dire qu'il fait partie de la définition et ne change jamais. Par exemple, + signifie toujours addition car il est "défini" comme tel.

Nom

Un nom est une suite de caractères pouvant être :

  • des lettres (A-Z, a-z)
  • des tirets bas (_)
  • des chiffres (0-9)

Seule exception : un nom ne peut pas commencer par un chiffre.


Expression

Une expression est :

  • un litéral de nombre
    • décimal : 10
    • hexadécimal : 0xFF
    • octal : 0755
    • flottant : 3.1415 ou 2.99e8
  • un litéral de caractère : 'A'
  • un litéral de chaîne : "bonjour"
  • [C#, Java] un booléen : true ou false
  • une opération
  • un appel de fonction
  • un accès
  • [C#, Java] une instanciation
  • une affectation
  • une conversion de type

Une expression, comme en mathématiques, possède une valeur. Cette valeur, bien évidemment, a un type.

Exemples :

  • 2 + 3 est une opération composée de 2 et 3, chacun de type int. Le résultat est également de type int.
  • cos(x) est définie ainsi : double cos(double x);. Ainsi, cos(5) est de type double.

Opération

Une opération est :

  • une opération unaire : OP_UNAIRE expr
  • une opération binaire : expr1 OP_BINAIRE expr2
  • un opérateur ternaire : expr_condition ? expr_si_vrai : expr_si_faux

OP_UNAIRE :

  • négation numérique : -
  • négation logique : !
  • négation binaire : ~
  • [C, C#] déréférencement de pointeur : *

OP_BINAIRE :

  • arithmétique : +, -, *, / (division entière), % (reste)
  • logique : &&, ||
  • comparaison : ==, !=, <, <=, >, >=
  • binaire : &, |, ^

Type de retour : dépend des types des différents termes.

Pour les opérations numériques, c'est généralement le type le plus "large" :

  • int + floatfloat, car float a un domaine plus grand qu'int
  • float + doubledouble, pour la même raison

Les opérateurs de comparaison renvoient toujours un type booléen s'il existe (Java, C#, mais pas C) sinon quoi il renvoie une valeur numérique vraie ou fausse (généralement 1 ou 0).

[C, C#] Dans le cas d'un déréférencement, l'opération renvoie une valeur du type de celle pointée par le pointeur. Exemple:

  • *ptr avec int* ptr;int
  • **p avec char*** p;char*

Liste de paramètres

Une liste de paramètres se note : expr1 , expr2 , ...

Ce n'est pas un type d'expression, mais je le note séparément pour simplifier la suite.


Appel de fonction

Un appel de fonction est : accès ( [ liste_paramètres ] )

Note : en C, une fonction est toujours globale, donc l'accès ne peut pas être un accès membre.

Type de retour : identique à celui de la déclaration d'accès.

Important : si la fonction est déclarée comme renvoyant void, alors un appel de cette dernière n'est pas une expression, car il n'aurait pas de valeur.


Accès

Un accès est : [ expr . ] nom

Exemples :

  • x est un accès de variable
  • pers1.prenom est un accès de membre

Type de retour : identique à la définition de nom.


[C#, Java] Instanciation

Une instanciation se note new accès ( [ liste_paramètres ] )

Important : l'accès doit être de type classe.

Type de retour : identique à celui d'accès.


Affectation

Une affectation se note accès = expr.

Type de retour : identique à celui d'accès.

Important : on ne peut pas affecter de valeur à tout et n'importe quoi. accès doit être ce qu'on appelle une lvalue, c'est-à-dire une "valeur affectable". Types possibles :

  • variable
  • membre/attribut d'une structure ou d'une classe
  • [C#] propriété possédant un setter
  • [C, C#] déréférencement d'un pointeur

Conversion de type

Une conversion de type se note ( accès ) expr.

Conditions : accès doit être un type.

  • [C] : type primitif, type tableau, type pointeur ou type pointeur de fonction
  • [C#, Java] : type instanciable quelconque

Type de retour : accès.

Important :

  • [C#, Java] si expr ne peut pas être converti en accès, une exception sera produite.

[C#, Java] Modificateurs d'accès

Ils permettent de définir les modalités d'accès à un attribut, une fonction ou une classe.

Il en existe plusieurs :

[C#]
public internal protected private
Classe mère
Classes filles (même projet)
Classes différentes (même projet)
Tout le reste
[Java]
public protected default private
Classe mère
Classes filles (même projet)
Classes différentes (même projet)
Classes filles (autre projet)
Classes différentes (autre projet)

Globalement, seuls public et private sont essentiels à retenir.

Déclaration

Une déclaration est :

  • [C] une variable globale / [C#, Java] attribut
  • une fonction
  • [C#, Java] une classe
  • [C#, Java] une interface

[C] Variable globale

Syntaxe : [ static ] accès nom [ = expr ];

static signifie que la variable globale n'existe que dans le fichier .C en question.

[C#, Java] Attribut

Syntaxe : [ modif_accès ] [ static ] accès nom [ = expr ];

static signifie que l'attribut est accessible sans passer par une instance de la classe.

[C#, Java] Classe

Syntaxe : [ modif_accès ] class nom [ extends accès ] [ implements accès ]

Important : modif_accès ne peut être que vide, public ou internal (en C#).

Note : En C#, une classe peut être marquée static mais cela sort du cadre de ce cours.

[C#, Java] Interface

Syntaxe : [ modif_accès ] interface nom

Important : modif_accès ne peut être que vide, public ou internal (en C#).

Exemples

Note : sur les schémas j'ai noté dans deux couleurs différentes les accès directs et les accès de membres pour faciliter la lecture.