Article de reference

Syntaxe (langages de programmation)

Ce code Python est présenté avec une coloration qui met en évidence les aspects syntaxiques. La syntaxe du code source informatique est un code structuré et ordonné, soumis aux ...

Ce code Python est présenté avec une coloration qui met en évidence les aspects syntaxiques.

La syntaxe du code source informatique est un code structuré et ordonné, soumis aux règles du langage informatique. À l'instar d'une langue naturelle , un langage informatique (c'est-à-dire un langage de programmation ) définit la syntaxe valide pour ce langage. Une erreur de syntaxe se produit lorsqu'un code source syntaxiquement invalide est traité par un outil tel qu'un compilateur ou un interpréteur .

Les langages les plus couramment utilisés sont textuels et leur syntaxe repose sur des chaînes de caractères . À l'inverse, la syntaxe d'un langage de programmation visuel est basée sur les relations entre des éléments graphiques.

Lors de la conception de la syntaxe d'un langage, un concepteur peut commencer par écrire des exemples de chaînes valides et invalides , avant de tenter de dégager les règles générales à partir de ces exemples. Ainsi, la structure générale de la syntaxe peut être déterminée par sa forme de composition, afin de produire systématiquement des plages sémantiquement valides pour chaque modification possible. Sinon, le langage renvoie des erreurs et des avertissements pour chaque entrée invalide.

des jetons ;
  • Les syntagmes – le niveau grammatical, au sens strict, qui détermine comment les éléments forment des syntagmes ;
  • Contexte – déterminer à quels objets ou noms de variables font référence, si les types sont valides, etc.
  • Cette distinction permet d'obtenir une modularité, autorisant la description et le traitement de chaque niveau séparément et souvent indépendamment.

    Tout d’abord, un analyseur lexical transforme la séquence linéaire de caractères en une séquence linéaire de jetons ; c’est ce qu’on appelle « l’analyse lexicale » ou « l’analyse lexicale ».

    Deuxièmement, l'analyseur syntaxique transforme la séquence linéaire de jetons en un arbre syntaxique hiérarchique ; c'est ce qu'on appelle, au sens strict, « l'analyse syntaxique ». Cela garantit que la séquence de jetons respecte les grammaires formelles du langage de programmation. L'étape d'analyse syntaxique se divise en deux parties : l' arbre d'analyse , ou « arbre syntaxique concret », déterminé par la grammaire, mais généralement trop détaillé pour une utilisation pratique, et l' arbre syntaxique abstrait (AST), qui le simplifie en une forme utilisable. Les étapes d'AST et d'analyse contextuelle peuvent être considérées comme une forme d' analyse sémantique , car elles ajoutent du sens et une interprétation à la syntaxe, ou encore comme des implémentations informelles et manuelles de règles syntaxiques qu'il serait difficile, voire complexe, de décrire ou d'implémenter formellement.

    Troisièmement, l'analyse contextuelle résout les noms et vérifie les types. Cette modularité est parfois possible, mais dans de nombreux langages réels, une étape antérieure dépend d'une étape ultérieure ; par exemple, l'astuce du lexer en C est due au fait que la tokenisation dépend du contexte. Même dans ces cas, l'analyse syntaxique est souvent considérée comme une approximation de ce modèle idéal.

    Les niveaux correspondent généralement aux niveaux de la hiérarchie de Chomsky . Les mots appartiennent à un langage régulier , spécifié par la grammaire lexicale (une grammaire de type 3), généralement exprimée sous forme d'expressions régulières . Les syntagmes appartiennent à un langage hors contexte (LHC), généralement un langage hors contexte déterministe (LHCD), spécifié par une grammaire de structure de syntagme (une grammaire de type 2), généralement exprimée sous forme de règles de production en notation BNF (Backus-Naur ). Les grammaires de syntagmes sont souvent spécifiées par des grammaires beaucoup plus contraintes que les grammaires hors contexte complètes , afin de faciliter leur analyse syntaxique. Si l' analyseur LR peut analyser n'importe quel LHCD en temps linéaire, les analyseurs LALR et LL, plus simples , sont plus efficaces, mais ne peuvent analyser que les grammaires dont les règles de production sont contraintes. En principe, la structure contextuelle peut être décrite par une grammaire sensible au contexte et analysée automatiquement par des moyens tels que les grammaires d'attributs ; toutefois, en général, cette étape est effectuée manuellement, via des règles de résolution de noms et de vérification de types , et mise en œuvre via une table de symboles qui stocke les noms et les types pour chaque portée.

    Des outils ont été développés pour générer automatiquement un analyseur lexical à partir d'une spécification lexicale écrite en expressions régulières et un analyseur syntaxique à partir de la grammaire de syntagmes écrite en BNF : cela permet d'utiliser la programmation déclarative , sans avoir recours à la programmation procédurale ou fonctionnelle . Un exemple notable est la paire lex - yacc . Ces outils produisent automatiquement un arbre syntaxique concret ; le développeur de l'analyseur syntaxique doit ensuite écrire manuellement le code décrivant sa conversion en un arbre syntaxique abstrait . L'analyse contextuelle est également généralement implémentée manuellement. Malgré l'existence de ces outils automatiques, l'analyse syntaxique est souvent implémentée manuellement pour diverses raisons : la structure des syntagmes n'est peut-être pas indépendante du contexte, une autre implémentation améliore les performances ou la gestion des erreurs, ou permet de modifier plus facilement la grammaire. Les analyseurs syntaxiques sont souvent écrits dans des langages de programmation fonctionnelle, tels que Haskell , ou dans des langages de script , tels que Python ou Perl , ou encore dans des langages de programmation impérative, tels que C ou C++ .

    Définition de la syntaxe

    Arbre d'analyse syntaxique du code Python avec tokenisation par insertion

    La syntaxe des langages de programmation textuels est généralement définie par une combinaison d' expressions régulières (pour la structure lexicale ) et de formes de Backus-Naur (un métalangage pour la structure grammaticale ) afin de spécifier inductivement les catégories syntaxiques ( non-terminaux ) et les symboles terminaux . Les catégories syntaxiques sont définies par des règles appelées productions , qui spécifient les valeurs appartenant à une catégorie syntaxique particulière. Les symboles terminaux sont les caractères concrets ou les chaînes de caractères (par exemple , les mots-clés tels que `define` , `if` , `let` ou `void` ) à partir desquels sont construits des programmes syntaxiquement valides.

    La syntaxe peut être divisée en syntaxe hors contexte et syntaxe sensible au contexte. La syntaxe hors contexte est constituée de règles dictées par le métalangage du langage de programmation. Ces règles ne sont pas contraintes par le contexte qui les entoure ou auquel elles font référence, contrairement à la syntaxe sensible au contexte.

    Une langue peut avoir différentes grammaires équivalentes, telles que des expressions régulières équivalentes (au niveau lexical), ou différentes règles de syntagme générant le même langage. L'utilisation d'une catégorie de grammaires plus large, comme les grammaires LR, permet d'obtenir des grammaires plus courtes ou plus simples que des catégories plus restreintes, comme les grammaires LL, qui peuvent nécessiter des grammaires plus longues et comportant davantage de règles. Des grammaires de syntagme différentes mais équivalentes produisent des arbres d'analyse syntaxique différents, bien que le langage sous-jacent (l'ensemble des documents valides) soit le même.

    Exemple : Expressions S Lisp

    Voici une grammaire simple, définie à l'aide de la notation des expressions régulières et de la forme étendue de Backus-Naur . Elle décrit la syntaxe des S-expressions , une syntaxe de données du langage de programmation Lisp , qui définit des productions pour les catégories syntaxiques expression , atome , nombre , symbole et liste :

    hiérarchie de Chomsky . La grammaire de syntagme de la plupart des langages de programmation peut être spécifiée à l'aide d'une grammaire de type 2, c'est-à - dire une grammaire hors contexte , bien que la syntaxe globale soit sensible au contexte (en raison des déclarations de variables et des portées imbriquées), d'où le type 1. Cependant, il existe des exceptions, et pour certains langages, la grammaire de syntagme est de type 0 (Turing-complète).

    Dans certains langages comme Perl et Lisp, la spécification (ou l'implémentation) autorise des constructions qui s'exécutent pendant la phase d'analyse syntaxique. De plus, ces langages possèdent des constructions permettant au programmeur de modifier le comportement de l'analyseur syntaxique. Cette combinaison brouille la frontière entre analyse et exécution, et rend l'analyse syntaxique indécidable dans ces langages, ce qui signifie que la phase d'analyse syntaxique peut ne pas se terminer. Par exemple, en Perl, il est possible d'exécuter du code pendant l'analyse syntaxique à l'aide d'une BEGINinstruction `catch`, et les prototypes de fonctions Perl peuvent modifier l'interprétation syntaxique, voire la validité syntaxique du reste du code. On dit couramment que « seul Perl peut analyser du Perl » (car du code doit être exécuté pendant l'analyse et peut modifier la grammaire), ou plus catégoriquement « même Perl ne peut pas analyser du Perl » (car le problème est indécidable). De même, les macros Lisp introduites par la defmacrosyntaxe s'exécutent également lors de l'analyse syntaxique, ce qui signifie qu'un compilateur Lisp doit disposer d'un système d'exécution Lisp complet. En revanche, les macros C ne sont que des remplacements de chaînes de caractères et ne nécessitent pas l'exécution de code.

    Syntaxe versus sémantique

    La syntaxe d'un langage décrit la forme d'un programme valide, mais ne fournit aucune information sur sa signification ni sur les résultats de son exécution. La signification attribuée à une combinaison de symboles est gérée par la sémantique ( formelle ou codée en dur dans une implémentation de référence ). Une syntaxe valide doit être établie avant que la sémantique puisse en extraire le sens. Tous les programmes syntaxiquement corrects ne sont pas sémantiquement corrects. Nombre d'entre eux, bien que syntaxiquement corrects, sont néanmoins mal formés, selon les règles du langage ; et peuvent (en fonction de la spécification du langage et de la robustesse de l'implémentation) entraîner une erreur de traduction ou d'exécution. Dans certains cas, de tels programmes peuvent présenter un comportement indéfini . Même lorsqu'un programme est bien défini au sein d'un langage, il peut néanmoins avoir une signification non voulue par son auteur.

    Prenons l'exemple du langage naturel : il peut être impossible d'attribuer une signification à une phrase grammaticalement correcte, ou la phrase peut être fausse.

    • « Des idées vertes incolores dorment furieusement . » est grammaticalement correct, mais n'a pas de signification généralement acceptée.
    • « John est un célibataire marié. » est grammaticalement correct, mais exprime une idée qui ne peut être vraie.

    Le fragment de code C suivant est syntaxiquement correct, mais effectue une opération qui n'est pas définie sémantiquement (car ` pointeur nul , les opérations `and` et `nil` n'ont aucun sens) :real"},"parts":[{"template":{"target":{"wt":"code","href":"./Template:Code"},"params":{"lang":{"wt":"c"},"1":{"wt":"p->real"}},"i":0}}] p->realim"},"parts":[{"template":{"target":{"wt":"code","href":"./Template:Code"},"params":{"lang":{"wt":"c"},"1":{"wt":"p->im"}},"i":0}}] p->im

    real * p->real + p->im * p->im); "
    complexe * p = NULL ; complexe abs_p = sqrt ( p -> réel * p -> réel + p -> im * p -> im );

    À titre d'exemple plus simple,

    , x );

    Cette instruction est syntaxiquement valide, mais non définie sémantiquement, car elle utilise une variable non initialisée . Bien que les compilateurs de certains langages de programmation (par exemple, Java et C#) détectent ce type d'erreur de variable non initialisée, il convient de la considérer comme une erreur sémantique plutôt que comme une erreur de syntaxe.

    Plus d articles de Worldlex Wiki

    Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

    Explorer l index