Englishfrançaisespagnol

Icône de favori OnWorks

jambe - En ligne dans le Cloud

Exécutez la jambe dans le fournisseur d'hébergement gratuit OnWorks sur Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

Il s'agit de la branche de commande qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos multiples postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

PROGRAMME:

Nom


peg, leg - générateurs d'analyseur syntaxique

SYNOPSIS


cheville [-hvV -sortie] [nom de fichier ...]
jambe [-hvV -sortie] [nom de fichier ...]

DESCRIPTION


cheville et jambe sont des outils pour générer des parseurs à descente récursive : des programmes qui
correspondance de motif sur le texte. Ils traitent une grammaire d'expression d'analyse (PEG) [Ford 2004] pour
produire un programme qui reconnaît les phrases légales de cette grammaire. cheville traite les PEG
écrit en utilisant la syntaxe originale décrite par Ford ; jambe traite les PEG écrits en utilisant
syntaxe et conventions légèrement différentes qui visent à en faire un
remplacement des parseurs construits avec lexde Géographie (1) et avec la yacc(1). contrairement à lex et yacc, cheville et jambe
prendre en charge un retour en arrière illimité, fournir un choix ordonné comme moyen de désambiguïsation, et
peut combiner l'analyse (analyse lexicale) et l'analyse (analyse syntaxique) en un seul
activité.

cheville lit le spécifié nom de fichiers, ou entrée standard si non nom de fichiers sont donnés, pour un
grammaire décrivant l'analyseur à générer. cheville génère ensuite un fichier source C qui
définit une fonction yyparse(). Ce fichier source C peut être inclus ou compilé puis
lié avec, un programme client. Chaque fois que le programme client appelle yyparser() l'analyseur
consomme le texte d'entrée selon les règles d'analyse, à partir de la première règle dans le
grammaire. yyparser() renvoie une valeur non nulle si l'entrée a pu être analysée selon le
grammaire; il renvoie zéro si l'entrée n'a pas pu être analysée.

Le préfixe « yy » ou « YY » est ajouté à tous les symboles visibles de l'extérieur dans le fichier généré.
analyseur. Ceci est destiné à réduire le risque de pollution de l'espace de noms dans les programmes clients.
(Le choix de 'yy' est historique ; voir lexde Géographie (1) et avec la yacc(1), par exemple.)

OPTIONS


cheville et jambe proposer les options suivantes :

-h imprime un résumé des options disponibles, puis quitte.

-sortie
écrit l'analyseur généré dans le fichier sortie au lieu de la sortie standard.

-v écrit des informations détaillées sur l'erreur standard tout en travaillant.

-V écrit les informations de version dans l'erreur standard puis se ferme.

A SIMPLE EXEMPLE


cheville input spécifie une grammaire avec une seule règle (appelée 'start') qui est
satisfait lorsque l'entrée contient la chaîne "username".

démarrer <- "nom d'utilisateur"

(Les guillemets sont pas partie du texte correspondant ; ils servent à indiquer un littéral
chaîne à rechercher.) En d'autres termes, yyparser() dans la source C générée renverra
différent de zéro uniquement si les huit prochains caractères lus à partir de l'entrée épellent le mot « nom d'utilisateur ».
Si l'entrée contient autre chose, yyparser() renvoie zéro et aucune entrée n'aura été
consommé. (Appels ultérieurs à yyparser() renverra également zéro, puisque l'analyseur est
effectivement bloqué à la recherche de la chaîne "nom d'utilisateur".) Pour assurer la progression, nous pouvons ajouter un
clause alternative à la règle 'start' qui correspondra à n'importe quel caractère si "username"
n'est pas trouvé.

démarrer <- "nom d'utilisateur"
/.

yyparser() renvoie désormais toujours une valeur non nulle (sauf à la toute fin de l'entrée). À faire
quelque chose d'utile, nous pouvons ajouter des actions aux règles. Ces actions sont effectuées après un
correspondance complète est trouvée (à partir de la première règle) et sont choisis en fonction de la
« chemin » pris à travers la grammaire pour correspondre à l'entrée. (Les linguistes appelleraient ce chemin un
'marqueur de phrase'.)

start <- "username" { printf("%s\n", getlogin()); }
/ < . > { putchar(yytext[0]); }

La première ligne indique à l'analyseur d'imprimer le nom de connexion de l'utilisateur chaque fois qu'il voit
"nom d'utilisateur" dans l'entrée. Si cette correspondance échoue, la deuxième ligne indique à l'analyseur de faire écho
le caractère suivant sur l'entrée la sortie standard. Notre analyseur exécute maintenant utile
work : il copiera l'entrée dans la sortie, en remplaçant toutes les occurrences de "nom d'utilisateur" par
le nom de compte de l'utilisateur.

Notez les crochets angulaires ('<' et '>') qui ont été ajoutés à la deuxième alternative. Ces
n'ont aucune incidence sur le sens de la règle, mais servent à délimiter le texte mis à la disposition des
l'action suivante dans la variable yytexte.

Si la grammaire ci-dessus est placée dans le fichier nom d'utilisateur.peg, en exécutant la commande

peg -o nom d'utilisateur.c nom d'utilisateur.peg

enregistrera l'analyseur correspondant dans le fichier nom d'utilisateur.c. Pour créer un programme complet
cet analyseur syntaxique pourrait être inclus par un programme C comme suit.

#comprendre /* printf(), putchar() */
#comprendre /* se connecter() */

#include "nom d'utilisateur.c" /* yyparse() */

int main ()
{
while (yyparse()) /* répéter jusqu'à EOF */
;
0 revenir;
}

PEG GRAMMAIRES


Une grammaire est constituée d'un ensemble de règles nommées.

nom <- motif

La modèle contient un ou plusieurs des éléments suivants.

prénom L'élément représente l'ensemble du motif dans la règle avec le prénom.

"caractères"
Un caractère ou une chaîne entre guillemets doubles est mis en correspondance littéralement. L'ANSI C
les séquences d'échappement sont reconnues dans le caractères.

'caractères'
Un caractère ou une chaîne entre guillemets simples est mis en correspondance littéralement, comme ci-dessus.

[caractères]
Un ensemble de caractères entre crochets correspond à n'importe quel caractère de
l'ensemble, avec des caractères d'échappement reconnus comme ci-dessus. Si l'ensemble commence par un
uparrow (^) alors l'ensemble est nié (l'élément correspond à n'importe quel caractère pas dans le
ensemble). Toute paire de caractères séparés par un tiret (-) représente la plage de
caractères du premier au second inclus. Un seul caractère alphabétique
ou le trait de soulignement correspond à l'ensemble suivant.

[a-zA-Z_]

De même, ce qui suit correspond à n'importe quel caractère non numérique.

[^ 0-9]

. Un point correspond à n'importe quel caractère. Notez que la seule fois où cela échoue est à la fin de
fichier, où il n'y a aucun caractère à faire correspondre.

( modèle )
Les parenthèses sont utilisées pour le regroupement (modification de la priorité des opérateurs
décrit ci-dessous).

{ action }
Des accolades entourent les actions. L'action est un code source C arbitraire à
exécuté à la fin de l'appariement. Toutes les accolades dans l'action doivent être correctement
imbriqué. Tout texte d'entrée qui a été mis en correspondance avant l'action et délimité par un angle
crochets (voir ci-dessous) est disponible dans l'action en tant que contenu du
tableau de caractères yytexte. La longueur de (nombre de caractères dans) yytexte is
disponible dans la variable yyleng. (Ces noms de variables sont historiques ; voir
lex(1).)

< Une équerre ouvrante correspond toujours (ne consommant aucune entrée) et provoque l'analyseur
pour commencer à accumuler le texte correspondant. Ce texte sera mis à disposition des actions en
la variable yytexte.

> Un crochet fermant correspond toujours (ne consommant aucune entrée) et provoque l'analyseur
arrêter d'accumuler du texte pour yytexte.

Le dessus un éléments peut être rendu facultatif et/ou répétable avec les suffixes suivants :

un élément ?
L'élément est facultatif. S'il est présent sur l'entrée, il est consommé et le match
réussit. S'il n'est pas présent sur l'entrée, aucun texte n'est consommé et la correspondance réussit
de toute façon.

un élément +
L'élément est répétable. S'il est présent sur l'entrée, une ou plusieurs occurrences de
un élément sont consommés et le match réussit. Si aucune occurrence de un élément are
présent sur l'entrée, la correspondance échoue.

un élément *
L'élément est facultatif et répétable. S'il est présent sur l'entrée, un ou plusieurs
occurrences de un élément sont consommés et le match réussit. Si aucune occurrence de
un élément sont présents sur l'entrée, le match réussit quand même.

Les éléments et suffixes ci-dessus peuvent être convertis en prédicats (qui correspondent à des
saisir du texte et réussir ou échouer par la suite sans consommant cette entrée) avec le
préfixes suivants :

& un élément
Le prédicat ne réussit que si un élément peut être égalé. Saisir du texte numérisé pendant
assorti un élément n'est pas consommé à partir de l'entrée et reste disponible pour
correspondance ultérieure.

! un élément
Le prédicat ne réussit que si un élément ne peut pas être égalé. Saisir du texte numérisé pendant
assorti un élément n'est pas consommé à partir de l'entrée et reste disponible pour
correspondance ultérieure. Un idiome populaire est

!.

qui correspond à la fin du fichier, après que le dernier caractère de l'entrée a déjà
été consommé.

Une forme spéciale du prédicat « & » est fournie :

&{ expression }
Dans ce prédicat le simple C expression (pas instruction) est évalué immédiatement
lorsque l'analyseur atteint le prédicat. Si la expression rendements non nuls (vrai)
la "correspondance" réussit et l'analyseur continue avec l'élément suivant dans le motif.
Si la expression renvoie zéro (faux) la « correspondance » échoue et l'analyseur sauvegarde jusqu'à
recherchez une autre analyse de l'entrée.

Plusieurs éléments (avec ou sans préfixes et suffixes) peuvent être combinés en un séquence
en les écrivant l'un après l'autre. La séquence entière ne correspond que si chaque individu
l'élément qu'il contient correspond, de gauche à droite.

Les séquences peuvent être séparées en alternatives disjointes par l'opérateur d'alternance '/'.

séquence-1 / séquence-2 / / séquence-N
Chaque séquence est essayée à tour de rôle jusqu'à ce que l'une d'elles corresponde, moment auquel la correspondance
pour le modèle global réussit. Si aucune des séquences ne correspond, alors la correspondance
du schéma global échoue.

Enfin, le signe dièse (#) introduit un commentaire (ignoré) qui se poursuit jusqu'à la fin
de la ligne.

Pour résumer ce qui précède, l'analyseur essaie de faire correspondre le texte d'entrée à un modèle
contenant des littéraux, des noms (représentant d'autres règles) et divers opérateurs (écrits sous la forme
préfixes, suffixes, juxtaposition pour le séquençage et opérateur d'alternance d'infixes) qui
modifier la façon dont les éléments du motif sont mis en correspondance. Les correspondances se font de gauche à
à droite, 'descendant' dans les sous-règles nommées au fur et à mesure qu'elles sont rencontrées. Si le processus d'appariement
échoue, l'analyseur « retrouve » (« rembobinage » de l'entrée de manière appropriée dans le processus) pour
trouver le « chemin » alternatif le plus proche à travers la grammaire. En d'autres termes, l'analyseur
effectue une recherche en profondeur d'abord de gauche à droite pour le premier chemin correspondant avec succès
par les règles. Si elles sont trouvées, les actions le long du chemin réussi sont exécutées (dans le
ordre où ils ont été rencontrés).

Notez que les prédicats sont évalués immédiatement lors de la recherche d'une correspondance réussie,
car ils contribuent au succès ou à l'échec de la recherche. Cependant, les actions sont
évalué seulement après qu'une correspondance réussie a été trouvée.

PEG GRAMMAIRE POUR PEG GRAMMAIRES


La grammaire pour cheville grammaires est présentée ci-dessous. Cela illustrera et formalisera à la fois
description ci-dessus.

Grammaire <- Définition de l'espacement+ EndOfFile

Définition <- Identifiant LEFTARROW Expression
Expression <- Séquence ( Séquence SLASH )*
Séquence <- Préfixe*
Préfixe <- ET Action
/ ( ET | NON ) ? Suffixe
Suffixe <- Primaire ( QUERY / STAR / PLUS ) ?
Primaire <- Identifiant !LEFTARROW
/ OUVRIR Expression FERMER
/ Littéral
/ Classer
/ POINT
/ Action
/ COMMENCER
/ FINIR

Identifiant <- < IdentStart IdentCont* > Espacement
IdentStart <- [a-zA-Z_]
IdentCont <- IdentStart / [0-9]
Littéral <- ['] < ( !['] Char )* > ['] Espacement
/ ["] < ( !["] Caract. )* > ["] Espacement
Classe <- '[' < ( !']' Range )* > ']' Espacement
Plage <- Car '-' Car / Car
Caractère <- '\\' [abefnrtv'"\[\]\\]
/ '\\' [0-3][0-7][0-7]
/ '\\' [0-7][0-7] ?
/ '\\' '-'
/ !'\\' .
FLÈCHE GAUCHE <- '<-' Espacement
Barre oblique <- '/' Espacement
ET <- '&' Espacement
PAS <- '!' Espacement
REQUÊTE <- '?' Espacement
ETOILE <- '*' Espacement
PLUS <- '+' Espacement
OPEN <- '(' Espacement
Espacement FERMER <- ')'
POINT <- '.' Espacement
Espacement <- ( Espace / Commentaire )*
Commentaire <- '#' ( !EndOfLine . )* EndOfLine
Espace <- ' ' / '\t' / EndOfLine
EndOfLine <- '\r\n' / '\n' / '\r'
FinDeFichier <- !.
Action <- '{' < [^}]* > '}' Espacement
COMMENCER <- '<' Espacement
END <- '>' Espacement

LEG GRAMMAIRES


jambe est une variante de cheville qui ajoute quelques fonctionnalités de lexde Géographie (1) et avec la yacc(1). Il diffère de
cheville des manières suivantes.

%{ texte... %}
Une section de déclaration peut apparaître partout où une définition de règle est attendue. Les
texte entre les délimiteurs '%{' et '%}' est copié mot à mot dans le C généré
code d'analyseur avant le code qui implémente l'analyseur lui-même.

prénom = modèle
L'opérateur 'affectation' remplace l'opérateur flèche gauche '<-'.

nom-règle
Les traits d'union peuvent apparaître sous forme de lettres dans les noms de règles. Chaque trait d'union est converti en
un trait de soulignement dans le code source C généré. Un seul trait d'union '-' est un
nom de la règle légale.

- = [ \t\n\r]*
nombre = [0-9]+ -
nom = [a-zA-Z_][a-zA_Z_0-9]* -
l-paren = '(' -
r-paren = ')' -

Cet exemple montre comment les espaces ignorés peuvent être évidents lors de la lecture de la grammaire
et pourtant discret lorsqu'il est placé généreusement à la fin de chaque règle associée à
un élément lexical.

suite-1 | suite-2
L'opérateur d'alternance est la barre verticale '|' plutôt que la barre oblique '/'. Les
cheville exclure

nom <- séquence-1
/ séquence-2
/ séquence-3

s'écrit donc

nom = séquence-1
| séquence-2
| séquence-3
;

in jambe (le dernier point-virgule étant facultatif, comme décrit ci-après).

exp ~ { action }
Un opérateur suffixe ~{ action } peut être placé après n'importe quelle expression et se comportera
comme une action normale (code C arbitraire) sauf qu'elle n'est invoquée que lorsque exp
échoue. Il se lie moins étroitement que tout autre opérateur sauf alternance et
séquençage, et est destiné à faciliter la gestion des erreurs et le code de récupération
écrivez. Noter que yytexte et yyleng ne sont pas disponibles dans ces actions, mais les
variable de pointeur yy est disponible pour donner accès au code à n'importe quel
membres de l'état de l'analyseur (voir « PERSONNALISER L'ANALYSEUR » ci-dessous). Notez également que
exp est toujours une seule expression ; pour invoquer une action d'erreur pour tout échec dans
une séquence, les parenthèses doivent être utilisées pour regrouper la séquence en un seul
expression.

règle = e1 e2 e3 ~{ error("e[12] ok; e3 a échoué"); }
| ...

règle = (e1 e2 e3) ~{ error("un des e[123] a échoué"); }
| ...

modèle ;
Un point-virgule de ponctuation peut éventuellement terminer un modèle.

%% texte...
Un double pourcentage '%%' termine la section des règles (et déclarations) du
grammaire. Tous texte suivant '%%' est copié mot à mot dans le code d'analyseur C généré
après le code d'implémentation de l'analyseur.

$$ = Plus-value
Une sous-règle peut renvoyer une sémantique Plus-value d'une action en l'affectant au
pseudo-variable '$$'. Toutes les valeurs sémantiques doivent avoir le même type (qui par défaut
à 'int'). Ce type peut être modifié en définissant YYSTYPE dans une section de déclaration.

identifiant:prénom
La valeur sémantique renvoyée (en attribuant à '$$') à partir de la sous-règle prénom is
associé au identifiant et peut être invoqué dans les actions ultérieures.

L'exemple de calculatrice de bureau ci-dessous illustre l'utilisation de '$$' et ':'.

LEG Exemple: A BUREAU CALCULATRICE


Les extensions en jambe décrites ci-dessus permettent des analyseurs et des évaluateurs utiles (y compris
déclarations, règles de grammaire et fonctions C de support telles que « principal ») à conserver dans
un seul fichier source. Pour illustrer cela, nous montrons une simple calculatrice de bureau prenant en charge le
quatre opérateurs arithmétiques communs et des variables nommées. Les résultats intermédiaires de
l'évaluation arithmétique sera accumulée sur une pile implicite en les retournant comme
valeurs sémantiques des sous-règles.

%{
#comprendre /* printf() */
#comprendre /* atoi() */
int vars[26] ;
%}

Stmt = - e:Expr EOL { printf("%d\n", e); }
| ( !EOL . )* EOL { printf("erreur\n"); }

Expr = i:ID ASSIGN s:Somme { $$ = vars[i] = s; }
| s:Somme { $$ = s; }

Somme = l:Produit
( PLUS r:Produit { l += r; }
| MOINS r:Produit { l -= r; }
)* { $$ = l; }

Produit = l:Valeur
( FOIS r:Valeur { l *= r; }
| DIVIDE r:Valeur { l /= r; }
)* { $$ = l; }

Valeur = i:NUMBER { $$ = atoi(yytext); }
| i:ID !ASSIGN { $$ = vars[i] ; }
| OUVRIR i:Expr FERMER { $$ = i; }

NOMBRE = < [0-9]+ > - { $$ = atoi(yytext); }
ID = < [az] > - { $$ = yytext[0] - 'a'; }
ASSIGNER = '=' -
PLUS = '+' -
MOINS = '-' -
FOIS = '*' -
DIVISER = '/' -
OUVERT = '(' -
FERMER = ')' -

- = [ \t]*
EOL = '\n' | '\r\n' | '\r' | ';'

%%

int main ()
{
tandis que (yyparse())
;
0 revenir;
}

LEG GRAMMAIRE POUR LEG GRAMMAIRES


La grammaire pour jambe grammaires est présentée ci-dessous. Cela illustrera et formalisera à la fois
description ci-dessus.

grammaire = -
( déclaration | définition )+
bande annonce? fin de fichier

déclaration = '%{' < ( !'%}' . )* > RPERCENT

bande-annonce = '%%' < .* >

définition = identifiant EQUAL expression SEMICOLON?

expression = séquence ( séquence BAR )*

séquence = erreur+

erreur = préfixe ( action TILDE ) ?

préfixe = ET action
| ( ET | NON ) ? suffixe

suffixe = primaire ( QUERY | STAR | PLUS ) ?

primaire = identifiant identifiant COLON !EQUAL
| identifiant !EQUAL
| OUVERT expression FERMER
| littéral
| classer
| POINT
| action
| COMMENCER
| FINIR

identifiant = < [-a-zA-Z_][-a-zA-Z_0-9]* > -

littéral = ['] < ( !['] char )* > ['] -
| ["] < ( !["] caractère )* > ["] -

classe = '[' < ( !']' range )* > ']' -

plage = car '-' car | carboniser

char = '\\' [abefnrtv'"\[\]\\]
| '\\' [0-3][0-7][0-7]
| '\\' [0-7][0-7] ?
| !'\\' .

action = '{' < accolades* > '}' -

accolades = '{' accolades* '}'
| !'}' .

ÉGAL = '=' -
COLON = ':' -
SEMICOLON = ';' -
BARRE = '|' -
ET = '&' -
NON = '!' -
REQUÊTE = '?' -
ÉTOILE = '*' -
PLUS = '+' -
OUVERT = '(' -
FERMER = ')' -
POINT = '.' -
COMMENCER = '<' -
FIN = '>' -
TILDE = '~' -
RPERCENT = '%}' -

- = ( espace | commentaire )*
espace = ' ' | '\t' | fin de ligne
comment = '#' ( !fin de ligne . )* fin de ligne
fin de ligne = '\r\n' | '\n' | '\r'
fin de fichier = !.

PERSONNALISATION L' PARSEUR


Les symboles suivants peuvent être redéfinis dans les sections de déclaration pour modifier le
code d'analyseur.

YYTYPE
Le type de valeur sémantique. La pseudo-variable '$$' et les identifiants 'liés' à
les résultats de la règle avec l'opérateur deux-points ':' doivent tous être considérés comme étant déclarés
avoir ce genre. La valeur par défaut est 'int'.

YYPARSE
Le nom du point d'entrée principal de l'analyseur. La valeur par défaut est 'yyparse'.

YYPAREFÀ PARTIR
Le nom d'un point d'entrée alternatif à l'analyseur. Cette fonction attend un
argument : la fonction correspondant à la règle à partir de laquelle la recherche d'une correspondance
devrait commencer. La valeur par défaut est 'yyparsefrom'. Notez que yyparse() est défini comme

int yyparse() { return yyparsefrom(yy_foo); }

où 'foo' est le nom de la première règle de la grammaire.

AA_INPUT(buf, résultat, taille max)
Cette macro est invoquée par l'analyseur pour obtenir plus de texte d'entrée. buf pointe vers un
zone de mémoire pouvant contenir au maximum taille max personnages. La macro doit copier
saisir du texte dans buf puis affecter la variable entière résultat pour indiquer le
nombre de caractères copiés. Si plus aucune entrée n'est disponible, la macro devrait
attribuer 0 à résultat. Par défaut, la macro YY_INPUT est définie comme suit.

#define YY_INPUT(buf, résultat, max_size) \
{\
int yyc=getchar(); \
résultat= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \
}

Notez que si YY_CTX_LOCAL est défini (voir ci-dessous) alors un premier argument supplémentaire,
contenant le contexte de l'analyseur, est passé à YY_INPUT.

YY_DEBUG
Si ce symbole est défini, un code supplémentaire sera inclus dans l'analyseur qui
imprime de grandes quantités d'informations obscures à l'erreur standard tandis que l'analyseur
est en cours d'exécution.

AA_BEGIN
Cette macro est invoquée pour marquer le début du texte d'entrée qui sera rendu disponible
dans les actions comme 'yytext'. Cela correspond aux occurrences de '<' dans la grammaire.
Ceux-ci sont convertis en prédicats qui devraient réussir. Le défaut
définition

#define YY_BEGIN (yybegin= yypos, 1)

enregistre donc la position d'entrée actuelle et renvoie 1 ('true') comme résultat de
le prédicat.

YY_END Cette macro correspond à '>' dans la grammaire. Encore une fois, c'est un prédicat donc le
la définition par défaut enregistre la position d'entrée avant de « réussir ».

#define YY_END (yyend= yypos, 1)

AA_PARSE(T)
Cette macro déclare que les points d'entrée de l'analyseur (yyparse et yyparsefrom) sont de type
T. La définition par défaut

#définir YY_PARSE(T) T

laisse yyparse() et yyparsefrom() avec une visibilité globale. S'ils ne doivent pas être
visible de l'extérieur dans d'autres fichiers source, cette macro peut être redéfinie pour déclarer
eux « statiques ».

#define YY_PARSE(T) statique T

YY_CTX_LOCAL
Si ce symbole est défini lors de la compilation d'un parseur généré alors global
l'état de l'analyseur sera conservé dans une structure de type 'yycontext' qui peut être déclarée
comme variable locale. Cela permet à plusieurs instances d'analyseurs de coexister et de
être thread-safe. La fonction d'analyse yyparser() sera déclaré s'attendre à un premier
argument de type 'yycontext *', une instance de la structure contenant le global
état pour l'analyseur. Cette instance doit être allouée et initialisée à zéro par
le client. Un exemple trivial mais complet est le suivant.

#inclut

#définir YY_CTX_LOCAL

#include "l'analyseur-généré.peg.c"

int main ()
{
yycontexte ctx ;
memset(&ctx, 0, sizeof(yycontext));
while (yyparse(&ctx));
0 revenir;
}

Notez que si ce symbole n'est pas défini, l'analyseur compilé sera statiquement
allouer son état global et ne sera ni réentrant ni thread-safe. Notez également
que la structure de l'analyseur yycontext est initialisée automatiquement la première fois
yyparser() est appelé; cette structure doit donc être correctement initialisé à zéro
avant le premier appel à yyparser()

YY_CTX_MEMBERS
Si YY_CTX_LOCAL est défini (voir ci-dessus) alors la macro YY_CTX_MEMBERS peut être définie
pour étendre à toutes les déclarations de champ de membre supplémentaires que le client souhaite
inclus dans la déclaration du type de structure 'yycontext'. Ces supplémentaires
les membres sont sinon ignorés par l'analyseur généré. L'instance de 'yycontext'
associé à l'analyseur syntaxique actuellement actif est disponible dans les actions en tant que
variable de pointeur yy.

YY_BUFFER_SIZE
La taille initiale du tampon de texte, en octets. La valeur par défaut est 1024 et le tampon
la taille est doublée chaque fois que cela est nécessaire pour répondre à la demande lors de l'analyse. Une application
qui analyse généralement des chaînes beaucoup plus longues pourrait augmenter cela pour éviter des
réallocation de tampon.

YY_STACK_SIZE
La taille initiale des piles de variables et d'actions. La valeur par défaut est 128, ce qui est
doublé chaque fois que cela est nécessaire pour répondre à la demande lors de l'analyse. Les applications qui ont
des piles d'appels profonds avec de nombreuses variables locales, ou qui effectuent de nombreuses actions après un
une seule correspondance réussie, pourrait augmenter cela pour éviter un tampon inutile
réaffectation.

AA_MALLOC(YY, TAILLE)
L'allocateur de mémoire pour tout le stockage lié à l'analyseur. Les paramètres sont les
la structure yycontext actuelle et le nombre d'octets à allouer. Le défaut
la définition est : malloc(TAILLE)

AA_REALLOC(YY, PTR, TAILLE)
Le réallocateur de mémoire pour le stockage à croissance dynamique (comme les tampons de texte et
piles variables). Les paramètres sont la structure yycontext actuelle, le
stockage précédemment alloué, et le nombre d'octets auxquels ce stockage doit
être cultivé. La définition par défaut est : realloc(PTR, TAILLE)

AA_FREE(YY, PTR)
Le désallocateur de mémoire. Les paramètres sont la structure yycontext actuelle et le
stockage à désallouer. La définition par défaut est : free(PTR)

ANNONCE
Le nom de la fonction qui libère toutes les ressources détenues par une structure yycontext.
La valeur par défaut est 'yyrelease'.

Les variables suivantes peuvent être référencées dans les actions.

carboniser *aabuf
Cette variable pointe vers le tampon d'entrée de l'analyseur utilisé pour stocker le texte d'entrée qui a
pas encore été apparié.

int ypos
Il s'agit du décalage (en yybuf) du prochain caractère à associer et à consommer.

carboniser *yytexte
Le texte correspondant le plus récent délimité par '<' et '>' est stocké dans cette variable.

int yyleng
Cette variable indique le nombre de caractères dans 'yytext'.

yycontexte *aaa
Cette variable pointe vers l'instance de 'yycontext' associée au
analyseur syntaxique actuellement actif.

Les programmes qui souhaitent libérer toutes les ressources associées à un parseur peuvent utiliser le
fonction suivante.

yylibération(yycontexte*yy)
Renvoie tout le stockage alloué par l'analyseur associé à yy au système. Le stockage
sera réaffecté lors du prochain appel à yyparser()

Notez que le stockage de la structure yycontext elle-même n'est jamais alloué ou récupéré
implicitement. L'application doit allouer ces structures en stockage automatique, ou utiliser
callo() et gratuitement() pour les gérer explicitement. L'exemple dans la section suivante
démontre une approche de la gestion des ressources.

LEG Exemple: EXTENSION L' PARSER CONTEXTE


La yy la variable passée aux actions contient l'état de l'analyseur ainsi que tout autre
champs définis par YY_CTX_MEMBERS. Ces champs peuvent être utilisés pour stocker des informations spécifiques à l'application
des informations globales à un appel particulier de yyparser(). Un trivial mais complet jambe
l'exemple suivant dans lequel la structure yycontext est étendue avec un compter du nombre de
caractères de nouvelle ligne vus dans l'entrée jusqu'à présent (la grammaire consomme et ignore
la totalité de l'entrée). L'appelant de yyparser() les usages compter pour imprimer le nombre de lignes de
entrée qui ont été lus.

%{
#définir YY_CTX_LOCAL 1
#définir YY_CTX_MEMBERS \
nombre int;
%}

Char = ('\n' | '\r\n' | '\r') { yy->count++ }
| .

%%

#inclut
#comprendre

int main ()
{
/* crée un contexte d'analyseur local dans le stockage automatique */
yycontexte yy ;
/* le contexte *doit* être initialisé à zéro avant la première utilisation*/
memset(&yy, 0, sizeof(yy));

tandis que (yyparse(&yy))
;
printf("%d nouvelles lignes\n", yy.count);

/* libère toutes les ressources associées au contexte */
yyrelease(&yy);

0 revenir;
}

DIAGNOSTIC


cheville et jambe avertir des conditions suivantes lors de la conversion d'une grammaire en un analyseur.

syntaxe erreur
La grammaire d'entrée était malformée d'une manière ou d'une autre. Le message d'erreur comprendra le
texte sur le point d'être mis en correspondance (souvent sauvegardé une énorme quantité de l'emplacement réel de
l'erreur) et le numéro de ligne du dernier caractère considéré (qui est
souvent l'emplacement réel du problème).

exclure 'foo' d'utiliser mais pas défini
La grammaire faisait référence à une règle nommée 'foo' mais aucune définition n'en a été donnée.
Tenter d'utiliser l'analyseur généré entraînera probablement des erreurs de la part de l'éditeur de liens
en raison de symboles non définis associés à la règle manquante.

exclure 'foo' défini mais pas d'utiliser
La grammaire a défini une règle nommée 'foo' puis l'a ignorée. Le code associé
avec la règle est inclus dans l'analyseur généré qui sera à tous autres égards
être en bonne santé.

possible infinis à gauche récursion in exclure 'foo'
Il existe au moins un chemin dans la grammaire qui part de la règle 'foo'
revenir à (une invocation récursive de) la même règle sans consommer aucune entrée.

La récursivité à gauche, en particulier celle trouvée dans les documents de normes, est souvent « directe » et
implique une répétition triviale.

# (6.7.6)
déclarant-abstrait-direct =
Abrégé-déclarant LPAREN RPAREN
| déclarant-abstrait-direct ? LBRACKET assign-expr? RACCORD
| déclarant-abstrait-direct ? LBRACKET ÉTOILE RBRACKET
| déclarant-abstrait-direct ? Liste des types de paramètres LPAREN ? RPAREN

La récursivité peut facilement être éliminée en convertissant les parties du motif suivant
la récursivité dans un suffixe répétable.

# (6.7.6)
déclarant-abstrait-direct =
tête-déclaratrice directe-abstraite ?
direct-résumé-déclarateur-queue*

direct-abstract-declarator-head =
Abrégé-déclarant LPAREN RPAREN

direct-abstrait-déclarateur-queue =
LBRACKET assign-expr? RACCORD
| LBRACKET ÉTOILE RBRACKET
| Liste des types de paramètres LPAREN ? RPAREN

MISES EN GARDE


Un analyseur qui accepte une entrée vide toujours réussir. Considérons l'exemple suivant,
pas atypique d'une première tentative d'écriture d'un analyseur basé sur PEG :

Programme = Expression*
Expression = " peu importe "
%%
int main () {
tandis que (yyparse())
puts("succès!");
0 revenir;
}

Ce programme boucle indéfiniment, quelle que soit l'entrée (le cas échéant) fournie sur stdin. De nombreux
des correctifs sont possibles, le plus simple étant d'insister sur le fait que l'analyseur en consomme toujours
entrée non vide. Changer la première ligne en

Programme = Expression+

accomplit cela. Si l'analyseur est censé consommer la totalité de l'entrée, alors explicitement
il est également fortement recommandé d'exiger la fin de fichier :

Programme = Expression+ !.

Cela fonctionne parce que l'analyseur ne réussira à faire correspondre aucun caractère (prédicat "!")
(expression ".") lorsqu'il tente de lire au-delà de la fin de l'entrée.

Utilisez la jambe en ligne en utilisant les services onworks.net


Serveurs et postes de travail gratuits

Télécharger des applications Windows et Linux

  • 1
    PostInstallerF
    PostInstallerF
    PostInstallerF installera tous les
    logiciels que Fedora Linux et d'autres
    n'inclut pas par défaut, après
    exécutant Fedora pour la première fois. Son
    facile pour...
    Télécharger PostInstallerF
  • 2
    strass
    strass
    Le projet strace a été déplacé vers
    https://strace.io. strace is a
    diagnostic, débogage et instruction
    traceur d'espace utilisateur pour Linux. C'est utilisé
    surveiller un...
    Télécharger
  • 3
    gMKVExtract GUI
    gMKVExtract GUI
    Une interface graphique pour l'utilitaire mkvextract (qui fait partie de
    MKVToolNix) qui intègre la plupart (si
    pas tous) les fonctionnalités de mkvextract et
    utilitaires mkvinfo. Écrit en C#NET 4.0,...
    Télécharger gMKVExtractGUI
  • 4
    Bibliothèque JasperReports
    Bibliothèque JasperReports
    La bibliothèque JasperReports est la
    l'open source le plus populaire au monde
    veille économique et reporting
    moteur. Il est entièrement écrit en Java
    et il est capable de...
    Télécharger la bibliothèque JasperReports
  • 5
    Livres Frappe
    Livres Frappe
    Frappe Books est une source gratuite et ouverte
    logiciel de comptabilité de bureau
    simple et bien conçu pour être utilisé par
    petites entreprises et indépendants. Ce'...
    Télécharger Frappe Books
  • 6
    Python numérique
    Python numérique
    NEWS : NumPy 1.11.2 est la dernière version
    qui sera fait sur sourceforge. roues
    pour Windows, Mac et Linux ainsi que
    les distributions source archivées peuvent être fou ...
    Télécharger Python numérique
  • Plus "

Commandes Linux

Ad