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 :

Retour de fonction étrange dans Flex/Bison en C


Sujet :

Générateurs de compilateur

  1. #1
    Membre régulier
    Avatar de DjPoke
    Homme Profil pro
    Invalide temporaire
    Inscrit en
    Août 2005
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Invalide temporaire

    Informations forums :
    Inscription : Août 2005
    Messages : 93
    Points : 77
    Points
    77
    Billets dans le blog
    1
    Par défaut Retour de fonction étrange dans Flex/Bison en C
    Bonjour,

    J'aurais besoin de vos talents en matière de Flex/Bison car je suis face à un bug dont je ne comprend pas grand chose. J'ai beau chercher depuis des jours, rien n'y fait.

    Je suis en train de développer un interpréteur BASIC genre Amstrad CPC. (ci dessous la partie du code qui ne fonctionne bizarrement pas bien)
    1) functionstring retourne une chaine en fonction de ce que je lui rentre comme paramlist, qui est une liste de paramètres numériques ou chainés. Par exemple CHR$(65) me retournera le caractère 'A'.
    2) stringterm est donc un terme contenant une chaine de caractère, ou le résultat de la fonction CHR$.
    3) stringexp sera donc un stringterm ou plusieurs stringterm concaténés.
    4) param sera une liste d'expressions mathématiques et de chaines. Elles sont contenues dans une structure (dans le union principal)
    5) paramlist sera une combinaison de chaines stockées dans une structure (dans le union principal).

    Mon problème est que si je fais une somme de CHR$, j'ai des données qui se perdent dans stringexp, qui ne fonctionne pas comme je le souhaite.
    Par exemple, CHR$(65)+CHR$(66), qui est censé me retourner dans paramlist "AB", me retoune "BB".
    Et CHR$(65)+CHR$(66)+CHR$(67) me retourne carrément "CHR$(C".

    Auriez-vous une idée ?

    Merci d'avance.

    EDIT: Si j'affiche ce que contient $1 dans les parametres de stringterm, j'obtiens 'A' et 'B'.
    Si j'affiche ce que contient $1 dans stringexp: stringterm, j'obtiens 'A'.
    Mais si j'affiche $1 et $3 dans stringexp ADD stringterm, $1 contient l'erreur au lieu de 'A'. $3 contient 'B'.

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    functionstring:
    STRINGFUNC paramlist CP
    {
        int count = $2.count;
        if(strcmp($1,"CHR$(") == 0)
        {
            if(count == 1)
            {
                if($2.t[1] == _TYPEINT_)
                {
                    int i = $2.i[1];
                    if((i >= 0) && (i <= 255))
                    {
                        char c[2];
                        c[0] = (char)i;
                        c[1] = '\0';
                        $$ = c;
                    }
                    else
                    {
                        printf("Improper argument\n");
                        return;
                    }
                }
                else if($2.t[1] == _TYPEFLOAT_)
                {
                    int i = (int)$2.f[1];
                    if((i >= 0) && (i <= 255))
                    {
                        char c[2];
                        c[0] = (char)i;
                        c[1] = '\0';
                        $$ = c;
                    }
                    else
                    {
                        printf("Improper argument\n");
                        return;
                    }
                }
                else
                {
                    printf("Type mismatch\n");
                    return;
                }
            }
            else
            {
                printf("Syntax error\n");
                return;
            }
        }
        else {
            printf("Syntax error\n");
            return;
        }
    }
    ;
     
    paramlist:
    param
    | paramlist COMMA param
    {
        if(($3.t[$3.count] == _TYPEFLOAT_) || ($3.t[$3.count] == _TYPEINT_))
        {
            $$.count++;
            $$.t[$$.count] = $3.t[$3.count];
            $$.f[$$.count] = $3.f[$3.count];
            $$.i[$$.count] = $3.i[$3.count];
     
        }
        else {
            $$.count++;
            $$.t[$$.count] = $3.t[$3.count];
            $$.s[$$.count] = $3.s[$3.count];
        }
    }
    ;
     
    param:
    boolexp
    {
        $$.count = 1;
        $$.t[$$.count] = $1.t;
        $$.f[$$.count] = $1.f;
        $$.i[$$.count] = $1.i;
    }
    | stringexp
    {
        $$.count = 1;
        $$.t[$$.count] = _TYPESTRI_;
        $$.s[$$.count] = $1;
    }
    ;
     
    stringexp:
    stringterm { stype = _NOTYPE_; $$ = $1; }
    | stringexp ADD stringterm
    {
        if((stype == _NOTYPE_) || (stype == _TYPEADDSTRING_))
        {
            char* s=malloc(sizeof(char)*(strlen($1)+strlen($3)+1));
            strcpy(s,$1);
            strcat(s,$3);
            $$=s;
            free(s);
            stype = _TYPEADDSTRING_;
        }
        else {
            printf("Syntax error\n");
            return;
        }
    }
    | stringexp SEMICOLON stringterm
    {
        if((stype == _NOTYPE_) || (stype == _TYPESEMICOLONSTRING_))
        {
            char* s=malloc(sizeof(char)*(strlen($1)+strlen($3)+1));
            strcpy(s,$1);
            strcat(s,$3);
            $$=s;
            free(s);
            stype = _TYPESEMICOLONSTRING_;
        }
        else {
            printf("Syntax error\n");
            return;
        }
    }
    ;
     
    stringterm:
    STRING
    | functionstring
    ;

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il faudrait les connaître les membres associés de ta %union, leur type ainsi que leurs tokens associés, pour répondre efficacement.

    Mais déjà, je pense que tu devrais faire des fonctions, des vraies fonctions, pour parser un CHR$ et pour gérer la concaténation de deux chaînes.

    PS: Ton code Bison, il est censé faire immédiatement l'interprétation du code ou faire de la compilation? En gros, si on lui dit prenom$ + " " + nom$, est-il censé pisser un code/bytecode qui concatène (ou établir un arbre syntaxique), ou bien immédiatement lire et concaténer les variables?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre régulier
    Avatar de DjPoke
    Homme Profil pro
    Invalide temporaire
    Inscrit en
    Août 2005
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Invalide temporaire

    Informations forums :
    Inscription : Août 2005
    Messages : 93
    Points : 77
    Points
    77
    Billets dans le blog
    1
    Par défaut
    Voici ce que tu as demandé :

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    %{
    # include <stdio.h>
    # include <stdlib.h>
    # include <string.h>
    # include <math.h>
     
    extern char *linep;
     
    #define _NOTYPE_ 0
    #define _TYPEFLOAT_ 1
    #define _TYPEINT_ 2
    #define _TYPESTRING_ 3
    #define _TYPEADDSTRING_ 4
    #define _TYPESEMICOLONSTRING_ 5
     
    int stype;
     
    %}
     
    %union {
    	 struct number {
    		int t;
    		int i;
    		float f;
    	} nval;
    	struct prmtype {
    		int count;
    		int t[128];
    		int i[128];
    		float f[128];
    		char *s[128];
    	} pval;
    	int ival;
    	float fval;
    	char *strval;
    }
     
    %type <pval> paramlist param
    %type <nval> boolexp exp modfactor factor powterm term
    %type <nval> functionnumber  
    %type <strval> functionstring stringexp stringterm
    %token <fval> FLOAT
    %token <ival> INT
    %token MODULO ADD SUB MUL DIV RDIV EXPONENT AND OR
    %token OP CP
    %token LESS MORE LESSOREQUAL MOREOREQUAL EQUAL
    %token COLON
    %token SEMICOLON
    %token COMMA
    %token EOL
    %token <strval> STRING
    %token <strval> FLOATVAR
    %token <strval> INTVAR
    %token <strval> STRINGVAR
    %token <strval> NUMFUNC
    %token <strval> STRINGFUNC
     
    %%
    Sinon, mon code bison est censé faire l'interprétation d'une ligne de code BASIC à la fois.
    Il renverra soit un code d'erreur, soit une liste de paramètres correspondant à ce que mon code C/SDL mettra en application.

    EDIT: Dans les structure, par exemple nval, 't' correspond au type INT ou FLOAT, 'f' contient la valeur float d'un nombre et 'i' la même valeur en integer.
    EDIT2 : 't' prend respectivement les valeurs des constantes _TYPEINT_ ou _TYPEFLOAT_ selon les cas.
    EDIT3: Pour les fonctions comme ABS(n) ou CHR$(n), il execute directement le code...

  4. #4
    Membre régulier
    Avatar de DjPoke
    Homme Profil pro
    Invalide temporaire
    Inscrit en
    Août 2005
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Invalide temporaire

    Informations forums :
    Inscription : Août 2005
    Messages : 93
    Points : 77
    Points
    77
    Billets dans le blog
    1
    Par défaut
    J'ai remanié la partie du code qui semble buggée :

    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
    stringexp: stringterm
     | stringexp ADD stringterm {
    						printf("%s + %s\n",$1,$3);
    						if((stype == _TYPESTRING_) || (stype == _TYPEADDSTRING_)) {
    							char* s=malloc(sizeof(char)*(strlen($1)+strlen($3)+1));
    							strcpy(s,$1);
    							strcat(s,$3);
    							$$=s;
    							free(s);
    							stype = _TYPEADDSTRING_;
    						}
    						else {
    							printf("Syntax error\n");
    							return;
    						}						
    						printf("= %s\n",$$);
     }
    et voici le résultat des commandes printf :
    > "a"+"b"+"c"
    a + b
    = ab
    c + c
    = cc
    normalement cela devrait faire a+b = ab et ab + c = abc, non ?

    EDIT:
    Bon, en premier, il fallait ajouter un strdup pour obtenir un pointeur sur char dans ma fonction "functionstring", et en deuxième, le malloc dans stringexp ne fonctionnait pas bien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. retour d'un tableau dans une fonction
    Par FlyByck dans le forum Delphi
    Réponses: 3
    Dernier message: 19/01/2007, 00h00
  2. [Tableaux] Retour d'une variable dans une fonction
    Par Will Fou dans le forum Langage
    Réponses: 7
    Dernier message: 02/07/2006, 18h21
  3. [JSP]retour a la ligne dans fonction mailto
    Par logica dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 19/04/2006, 01h50
  4. Réponses: 1
    Dernier message: 25/01/2006, 10h30
  5. Utilisation d'un retour de fonction dans un decode
    Par CFVince dans le forum Oracle
    Réponses: 4
    Dernier message: 20/10/2005, 17h22

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