IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Générateurs de compilateur Discussion :

Undefined vtable : Bison++ Flex++


Sujet :

Générateurs de compilateur

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut Undefined vtable : Bison++ Flex++
    Bonjour,

    Voilà plus d'une semaine que je m'arrache les cheveux, passe des nuits blanches et pire encore à cause d'un problème à la base très simple.

    Je souhaite réaliser un petit programme en C++ utilisant Flex++ et Bison++ sous cygwin.

    Je dispose donc d'un fichier main.l qui sera utilisé par flex++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    %{
    #include "scanner.h"
    %}
     
    %%
     
    .* { ECHO; }
     
    %%
    d'un fichier main.y pour bison++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    %{
     
    %}
     
    %name parser
    %token PLOP
     
    %%
     
    test : PLOP
    	 ;
     
    %%
     
    int main()
    {
    	parser monParser;
    	monParser.yyparse();
     
    	return 0;
    }

    Et voici mon Makefile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    all: yacc lex comp
     
    yacc: main.y
        bison++ -d -hscanner.h -oscanner.c main.y
     
    lex: main.l scanner.h
        flex++ main.l
     
    comp: scanner.h scanner.c lex.yy.c
        g++ -o cpyrr lex.yy.c scanner.c -lfl -ly
    Le problème vient du fait que je rencontre l'erreur suivante :

    /cygdrive/c/Users/BOB/AppData/Local/Temp/ccyHUZxZ.o:scanner.c.text+0x8): undefined reference to `vtable for parser'
    /cygdrive/c/Users/BOB/AppData/Local/Temp/ccyHUZxZ.o:scanner.c.text+0x16): undefined reference to `vtable for parser'
    collect2: ld returned 1 exit status
    Je souhaiterais pouvoir au minimum compiler et linker sans erreur et au mieux que le programme marche.
    Et il y a très peu de documentation sur Internet ou les Manpages concernant l'utilisation de bison++ ET flex++ sous cygwin. J'ai besoin de résoudre ce problème rapidement. J'ai besoin de ce programme pour l'utiliser dans un projet plus grand pour lequel le temps est compté.
    C'est dans l'urgence et à cours de solution que je m'en remet donc à votre aide.

    Merci.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 48
    Par défaut
    Bonjour,
    Es-tu sûr de bien compiler tous les fichiers .c ?
    J'ai peur que tu n'es pas tous les fichiers objets nécéssaire au link.
    Je ferais plutôt un makefile comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    all: yacc lex comp
     
    yacc: main.y
        bison++ -d -hscanner.h -oscanner.c main.y
     
    lex: main.l scanner.h
        flex++ main.l
     
    %.o : %.c
        g++ -o $@ $<
     
    comp: scanner.o lex.yy.o
        g++ -o cpyrr lex.yy.o scanner.o -lfl -ly

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Bonjour,

    Ce makefile ce résoud pas le problème et n'arrive pas à compiler.
    J'ai l'impression qu'il faut mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    %.o : %.c
    	g++ -c $@ $<
    au lieu de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    %.o : %.c
    	g++ -o $@ $<
    Et sinon dans all, il n'y a aucun n'appel vers la partir du Makefile qui crée le .o
    Du coup des .o ne sont pas compilés et cela ne marche pas.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 48
    Par défaut
    Bizarre...
    As tu bien modifié le makefile ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    %.o : %.c
        g++ -o $@ $<
     
    comp: scanner.o lex.yy.o
        g++ -o cpyrr lex.yy.o scanner.o -lfl -ly
    Avec lex.yy.o et scanner.o ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Oui j'ai modifié le Makefile exactement comme vous me l'avez indiqué.
    Et j'ai toujours exactement la même erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    /cygdrive/c/Users/BOB/AppData/Local/Temp/cc6Bpzku.o:scanner.c:(.text+0x8): undefined reference to `vtable for parse'
    /cygdrive/c/Users/BOB/AppData/Local/Temp/cc6Bpzku.o:scanner.c:(.text+0x16): undefined reference to `vtable for parse'
    collect2: ld returned 1 exit status
    make: *** [scanner.o] Error 1

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 48
    Par défaut
    Et dans l'autre sens ?
    Sans le code source c'est un peu difficile...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    %.o : %.c
        g++ -o $@ $<
     
    comp: scanner.o lex.yy.o
        g++ -o cpyrr scanner.o lex.yy.o -lfl -ly

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Non, ca ne marche pas mieux.

    Le code des fichiers à compiler est fourni dans mon premier post (main.l et main.y).

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 48
    Par défaut
    Désolé je sèche, j'ai essayé de compiler chez moi, et j'ai les mêmes erreurs...

  9. #9
    screetch
    Invité(e)
    Par défaut
    Salut,
    le probleme c'est qu'il manue l'implémentation des fonctions virtuelles, et bison++ s'attend a ce que tu lui donnes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    %define LEX_BODY {return ......yylex();}
    %define ERROR_BODY {cerr << "error...\n";}
    (au moins ces fonctions la, voire d'autres)
    je ne sais pas comment specifier la classe du lexer dans bison++ cependant, l'exemple dit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    %define MEMBERS \
    private: yyFlexLexer lexer;
    mais je ne sais pas ou yyFlexLexer est défini

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Merci screetch,

    En effet ces deux lignes font grandement avancer les choses puisque j'arrive enfin à compiler.
    Cependant mon programme ne fait strictement rien. J'ai l'impression que la fonction main fait appel au parser mais que celui-ci n'appelle pas le lexer donc il ne lit pas les entrées et s'arrête.

    C'est peut-être là qu'intervient le fameux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    %define MEMBERS \
    private: yyFlexLexer lexer;
    Mais hélas je doute fort de la sémantique de ce code étant donné que yyFlexLexer n'est défini nulle part.

  11. #11
    screetch
    Invité(e)
    Par défaut
    en fait j'en etait au meme point, je crois que tu vas devoir faire une classe parente avec la fonction virtuelle pure (int yylex() = 0), sachant que lex en fournira l'implementation. peut etre d'autres tutoriaux peuvent t'aider.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Le problème c'est que je ne sais pas très bien manipuler tout ce qui est classes et méthodes virtuelles.

    Sur un site j'ai trouvé ceci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    virtual int yyFlexLexer::yylex 	( FLEXFIX)  	[virtual]
     
     
    Implements FlexLexer.
     
    Referenced by c_parser::yylex().
    Est-ce que cela signifie que je dois ajouter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    virtual int yylex() = 0;
    comme membres de la classe parser en utilisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    %define MEMBERS \
    protected: virtual int yylex() = 0;
    ?

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    En fait ce qui me pose problème c'est que je ne sais pas où définir cette classe parente ni comment.
    Avez-vous des liens vers des tutoriels ? Je ne trouve rien de satisfaisant avec mes recherches.

  14. #14
    screetch
    Invité(e)
    Par défaut
    je ne sais pas du tout en fait, j'ai toujours utilisé flex et bison (sans le ++) qui fonctionnent bien mieux et pour lesquels une quantité d'exemples existent.
    On peut peut etre tenter une deviation: pour quelle raison veux tu utiliser les versions ++? (sachant que les fichiers generes par flex et bison peuvent etre compilés par un compilateur C++)
    l'avantage principal de flex++ et bison++ c'est de pouvoir parser deux fichiers en parallèle et d'encapsuler le contexte, mais en general on s'en tire bien (mieux) avec flex et bison

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Pourquoi flex++ et bison++ ?
    Parce que le projet sur lequel je travaille est en C++ et que je ne préfère pas mélanger du code C et du C++.
    J'ai essayé flex avec l'option c++ et le résultat était affreux.

    Sinon j'ai trouvé mon bonheur :
    http://www-f9.ijs.si/~matevz/docs/C+...us19.html#l357

    Mais hélas, il me reste une erreur ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    %{
    #include <cstdlib>
    #include <iostream>
    #include <FlexLexer.h>
     
    class Scanner : public yyFlexLexer
    {
    };
     
     
    %}
     
    %name Parser
     
    %define MEMBERS    virtual ~Parser()   {} private: Scanner lexer;
     
    %define LEX_BODY {return lexer.yylex();}
     
    %define ERROR_BODY { std::cerr << "error encountered\n"; }
    Dans ce code qui constitue le début de mon fichier Yacc, j'ai une erreur qui survient à la compilation.

    error: ‘Scanner’ does not name a type
    Je ne comprends pas le problème, vu que la classe Scanner est clairement définie et que le code dans %{ %} se place avant la classe Parser dans le fichier de sortie.

  16. #16
    screetch
    Invité(e)
    Par défaut
    ils disent d'utiliser %header{ ... } dans le lien proposé. Tu as essayé?

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Oui j'ai essayé avec :

    car

    N'est pas reconnu par bison++ il faut mettre impérativement un '%' avant l'accolade fermante. Donc avec le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    %header{
     
    #include <cstdlib>
    #include <iostream>
    #include <FlexLexer.h>
     
    class Scanner : public yyFlexLexer
    {
    };
     
     
    %}
    J'obtient une autre erreur :

    C:\cygwin\bin\flexskel.h:307: error: redefinition of ‘class Scanner’
    main.y:8: error: previous definition of ‘class Scanner’
    Cela me paraît étrange vu que flexskel est un header statique ...

  18. #18
    screetch
    Invité(e)
    Par défaut
    ta classe dans le lexer devrait s'appeler yyFlexLexer
    apparemment tu as changé quelque chose pour qu'elle s'appelle Scanner?

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    Oui en effet dans main.l j'ai défini :
    Le conflit venait de la, vu que Scanner était défini dans le lexer et dans main.y.

    Par contre je me retrouve face à un autre problème :

    undefined reference to `yyFlexLexer::yyFlexLexer(std::basic_istream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*)'
    undefined reference to `yyFlexLexer::~yyFlexLexer()'
    undefined reference to `yyFlexLexer::yylex()'
    Apparement il est impossible de trouver ces fonctions.
    Est-ce que je dois ajouter leurs prototypes dans la déclaration de la classe Scanner ?

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 22
    Par défaut
    A propos, ceci est valable si je modifie les membres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %define MEMBERS    virtual ~Parser()   {} private: yyFlexLexer lexer;
    au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %define MEMBERS    virtual ~Parser()   {} private: Scanner lexer;
    Sinon j'ai beaucoup plus d'erreurs au niveau du linker.

Discussions similaires

  1. Réponses: 0
    Dernier message: 17/03/2012, 19h08
  2. erreur programmation bison\flex
    Par lucastof dans le forum Linux
    Réponses: 0
    Dernier message: 26/01/2011, 20h51
  3. tuto pour bison flex ou lex yacc
    Par Patnel dans le forum Générateurs de compilateur
    Réponses: 4
    Dernier message: 20/10/2010, 07h50
  4. GCC bison flex
    Par m3asmi dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 05/06/2010, 15h48
  5. Réponses: 1
    Dernier message: 09/12/2006, 10h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo