diff --git a/.gitignore b/.gitignore index b9f8003..9110e5c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ grammar.tab.c grammar.tab.h .vscode out -src \ No newline at end of file +src +tmp \ No newline at end of file diff --git a/Makefile b/Makefile index 7ec4e72..44c2969 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,40 @@ CC := gcc FLEX := flex -LEX := lexicalStructure.lex +LEX := src/lexicalStructure.lex EXE := alpha CFLAGS := +YACC := bison + +compiler: tmp/grammar.tab.c tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o + $(CC) $(CFLAGS) -o $(EXE) tmp/runner.o tmp/lex.yy.c tmp/symbol_table.o + +tmp/grammar.tab.c: src/grammar.y + mkdir -p tmp + $(YACC) -d src/grammar.y + mv grammar.tab.c tmp/ + mv grammar.tab.h tmp/ + +tmp/lex.yy.c: src/lexicalStructure.lex + $(FLEX) -o tmp/lex.yy.c $(LEX) + mv flex.h tmp/ + +tmp/runner.o: src/runner.c src/runner.h tmp/flex.h + $(CC) $(CFLAGS) -o tmp/runner.o -c src/runner.c + +tmp/symbol_table.o: src/symbol_table.c src/symbol_table.h + $(CC) $(CFLAGS) -o tmp/symbol_table.o -c src/symbol_table.c + +parser : tmp/lex.yy.c tmp/grammar.tab.c + $(CC) -o parser tmp/lex.yy.c tmp/grammar.tab.c src/symbol_table.c + +runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o + $(CC) $(CFLAGS) -o $(EXE) tmp/runner.o tmp/lex.yy.c tmp/symbol_table.o -compiler: lex.yy.c runner.o runner -lex.yy.c: lexicalStructure.lex - $(FLEX) -o lex.yy.c $(LEX) -runner.o: runner.c runner.h flex.h - $(CC) $(CFLAGS) -o runner.o -c runner.c -symbol.o: symbol_table.c symbol_table.h - $(CC) $(CFLAGS) -o symbol_table.o symbol_table.c -runner: lex.yy.c runner.o symbol_table.o - $(CC) $(CFLAGS) -o $(EXE) runner.o lex.yy.c symbol_table.o -bison: grammar.y - bison -d grammar.y debug: CFLAGS += -DDEBUG=1 debug: clean compiler @@ -49,4 +64,5 @@ clean: rm -f grammar.tab.c rm -f grammar.tab.h rm -f *.st - rm -rf out \ No newline at end of file + rm -rf out + rm -rf tmp \ No newline at end of file diff --git a/grammar.y b/grammar.y deleted file mode 100644 index c174533..0000000 --- a/grammar.y +++ /dev/null @@ -1,64 +0,0 @@ -/* Syntax Analyzer with Bison (3.8.1) */ -/* (referenced Bison manual for file boilerplate [3.1]) */ - -// Prologue -%{ - #include -%} - -%token ID 101 -%token T_INTEGER 201 -%token T_ADDRESS 202 -%token T_BOOLEAN 203 -%token T_CHARACTER 204 -%token T_STRING 205 -%token C_INTEGER 301 -%token C_NULL 302 -%token C_CHARACTER 303 -%token C_STRING 304 -%token C_TRUE 305 -%token C_FALSE 306 -%token WHILE 401 -%token IF 402 -%token THEN 403 -%token ELSE 404 -%token TYPE 405 -%token FUNCTION 406 -%token RETURN 407 -%token EXTERNAL 408 -%token AS 409 -%token L_PAREN 501 -%token R_PAREN 502 -%token L_BRACKET 503 -%token R_BRACKET 504 -%token L_BRACE 505 -%token R_BRACE 506 -%token SEMI_COLON 507 -%token COLON 508 -%token COMMA 509 -%token ARROW 510 -%token ADD 601 -%token SUB_OR_NEG 602 -%token MUL 603 -%token DIV 604 -%token REM 605 -%token LESS_THAN 606 -%token EQUAL_TO 607 -%token ASSIGN 608 -%token NOT 609 -%token AND 610 -%token OR 611 -%token DOT 612 -%token RESERVE 613 -%token RELEASE 614 -%token COMMENT 700 - -%% - DBLOCK: %empty; - - FUNCTION_DECLARATION: FUNCTION ID COLON ID - | EXTERNAL FUNCTION ID COLON ID - ; - RECORD_DECLARATION: TYPE ID COLON DBLOCK; - ARRAY_DECLARATION: ID ASSIGN RESERVE ID L_PAREN C_INTEGER R_PAREN; -%% diff --git a/src/grammar.y b/src/grammar.y new file mode 100644 index 0000000..2302167 --- /dev/null +++ b/src/grammar.y @@ -0,0 +1,279 @@ +/* Syntax Analyzer with Bison (3.8.1) */ +/* (referenced Bison manual for file boilerplate [3.1]) */ + +// Prologue +%{ + #include + #include "symbol_table.c" + extern int yylex(void); + void yyerror(const char *err); + extern char* yytext; + extern int yychar; + SymbolTable * st; + //char* cur_value; + //char* cur_type; + int token_tracker; + extern int line_number; + extern int column_number; +%} + +%union { + int integ; + char * words; +} +//precedence order +%precedence RESERVE +%precedence RELEASE +%precedence DOT +%precedence SUB_OR_NEG +%precedence NOT +%left MUL +%left DIV +%left REM +%left ADD +//need subtraction only here +%left LESS_THAN +%left EQUAL_TO +%left AND +%left OR +%left ASSIGN + +%token ID 101 +%token T_INTEGER 201 +%token T_ADDRESS 202 +%token T_BOOLEAN 203 +%token T_CHARACTER 204 +%token T_STRING 205 +%token C_INTEGER 301 +%token C_NULL 302 +%token C_CHARACTER 303 +%token C_STRING 304 +%token C_TRUE 305 +%token C_FALSE 306 +%token WHILE 401 +%token IF 402 +%token THEN 403 +%token ELSE 404 +%token TYPE 405 +%token FUNCTION 406 +%token RETURN 407 +%token EXTERNAL 408 +%token AS 409 +%token L_PAREN 501 +%token R_PAREN 502 +%token L_BRACKET 503 +%token R_BRACKET 504 +%token L_BRACE 505 +%token R_BRACE 506 +%token SEMI_COLON 507 +%token COLON 508 +%token COMMA 509 +%token ARROW 510 +/* %token ADD 601 +%token SUB_OR_NEG 602 +%token MUL 603 +%token DIV 604 +%token REM 605 +%token LESS_THAN 606 +%token EQUAL_TO 607 +%token ASSIGN 608 +%token NOT 609 +%token AND 610 +%token OR 611 +%token DOT 612 +%token RESERVE 613 +%token RELEASE 614 */ +%token COMMENT 700 + + +%% + +program: + prototype_or_definition_list; + +prototype_or_definition_list: + prototype prototype_or_definition_list + | definition prototype_or_definition_list + | prototype + | definition + ; +prototype: + L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + +definition: + TYPE ID COLON dblock + | TYPE ID COLON constant ARROW ID + | TYPE ID COLON types ARROW ID + | FUNCTION ID COLON ID + | TYPE ID COLON ID ARROW ID + | ID parameter ASSIGN sblock + ; + +parameter: + L_PAREN ID R_PAREN + | AS L_PAREN idlist R_PAREN + ; + +idlist: + ID COMMA idlist + |ID + ; + +sblock: + L_BRACE {st = CreateScope(st,2,2);} statement_list {st = getParent(st);} R_BRACE + | L_BRACE {st = CreateScope(st,2,2);} dblock statement_list {st = getParent(st);} R_BRACE + ; + +dblock: + L_BRACKET declaration_list R_BRACKET; + +declaration_list: + declaration + {printf( + "declaration list a rule encountered"); + //CreateEntry(st,cur_type,cur_value); + } + SEMI_COLON declaration_list + | declaration + {printf( + "declaration rule b encountered"); + //CreateEntry(st,cur_type,cur_value); + } + ; + +declaration: + ID COLON ID { + + CreateEntry(st,strdup($1),strdup($3)); +// printf("declaration rule encountered"); +// if(cur_value != NULL){ +// char* delete1 = cur_value; +// printf("delete1 var assigned to cur_value"); +// free(delete1); +// printf("delete1 var freed"); +// } +// if(cur_type != NULL){ +// char* delete2 = cur_type; +// free(delete2);} +// int len = strlen($1); +// printf("length determined"); +// cur_value = malloc(len + 1); +// printf("space allocated"); +// strcpy(cur_value, $1); +// printf("string copied over"); + +// len = strlen($3); +// cur_type = malloc(len + 1); +// strcpy(cur_type, $3); +// printf("value var is %s type var is %s\n",cur_value,cur_type); + } + | types COLON ID + ; + +statement_list: + compound_statement statement_list + | compound_statement + | simple_statement SEMI_COLON statement_list + | simple_statement SEMI_COLON + ; + +compound_statement: + WHILE L_PAREN expression R_PAREN sblock + | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock + | sblock + ; + +simple_statement: + assignable ASSIGN expression + | RETURN expression + ; + +assignable: + ID + | assignable ablock + | assignable DOT ID + ; + +expression: + constant + | UnaryOperator expression + | assignable + | constant binaryOperator expression + | L_PAREN expression R_PAREN + | memOp assignable + ; + +ablock: + L_PAREN argument_list R_PAREN; + +argument_list: + expression COMMA argument_list + | expression + ; + +UnaryOperator: + SUB_OR_NEG + | NOT + ; + +memOp: + RESERVE + | RELEASE + ; + +binaryOperator: + ADD + | SUB_OR_NEG + | MUL + | DIV + | REM + | AND + | OR + | LESS_THAN + | EQUAL_TO + ; + +constant: + C_STRING + | C_INTEGER + | C_NULL + | C_CHARACTER + | C_TRUE + | C_FALSE + ; + +types: + T_STRING + | T_INTEGER + | T_ADDRESS + | T_CHARACTER + | T_BOOLEAN + ; +// +%% + +void yyerror(const char *err) { + // fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,line_number,column_number); +} + +int main() { + //char *str = strdup("taco"); + //cur_value = NULL; + //cur_type = NULL; + + token_tracker = 1; + st=CreateScope(NULL,1,1); + //int a; + yyparse(); + //while ((a = yyparse() != EOF){ + // token_tracker++; + //printf("%d = a: yytext = %s: yychar = %d, token number: %d\n", a, yytext, yychar,token_tracker); + //if(yytext[0] == '\n'){ + FILE* f = fdopen(1,"w"); + print_symbol_table(getAncestor(st),f); + fclose(f); + // break; + //} + //} + return 0; +} diff --git a/lexicalStructure.lex b/src/lexicalStructure.lex similarity index 98% rename from lexicalStructure.lex rename to src/lexicalStructure.lex index 64b2863..5f1f8ec 100644 --- a/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -6,11 +6,14 @@ %option header-file="flex.h" %{ #include - #include "typedefs.h" + //#include "typedefs.h" + #include "grammar.tab.h" int line_number = 1, column_number = 1; #ifndef DEBUG #define DEBUG 0 #endif + + %} STARCOM [^\*]|\*+[^\)\*]+ @@ -78,7 +81,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {return C_FALSE;}} "null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {return C_NULL;}} -{ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {return ID;}} +{ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {yylval.words = strdup(yytext); return ID;}} \n {line_number++; column_number = 1;} \t {column_number++;} diff --git a/runner.c b/src/runner.c similarity index 99% rename from runner.c rename to src/runner.c index 49821f5..6e0a61b 100644 --- a/runner.c +++ b/src/runner.c @@ -81,7 +81,8 @@ int run(FILE *alpha) { } if(token == 1999){ printf("On line number %d and column number %d we have an invalid character:%s\n",line_number,column_number,yytext); - } + //return -1; +} column_number += yyleng; } diff --git a/runner.h b/src/runner.h similarity index 97% rename from runner.h rename to src/runner.h index 8c83748..63d6fd2 100644 --- a/runner.h +++ b/src/runner.h @@ -8,7 +8,7 @@ #include #include #include -#include "flex.h" +#include "../tmp/flex.h" #include "typedefs.h" #include #include "symbol_table.h" diff --git a/src/symbol_table.c b/src/symbol_table.c new file mode 100644 index 0000000..48a7a42 --- /dev/null +++ b/src/symbol_table.c @@ -0,0 +1,145 @@ +#include "symbol_table.h" + +#include +#include +#include + +SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { + SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable)); + table->Line_Number = Line; + table->Column_Number = Column; + table->Parent_Scope = ParentScope; + table->Children_Scope = NULL; + table->entries = NULL; + if (ParentScope != NULL) { + if (ParentScope->Children_Scope == NULL) { + ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); + newEntry->next = NULL; + // newEntry->prev = NULL; + newEntry->table = table; + ParentScope->Children_Scope = newEntry; + } else { + ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); + // newEntry->prev = NULL; + newEntry->table = table; + ListOfTable* oldEntry = ParentScope->Children_Scope; + ParentScope->Children_Scope = newEntry; + newEntry->next = oldEntry; + } + } + return table; +} + +TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) { + TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); + newEntry->theType = typeOf; + newEntry->theName = id; + if (table->entries == NULL) { + table->entries = newEntry; + return newEntry; + } else { + TableNode* oldEntry = table->entries; + table->entries = newEntry; + newEntry->next = oldEntry; + return newEntry; + } +} +TableNode* table_lookup(SymbolTable* table, char* x) { + TableNode* entrie = table->entries; + for (; entrie != NULL; entrie = entrie->next) { + if (!strcmp(entrie->theName, x)) { + return entrie; + } + } + return NULL; +} +TableNode* look_up(SymbolTable* table, char* x) { + if (table == NULL) { + return NULL; + } + TableNode* ret = table_lookup(table, x); + if (ret != NULL) { + return ret; + } + return look_up(table->Parent_Scope, x); +} + +void print_symbol_table(SymbolTable* table, FILE* file_ptr) { + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", + "PARENT", "TYPE", "Extra annotation"); + } + TableNode* entrie = table->entries; + fprintf(file_ptr, + "-----------------:--------:--------:----------------------:---------" + "--------------------\n"); + int parant_scope = 0; + int current_scope = 0; + if (table->Parent_Scope != NULL) { + parant_scope = table->Parent_Scope->Line_Number * 1000 + + table->Parent_Scope->Column_Number; + current_scope = table->Line_Number * 1000 + table->Column_Number; + } else { + current_scope = 1001; + } + + for (; entrie != NULL; entrie = entrie->next) { + if (parant_scope == 0) { + fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n", + entrie->theName, current_scope, entrie->theType, + "Extra annotation"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, + current_scope, parant_scope, entrie->theType, "Extra annotation"); + } + } + if (table->Children_Scope != NULL) { + ListOfTable* node = table->Children_Scope; + for (; node != NULL; node = node->next) { + print_symbol_table(node->table, file_ptr); + } + } + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, + "-----------------:--------:--------:----------------------:-------" + "----------------------\n"); + } +} + +SymbolTable* getAncestor(SymbolTable* table) { + if (table->Parent_Scope == NULL) { + // if table has no parent, return itself + return table; + } else { + // call function recursively to grab ancestor + return getAncestor(table->Parent_Scope); + } +} + +SymbolTable* getParent(SymbolTable* st) { return st->Parent_Scope; } + +ListOfTable* getChildren(SymbolTable* st) { return st->Children_Scope; } +SymbolTable* getFirstChild(ListOfTable* lt) { return lt->table; } +ListOfTable* getRestOfChildren(ListOfTable* lt) { return lt->next; } +TableNode* getFirstEntry(SymbolTable* st) { return st->entries; } +TableNode* getNextEntry(TableNode* tn) { return tn->next; } +char* getType(TableNode* tn) { return tn->theType; } +char* getName(TableNode* tn) { return tn->theName; } +int getLine(SymbolTable* st) { return st->Line_Number; } +int getColumn(SymbolTable* st) { return st->Column_Number; } +// uncomment the below main function along with the headers above for a simple +// standalone test of table and entry creation + +/* +int main(){ + char* String = "STRING"; + char* X = "X"; + SymbolTable* Second = CreateScope(NULL, 2,2); + printf("Line number is %d, Column number of scope is +%d\n",Second->Line_Number,Second->Column_Number); TableNode* First_Entry = +CreateEntry(Second,String,X); + + printf("The type of the first entry is %s\n",First_Entry->theType); + return 0; + } + */ diff --git a/src/symbol_table.h b/src/symbol_table.h new file mode 100644 index 0000000..0ef5c8a --- /dev/null +++ b/src/symbol_table.h @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +typedef struct ListOfTable { + struct SymbolTable* table; + // struct ListOfTable* prev; + struct ListOfTable* next; + +} ListOfTable; + +typedef struct TableNode { + char* theType; + char* theName; + struct TableNode* next; +} TableNode; + +typedef struct SymbolTable { + TableNode* entries; + struct SymbolTable* Parent_Scope; + struct ListOfTable* Children_Scope; + int Line_Number; + int Column_Number; +} SymbolTable; + +SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column); +TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id); +TableNode* table_lookup(SymbolTable* table, char* x); +TableNode* look_up(SymbolTable* table, char* x); +void print_symbol_table(SymbolTable* table, FILE* file_ptr); + +SymbolTable* getAncestor(SymbolTable* table); +SymbolTable* getParent(SymbolTable* st); +ListOfTable* getChildren(SymbolTable* st); +SymbolTable* getFirstChild(ListOfTable* lt); +ListOfTable* getRestOfChildren(ListOfTable* lt); +TableNode* getFirstEntry(SymbolTable* st); +TableNode* getNextEntry(TableNode* tn); +char* getType(TableNode* tn); +char* getName(TableNode* tn); +int getLine(SymbolTable* st); +int getColumn(SymbolTable* st); \ No newline at end of file diff --git a/typedefs.h b/src/typedefs.h similarity index 100% rename from typedefs.h rename to src/typedefs.h diff --git a/symbol_table.c b/symbol_table.c deleted file mode 100644 index e87ebd8..0000000 --- a/symbol_table.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include -#include - -#include "symbol_table.h" - -SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column){ - SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable)); - table->Line_Number = Line; - table->Column_Number = Column; - table->Parent_Scope = ParentScope; - table->Children_Scope = NULL; - table->entries = NULL; - if(ParentScope != NULL){ - if(ParentScope->Children_Scope == NULL){ - ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); - newEntry->next = NULL; - //newEntry->prev = NULL; - newEntry->table = table; - ParentScope->Children_Scope = newEntry; - } else{ - ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); - //newEntry->prev = NULL; - newEntry->table= table; - ListOfTable* oldEntry = ParentScope->Children_Scope; - ParentScope->Children_Scope = newEntry; - newEntry->next = oldEntry; - } - } - return table; - } - - -TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id){ - TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - newEntry->theType = typeOf; - newEntry->theName = id; - if(table->entries == NULL){ - table->entries = newEntry; - return newEntry; - } else{ - TableNode* oldEntry = table->entries; - table->entries = newEntry; - newEntry->next = oldEntry; - return newEntry; - } -} -TableNode * table_lookup(SymbolTable * table, char * x){ - TableNode * entrie = table->entries; - for(; entrie != NULL; entrie = entrie->next){ - if (!strcmp(entrie->theName, x)){ - return entrie; - } - } - return NULL; -} -TableNode * look_up(SymbolTable * table, char * x){ - if(table == NULL){ - return NULL; - } - TableNode * ret = table_lookup(table, x); - if (ret != NULL){ - return ret; - } - return look_up(table->Parent_Scope, x); -} -void print_symbol_table(SymbolTable *table, FILE *file_ptr){ - if(table->Parent_Scope == NULL){ - fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); - } - TableNode * entrie = table->entries; - fprintf(file_ptr, "-----------------:--------:--------:----------------------:-----------------------------\n"); - int parant_scope = 0; - int current_scope = 0; - if(table->Parent_Scope != NULL){ - parant_scope = table->Parent_Scope->Line_Number*1000 + table->Parent_Scope->Column_Number; - current_scope = table->Line_Number*1000 + table->Column_Number; - } else { - current_scope = 1001; - } - - for(; entrie != NULL; entrie = entrie->next){ - if (parant_scope == 0){ - fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->theType, "Extra annotation"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->theType, "Extra annotation"); - } - } - if (table->Children_Scope != NULL){ - ListOfTable* node = table->Children_Scope; - for(; node != NULL; node = node->next){ - print_symbol_table(node->table, file_ptr); - } - } - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "-----------------:--------:--------:----------------------:-----------------------------\n"); - } -} - -//uncomment the below main function along with the headers above for a simple standalone test of table and entry creation - -/* -int main(){ - char* String = "STRING"; - char* X = "X"; - SymbolTable* Second = CreateScope(NULL, 2,2); - printf("Line number is %d, Column number of scope is %d\n",Second->Line_Number,Second->Column_Number); - TableNode* First_Entry = CreateEntry(Second,String,X); - - printf("The type of the first entry is %s\n",First_Entry->theType); - return 0; - } - */ diff --git a/symbol_table.h b/symbol_table.h deleted file mode 100644 index 57ae1bc..0000000 --- a/symbol_table.h +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include - -typedef struct ListOfTable{ - struct SymbolTable* table; - //struct ListOfTable* prev; - struct ListOfTable* next; - -}ListOfTable; - -typedef struct TableNode{ - char* theType; - char* theName; - struct TableNode* next; -}TableNode; - -typedef struct SymbolTable{ - TableNode* entries; - struct SymbolTable* Parent_Scope; - struct ListOfTable* Children_Scope; - int Line_Number; - int Column_Number; -}SymbolTable; - - -TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id); -SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column); -TableNode * table_lookup(SymbolTable * table, char * x); -TableNode * look_up(SymbolTable * table, char * x); -void print_symbol_table(SymbolTable *table, FILE *file_ptr); diff --git a/tests/sprint2/other/calc.h b/tests/sprint2/other/calc.h new file mode 100644 index 0000000..2580e93 --- /dev/null +++ b/tests/sprint2/other/calc.h @@ -0,0 +1,48 @@ +/* Function type. */ +typedef double (func_t) (double); +/* Data type for links in the chain of symbols. */ +struct symrec +{ + char *name; /* name of symbol */ + int type; /* type of symbol: either VAR or FUN */ + union + { + double var; /* value of a VAR */ + func_t *fun; /* value of a FUN */ + } value; + struct symrec *next; /* link field */ +}; +typedef struct symrec symrec; + +/* The symbol table: a chain of 'struct symrec'. */ +extern symrec *sym_table; + +symrec *putsym (char const *name, int sym_type); +symrec *getsym (char const *name); +struct init +{ + char const *name; + func_t *fun; +}; +struct init const funs[] = +{ + { "atan", atan }, + { "cos", cos }, + { "exp", exp }, + { "ln", log }, + { "sin", sin }, + { "sqrt", sqrt }, + { 0, 0 }, +}; +/* The symbol table: a chain of 'struct symrec'. */ +symrec *sym_table; +/* Put functions in table. */ +static void +init_table (void) +{ + for (int i = 0; funs[i].name; i++) + { + symrec *ptr = putsym (funs[i].name, FUN); + ptr->value.fun = funs[i].fun; + } +} diff --git a/test.c b/tests/sprint2/other/test.c similarity index 100% rename from test.c rename to tests/sprint2/other/test.c diff --git a/tests/sprint2/other/testGrammar.y b/tests/sprint2/other/testGrammar.y new file mode 100644 index 0000000..04f8f17 --- /dev/null +++ b/tests/sprint2/other/testGrammar.y @@ -0,0 +1,41 @@ +%{ + #include /* For printf, etc. */ + #include /* For pow, used in the grammar. */ + #include "calc.h" /* Contains definition of 'symrec'. */ + int yylex (void); + void yyerror (char const *); +%} +%define api.value.type union /* Generate YYSTYPE from these types: */ +%token NUM /* Double precision number. */ +%token VAR FUN /* Symbol table pointer: variable/function. */ +%nterm exp +%precedence '=' +%left '-' '+' +%left '*' '/' +%precedence NEG /* negation--unary minus */ +%right '^' /* exponentiation */ +%% /* The grammar follows. */ +input: + %empty +| input line +; +line: + '\n' +| exp '\n' { printf ("%.10g\n", $1); } +| error '\n' { yyerrok; } +; +exp: + NUM +| VAR { $$ = $1->value.var; } +| VAR '=' exp { $$ = $3; $1->value.var = $3; } +| FUN '(' exp ')' { $$ = $1->value.fun ($3); } +| exp '+' exp { $$ = $1 + $3; } +| exp '-' exp { $$ = $1 - $3; } +| exp '*' exp { $$ = $1 * $3; } +| exp '/' exp { $$ = $1 / $3; } +| '-' exp %prec NEG { $$ = -$2; } +| exp '^' exp { $$ = pow ($1, $3); } +| '(' exp ')' { $$ = $2; } +; +/* End of grammar. */ +%%