Pypaper
Bonjour tout le monde! en fait je sais même pas si dans cette rubrique que dois poser ma question mais la voici:
j'ai un projet de developpement qui consiste à écrire un interpréteur de commandes à la manière du bash. pour cela je dois utiliser les outils GNU Flex (generateur d'analyseur lexicale) et Bison (generateur d'analyseur syntaxique) , dérivés de Lex et Yacc. Mais voilà je me demande si ces outils sont correctement installés avec la Fedora; c'est vrai que j'arrive à generer les fichiers .c (par flex et bison) et .h (par bison) mais je n'arrive pas à compiler ces fichiers; je crois qu'une librairie manque; en effet ces fichiers .c me sont générés par flex et bison et je comprends pas pourquoi ils ne se compilent pas! l'erreur pour le fichier lex.yy. c est la suivante: "aucune référence vers << yylval >> " et pourtant cette variable est normalement définie dans y.tab.h (qui est un fichier généré par bison).
Est ce que quelqu'un peut m'aider? Merci d'avance!
Anvil
library signifie bibliotheque et pas librairie. Et flex et bison fonctionnent tres bien.
Si la compilation echoue a l'edition de lien avec des symboles non resolus, c'est qu'il te manque surement les bib associees a flex.
La lib `fl', en l'occurrence.
Pypaper
Et où est ce que je peux trouver cette librairie? je crois que j'ai le même probleme avec bison: lui aussi lors de l'edition des liens il me dit "reference indefinie vers <<yyerror>>" alors que utilisé bison ainsi: "bison -o parser.c -d parser.y -ly" (il est ainsi supposé avoir defini lui même la routine yyerror) et un certain ensemble d'autres fonctions (que j'ai declarées dans un header que j'ai inclus dans parser.y).
merci d'avance.
Anvil
la lib fl est dans le package flex bien sur. Je n'ai jamais entendu parle d'une lib 'y' par contre. Je doute tres fortement que celle-ci existe.
Pypaper
J'ai vérifié et j'ai bien la biblio "fl" dans /usr/lib mais j'ai toujours le même probleme et vraiment je sais pas quoi faire! Un autre tuyau? merci d'avance!
Anvil
Sois plus precis. Dis-nous ce que tu fais et ce que tu recoltes comme erreurs.
Pypaper
Mon mini-projet consiste à ecrire un petit interpreteur de commandes. Pour cela j'utilise Flex et Bison pour l'analyse lexicale et syntaxique. J'ai ecrit les fichiers Lex (lexer.l) et Yacc (parser.y) et voici ce que j'ai tapé en ligne de comnade:
flex -olexer.c lexer.l : pour le fichier lex et il n'y a pas d'erruer;
bison -o parser.c -d parser.y : pour le fichier yacc; lui aussi m'a généré deux fichiers à savoir parser.c et parser.h (qui contient la définition de la variable yylval utilisée dans lexer.l) sans erreur.
J'utilise aussi un header nommé ineshell.h qui contient (à travers des #include ) l'ensemble des headers utilisés dans les fichiers lex et yacc ainsi que les prototypes des fonctions utilisées dans le fichier yacc. Il est inclus dans les deux fichiers (lex et yacc: #include "ineshell.h").
La compilation tout court ne donne pas d'erreur (gcc -c lexer.c et gcc -c parser.c). Par contre l'étape d'édition des liens me sort des erreurs:
pour lexer.c: "reference indéfinie vers << yylval >>;
pour parser.c: il me dit "reference indéfinie vers yyerror" et la même chose pour l'ensemble des fonctions qui y sont utilisées (dont les prototypes sont dans ineshell.h; mais là je crois que c'est parce que j'ai pas fini d'écrire le fichier ineshell.c qui contient les codes sources de ces fonctions...).
Voici mon Makefile:
ineshell.exe: parser.o lexer.o ineshell.o
parser.o: parser.c
Pypaper
Désolé j'ai cliqué sans avoir terminé ; je sais pas si vous vaez besoin du fichier Makefile;
J'espère que j'ai donné assez d'explications.
Alors est ce que quelqu'un peut m'aider? je suis bloqué depuis maintenant 3 jours et toute la doc que j'ai lu ne m'a rien apporté! Merci pour votre aide.
starmad88
perso moi je veut bien ton makefile et pourquoi pas le bout de code qui plante (.l et .y) (avec les include) parce que la, comme ca, je vois pas....
Pypaper
En fait le makefile c'est pas un probleme car pour le moment je compile à la main en attendant de tout finir notamment le ineshell.c. En ce qui concerne les .l et .y je vais essayer de les envoyer ùmais je pense pas qu'ils contiennent des erreurs puisque flex et bison ont déjà sorti les fichiers .c et .h .
Anvil
rha.. mais rajoute simplement la libfl sur la ligne d'edition de liens. Ca resoudra le probleme.
starmad88
tu utilises quelle commande pour l'edition des liens ?
Pour les erreurs dans les .l et .y je pense effectivement qu'ils ne contiennent pas d'erreur dans le sens de la syntaxe flex et bison mais peut etre des "erreurs" qui ferait que flex et bison generent des mauvais .c
Pour moi il y a deux possibilité :
- des mauvaises options lors de la compilation (lex, bison ou gcc)
- des erreurs dans les .l et .y qui genereraient de mauvais .c
J'ai du mal à incriminer flex ou bison mais tu peut toujours essayer avec lex et yacc (meme syntaxe)
edit : Anvil a surement raison si tu ne la pas déjà mis. rajoute -lfl
Pypaper
Merci pour votre aide. Voilà j'ai attendu de finir mon fichier contenant les codes sources des fonctions et j'ai compilé le tout pour avoir l'exécutable:
gcc -o ineshell.exe parser.o lexer.o ineshell.o -lfl
Et effectivement ça a marché! Mais voilà j'ai un autre probleme maintenant:
lorsque je lance l'exécutable le début marche sans probleme mais d'ès que je tape une des commandes de mon shell le programme echoue et on me dit : "Erreur de segmentation" ! Et là je comprends plus; j'ai essayé de débugger avec gdb et il paraît que l'erreur provienne d'un "strcpy" que j'ai utilisé dans le fichier yacc mais je comprends pas du tout! J'ai essayé de modifier ce fichier de plusieurs manières mais toujours la même erreur! Quelqu'un peut m'aider?
Merci d'avance.
starmad88
pour la copie de chaine de caractère il y a deux possibilités :
- la chaine a été aloué lors de sa déclaretion ( char chaine[256]; )
dans ce cas un simple strcpy suffi.
- la chaine n'a pas été aloué lors de sa déclaration (char* chaine; )
2 solution :
starmad88
j'ai validé trop tot , je continue : 😉
-tu l'alloue et tu copie :
chaine = (char*) malloc(sizeof(char)*strlen(chaine_src)+1);
strcpy(chaine,chaine_src);
-tu utilise strdup qui fait une copie de la chaine :
chaine = strdup(chaine_src);
il est evident que la deuxieme solution est plus simple mais j'ai mis la première pour bien voir ce qui ce passe. 😉
au fait l'erreur de segmentation vient du fait que quand tu utilises strcpy tu ecrit dans de la mémoire non alloué...
Pypaper
Juste pour vous dire merci! Le probleme est resolu.