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;
}