Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577

    [C] flex gcc ed espressioni regolari

    ho la necessità di verificare l'input per capire se ciò che sto leggendo fa parte di un certo linguaggio. Ho letto che con flex è possbile partendo da una espressione regolare, generare il codice C opportuno per quel linguaggio; il problema è riuscire a compilare quello che viene generato fa flex.

    Qualcuno ha esperienza in merito?

    grazie ovviamente

  2. #2
    Uhm, flex è un generatore di lexer, ovvero genera codice C in grado di fare il primo stadio di parsing di un certo linguaggio; a meno che tu non stia scrivendo un compilatore o un interprete, in genere è eccessivo usare flex... esattamente cosa stai cercando di fare?
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577
    sto scrivendo un piccolo interprete il quale, prima di eseguire un comando, deve capire se tale comando fa parte del linguaggio

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577
    nessuno ha mai usato flex?

  5. #5
    In buona sostanza flex viene usato per l'analisi lessicale e si usa spesso insieme a bison che effettua l'analisi sintattica.

    Quello che segue è un esempio di un piccolo interprete per un piccolo linguaggio di programmazione:

    symtab.h:
    codice:
    #ifndef SYMTAB_H
    #define SYMTAB_H
    
    #define HT_SIZE 251
    #define SCOPE_SIZE 4096
    
    typedef enum
    {
        T_INTEGER,
        T_REAL,
        T_STRING,
        T_BOOLEAN
    } enumTipo1;
    
    typedef enum
    {
        T_CONST,
        T_VAR
    } enumTipo2;
    
    typedef union
    {
        int iVal;
        double dblVal;
        char *strVal;
        enum {FALSE, TRUE} bVal;
    } Valore;
    
    typedef struct tagHashTable
    {
        char *Key;
        enumTipo1 Tipo1;
        enumTipo2 Tipo2;
        Valore Value;
        char bInizializzato;
        struct tagHashTable *next;
    } HashTable;
    
    typedef struct tagScope
    {
        int top;
        HashTable **stack[SCOPE_SIZE];
    } Scope;
    
    HashTable* htNewNode(char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato);
    int htFind(HashTable **pHashTable, char *Key, HashTable *pDati);
    void htInsert(HashTable **pHashTable, char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato);
    void htFree(HashTable* first);
    
    void scopeInit(Scope *pScope);
    void scopePush(Scope *pScope);
    int  scopePop(Scope *pScope);
    void scopeFree(Scope *pScope);
    int  scopeFind(Scope* pScope, char *Key, HashTable *pDati);
    int  scopeInsert(Scope *pScope, char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato);
    int scopeUpdateValue(Scope *pScope, char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato);
    
    
    #endif // SYMTAB_H
    symtab.c:
    codice:
    #include <stdio.h>
    #include <string.h>
    #include <malloc.h>
    
    #include "symtab.h"
    
    HashTable* htNewNode(char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato)
    {
        HashTable *n;
    
        n = (HashTable*)malloc(sizeof(HashTable));
    
        if( n == NULL )
            return NULL;
    
        n->Key = (char*)malloc(strlen(Key)+1);
        if ( n->Key == NULL )
        {
            free(n);
            return NULL;
        }
        strcpy(n->Key, Key);
        n->Tipo1 = t1;
        n->Tipo2 = t2;
        n->Value = v;
        n->bInizializzato = bInizializzato;
        n->next = NULL;
    
        if ( !bInizializzato )
        {
            switch(t1)
            {
            case T_INTEGER:
                n->Value.iVal = 0;
                break;
            case T_REAL:
                n->Value.dblVal = 0.0;
                break;
            case T_STRING:
                //n->Value.strVal = NULL;
                n->Value.strVal = (char*)malloc(sizeof(char)*1);
                strcpy(n->Value.strVal, "");
                break;
            case T_BOOLEAN:
                n->Value.bVal = FALSE;
                break;
            }
        }
    
        return n;
    }
    
    int htFind(HashTable **pHashTable, char *Key, HashTable *pDati)
    {
        int index = 0;
        HashTable *t;
        int a = 31415;
        int b = 27183;
        char *s = Key;
    
        for(; *s != '\0'; s++)
            index = (a*index + *s) % HT_SIZE;
        if ( index < 0 )
            index *= -1;
    
        t = pHashTable[index];
        while ( t != NULL )
        {
            if ( strcmp(t->Key, Key) == 0 )
            {
                pDati->Key = t->Key;
                pDati->Tipo1 = t->Tipo1;
                pDati->Tipo2 = t->Tipo2;
                pDati->Value = t->Value;
                pDati->bInizializzato = t->bInizializzato;
                return index;
            }
            t = t->next;
        }
    
        return -1;
    }
    
    void htInsert(HashTable **pHashTable, char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato)
    {
        int index = 0;
        HashTable *t = NULL;
        int a = 31415;
        int b = 27183;
        char *s = Key;
    
        for(; *s != '\0'; s++)
            index = (a*index + *s) % HT_SIZE;
        if ( index < 0 )
            index *= -1;
    
        t = pHashTable[index];
        if ( t == NULL )
        {
            pHashTable[index] = htNewNode(Key, t1, t2, v, bInizializzato);
            return;
        }
    
        while ( t != NULL )
        {
            if ( strcmp(t->Key, Key) == 0 )
            {
                //pHashTable[index]->pLista = ListAppend(pHashTable[index]->pLista, pos);
                printf("\nErrore: La chiave %s e' gia' presente nella hashtable\n", Key);
                return;
            }
            if ( t->next == NULL )
            {
                t->next = htNewNode(Key, t1, t2, v, bInizializzato);
                //t = t->next;
                //t->next = NULL;
                return;
            }
            t = t->next;
        }
    }
    
    void htFree(HashTable* first)
    {
        HashTable *n1 = first, *n2;
        while ( n1 != NULL )
        {
            n2 = n1->next;
            if ( n1->Key )
                free(n1->Key);
            if ( n1->Tipo1 == T_STRING )
            {
                if ( n1->Value.strVal )
                    free(n1->Value.strVal);
            }
            free(n1);
            n1 = n2;
        }
    }
    
    void scopeInit(Scope *pScope)
    {
        HashTable **pHT;
        int x;
    
        pScope->top = 0;
    
        pHT = (HashTable**)malloc(sizeof(HashTable*) * HT_SIZE);
        if ( pHT != NULL )
        {
            for ( x = 0; x < HT_SIZE; x++ )
            {
                pHT[x] = (HashTable*)malloc(sizeof(HashTable));
                if ( pHT[x] == NULL )
                {
                    printf("Memoria non sufficiente.\n");
                    return;
                }
                pHT[x] = NULL;
            }
        }
        else
        {
            printf("Memoria non sufficiente.\n");
            return;
        }
    
        pScope->stack[pScope->top] = pHT;
    
        for ( x = 1; x < SCOPE_SIZE; x++ )
            pScope->stack[x] = NULL;
    }
    
    void scopePush(Scope *pScope)
    {
        HashTable **pHT;
        int x;
    
        pScope->top++;
        if ( pScope->top > SCOPE_SIZE - 1 )
        {
            printf("Stack scope pieno!\n");
            pScope->top = SCOPE_SIZE - 1;
            return;
        }
    
        pHT = (HashTable**)malloc(sizeof(HashTable*) * HT_SIZE);
        if ( pHT != NULL )
        {
            for ( x = 0; x < HT_SIZE; x++ )
            {
                pHT[x] = (HashTable*)malloc(sizeof(HashTable));
                if ( pHT[x] == NULL )
                {
                    printf("Memoria non sufficiente.\n");
                    return;
                }
                pHT[x] = NULL;
            }
        }
        else
        {
            printf("Memoria non sufficiente.\n");
            return;
        }
    
        pScope->stack[pScope->top] = pHT;
    }
    
    int scopePop(Scope *pScope)
    {
        HashTable **pHT;
        int x;
    
        if ( pScope->top < 0 )
            return pScope->top;
    
        pHT = pScope->stack[pScope->top];
        for ( x = 0; x < HT_SIZE; x++)
            htFree(pHT[x]);
        free(pHT);
        pScope->stack[pScope->top] = NULL;
        pScope->top--;
    
        return pScope->top;
    }
    
    void scopeFree(Scope *pScope)
    {
        while ( scopePop(pScope) >= 0 )
            ;
    }
    
    int scopeFind(Scope* pScope, char *Key, HashTable *pDati)
    {
        HashTable **pHT;
        int x;
    
        for ( x = pScope->top; x >= 0; x-- )
        {
            pHT = pScope->stack[x];
            if ( htFind(pHT, Key, pDati) >= 0 )
            {
                return 1;
            }
        }
    
        return 0;
    }
    
    int scopeInsert(Scope *pScope, char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato)
    {
        HashTable **pHT;
        HashTable Dati;
    
        pHT = pScope->stack[pScope->top];
    
        if ( htFind(pHT, Key, &Dati) >= 0 )
        {
            printf("Errore: la variabile '%s' e' gia' stata dichiarata nello scope %d\n", Key, pScope->top);
            return 0;
        }
    
        htInsert(pHT, Key, t1, t2, v, bInizializzato);
    
        return 1;
    }
    
    int scopeUpdateValue(Scope *pScope, char *Key, enumTipo1 t1, enumTipo2 t2, Valore v, char bInizializzato)
    {
        HashTable **pHT;
        HashTable Dati;
        int x;
        int index;
    
        for ( x = pScope->top; x >= 0; x-- )
        {
            pHT = pScope->stack[x];
    
            index = htFind(pHT, Key, &Dati);
            if ( index >= 0 )
            {
                HashTable *pTable = pHT[index];
                while ( strcmp(pTable->Key, Key) != 0 )
                    pTable = pTable->next;
                pTable->Value = v;
                pTable->bInizializzato = bInizializzato;
                return 1;
            }
        }
    
        printf("Errore: variabile '%s' non dichiarata\n", Key);
        return 0;
    }
    ast.h:
    codice:
    #ifndef AST_H
    #define AST_H
    
    #include "symtab.h"
    
    typedef enum { typeCon, typeId, typeOpr } nodeEnum;
    
    /* Costanti */
    typedef struct
    {
        Valore value;
    } conNodeType;
    
    /* identificatori */
    typedef struct
    {
        char *name;
        char *uniqueName;
        Valore value;
        char bInizializzato;
    } idNodeType;
    
    /* operatori */
    typedef struct
    {
        int oper;                   /* operatori */
        int nops;                   /* numero di operandi */
        struct nodeTypeTag *op[1];  /* operandi */
    } oprNodeType;
    
    typedef struct nodeTypeTag
    {
        nodeEnum type;             
        enumTipo1 type1;
        enumTipo2 type2;
    
        union
        {
            conNodeType con;        /* costanti */
            idNodeType id;          /* identificatori */
            oprNodeType opr;        /* operatori */
        };
    } nodeType;
    
    nodeType *opr(int oper, int nops, ...);
    nodeType *id(char *name, char *uniqueName, enumTipo1 t1, enumTipo2 t2, Valore value, char bInizializzato);
    nodeType *con(enumTipo1 t1, Valore value);
    void freeNode(nodeType *p);
    
    #endif // AST_H
    ast.c:
    codice:
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <stdarg.h> 
    #include <string.h> 
    #include "ast.h" 
     
    #define SIZEOF_NODETYPE ((char *)&p->con - (char *)p) 
     
    extern void yyerror(char *s); 
     
    nodeType *con(enumTipo1 t1, Valore value) 
    { 
        nodeType *p = NULL; 
        size_t nodeSize; 
     
        nodeSize = SIZEOF_NODETYPE + sizeof(conNodeType); 
        if ((p = malloc(nodeSize)) == NULL) 
            yyerror("out of memory"); 
     
        p->type = typeCon; 
        p->type1 = t1; 
        p->type2 = T_CONST; 
        p->con.value = value; 
     
        return p; 
    } 
     
    nodeType *id(char *name, char *uniqueName, enumTipo1 t1, enumTipo2 t2, Valore value, char bInizializzato) 
    { 
        nodeType *p = NULL; 
        size_t nodeSize; 
     
        nodeSize = SIZEOF_NODETYPE + sizeof(idNodeType); 
        if ((p = malloc(nodeSize)) == NULL) 
            yyerror("out of memory"); 
     
        p->type = typeId; 
        p->type1 = t1; 
        p->type2 = t2; 
        p->id.name = (char*)malloc(sizeof(char)*strlen(name)+1); 
        strcpy(p->id.name, name); 
        p->id.uniqueName = (char*)malloc(sizeof(char)*strlen(uniqueName)+1); 
        strcpy(p->id.uniqueName, uniqueName); 
        p->id.value = value; 
        p->id.bInizializzato = bInizializzato; 
     
        return p; 
    } 
     
    nodeType *opr(int oper, int nops, ...) 
    { 
        va_list ap; 
        nodeType *p = NULL; 
        size_t nodeSize; 
        int i; 
     
        nodeSize = SIZEOF_NODETYPE + sizeof(oprNodeType) + 
            (nops - 1) * sizeof(nodeType*); 
        if ((p = malloc(nodeSize)) == NULL) 
            yyerror("out of memory"); 
     
        p->type = typeOpr; 
        p->opr.oper = oper; 
        p->opr.nops = nops; 
        va_start(ap, nops); 
        for (i = 0; i < nops; i++) 
            p->opr.op[i] = va_arg(ap, nodeType*); 
        va_end(ap); 
        return p; 
    } 
     
    void freeNode(nodeType *p) { 
        int i; 
     
        if (!p) return; 
        if (p->type == typeOpr) { 
            for (i = 0; i < p->opr.nops; i++) 
                freeNode(p->opr.op[i]); 
        } 
        free (p); 
    }

  6. #6
    main.c:
    codice:
    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>
    
    #include "ast.h"
    #include "symtab.h"
    #include "parser.h"
    
    extern FILE *yyin;
    extern int yyparse (nodeType **pTree, Scope *pScope, Scope **pScope2);
    
    Valore ex(nodeType *p, Scope *symtab)
    {
        static Valore valZero;
        valZero.iVal = 0;
    
        if (!p)
            return valZero;
    
        switch(p->type)
        {
        case typeCon:
            return p->con.value;
        case typeId:
            {
                HashTable Dati;
                Valore retVal;
                if ( scopeFind(symtab, p->id.uniqueName, &Dati) )
                {
                    retVal = Dati.Value;
                }
                else
                {
                    printf("Errore: X identificatore '%s' non dichiarato\n", p->id.name);
                    //printf("Errore: X identificatore non dichiarato\n");
                    retVal = valZero;
                }
                return retVal;
            }
        case typeOpr:
            {
                Valore retVal;
                Valore leftVal, rightVal;
                switch(p->opr.oper)
                {
                case WHILE:
                    while( ex(p->opr.op[0], symtab).iVal )
                        ex(p->opr.op[1], symtab);
                    return valZero;
                case IF:
                    if ( ex(p->opr.op[0], symtab).iVal )
                        ex(p->opr.op[1], symtab);
                    else if ( p->opr.nops > 2 )
                        ex(p->opr.op[2], symtab);
                    return valZero;
                case PRINT:
                    retVal = ex(p->opr.op[0], symtab);
                    printf("%d\n", retVal.iVal);
                    return valZero;
                case ';':
                    ex(p->opr.op[0], symtab);
                    return ex(p->opr.op[1], symtab);
                case '=':
                    retVal = ex(p->opr.op[1], symtab);
                    scopeUpdateValue(symtab, p->opr.op[0]->id.uniqueName, T_INTEGER, T_VAR, retVal, 1);
                    return retVal;
                case UMINUS:
                    retVal = ex(p->opr.op[0], symtab);
                    retVal.iVal = -retVal.iVal;
                case '+':
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal + rightVal.iVal;
                    return retVal;
                case '-':
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal - rightVal.iVal;
                    return retVal;
                case '*':
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal * rightVal.iVal;
                    return retVal;
                case '/':
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal / rightVal.iVal;
                    return retVal;
                case '<':
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal < rightVal.iVal;
                    return retVal;
                case '>':
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal > rightVal.iVal;
                    return retVal;
                case GE:
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal >= rightVal.iVal;
                    return retVal;
                case LE:
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal <= rightVal.iVal;
                    return retVal;
                case NE:
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal != rightVal.iVal;
                    return retVal;
                case EQ:
                    leftVal = ex(p->opr.op[0], symtab);
                    rightVal = ex(p->opr.op[1], symtab);
                    retVal.iVal = leftVal.iVal == rightVal.iVal;
                    return retVal;
                }
            }
        }
        return valZero;
    }
    
    int main(int argc, char *argv[])
    {
        nodeType *pTree = NULL;
        Scope myScope;
        Scope *myScope2 = NULL;
       
        if ( argc < 2 )
        {
            printf("Specificare il nome di un file, prego\n");
            return -1;
        }
    
        myScope2 = (Scope*)malloc(sizeof(Scope));
        if ( !myScope2 )
        {
            printf("Errore: memoria insufficiente\n");
            return -1;
        }
    
        yyin = fopen(argv[1], "r");
        if ( yyin == NULL )
        {
            printf("Errore nell'apertura del file '%s'\n", argv[1]);
            return -1;
        }
    
        scopeInit(&myScope);
        scopeInit(myScope2);
    
        if ( yyparse(&pTree, &myScope, &myScope2) == 0 )
        {
            ex(pTree, myScope2);
        }
        else
        {
            printf("Errore di parsing\n");
        }
    
        if ( !pTree )
            printf("\nAlbero nullo!!!\n");
    
        freeNode(pTree);
        scopeFree(&myScope);
        scopeFree(myScope2);
        free(myScope2);
    
        fclose(yyin);
    
        return 0;
    }
    lexer.l:
    codice:
    %{
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    #include "symtab.h"
    #include "ast.h"
    #include "parser.h"
    
    char buf[1024];
    char *s;
    
    void yyerror(char *);
    %}
    %x STRING
    
    %%
    
    [0-9]+          {
                        yylval.iValue = atoi(yytext);
                        return INTEGER_LITERAL;
                    }
                   
    (([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
                        yylval.dblValue = atof(yytext);
                        return REAL_LITERAL;
                    }
                   
               
    \"                 { BEGIN STRING; s = buf; }
    <STRING>\\n     { *s++ = '\n'; }
    <STRING>\\t     { *s++ = '\t'; }
    <STRING>\\\"     { *s++ = '\"'; }
    <STRING>\"         {
                        *s = 0;
                        BEGIN 0;
                        yylval.strValue = (char*)malloc(sizeof(char)*strlen(yytext)+1);
                        strcpy(yylval.strValue, yytext);
                        return STRING_LITERAL;                   
                    }
    <STRING>\n         { printf("stringa non valida."); exit(1); }
    <STRING>.         { *s++ = *yytext; }
               
    
    [-()<>=+*/;{},.] {
                        return *yytext;
                    }
    
    ">="            return GE;
    "<="            return LE;
    "=="            return EQ;
    "!="            return NE;
    "while"         return WHILE;
    "if"            return IF;
    "else"          return ELSE;
    "print"         return PRINT;
    "bool"          return BOOL;
    "int"           return INT;
    "real"          return REAL;
    "string"        return STRINGA;
    
    "false"         { yylval.iValue = 0; return BOOLEAN_LITERAL; }
    "true"          { yylval.iValue = 1; return BOOLEAN_LITERAL; }
    
    
    [A-Za-z][A-Za-z0-9]*    {
                                yylval.strValue = (char*)malloc(sizeof(char)*strlen(yytext)+1);
                                strcpy(yylval.strValue, yytext);
                                return ID;
                            }
    
    [ \t\n]+        ;       /* ignore whitespace */
    
    .               yyerror("Unknown character");
    %%
    int yywrap(void) {
        return 1;
    }

  7. #7
    parser.y:
    codice:
    %{
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include "symtab.h"
    #include "ast.h"
    
    static int currType = 0;
    static int uname = 0;
    char *strUname[21];
    
    int yylex(void);
    void yyerror(nodeType **pTree, Scope *pScope, Scope **pScope2, char *s);
    char *makeUniqueName(char *strName);
    %}
    
    %union {
        int iValue;                 /* interi e booleani */
        double dblValue;            /* valori in virgola mobile */   
        char *strValue;                /* stringhe */
        nodeType *nPtr;             /* puntatore al nodo dell'AST */
    };
    
    %token <strValue> ID
    %token <strValue> STRING_LITERAL
    %token <iValue> INTEGER_LITERAL
    %token <dblValue> REAL_LITERAL
    %token <iValue> BOOLEAN_LITERAL
    %token WHILE IF PRINT
    %token INT REAL BOOL STRINGA
    %nonassoc IFX
    %nonassoc ELSE
    
    %left GE LE EQ NE '>' '<'
    %left '+' '-'
    %left '*' '/'
    %nonassoc UMINUS
    
    %type <nPtr> program stmt expr stmt_list
    
    
    %parse-param {nodeType **pTree}
    %parse-param {Scope *pScope}
    %parse-param {Scope **pScope2}
    
    %%
    
    program:
            decl_list stmt_list               { *pTree = $2; }
            ;
    
    decl_list:
            decl
            | decl_list decl
            ;
           
    decl:    /* Vuoto */
            | type { sprintf(strUname, "%d", uname++); } var_list ';'
            ;       
           
    type:
            INT { currType = T_INTEGER; }
            | REAL { currType = T_REAL; }
            | BOOL { currType = T_BOOLEAN; }       
            | STRINGA { currType = T_STRING; }       
            ;       
           
    var_list:
            ID
            {
                Valore val;
                char *uniqueName;
                if ( currType == T_INTEGER )
                    val.iVal = 0;
                else if ( currType == T_REAL )
                    val.dblVal = 0.0;
                else if ( currType == T_BOOLEAN )
                    val.bVal = 0;
                else
                {
                    val.strVal = (char*)malloc(sizeof(char)*strlen($1)+1);
                    strcpy(val.strVal, yylval.strValue);
                }
                scopeInsert(pScope, $1, currType, T_VAR, val, 0);
                uniqueName = makeUniqueName($1);
                scopeInsert(*pScope2, uniqueName, currType, T_VAR, val, 0);
            }       
            | var_list ',' ID
            {
                Valore val;
                char *uniqueName;           
                if ( currType == T_INTEGER )
                    val.iVal = 0;
                else if ( currType == T_REAL )
                    val.dblVal = 0.0;
                else if ( currType == T_BOOLEAN )
                    val.bVal = 0;
                else
                {
                    val.strVal = (char*)malloc(sizeof(char)*strlen($3)+1);
                    strcpy(val.strVal, yylval.strValue);
                }           
                scopeInsert(pScope, $3, currType, T_VAR, val, 0);
                uniqueName = makeUniqueName($3);           
                scopeInsert(*pScope2, uniqueName, currType, T_VAR, val, 0);
            }
            ;       
           
    stmt_list:
              stmt                  { $$ = $1; }
            | stmt_list stmt        { $$ = opr(';', 2, $1, $2); }
            ;
           
    stmt:
              ';'                            { $$ = opr(';', 2, NULL, NULL); }
            | expr ';'                       { $$ = $1; }
            | PRINT expr ';'                 { $$ = opr(PRINT, 1, $2); }
            | ID '=' expr ';'                   {
                                                HashTable Dati;
                                                nodeType *nodePtr;
                                                char *uniqueName;               
                                                if ( !scopeFind(pScope, $1, &Dati) )
                                                {
                                                    yyerror(pTree, pScope, pScope2, "identificatore non dichiarato\n");
                                                    Dati.Tipo1 = T_BOOLEAN;
                                                    Dati.Tipo2 = T_VAR;
                                                    Dati.Value.bVal = 0;
                                                    Dati.bInizializzato = 0;
                                                    uniqueName = makeUniqueName($1);
                                                    return 1;
                                                }                                                                               
                                                uniqueName = makeUniqueName($1);                                           
                                                nodePtr = id($1, uniqueName,  Dati.Tipo1, Dati.Tipo2, Dati.Value, Dati.bInizializzato);
                                                $$ = opr('=', 2, nodePtr, $3);
                                             }
            | WHILE '(' expr ')' stmt        { $$ = opr(WHILE, 2, $3, $5); }
            | IF '(' expr ')' stmt %prec IFX { $$ = opr(IF, 2, $3, $5); }
            | IF '(' expr ')' stmt ELSE stmt { $$ = opr(IF, 3, $3, $5, $7); }
            | '{' { scopePush(pScope); } decl_list stmt_list '}'    { $$ = $4; scopePop(pScope); }
            ;
    
    expr:
              INTEGER_LITERAL       {
                                        Valore val;
                                        val.iVal = $1;
                                        $$ = con(T_INTEGER, val);
                                    }
              | REAL_LITERAL        {
                                        Valore val;
                                        val.dblVal = $1;
                                        $$ = con(T_REAL, val);
                                    }                               
              | BOOLEAN_LITERAL     {
                                        Valore val;
                                        val.bVal = $1;
                                        $$ = con(T_BOOLEAN, val);
                                    }
              | STRING_LITERAL      {
                                        Valore val;
                                        int len = strlen($1);                                                                       
                                        val.strVal = (char*)malloc(sizeof(char)*len+1);
                                        strcpy(val.strVal, $1);
                                        $$ = con(T_STRING, val);
                                    }                                                                                               
            | ID                    {
                                        HashTable Dati;       
                                        char *uniqueName;
                                        if ( !scopeFind(pScope, $1, &Dati) )
                                        {
                                            yyerror(pTree, pScope, pScope2, "identificatore non dichiarato\n");
                                            Dati.Tipo1 = T_BOOLEAN;
                                            Dati.Tipo2 = T_VAR;
                                            Dati.Value.bVal = 0;
                                            Dati.bInizializzato = 0;
                                            uniqueName = makeUniqueName($1);
                                            return 1;
                                        }                                   
                                        uniqueName = makeUniqueName($1);
                                        $$ = id($1, uniqueName, Dati.Tipo1, Dati.Tipo2, Dati.Value, Dati.bInizializzato);
                                    }
            | '-' expr %prec UMINUS { $$ = opr(UMINUS, 1, $2); }
            | expr '+' expr         { $$ = opr('+', 2, $1, $3); }
            | expr '-' expr         { $$ = opr('-', 2, $1, $3); }
            | expr '*' expr         { $$ = opr('*', 2, $1, $3); }
            | expr '/' expr         { $$ = opr('/', 2, $1, $3); }
            | expr '<' expr         { $$ = opr('<', 2, $1, $3); }
            | expr '>' expr         { $$ = opr('>', 2, $1, $3); }
            | expr GE expr          { $$ = opr(GE, 2, $1, $3); }
            | expr LE expr          { $$ = opr(LE, 2, $1, $3); }
            | expr NE expr          { $$ = opr(NE, 2, $1, $3); }
            | expr EQ expr          { $$ = opr(EQ, 2, $1, $3); }
            | '(' expr ')'          { $$ = $2; }
            ;
    
    %%
    
    void yyerror(nodeType **pTree, Scope *pScope, Scope **pScope2, char *s)
    {
        fprintf(stdout, "%s\n", s);
    }
    
    char *makeUniqueName(char *strName)
    {
        char *uniqueName;
        int len1, len2;
       
        len1 = strlen(strName);
        len2 = strlen(strUname);
        uniqueName = (char*)malloc(len1+len2+1);
        strcpy(uniqueName, strName);
       
        return strcat(uniqueName, strUname);
    }
    codice:
    bison -l -d -o parser.c parser.y
    flex -f -L -Ca -olexer.c lexer.l
    gcc -Wall -O2 main.c parser.c lexer.c ast.c symtab.c -o myparser
    Il primo comando utilizza bison e produce i file parser.c e parser.h
    Il secondo comando utilizza flex per produrre l'analizzatore lessicale, lexer.c

    Il programma prodotto da gcc va richiamato passandogli da riga di comando un file che contiene il programmino che vogliamo interpretare.
    Per esempio:

    prova.prg:
    codice:
    int x, y;
    
    x = 5;
    y = 8;
    
    print x + y;
    codice:
    ./myparser prova.prg
    output:
    codice:
    13
    prova2.prg:
    codice:
    int i;
    
    i = 0;
    
    while ( i < 10 )
    {
       print i;
       i = i + 1;
    }
    codice:
    ./myparser prova2.prg
    output:
    codice:
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

  8. #8
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577
    grazie per il tuo intervento.

    E' possibile ricavare con flex, ad esempio, un riconoscitore del codice fiscale?
    Tutto ciò partendo dall'espressione regolare che lo identifica

    [A-Z]{6}[0-9]{2}[A-Z][0-9]{2}[A-Z][0-9]{3}[A-Z]

  9. #9
    Quote Originariamente inviata da misterx Visualizza il messaggio
    grazie per il tuo intervento.

    E' possibile ricavare con flex, ad esempio, un riconoscitore del codice fiscale?
    Tutto ciò partendo dall'espressione regolare che lo identifica

    [A-Z]{6}[0-9]{2}[A-Z][0-9]{2}[A-Z][0-9]{3}[A-Z]
    Con flex puoi verificare la correttezza formale del codice fiscale immesso ma poi devi effettuare dei controlli aggiuntivi. Devi verificare, per esempio, che il codice del comune sia valido(e qui ti serve un database con i codici dei comuni d'Italia e stati esteri).


    Altro esempio facile facile, col solo flex.
    Il programma seguente serve a contare il numero di linee, parole e caratteri in un file di testo:
    codice:
    %option noyywrap
    
    %{
        int chars = 0;
        int words = 0;
        int lines = 0;
    %}
    
    %%
    
    [a-zA-Z]+ { words++; chars += strlen(yytext); }
    \n { chars++; lines++; }
    . { chars++; }
    
    %%
    
    int main(int argc, char **argv)
    {
        if(argc > 1)
        {
            if(!(yyin = fopen(argv[1], "r")))
            {
                perror(argv[1]);
                return -1;
            }
        }
        else
        {
            printf("Specificare il nome di un file, prego.\n");
        }
        
        yylex();
        
        printf("%8d%8d%8d\n", lines, words, chars);    
        
        return 0;
    }





  10. #10




    codici.txt:
    codice:
    LCCVCN98H05G273H
    ASDF415
    AZXSDF0145KFHF
    codfisc.l:
    codice:
    %option noyywrap
    
    %%
    
    [A-Z]{6}[0-9]{2}[A-Z][0-9]{2}[A-Z][0-9]{3}[A-Z] { printf("Codice fiscale valido: %s\n", yytext); }
    [a-zA-Z0-9]+ { printf("Codice fiscale non valido: %s\n", yytext); }
    . { printf("Carattere non valido: %c", yytext[0]); }
    
    %%
    
    int main(int argc, char **argv)
    {
        if(argc > 1)
        {
            if(!(yyin = fopen(argv[1], "r")))
            {
                perror(argv[1]);
                return -1;
            }
        }
        else
        {
            printf("Specificare il nome di un file, prego.\n");
        }
        
        yylex();
        
        return 0;
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.