Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Bison et flex

10 réponses
Avatar
Pascal
Bonjour,

Je sais que ce n'est pas le meilleur ng, alors désolé d'avance. Mais je
sais que certaines de ses lecteurs connaissent flex et bison.

J'utilises 2 parsers (lexicaux et syntaxiques). Pour les faire
cohabiter, il faut en renommer un. On compile avec flex -Pzz et bison -p
zz qui permet de renommer la fonction qui lance le parser yyparse en
zzparse. J'ai donc un parser avec le nom par défaut yyparse, et un autre
zzparse. Ca, ça marche. Mon pb vient pour les lancer les deux
(séparement, ca marche). D'après le man de flex, il faut rediriger
l'entrée de flex qui se nomme yyin par défaut, l'autre s'appelle zzin.
Première surprise, il faut que je déclare ces deux variables (pourtant
elles sont dans le man de flex!). Je fais donc :

extern FILE *yyin, *zzin;
yyin = fopen("fichier_test1erparser.txt", "r");
yyparse();
zzin = fopen("fichier_test2emeparseur.txt", "r");
zzparse();

Ca compile, mais ca reste bloqué. En fait yyparse est bien lancé, mais
ne se termine pas. Si j'appuis crtl+D, alors là yyparse se termine. Mais
zzparse ne se lance pas. J'ai cherché, et là vraiment cherché, mais je
ne comprends pas.

--
Pascal

10 réponses

Avatar
bernard.barbier
Pascal wrote:
Bonjour,

Je sais que ce n'est pas le meilleur ng, alors désolé d'avance. Mai s je
sais que certaines de ses lecteurs connaissent flex et bison.

J'utilises 2 parsers (lexicaux et syntaxiques). Pour les faire
cohabiter, il faut en renommer un.


A vérifier :

analyseur.l -> contient les expressions régulières pour le lexique
analyseur.y -> contient les règles de grammaire

bison -d -v -g analyseur.y
flex -oanalyseur.yy.c analyseur.l
gcc -c analyseur.yy.c
gcc -c analyseur.tab.c
gcc -o analyseur analyseur.yy.o analyseur.tab.o -lfl

analyseur.l
--------------------------
%{
/* declarations C */
%}
definitions régulières
%%
règles de lexique
%%
-------------------------
Et c'est tout ! pas de code C dans analyseur.l


analyseur.y
-------------------------
%{
/* declarations C */
%}
%token ....
%%
règles de grammaire
%%
int main(void) {
return yyparse () ;
}

yyerror (char * s) { /* Called by yyparse on error */
printf ("nC'est une erreur sur la ligne : %d ! %s n",nblignes,s);
}
-------------------------

On compile avec flex -Pzz et bison -p
zz qui permet de renommer la fonction qui lance le parser yyparse en
zzparse. J'ai donc un parser avec le nom par défaut yyparse, et un au tre
zzparse. Ca, ça marche. Mon pb vient pour les lancer les deux
(séparement, ca marche). D'après le man de flex, il faut rediriger
l'entrée de flex qui se nomme yyin par défaut, l'autre s'appelle zz in.
Première surprise, il faut que je déclare ces deux variables (pourt ant
elles sont dans le man de flex!). Je fais donc :

extern FILE *yyin, *zzin;
yyin = fopen("fichier_test1erparser.txt", "r");
yyparse();
zzin = fopen("fichier_test2emeparseur.txt", "r");
zzparse();

Ca compile, mais ca reste bloqué. En fait yyparse est bien lancé, m ais
ne se termine pas. Si j'appuis crtl+D, alors là yyparse se termine.


utilises tu la règle <EOF> ?

Mais
zzparse ne se lance pas. J'ai cherché, et là vraiment cherché, ma is je
ne comprends pas.


Je compatis...





--
Cordialement,
Bernard.

--
"Vous avez beau dire, y'a pas seulement que de la pomme, y'a
autre chose, ce serait pas des fois de la betterave ? Hein ?"
Paul Volfoni (Jean Lefebvre) - Les Tontons Flingueurs.

Avatar
AG
Pascal wrote:
Le pb vient peut être du fait que je rédéfinis une fonction yywrap qui
retourne 1 systématiquement. Je suis obligé de le rédéfinir car sinon j'ai
une erreur de compilation qui m'indique :
undefined reference to yywrap.

Meme chose pour zzwrap.

Mais je ne comprends toujours pas comment faire fonctionner 2 parseurs!
es tu sur qu'ils sont réentrants ?

as tu vraiment besoin de 2 parseurs ?

Avatar
bernard.barbier
Pascal wrote:
Le pb vient peut être du fait que je rédéfinis une fonction yywra p qui
retourne 1 systématiquement. Je suis obligé de le rédéfinir car sinon j'ai
une erreur de compilation qui m'indique :
undefined reference to yywrap.

Meme chose pour zzwrap.

Mais je ne comprends toujours pas comment faire fonctionner 2 parseurs!



Je ne comprends pas ton pb : faire fonctionner 2 parseurs.
Quand on fait de la compilation,
- le flot d'entrée est donné à l'analyseur lexical qui retourne
à l'analyseur ssyntaxique 1- une unité lexicale (token) et un lexèm e
(yytext).
- l'analyseur syntaxique récupère les UL et vérifie si elles concor dent
avec la grammaire, puis génère un arbre syntaxique (décoré ou non , dans
ton cas, non).

Cela constitue un seul et même programme, c'est une chaîne de traitem ent.

Pour ton cas, une ligne de ton fichier :
11 DUPONT 515 DAUGPHIN04ff
11 DUPONT 515.4 DAUGPHIN04ff

une simple analyse lexicale pourrait convenir si c'est vraiment ce que
tu présentes dans ton exemple :

%{

%}

SP [ t b]
NSP {SP}+
LIGNE [0-9]+{NSP}[:alpha:]+{NSP}[0-9]+(.[0-9]+)*{NSP}[:alpha:]+{NSP}n
%%
{LIGNE} {cptlig++}

Par contre, si t'as besoin d'une grammaire, j'ai du mal à vérifier si ta
grammaire est bien LR en l'absence des UL, et elle me semble qd même
ambigüe. ( aucune erreur dans le fichier .output ? )

D'autre part, je mettrai le compteur de lignes dans la partie lex.

Dis donc, c'est pour faire un arbre généalogique ?....
--
Cordialement,
Bernard.

--
"Vous avez beau dire, y'a pas seulement que de la pomme, y'a
autre chose, ce serait pas des fois de la betterave ? Hein ?"
Paul Volfoni (Jean Lefebvre) - Les Tontons Flingueurs.

Avatar
Pascal
On Fri, 03 Dec 2004 11:31:56 +0100, bernard.barbier wrote:


utilises tu la règle <EOF> ?



Dans le lexer, si je détecte la fin de fichier avec la ligne :
<<EOF>> return FIN;

Pis dans bison, si je fais :
prog :
| exp //pour pouvoir traiter plusieurs requetes dans le meme fichier
| exp FIN
;

Il me met systématiquement une erreur sur la ligne de la fin de fichier.

Avatar
Pascal
Le pb vient peut être du fait que je rédéfinis une fonction yywrap qui
retourne 1 systématiquement. Je suis obligé de le rédéfinir car sinon j'ai
une erreur de compilation qui m'indique :
undefined reference to yywrap.

Meme chose pour zzwrap.

Mais je ne comprends toujours pas comment faire fonctionner 2 parseurs!
Avatar
drkm
"bernard.barbier" writes:

Je ne comprends pas ton pb : faire fonctionner 2 parseurs.


Je pense que le PO ne parle pas du fichier Lex et du fichier Bison,
en parlant de deux parsers, mais bien de deux tels ensembles :

monparser1.l
monparser1.y
monparser2.l
monparser2.y

--drkm

Avatar
bernard.barbier
Pascal wrote:
On Fri, 03 Dec 2004 17:02:20 +0100, drkm wrote:


Je pense que le PO ne parle pas du fichier Lex et du fichier Bison,
en parlant de deux parsers, mais bien de deux tels ensembles :

monparser1.l
monparser1.y
monparser2.l
monparser2.y




oui c'est exactement ca. J'ai deux fichier lex, deux fichiers bison pou r
deux grammaires differentes. Car c'est imposé pour mon projet.


OK !

Bon est-ce qu'il n'y aurait pas une idée à exploiter avec les fonctio ns
- yy_switch_to_buffer
- yy_delete_buffer

#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
int include_stack_ptr = 0 ;

[...]
if (include_stack_ptr >= MAX_INCLUDE_DEPTH) {
ERREUR ("Nombre d'inclusion trop grand") ;
}
include_stack[include_stack_ptr++]=YY_CURRENT_BUFFER ;
yyin = fopen (yytext,"r") ;
if (! yyin ) {
ERREURSTR ("Fichier inexistant : ",yytext);
}
yy_switch_to_buffer (yy_create_buffer (yyin,YY_BUF_SIZE)) ;
[...]
<<EOF>> {
if (--include_stack_ptr < 0) { /* On est en fin de pile */
printf ("nnEOF. Normal mode exiting yylex.n");
return 0 ;
} else { /* On dépile les buffers */
yy_delete_buffer (YY_CURRENT_BUFFER) ;
yy_switch_to_buffer (include_stack [include_stack_ptr]);
}
}
[...]

Mais je peux me tromper complètement !!!!
--
Cordialement,
Bernard.

--
"Vous avez beau dire, y'a pas seulement que de la pomme, y'a
autre chose, ce serait pas des fois de la betterave ? Hein ?"
Paul Volfoni (Jean Lefebvre) - Les Tontons Flingueurs.


Avatar
Pascal
On Fri, 03 Dec 2004 17:02:20 +0100, drkm wrote:

Je pense que le PO ne parle pas du fichier Lex et du fichier Bison,
en parlant de deux parsers, mais bien de deux tels ensembles :

monparser1.l
monparser1.y
monparser2.l
monparser2.y



oui c'est exactement ca. J'ai deux fichier lex, deux fichiers bison pour
deux grammaires differentes. Car c'est imposé pour mon projet.

Avatar
Pascal
bernard.barbier wrote:
OK !



PFFF!!!! Fini par trouver. En fait, il faut rediriger le flux d'entrée
yyin et zzin avec un fopen. Or lorsque je faisais ceci dans un main
situé dans l'un des fichier.y (dans la partie du bas réservée au
fichier), cela n'exécutait qu'un seul parseur.... Le deuxième ne
marchait pas comme je l'ai déjà expliqué.

La solution : mettre le main dans un fichier séparé!!!! C'est vraiment
pourri! Apparament, même si deux fonctions yyparse et zzparse existent,
bison s'en fout et appelle la fonction du fichier.y.

ex : si file.y définit un parser yyparse. fil2.y définit un parser
zzparse. Si dans le main de file.y j'appelle zzparse, c'est.... yyparse
qui se lance!!!!
--
Pascal

Avatar
Jean-Marc Bourguet
Pascal writes:

bernard.barbier wrote:
OK !



PFFF!!!! Fini par trouver. En fait, il faut rediriger le flux d'entrée yyin
et zzin avec un fopen. Or lorsque je faisais ceci dans un main situé dans
l'un des fichier.y (dans la partie du bas réservée au fichier), cela
n'exécutait qu'un seul parseur.... Le deuxième ne marchait pas comme je
l'ai déjà expliqué.

La solution : mettre le main dans un fichier séparé!!!! C'est vraiment
pourri! Apparament, même si deux fonctions yyparse et zzparse existent,
bison s'en fout et appelle la fonction du fichier.y.

ex : si file.y définit un parser yyparse. fil2.y définit un parser
zzparse. Si dans le main de file.y j'appelle zzparse, c'est.... yyparse qui
se lance!!!!


Le renommage yy???? -> zz???? est fait par des macros. D'où
ton problème.

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org