From ab0c3bedae9db85b428899cbc5969d6a222dc182 Mon Sep 17 00:00:00 2001 From: Jack Cloudman Date: Wed, 15 May 2019 07:03:10 -0500 Subject: [PATCH] Add Symbol table like hoc 3 --- Makefile | 4 ++-- Objects/LLang.l | 18 +++++++++++++----- Objects/LLang.y | 24 +++++++++++++++++++++--- Objects/Symbol.c | 39 +++++++++++++++++++++++++++++++++++++++ include/Object.h | 1 - include/Symbol.h | 20 ++++++++++++++++++++ 6 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 Objects/Symbol.c create mode 100644 include/Symbol.h diff --git a/Makefile b/Makefile index 8e73f8d..2a2be45 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ Gram=Objects/y.tab.c Objetcs/y.tab.h -all: $(Gram) Objects/lex.yy.c Objects/Object.c Objects/stringObject.c Objects/listObject.c Objects/intObject.c Objects/init.c Objects/abstract.c - @gcc -I include -o Lala Objects/y.tab.c Objects/lex.yy.c Objects/Object.c Objects/stringObject.c Objects/listObject.c Objects/intObject.c Objects/init.c Objects/abstract.c +all: $(Gram) Objects/lex.yy.c Objects/Object.c Objects/stringObject.c Objects/listObject.c Objects/intObject.c Objects/init.c Objects/abstract.c Objects/Symbol.c + @gcc -I include -o Lala Objects/y.tab.c Objects/lex.yy.c Objects/Object.c Objects/stringObject.c Objects/listObject.c Objects/intObject.c Objects/init.c Objects/abstract.c Objects/Symbol.c @echo Compiled $(Gram): Objects/LLang.y diff --git a/Objects/LLang.l b/Objects/LLang.l index 02d60e5..ab093d4 100644 --- a/Objects/LLang.l +++ b/Objects/LLang.l @@ -3,7 +3,7 @@ #include #include #include "Lala.h" -#define YYSTYPE APLLObject +#include "Symbol.h" #include "y.tab.h" extern LLIntObject* LLInt_Make(int); extern LLStringObject* LLString_Make(char*); @@ -12,24 +12,32 @@ extern YYSTYPE yylval; %} /* Add your Flex definitions here */ /* Some definitions are already provided to you*/ -op [-+*\/()] +op [-+*\/()=] ws [ \t]+ digits [0-9] number (0|[1-9]+{digits}*)\.?{digits}* STRING \"(\\.|[^"\\])*\" +VAR [_]*[a-zA-Z][a-zA-Z0-9_]* %% +{VAR} { + Symbol *s; + if((s=lookup(yytext))==0) + s = install(yytext,INDEF,0); + yylval.sym = s; + return s->type==INDEF?VAR:s->type; +} {number} { int dato; RmWs(yytext); sscanf(yytext,"%d",&dato); - yylval=(LLObject*) LLInt_Make(dato); + yylval.val=(LLObject*) LLInt_Make(dato); return object;} {op} | \n {return *yytext;} {ws} { /* Do nothing */ } . { /* Do nothing */ } {STRING} { - yylval = (LLObject*)LLString_Make(yytext); + yylval.val = (LLObject*)LLString_Make(yytext); return object; } %% @@ -45,4 +53,4 @@ void RmWs(char* str) { j++; } str[j] = '\0'; -} \ No newline at end of file +} diff --git a/Objects/LLang.y b/Objects/LLang.y index 66d7f98..8a8dafd 100644 --- a/Objects/LLang.y +++ b/Objects/LLang.y @@ -2,25 +2,43 @@ #include #include "Lala.h" #include "abstract.h" +#include "Symbol.h" void yyerror (char *s); int yylex (); void warning(char *s, char *t); extern void init(); %} -%token object +%union { + LLObject* val; + Symbol *sym; +} +%token object +%token VAR BLTIN INDEF +%type exp asgn + +%right '=' %left '+' '-' %left '*' '/' %% list: | list'\n' - | list exp '\n' {LL_FUNC_PRINT($2,"\n");printf(">>> ");} + | list exp '\n' {LL_FUNC_PRINT($2,"\n");printf(">>> ");} + | list asgn '\n' {printf(">>> ");} + | list error '\n' {yyerrok;} + ; +asgn: VAR '=' exp {$$=$1->u.val=$3; $1->type=VAR;} ; exp: object { $$ = $1;} + | VAR {if($1->type == INDEF) + printf("Error: '%s' no esta definido\n",$1->name); + $$ = $1->u.val;} + | asgn | exp '+' exp { $$ = LL_FUNC_ADD($1,$3); } | exp '-' exp { $$ = LL_FUNC_SUB($1,$3); } | exp '*' exp { $$ = LL_FUNC_MUL($1,$3);} | exp '/' exp { $$ = LL_FUNC_DIV($1,$3); } | '(' exp ')' { $$ = $2;} + |BLTIN '(' exp ')' { $$=(*($1->u.ptr))($3);} ; %% #include @@ -40,4 +58,4 @@ void warning(char *s, char *t){ fprintf (stderr, "%s: %s", progname, s); if(t) fprintf (stderr, " %s", t); -} \ No newline at end of file +} diff --git a/Objects/Symbol.c b/Objects/Symbol.c new file mode 100644 index 0000000..4e5638a --- /dev/null +++ b/Objects/Symbol.c @@ -0,0 +1,39 @@ +#include "Symbol.h" +static Symbol *symlist=0; /* tabla de simbolos: lista ligada */ + +Symbol *lookup(char *s) /* encontrar s en la tabla de símbolos */ +{ + Symbol *sp; + for (sp = symlist; sp != (Symbol *)0; sp = sp->next){ + if (strcmp(sp->name, s)== 0) + return sp; + } + return 0; /* 0 ==> no se encontró */ +} +/*La funcion install crea la variable en la tabla +de simbolos si esta que esta no existe*/ +Symbol *install(char *s,int t,LLObject* o) +{ + Symbol *sp; + char *emalloc(); + + sp = (Symbol *) emalloc(sizeof(Symbol)); + + sp->name = emalloc(strlen(s)+ 1) ; /* +1 para '\0' */ + strcpy(sp->name, s); + + sp->type = t; + sp->u.val = o; + sp->next = symlist; /* poner al frente de la lista */ + symlist = sp; + return sp; +} + +/* revisar el regreso desde malloc */ +char *emalloc(unsigned n){ + char *p; + p =(char*) malloc(n); + if(p == 0) + perror("out of memory"); + return p; +} \ No newline at end of file diff --git a/include/Object.h b/include/Object.h index e457666..32c1610 100644 --- a/include/Object.h +++ b/include/Object.h @@ -17,5 +17,4 @@ LLObject_HEAD }LLObject; typedef LLObject *APLLObject; - #define YYSTYPE APLLObject #endif diff --git a/include/Symbol.h b/include/Symbol.h new file mode 100644 index 0000000..54f216e --- /dev/null +++ b/include/Symbol.h @@ -0,0 +1,20 @@ +#ifndef __SYMBOL_H__ +#define __SYMBOL_H__ +#include "Lala.h" +#include +/*entrada a tabla de simbolos, +es una lista simplemente ligada*/ +typedef struct Symbol { + char *name; + short type; /* VAR, BLTIN, UNDEF */ + + union { + LLObject* val; /* si es VAR */ + LLObject* (*ptr)(); /* sí es BLTIN */ + } u; + + struct Symbol *next; /* para ligarse a otro */ +} Symbol; + +Symbol *install(char *s,int t, LLObject*), *lookup(char *s); +#endif