8
votes

Comment utiliser Yylval avec des cordes dans YACC

Je veux transmettre la chaîne d'un jeton. Si j'ai un jeton appelé id, alors je veux que mon fichier YACC connaisse réellement ce que l'identifiant est appelé. Je dois transmettre une chaîne en utilisant Yylval vers le fichier YACC du fichier Flex. Comment puis-je faire ça?


1 commentaires

S'il vous plaît, au moins regarder la documentation avant de poser une question ici.


3 Réponses :


7
votes

voir La section manuelle Flex sur l'interface avec YACC .

15 Interface avec YACC H1>

Une des utilisations principales de Flex est en tant que compagnon au yacc analyseur-générateur. Les analyseurs YACC attendent appeler une routine nommée yylex () à Trouvez le prochain jeton d'entrée. La routine est censé retourner le type de prochain jeton ainsi que mettre tout Valeur associée dans le global Yylval. Utiliser Flex avec YACC, on spécifie l'option `-d 'à YACC pour l'instruire Pour générer le fichier y.tab.h contenant des définitions de tous les % de jetons apparaissant dans l'entrée YACC. Ce fichier est ensuite inclus dans le flex scanner. Par exemple, si l'un des Les jetons sont tok_number, une partie de la Scanner pourrait ressembler à: p>

     %{
     #include "y.tab.h"
     %}

     %%

     [0-9]+        yylval = atoi( yytext ); return TOK_NUMBER;


1 commentaires

Cela n'explique pas du tout comment retourner une chaîne depuis que YysType (non mentionné ici) est INT par défaut.



21
votes

La clé pour renvoyer une chaîne ou tout type complexe via Yylval est l'Union de YysType créée par YACC dans le fichier Y.TAB.H. Le YysType est une union avec un membre pour chaque type de jeton défini dans le fichier source YACC. Par exemple, pour renvoyer la chaîne associée à un jeton de symbole dans le fichier source YACC, vous déclarez cet union de YACTTYPE en utilisant %% Union strong> dans le fichier source YACC:

[A-Za-z_][A-Za-z0-9_]*  {{
    int i;

    /*
    * condition letter followed by zero or more letters
    * digits or underscores
    *      Convert matched text to uppercase
    *      Search keyword table
    *      if found
    *          return <keyword>
    *      endif
    * 
    *      set lexical value string to matched text
    *      return <SYMBOL>
    */

    /*** KEYWORDS and SYMBOLS ***/
    /* Here we match a keywords or SYMBOL as a letter
    * followed by zero or more letters, digits or 
    * underscores.
    */

    /* Convert the matched input text to uppercase */
    _strupr(yytext);         /* Convert to uppercase */

    /* First we search the keyword table */
    for (i = 0; i<NITEMS(keytable); i++) {
        if (strcmp(keytable[i].name, yytext)==0)
            return (keytable[i].token);
    }

    /* Return a SYMBOL since we did not match a keyword */
    yylval.str=_strdup(yytext);
    return (SYMBOL);
}}


0 commentaires

3
votes

Configuration du contexte fort>

Analyse de la syntaxe (Pour vérifier si un texte d'entrée suit une grammaire spécifiée) se composent de deux phases: p>

  1. TOKENISING, qui est fait par des outils tels que Lex ou Flex, avec interface YYLEX ()) et LI>
  2. L'analyse du flux de jeton généré à l'étape 1 (conformément à une grammaire spécifiée par l'utilisateur), qui est effectuée par des outils tels que Bison / Yacc avec l'interface Yyparse ()). LI> ol>

    en faisant Phase 1 forte>, donné un flux d'entrée, chaque appel à yylex () identifie un jeton (une chaîne de charme) et un yytext pointe vers le premier caractère de cette chaîne. Exemple: avec un flux d'entrée de "int x = 10;" et avec des règles Lex pour la tokénisation conforme au langage C, les 5 premiers appels à Yylex () identifieront les 5 jetons suivants "int", "x", "=", "10", "; Et chaque fois que le YyText pointera au premier caractère du jeton de retour. P>

    Phase 2 forte>, l'analyseur (que vous avez mentionné comme YACC) est un programme qui appelle cette fonction de yylex À chaque fois pour obtenir un jeton et utiliser ces jetons pour voir si cela correspond aux règles d'une grammaire. Ces appels à Yylex retourneront des jetons comme des codes entier. Par exemple, dans l'exemple précédent, les 5 premiers appels à Yylex () peuvent renvoyer les entiers suivants à l'analyseur: Type, ID, EQ_Operateur et Integer (dont les valeurs entières réelles sont définies dans certains fichiers d'en-tête). P>

    Maintenant que tous les analyseurs peuvent voir sont ces codes entier, ce qui peut ne pas être utile parfois. Par exemple, dans l'exemple de fonctionnement, vous souhaiterez peut-être associer le type à INT, ID à un pointeur de table de symboles et entier à décimal 10. Pour faciliter cela, chaque jeton est retourné par YYLEX avec une autre valeur dont le type par défaut est INT, mais Vous pouvez avoir des types personnalisés pour cela. Dans l'environnement Lex, cette valeur est accessible en Yylval. P>

    Par exemple, à nouveau selon l'exemple de fonctionnement, YYLEX peut avoir la règle suivante pour identifier 10 P>

    TYPE ID '=' VAL:  { //In this action part of the yacc rule, use $2 to get the symbol table pointer associated with ID, use $4 to get decimal 10.}
    


0 commentaires