2010-02-14 15 views
1

J'écris un programme avec YACC/Flex et je suis en utilisant le code suivant (pas exactement la même chose parce que je mélange le code d'un autre fichier):types pour plusieurs membres

DataType datat; 
%union { 
    int integer; 
    char *string; 
    DataType type; 
} 

Integer { yylval.type = INTEGER; return INT; } 
%type <type> INT 
data : INTNUM { yylval.type = INTEGER; } 

Ensuite, si j'écris quelque chose comme ceci:

foo : data { bar(yylval.type); } 

bar reçoit correctement le type de données ENTIER, mais si j'ai ceci:

foo : data data { ??? } 

Comment puis-je obtenir le yylval.type pour le premier et le second membre séparément?

Merci beaucoup!

Répondre

1

Je ne comprends pas tout à fait votre question, mais dans lex/yacc (ou flex/bison) vous devez utiliser les conventions suivantes:

  • Utilisez 1 $ pour faire référence à la yylval du premier élément
  • utiliser 2 $ pour se référer à la yylval du second élément
  • Utiliser $$ pour se référer à la yylval de la résultante (cible) point

Exemples si vous écririez une simple calculatrice entier, la règle qui définit la somme, serait écrit quelque chose comme ceci:

Sum : Term '+' Term 
    { 
    $$.Value = $1.Value + $3.Value 
    } 

Hope this helps.

+0

Merci, mais * 1.type de $ * ou * $ 2.type * ne fonctionne pas pour moi. J'ai des erreurs de compilation. – Menda

+0

Regardez les manuels Lex et Yacc à http://dinosaur.compilertools.net/. Sur la page http://memphis.compilertools.net/interpreter.html vous pouvez trouver un simple interprète/calculatrice qui montre que vous devriez vraiment utiliser 1 $, 2 $, ... – Patrick

0

yylval.type vous renvoie le type du dernier jeton numérisé, ce qui pourrait être le nombre entier qui a obtenu réduit aux données, mais peut-être le jeton après. Vous ne devriez JAMAIS accéder à yylval directement dans le fichier yacc/bison, car ce n'est pas fiable. Au lieu de cela, vous devez utiliser $1, $2, etc pour accéder à l'information YYSTYPE des articles tel que noté par Patrick. Pour faire ce travail pour les non-terminaux, vous devez utiliser %type déclarations pour eux dans le yacc/fichier bison, et les règles pour les terminaux non besoin de définir $$, par exemple:

%type <type> data 

%% 

data : INTNUM { $$ = INTEGER; } 

foo : data { bar($1); } 

foo : data data { bar($1, $2); }