diff --git a/platy_st.c b/platy_st.c new file mode 100755 index 0000000..3e686e7 --- /dev/null +++ b/platy_st.c @@ -0,0 +1,260 @@ +/* File name: platy_st.c + * Purpose:This is the main program for Assignment #2 - Scanner + * CST8152 - Compilers + * Version: 1.17.1 + * Author: Svillen Ranev + * Date: 30 January 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 +#include +#include + +#include "buffer.h" +#include "token.h" + +/* constant definitions */ +#define INIT_CAPACITY 200 /* initial buffer capacity */ +#define INC_FACTOR 15 /* increment factor */ + +#define STR_INIT_CAPACITY 100 /* initial string literal table capacity */ +#define STR_CAPACITY_INC 50 /* initial string literal table capacity inc */ + +/*check for ANSI C compliancy */ +#define ANSI_C 0 +#if defined(__STDC__) +#undef ANSI_C +#define ANSI_C 1 +#endif + +/* Global objects - variables */ + +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) */ + +/*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 print_token(Token t); + +/* main function takes a PLATYPUS source file as + * an argument at the command line. + * usage: scanner source_file_name" + */ +int main(int argc, char ** argv){ + + Buffer *sc_buf; /* pointer to input (source) buffer */ + 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 ansi_c = !ANSI_C; /* ANSI C compliancy 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: ", "scanner", " source_file_name"); + exit(1); + } + + + /* 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(1); + } + +/*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 literals buffer"); + exit(1); + } + + /*Testbed for the scanner */ +/* add SEOF to input program buffer*/ + b_addc(sc_buf,'\0'); + + /* Initialize scanner input buffer */ + if(scanner_init(sc_buf)){; + err_printf("%s%s%s",argv[0],": ","Empty program buffer - scanning canceled"); + exit(1); + } + + printf("\nScanning source file...\n\n"); + printf("Token\t\tAttribute\n"); + printf("----------------------------------\n"); + do{ + t= malar_next_token(sc_buf); + print_token(t); + }while(t.code != SEOF_T); + if(b_size(str_LTBL)) b_print(str_LTBL); + b_free(sc_buf); + b_free(str_LTBL); + sc_buf = str_LTBL = NULL; + + return (0); +} + +/* 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 displays buffer contents + */ +void display (Buffer *ptrBuffer){ + printf("\nPrinting 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("\nPrinting buffer contents:\n\n"); + b_print(ptrBuffer); +} + +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 0L; + } + fseek(input, 0L, SEEK_END); + flength = ftell(input); + fclose(input); + return flength; +} + +/* The function prints the token returned by the scanner + */ + +void print_token(Token t){ + extern char * kw_table []; /* link to keyword table in */ + switch(t.code){ + case ERR_T: + printf("ERR_T\t\t%s",t.attribute.err_lex); + if(scerrnum){ + printf("%d",scerrnum); + exit(scerrnum); + }printf("\n"); + break; + case SEOF_T: + printf("SEOF_T\n" ); + break; + case AVID_T: + printf("AVID_T\t\t%s\n",t.attribute.vid_lex); + break; + case SVID_T: + printf("SVID_T\t\t%s\n",t.attribute.vid_lex); + break; + case FPL_T: + printf("FPL_T\t\t%f\n",t.attribute.flt_value); + break; + case INL_T: + printf("IL_T\t\t%d\n",t.attribute.get_int); + break; + case STR_T: + printf("STR_T\t\t%d\t ",(short)t.attribute.get_int); + printf("%s\n", b_setmark(str_LTBL, (short)t.attribute.get_int)); + break; + case SCC_OP_T: + printf("SCC_OP_T\n" ); + break; + case ASS_OP_T: + printf("ASS_OP_T\n" ); + break; + case ART_OP_T: + printf("ART_OP_T\t%d\n",t.attribute.get_int); + break; + case REL_OP_T: + printf("REL_OP_T\t%d\n",t.attribute.get_int); + break; + case LOG_OP_T: + printf("LOG_OP_T\t%d\n",t.attribute.get_int); + break; + case LPR_T: + printf("LPR_T\n" ); + break; + case RPR_T: + printf("RPR_T\n" ); + break; + case LBR_T: + printf("LBR_T\n" ); + break; + case RBR_T: + printf("RBR_T\n" ); + break; + case KW_T: + printf("KW_T\t\t%s\n",kw_table [t.attribute.get_int]); + break; + case COM_T: + printf("COM_T\n"); + break; + case EOS_T: + printf("EOS_T\n" ); + break; + + default: + printf("Scanner error: invalid token code: %d\n", t.code); + } +} + diff --git a/scanner.c b/scanner.c index 931987a..ad347f0 100755 --- a/scanner.c +++ b/scanner.c @@ -5,8 +5,8 @@ * scanner_init() must be called before using the scanner. * The file is incomplete; * Provided by: Svillen Ranev - * Version: 1.16.02 - * Date: 29 September 2016 + * Version: 1.17.1 + * Date: 30 January 2017 ******************************************************************* * REPLACE THIS HEADER WITH YOUR HEADER ******************************************************************* @@ -66,7 +66,7 @@ int scanner_init(Buffer * sc_buf) { /* scerrnum = 0; *//*no need - global ANSI C */ } -Token mlwpar_next_token(Buffer * sc_buf) +Token malar_next_token(Buffer * sc_buf) { Token t; /* token to return after recognition */ unsigned char c; /* input symbol */ @@ -290,7 +290,7 @@ WHEN CALLED THE FUNCTION MUST IF THE lexeme IS LONGER than VID_LEN characters, ONLY FIRST VID_LEN-1 CHARACTERS ARE STORED INTO THE VARIABLE ATTRIBUTE ARRAY vid_lex[], - AND THEN THE % CHARACTER IS APPENDED TO THE NAME. + AND THEN THE # CHARACTER IS APPENDED TO THE NAME. ADD \0 AT THE END TO MAKE A C-type STRING. return t; @@ -305,22 +305,24 @@ WHICH IS THE ATTRIBUTE FOR THE TOKEN. THE VALUE MUST BE IN THE SAME RANGE AS the value of 4-byte float in C. IN CASE OF ERROR (OUT OF RANGE) THE FUNCTION MUST RETURN ERROR TOKEN THE ERROR TOKEN ATTRIBUTE IS lexeme. IF THE ERROR lexeme IS LONGER -than ERR_LEN caharacters, only the first ERR_LEN character are -stored in err_lex. +than ERR_LEN characters, ONLY THE FIRST ERR_LEN-3 characters ARE +STORED IN err_lex. THEN THREE DOTS ... ARE ADDED TO THE END OF THE +err_lex C-type string. return t; } -ACCEPTING FUNCTION FOR THE integer literal(IL) - decimal constant (DIL) AND ZERO (0) +ACCEPTING FUNCTION FOR THE integer literal(IL) - decimal constant (DIL) Token aa_funcXX(char lexeme[]){ -THE FUNCTION MUST CONVERT THE LEXEME REPRESENTING A DECIMAL CONSTANT AND 0 +THE FUNCTION MUST CONVERT THE LEXEME REPRESENTING A DECIMAL CONSTANT TO A DECIMAL INTEGER VALUE, WHICH IS THE ATTRIBUTE FOR THE TOKEN. THE VALUE MUST BE IN THE SAME RANGE AS the value of 2-byte integer in C. IN CASE OF ERROR (OUT OF RANGE) THE FUNCTION MUST RETURN ERROR TOKEN THE ERROR TOKEN ATTRIBUTE IS lexeme. IF THE ERROR lexeme IS LONGER -than ERR_LEN caharacters, only the first ERR_LEN character are -stored in err_lex. +than ERR_LEN characters, ONLY THE FIRST ERR_LEN-3 characters ARE +STORED IN err_lex. THEN THREE DOTS ... ARE ADDED TO THE END OF THE +err_lex C-type string. return t; } @@ -338,8 +340,9 @@ THE FUNCTION atool(char * lexeme) WHICH CONVERTS AN ASCII STRING REPRESENTING AN OCTAL NUMBER TO INTEGER VALUE IN CASE OF ERROR (OUT OF RANGE) THE FUNCTION MUST RETURN ERROR TOKEN THE ERROR TOKEN ATTRIBUTE IS lexeme. IF THE ERROR lexeme IS LONGER -than ERR_LEN caharacters, only the first ERR_LEN character are -stored in err_lex. +than ERR_LEN characters, ONLY THE FIRST ERR_LEN-3 characters ARE +STORED IN err_lex. THEN THREE DOTS ... ARE ADDED TO THE END OF THE +err_lex C-type string. return t; } @@ -350,9 +353,10 @@ Token aa_funcXX(char lexeme[]){ THE FUNCTION SETS THE ERROR TOKEN. lexeme[] CONTAINS THE ERROR THE ATTRIBUTE OF THE ERROR TOKEN IS THE lexeme ITSELF -AND IT MUST BE STORED in err_lex. IF THE ERROR lexeme IS LONGER -than ERR_LEN caharacters, only the first ERR_LEN character are -stored in err_lex. +AND IT MUST BE STORED in err_lex. IF THE ERROR lexeme IS LONGER +than ERR_LEN characters, ONLY THE FIRST ERR_LEN-3 characters ARE +STORED IN err_lex. THEN THREE DOTS ... ARE ADDED TO THE END OF THE +err_lex C-type string. return t; } diff --git a/table.h b/table.h index d8684dd..052ab0c 100755 --- a/table.h +++ b/table.h @@ -1,8 +1,8 @@ /* Filename: table.h * Transition Table and function declarations necessary for the scanner implementation * as required for CST8152 - Assignment #2. - * Version: 1.16.02 - * Date: 29 September 2016 + * Version: 1.17.1 + * Date: 30 January 2017 * Provided by: Svillen Ranev * The file is incomplete. You are to complete it. *************************************************** @@ -29,7 +29,7 @@ * in the token-driven part of the scanner * '=' , ' ' , '(' , ')' , '{' , '}' , == , <> , '>' , '<' , * space - * !cb_head) */ - float flt_value; /* floating-point literal attribute (value) */ - char vid_lex[VID_LEN+1]; /* variable identifier token attribute */ - char err_lex[ERR_LEN+1]; /* error token attribite */ + int get_int; /* integer attributes accessor */ + Arr_Op arr_op; /* arithmetic operator attribute code */ + Rel_Op rel_op; /* relational operator attribute code */ + Log_Op log_op; /* logical operator attribute code */ + int int_value; /* integer literal attribute (value) */ + int kwt_idx; /* keyword index in the keyword table */ + short str_offset; /* sring literal offset from the beginning of */ + /* the string literal buffer (str_LTBL->cb_head) */ + float flt_value; /* floating-point literal attribute (value) */ + char vid_lex[VID_LEN+1]; /* variable identifier token attribute */ + char err_lex[ERR_LEN+1]; /* error token attribite */ } TA; typedef struct Token