déclarations de fichier de grammaire yacc

La section des déclarations du fichier de grammaire yacc contient les éléments suivants:

  • Déclarations pour toutes les variables ou constantes utilisées dans d'autres parties du fichier de grammaire
  • #incluez des instructions pour utiliser d'autres fichiers dans ce fichier (utilisés pour les fichiers d'en-tête de bibliothèque)
  • Instructions qui définissent les conditions de traitement de l'analyseur syntaxique généré

Vous pouvez conserver les informations sémantiques associées aux jetons qui se trouvent actuellement dans la pile d'analyse dans une unionde langage C définie par l'utilisateur, si les membres de l'union sont associés aux différents noms dans le fichier de grammaire.

Une déclaration pour une variable ou une constante utilise la syntaxe suivante du langage de programmation C:
TypeSpecifier Declarator ;

TypeSpecifier est un mot clé de type de données et Declarator est le nom de la variable ou de la constante. Les noms peuvent être de n'importe quelle longueur et se composer de lettres, de points, de traits de soulignement et de chiffres. Un nom ne peut pas commencer par un chiffre. Les majuscules et les minuscules sont distinctes.

Les noms de terminal (ou de jeton) peuvent être déclarés à l'aide du%La déclaration token et les noms non terminaux peuvent être déclarés à l'aide de la%Déclaration type . :NONE.%La déclaration type n'est pas requise pour les noms non terminaux. Les noms non terminaux sont définis automatiquement s'ils apparaissent dans la partie gauche d'au moins une règle. Sans déclarer de nom dans la section des déclarations, vous ne pouvez utiliser ce nom qu'en tant que symbole non terminal. :NONE.#Les instructions include sont identiques à la syntaxe du langage C et exécutent la même fonction.

Le programme yacc comporte un ensemble de mots clés qui définissent les conditions de traitement de l'analyseur syntaxique généré. Chacun des mots clés commence par un%(signe de pourcentage), qui est suivi d'un jeton ou d'un nom non terminal. Ces mots clés sont les suivants:

Mot clé Descriptif
%à prendre Identifie les jetons qui sont associatifs à gauche avec d'autres jetons.

%non assoc Identifie les jetons qui ne sont pas associés à d'autres jetons.

%droit Identifie les jetons qui sont associatifs avec d'autres jetons.

%DÉBUT Identifie un nom non terminal pour le symbole de début.

%jeton Identifie les noms de jeton acceptés par la commande yacc . Déclare tous les noms de jeton dans la section des déclarations.

%type Identifie le type de non-terminaux. La vérification du type est effectuée lorsque cette construction est présente.

%union Identifie la pile de valeurs yacc comme l'union des différents types de valeurs souhaités. Par défaut, les valeurs renvoyées sont des entiers. Cette construction a pour effet de fournir la déclaration de YYSTYPE directement à partir de l'entrée.

%{
Code
%}
Copie le Code spécifié dans le fichier de code. Cette construction peut être utilisée pour ajouter des déclarations et des définitions de langage C à la section des déclarations.
Remarque:%{(signe de pourcentage, crochet gauche) et%}(signe pourcentage, crochet droit) les symboles doivent apparaître sur les lignes par eux-mêmes.
:NONE.%jeton,%gauche,%droite, et%Les mots clés nonassoc prennent éventuellement en charge le nom d'un membre de l'union C (tel que défini par%union) appelée<Balise>(les crochets d'angle littéraux entourant le nom d'un membre de l'union). :NONE.%Le mot clé type requiert un<Balise>. L'utilisation de<Balise>indique que les jetons nommés sur la ligne doivent être du même type C que le membre de l'union référencé par<Balise>. Par exemple, la déclaration suivante déclare que le paramètre Name est un jeton:
%token [<Tag>] Name [Number] [Name [Number]]...

Plus<Balise>est présent, le type C pour tous les jetons sur cette ligne sont déclarés comme étant du type référencé par<Balise>. Si un entier positif, Nombre, suit le paramètre Nom , cette valeur est affectée au jeton.

Tous les jetons sur la même ligne ont le même niveau de priorité et la même associativité. Les lignes apparaissent dans le fichier par ordre croissant de priorité ou de force de liaison. Par exemple, ce qui suit décrit la priorité et l'associativité des quatre opérateurs arithmétiques:
%left '+' '-'
%left '*' '/'

:NONE.+(signe plus) et-(signe moins) sont associatifs de gauche et ont une priorité plus faible que*(astérisque) et/(barre oblique), qui sont également associatives à gauche.

Définition de variables globales

Pour définir les variables à utiliser par certaines ou toutes les actions, ainsi que par l'analyseur lexical, placez les déclarations de ces variables entre%{(signe de pourcentage, crochet gauche) et%}(signe de pourcentage, crochet droit). Les déclarations contenues dans ces symboles sont appelées variables globales. Par exemple, pour rendre la variable var disponible pour toutes les parties du programme complet, utilisez l'entrée suivante dans la section des déclarations du fichier de grammaire:

%{
int var = 0;
%}

Conditions de démarrage

L'analyseur syntaxique reconnaît un symbole spécial appelé start . Le symbole de début est le nom de la règle dans la section des règles du fichier de grammaire qui décrit la structure la plus générale du langage à analyser. Etant donné qu'il s'agit de la structure la plus générale, l'analyseur syntaxique démarre dans son analyse descendante du flux d'entrée à ce stade. Déclarez le symbole de début dans la section des déclarations à l'aide du%Mot clé start . Si vous ne déclarez pas le nom du symbole de début, l'analyseur syntaxique utilise le nom de la première règle de grammaire dans le fichier de grammaire.

Par exemple, lors de l'analyse syntaxique d'une fonction de langage C, la structure la plus générale à reconnaître par l'analyseur syntaxique est la suivante:
main()
{
        code_segment
}

Le symbole de début pointe vers la règle qui décrit cette structure. Toutes les règles restantes dans le fichier décrivent les moyens d'identifier les structures de niveau inférieur au sein de la fonction.

Numéros de jeton

Les numéros de jeton sont des entiers non négatifs qui représentent les noms des jetons. Si l'analyseur lexical transmet le numéro de jeton à l'analyseur syntaxique, au lieu du nom de jeton réel, les deux programmes doivent s'accorder sur les numéros attribués aux jetons.

Vous pouvez affecter des numéros aux jetons utilisés dans le fichier de grammaire yacc . Si vous n'affectez pas de numéros aux jetons, le fichier de grammaire yacc affecte des numéros en utilisant les règles suivantes:
  • Un caractère littéral est la valeur numérique du caractère du jeu de caractères ASCII.
  • Les autres noms se voient attribuer des numéros de jeton à partir de 257.
    Remarque: n'affectez pas le numéro de jeton 0. Ce numéro est affecté au jeton endmarker. Vous ne pouvez pas le redéfinir.

Pour affecter un nombre à un jeton (y compris les littéraux) dans la section des déclarations du fichier de grammaire, placez un entier positif (différent de 0) immédiatement après le nom du jeton dans le%tokenligne. Cet entier est le numéro de jeton du nom ou du littéral. Chaque numéro de jeton doit être unique. Tous les analyseurs lexicaux utilisés avec la commande yacc doivent renvoyer une valeur nulle ou négative pour un jeton lorsqu'ils atteignent la fin de leur entrée.