From bc5b48ec82b9e014736416e3ad44819ced54aa8c Mon Sep 17 00:00:00 2001 From: Victor Fernandes Date: Tue, 28 Mar 2017 12:01:07 -0400 Subject: [PATCH] h --- buffer.h | 2 +- platy_tt.c | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++++ scanner.c | 3 +- stable.c | 32 +++---- stable.h | 9 +- table.h | 4 +- 6 files changed, 302 insertions(+), 24 deletions(-) create mode 100755 platy_tt.c diff --git a/buffer.h b/buffer.h index 7ac4029..676c035 100755 --- a/buffer.h +++ b/buffer.h @@ -14,7 +14,7 @@ #define BUFFER_H_ #define MACOS_DEP -#undef MACOS_DEP +/*#undef MACOS_DEP /*#pragma warning(1:4001) *//*to enforce C89 type comments - to make //comments an warning */ /*#pragma warning(error:4001)*//* to enforce C89 comments - to make // comments an error */ diff --git a/platy_tt.c b/platy_tt.c new file mode 100755 index 0000000..7bb8524 --- /dev/null +++ b/platy_tt.c @@ -0,0 +1,276 @@ +/* File name: platy_tt.c + * Purpose:This is the main program for Assignment #3 - Symbol Table + * CST8152 - Compilers + * Version: 1.17.01 + * Author: Svillen Ranev + * Date: 1 March 2017 + */ + +/* The #define _CRT_SECURE_NO_WARNINGS should be used in MS Visual Studio projects + * to suppress the warnings about using "unsafe" functions like fopen() + * and standard sting library functions defined in string.h. + * The define does not have any effect in other compiler projects. + */ +#define _CRT_SECURE_NO_WARNINGS + + +#include +#include /* Constants for calls to exit()*/ + +#include +#include + +#include "buffer.h" +#include "token.h" +#include "stable.h" /*Do not remove this line. SiR */ +#include "stable.h" /*Do not remove this line. SiR */ + +/* constant definitions */ +/* Input buffer parameters */ +#define INIT_CAPACITY 200 /* initial buffer capacity */ +#define INC_FACTOR 15 /* increment factor */ +/* String Literal Table parameters */ +#define STR_INIT_CAPACITY 100 /* initial string literal table capacity */ +#define STR_CAPACITY_INC 50 /* initial string literal table capacity inc */ +/* Symbol Table default size */ +#define ST_DEF_SIZE 100 + +/*check for ANSI C compliancy */ +#define ANSI_C 0 +#if defined(__STDC__) +#undef ANSI_C +#define ANSI_C 1 +#endif + +/* Global objects - variables */ + +static Buffer *sc_buf; /* pointer to input (source) buffer */ +Buffer * str_LTBL; /* this buffer implements String Literal Table */ + /* it is used as a repository for string literals */ +int scerrnum; /* run-time error number = 0 by default (ANSI) */ +STD sym_table; /* Symbol Table Descriptor */ + +/*external objects */ +extern int line; /* source code line numbers - defined in scanner.c */ +extern int scanner_init(Buffer * sc_buf); +extern Token malar_next_token(Buffer * sc_buf); +/*function declarations */ +void err_printf(char *fmt, ...); +void display (Buffer *ptrBuffer); +long get_filesize(char *fname); +void garbage_collect(void); + +/* The main function takes a PLATYPUS source file and optional switches + * as command line arguments. + * usage: stable source_file_name [-stz size][-sts:A | -sts:D] + */ +int main(int argc, char ** argv){ + + FILE *fi; /* input file handle */ + Token t; /* token produced by the scanner */ + int loadsize = 0; /*the size of the file loaded in the buffer */ + int st_def_size = ST_DEF_SIZE; /* Sumbol Table default size */ + char sort_st = 0; /*Symbol Table sort switch */ + int ansi_c = !ANSI_C; /* ANSI C flag */ +/* Check if the compiler option is set to compile ANSI C */ +/* __DATE__, __TIME__, __LINE__, __FILE__, __STDC__ are predefined preprocessor macros*/ + if(ansi_c){ + err_printf("Date: %s Time: %s",__DATE__, __TIME__); + err_printf("ERROR: Compiler is not ANSI C compliant!\n"); + exit(1); + } + +/*check for correct arrguments - source file name */ + if (argc <= 1){ +/* __DATE__, __TIME__, __LINE__, __FILE__ are predefined preprocessor macros*/ + err_printf("Date: %s Time: %s",__DATE__, __TIME__); + err_printf("Runtime error at line %d in file %s", __LINE__, __FILE__); + err_printf("%s%s%s",argv[0],": ","Missing source file name."); + err_printf("%s%s%s","Usage: ", "stable", " source_file_name [-stz size][-sts:A | -sts:D]"); + exit(EXIT_FAILURE); + } + + /* check for optional switches - symbol table size and/or sort */ + if (argc == 3){ + if (strcmp(argv[2],"-sts:A") && strcmp(argv[2],"-sts:D") ){ + err_printf("%s%s%s",argv[0],": ","Invalid switch."); + err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]"); + exit(EXIT_FAILURE); + } +/*set sort switch*/ + if(strcmp(argv[2],"-sts:A")) + sort_st = 'D'; + else + sort_st = 'A'; + } +/* symbol table size specified */ + if (argc == 4){ + if (strcmp(argv[2],"-stz")){ + err_printf("%s%s%s",argv[0],": ","Invalid switch."); + err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]"); + exit(EXIT_FAILURE); + } +/* convert the symbol table size */ + st_def_size = atoi(argv[3]); + if (st_def_size <= 0){ + err_printf("%s%s%s",argv[0],": ","Invalid switch."); + err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]"); + exit(EXIT_FAILURE); + } + } +if (argc == 5){ + if (strcmp(argv[2],"-stz")){ + err_printf("%s%s%s",argv[0],": ","Invalid switch."); + err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]"); + exit(EXIT_FAILURE); + } +/* convert the symbol table size */ + st_def_size = atoi(argv[3]); + if (st_def_size <= 0){ + err_printf("%s%s%s",argv[0],": ","Invalid switch."); + err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]"); + exit(EXIT_FAILURE); + } + + if (strcmp(argv[4],"-sts:A")&& strcmp(argv[4],"-sts:D") ){ + err_printf("%s%s%s",argv[0],": ","Invalid switch."); + err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]"); + exit(EXIT_FAILURE); + } + + if(strcmp(argv[4],"-sts:A")) + sort_st = 'D'; + else + sort_st = 'A'; + } + +/* create a source code input buffer - multiplicative mode */ + sc_buf = b_create(INIT_CAPACITY,INC_FACTOR,'m'); + if (sc_buf == NULL){ + err_printf("%s%s%s",argv[0],": ","Could not create source buffer"); + exit(EXIT_FAILURE); + } + +/* create symbol table */ + sym_table = st_create(st_def_size); + if (!sym_table.st_size){ + err_printf("%s%s%s",argv[0],": ","Could not create symbol table"); + exit (EXIT_FAILURE); + } + +/*open source file */ + if ((fi = fopen(argv[1],"r")) == NULL){ + err_printf("%s%s%s%s",argv[0],": ", "Cannot open file: ",argv[1]); + exit (1); + } +/* load source file into input buffer */ + printf("Reading file %s ....Please wait\n",argv[1]); + loadsize = b_load (fi,sc_buf); + if(loadsize == R_FAIL1) + err_printf("%s%s%s",argv[0],": ","Error in loading buffer."); + +/* close source file */ + fclose(fi); +/*find the size of the file */ + if (loadsize == LOAD_FAIL){ + printf("The input file %s %s\n", argv[1],"is not completely loaded."); + printf("Input file size: %ld\n", get_filesize(argv[1])); + } +/* pack and display the source buffer */ + + if(b_pack(sc_buf)){ + display(sc_buf); + } + +/* create string Literal Table */ + str_LTBL = b_create(INIT_CAPACITY,INC_FACTOR,'a'); + if (str_LTBL == NULL){ + err_printf("%s%s%s",argv[0],": ","Could not create string buffer"); + exit(EXIT_FAILURE); + } + +/*registrer exit function */ + atexit(garbage_collect); + +/*Testbed for the scanner and the symbol table*/ +/* add SEOF to input program buffer*/ + b_addc(sc_buf,'\0'); + +/* Initialize the scanner*/ + if(scanner_init(sc_buf)){; + err_printf("%s%s%s",argv[0],": ","Empty program buffer - scanning canceled"); + exit(1); + } + + printf("Scanning source file...\n\n"); + + do{ + t= malar_next_token(sc_buf); + }while(t.code != SEOF_T); +/* print Symbol Table */ + if(sym_table.st_size){ + st_print(sym_table); + if(sort_st){ + printf("\nSorting symbol table...\n"); + st_sort(sym_table,sort_st); + st_print(sym_table); + } + } +/*Test bed for type and update functions */ + +/*Test bed for bonus*/ + return (0); /* same effect as exit(EXIT_SUCCESS) */ +} + +/* Error printing function with variable number of arguments + */ +void err_printf( char *fmt, ... ){ + + va_list ap; + va_start(ap, fmt); + + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + + /* Move to new line */ + if( strchr(fmt,'\n') == NULL ) + fprintf(stderr,"\n"); +} + +/* The function return the size of an open file + */ +long get_filesize(char *fname){ + FILE *input; + long flength; + input = fopen(fname, "r"); + if(input == NULL){ + err_printf("%s%s","Cannot open file: ",fname); + return 0; + } + fseek(input, 0L, SEEK_END); + flength = ftell(input); + fclose(input); + return flength; +} + +/* The function display buffer contents + */ +void display (Buffer *ptrBuffer){ + printf("\nPrinting input buffer parameters:\n\n"); + printf("The capacity of the buffer is: %d\n",b_capacity(ptrBuffer)); + printf("The current size of the buffer is: %d\n",b_size(ptrBuffer)); + printf("The reallocation flag is: %d\n",b_rflag(ptrBuffer)); + printf("\nPrinting input buffer contents:\n\n"); + b_print(ptrBuffer); +} + +/* The function frees all dynamically allocated memory. + This function is always called + despite how the program terminates - normally or abnormally. +*/ +void garbage_collect(void){ + printf("\nCollecting garbage...\n"); + b_free(sc_buf); + b_free(str_LTBL); + st_destroy(sym_table); +} diff --git a/scanner.c b/scanner.c index fee3d9a..f2a427a 100755 --- a/scanner.c +++ b/scanner.c @@ -175,7 +175,7 @@ Token malar_next_token(Buffer * sc_buf) if (c == '<') { /* It's a comment line */ /* Consume chars until line ends */ for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf)); - line++; + ++line; continue; } else { /* Bad character, pump out an error token */ @@ -187,6 +187,7 @@ Token malar_next_token(Buffer * sc_buf) t.attribute.err_lex[2] = '\0'; /* Consume the rest of the caracters to ignore the line*/ for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf)); + ++line; return t; } case '=': diff --git a/stable.c b/stable.c index 2d643aa..2065eb5 100644 --- a/stable.c +++ b/stable.c @@ -24,6 +24,9 @@ extern STD sym_table; */ STD st_create(int st_size){ STD new_stable; + + new_stable.plsBD = NULL; + if (st_size <= 0 || (new_stable.pstvr = (STVR*)malloc((size_t)st_size * sizeof(STVR)) == NULL)) new_stable.st_size = 0; @@ -48,7 +51,7 @@ STD st_create(int st_size){ */ int st_install(STD sym_table, char *lexeme, char type, int line){ unsigned int offset, i; - char f_realloc = UNSET_R_FLAG; /* Reallocation flag. Initially 0 */ + char f_realloc; /* Reallocation flag */ /* Cannot add new entry, table full */ if (sym_table.st_offset >= sym_table.st_size) @@ -67,28 +70,28 @@ int st_install(STD sym_table, char *lexeme, char type, int line){ if (!b_addc(sym_table.plsBD, lexeme[i])) return -1; - if (b_rflag(sym_table.plsBD)== SET_R_FLAG) + if (b_rflag(sym_table.plsBD) == SET_R_FLAG) f_realloc = SET_R_FLAG; } - if (!b_addc(sym_tabl.plsBD, '\0')) + if (!b_addc(sym_table.plsBD, '\0')) return -1; /* Set the default mask before setting the rest of the masks */ - sym_table.pstvr[sym_table.st_offset].status_field = DEFAULT_MASK; + sym_table.pstvr[sym_table.st_offset].status_field = DFT_MASK; switch (type){ case 'I': /* Integer type */ sym_table.pstvr[sym_table.st_offset].status_field != INT_MASK; - sym_Table.pstvr[sym_table.st_offset].i_value.int_val = 0; + sym_table.pstvr[sym_table.st_offset].i_value.int_val = 0; break; case 'F': /* Floating point type */ sym_table.pstvr[sym_table.st_offset].status_field != FLT_MASK; - sym_Table.pstvr[sym_table.st_offset].i_value.int_val = 0.0f; + sym_table.pstvr[sym_table.st_offset].i_value.int_val = 0.0f; break; case 'S': /* String type */ sym_table.pstvr[sym_table.st_offset].status_field != STR_MASK; - sym_Table.pstvr[sym_table.st_offset].i_value.str_offset = -1; + sym_table.pstvr[sym_table.st_offset].i_value.str_offset = -1; break; default: return -1; /* Not supposed to fall into here */ @@ -138,7 +141,7 @@ int st_change_type(STD sym_table, int vid_offset, char v_type) { Note: Can separate the statements to set the update flag at the end, but this resets AND updates at once */ - sym_table.psvtr[vid_offset].status_field = sym_table.psvtr[vid_offset].status_field & DFT_U_MASK; + sym_table.pstvr[vid_offset].status_field = sym_table.pstvr[vid_offset].status_field & DFT_U_MASK; /*TODO: Ask if re-setting flags and "bailing out" is spec breaking, and if flags should only be set if v_type is valid */ @@ -263,19 +266,16 @@ int st_store(STD sym_table){ for(i = 0; i < sym_table.st_size; ++i){ fprintf(out, " %4X", sym_table.pstvr[i].status_field); /* Status flag */ fprintf(out, " %d", (int)strlen(sym_table.pstvr[i].plex)); /* Length of lexeme */ - fprintf(out, " %s", sym_table.stvr[i].plex); /* The lexeme itself */ - fprintf(out, " %d", sym_table.stvr[i].o_line); /* Line number */ + fprintf(out, " %s", sym_table.pstvr[i].plex); /* The lexeme itself */ + fprintf(out, " %d", sym_table.pstvr[i].o_line); /* Line number */ /* Initial value */ - switch (st_get_type(sym_table, i)){ + char type = st_get_type(sym_table, i); + switch (type){ case 'I': - fprintf(out,""); - break; case 'F': - fprintf(out,""); - break; case 'S': - fprintf(out,""); + fprintf(out, " %c", type); break; } } diff --git a/stable.h b/stable.h index e1e7371..059d1c4 100644 --- a/stable.h +++ b/stable.h @@ -30,14 +30,14 @@ typedef union InitialValue { int int_val; /* Integer variable initial value */ - float fpl_val /* Floating-point variable initial value */ - int str_offset /* String variable initial value (location offset) */ + float fpl_val; /* Floating-point variable initial value */ + int str_offset; /* String variable initial value (location offset) */ } Value; typedef struct SymbolTableVidRecord { - unsigned short status_field /* Variable record status field */ + unsigned short status_field; /* Variable record status field */ char *plex; /* Pointer to lexeme (VID name) in CA (character array) */ - int o_line /* Line of first occurence */ + int o_line; /* Line of first occurence */ Value i_value; /* Variable initial value */ void *reserved; /* Reserved for future use, not needed right now */ } STVR; @@ -49,6 +49,7 @@ typedef struct SymbolTableDescriptor { Buffer *plsBD; /* Pointer to the lexeme storage buffer descriptor */ } STD; +STD st_create(int); int st_install(STD, char*, char, int); int st_lookup(STD, char*); int st_change_type(STD, int, char); diff --git a/table.h b/table.h index 05afe29..2dfab6b 100755 --- a/table.h +++ b/table.h @@ -47,7 +47,7 @@ int st_table[][TABLE_COLUMNS] = { COLUMN # | 0 | 1 | 2 | 3 | 4 | 5 | 6 | |[a-zA-Z]| 0 |[1-7]|[8-9]| . | # | other | */ - /* State 0 */ {1, 6 , 4 , 4 , ES , ES , ES}, + /* State 0 */ {1, 6 , 4 , 4 , IS , IS , IS}, /* State 1 */ {1, 1 , 1 , 1 , 2 , 3 , 2 }, /* State 2 */ {IS, IS , IS, IS, IS , IS , IS}, /* State 3 */ {IS, IS , IS, IS, IS , IS , IS}, @@ -56,7 +56,7 @@ int st_table[][TABLE_COLUMNS] = { /* State 6 */ {ES, 9 , 9 , ES, 7 , ES , 5 }, /* State 7 */ {8 , 7 , 7 , 7, 8 , 8 , 8 }, /* State 8 */ {IS, IS , IS, IS, IS , IS , IS}, - /* State 9 */ {ES, ES , 11, ES, ES , ES , 10}, + /* State 9 */ {ES, 9 , 11, ES, ES , ES , 10}, /* State 10 */ {IS, IS , IS, IS, IS , IS , IS}, /* State 11 */ {ES, 11 , 11, ES, ES , ES , 10}, /* State 12 */ {IS, IS , IS, IS, IS , IS , IS},