This commit is contained in:
parent
1bfef0f5fc
commit
bc5b48ec82
2
buffer.h
2
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 */
|
||||
|
|
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h> /* Constants for calls to exit()*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#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);
|
||||
}
|
|
@ -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 '=':
|
||||
|
|
32
stable.c
32
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;
|
||||
}
|
||||
}
|
||||
|
|
9
stable.h
9
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);
|
||||
|
|
4
table.h
4
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},
|
||||
|
|
Loading…
Reference in New Issue