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