Example #1
0
/*********************************************************************
*	Purpose: Load File content into the Buffer
*	Author: Kwok Hong Kelvin Chan
*	History/Versions: 1.0, September 24th, 2013
*	Called functions: 
						fgetc()
						feof()
						b_addc()

*	Parameters: 
					Type:		Parameter:			Values/Range:
					FILE * 		fi
					Buffer * 	pBD	
					
*	Return value: 
					type:		value:
					int 		-2 / -1 / number_of_char

*	Algorithm: 		Check if the input Buffer's pointer is NULL, 
					if not, read characters from file as long as it does not get to end of file.
					Meanwhile, increment number_of_char to keep count the total of characters that added to the Buffer
*********************************************************************/
int b_load (FILE * const fi, Buffer * const pBD){
	int number_of_char = 0; /* variable to store the total number of characters added */
	char symbol; /* variable to store the character read from the file */
	Buffer * temp; /* temporarily character pointer to store the b_addc function result */
	/* 
	 *	Check whether if the Buffer pointer and the File pointer is NULL, if so, return NULL.
	 */
	 if (fi != NULL && pBD != NULL){
		/* 
		 *	while true, using fgetc to read one character at a time from the file and add it into the Buffer using b_addc.
		 */
		 while (NUM_1) {
			symbol = fgetc (fi); /* read one character from file */
			/*
			* check if the file reaches end of file, if not, continue reading character from file and store it in the Buffer
			*/
			if (feof(fi)){
				return number_of_char;
			}
			temp = b_addc(pBD, symbol);
			/* 
			 *	Check whether the character is added properly to the Buffer's character array, if so, increment the number_of_char.
			 */
			 if (temp == NULL){
			 	return LOAD_FAIL;
			 }
			 else{
			 	++number_of_char;
			 }
			}
			return number_of_char;
	}else{
		return R_FAIL_1;
	}
}
Example #2
0
/**********************************************************************************************************
Purpose:				Find the column in the transition table that corresponds to the current character
Author:					Thom Palmer
History/Versions:		10.18.13
Called functions:		chk_sym_tbl(), qsort(), malloc(), st_compare_A(), b_getsize(), strlen(), b_reset(),
						b_addc, free(), b_get_chmemloc()
Parameters:				STD sym_table, char s_order
Return value:			1 on success, 0 on failure
Algorithm:				Check that the symbol table is valid, if s_order is A or D call qsort with the 
						corresponding function call, allocated memory for the temporary char *, iterate
						over each STVR and store the contents of their plexs in the char *, use b_reset
						to prepare the buffer for its new contents, store the contents of the char * into
						the buffer, free the char *, correct the plex pointers and return.
**********************************************************************************************************/
int st_sort(STD sym_table, char s_order)
{
	unsigned int i;											/* Used to iterate over STVR array */
	unsigned int j;											/* Used to iterate over characters in each plex */
	short initOffset = 0;									/* Stores the offset from the beginning of the buffer */
	int charOffset = 0;										/* Counts the offset from the beginning of the char* */
	char * orderedBufferCont = NULL;						/* Used to store the ordered lexemes from the buffer temporarily */
	unsigned short buffSize = b_getsize(sym_table.plsBD);	/* Needed to store the size of the buffer */	

	chk_sym_tbl(sym_table);
	
	switch(s_order)
	{
		/* Call qsort to sort the STVR array in ascending order */
		case 'A':
			qsort((void*)sym_table.pstvr, sym_table.st_offset,sizeof(STVR), st_compare_A);
			break;
		/* Call qsort to sort the STVR array in descending order */
		case 'D':
			qsort((void*)sym_table.pstvr, sym_table.st_offset,sizeof(STVR), st_compare_D);
			break;
		/* Invalid s_order return -1 */
		default:
			return INVLD_TYPE;
	}
	/* Allocate memory for a char* the same size as the buffsize */
	orderedBufferCont = (char*)malloc(sizeof(char)*buffSize);
	
	/* Iterate over the array of STVRs */
	/* Cast to unsigned because the offset is and index value which cannot be negative*/
	for(i = 0; i<(unsigned)sym_table.st_offset;i++)
	{	
		/* For each STVR.plex store its contents character by character into the temporary char* */
		for (j = 0;j<=strlen(sym_table.pstvr[i].plex);j++)
		{
			orderedBufferCont[charOffset] = sym_table.pstvr[i].plex[j];
			/* Increment charOffset each time */
			++charOffset;
		}	
	}
	/* Reset the buffer in preparation for adding the contents of the temporary char* to it */
	b_reset(sym_table.plsBD);

	/* Iterate over the buffer and add the ordered contents in */
	for( i = 0; i<buffSize;++i)
	{
		b_addc(sym_table.plsBD, orderedBufferCont[i]);	
	}
	/* Free the temprary char *. It is no longer neeeded */
	free((char*)orderedBufferCont);
	/* Cast to unsigned because the offset is and index value which cannot be negative*/
	/* Iterate over the STVR array and ensure that each plex is point to the correct memory location */
	for(i=0; i<(unsigned)sym_table.st_offset; i++)
	{			
		sym_table.pstvr[i].plex  = b_get_chmemloc(sym_table.plsBD, initOffset);
		/* Casting to a short because the plex is stored in the buffer which could never be larget that SHRT_MAX*/
		initOffset += (short)strlen(sym_table.pstvr[i].plex)+1;	
	}	
	return SRT_SUCCESS;
}
Example #3
0
/*
Purpose: Installs a new entry (VID record) in the symbol table.
Authors: Kwok Hong Kelvin Chan, Kyle Hinskens
Version: 13.11.14
Called functions: st_lookup(), b_setmark(), b_getsize(), strlen(), b_addc(), printf(),
				b_get_r_flag(), b_get_chmemloc(), b_getmark(), st_incoffset()
Parameters:
			STD sym_table The symbol table
			char *lexeme The lexeme
			int line The line number
Return value: int The offset of the lexeme or -1 on error
*/
int st_install(STD sym_table, char *lexeme, int line) {
	int offset; /* lookup() return value*/
	unsigned int i; /* loop counter for strlen */
	int j; /* loop counter */
	unsigned short buffer_offset = 0; /* buffer_offset, used for reorganize plex on the symbol table */

	offset = st_lookup(sym_table, lexeme);

	/* check if the symbol table is full */
	if (sym_table.st_offset == sym_table.st_size) return R_FAIL_1;

	/* lexeme is not found from the symbol table */ 
	if (offset == -1) {
		b_setmark(sym_table.plsBD, b_getsize(sym_table.plsBD)); /* set mark on the Buffer at the addc_offset index */
		/* store lexeme into the symbol table Buffer */
		for (i = 0; i < strlen(lexeme) + 1; ++i) {
			/* check if b_addc() executed successfully, just in case! */
			if (b_addc(sym_table.plsBD, lexeme[i]) == NULL) {
				return R_FAIL_2;
			}

			/* Buffer reallocation, reorganize plex on the symbol table */
			if (b_get_r_flag(sym_table.plsBD)) {
				/* traverse the symbol table, and reassign the correct memory address from the new Buffer */
				 for (j = 0; j < sym_table.st_offset; ++j) {
					sym_table.pstvr[j].plex = b_get_chmemloc(sym_table.plsBD, buffer_offset); /* get the character pointer from the buffer_offset */
					buffer_offset += (unsigned short)strlen(b_get_chmemloc(sym_table.plsBD, buffer_offset)) + 1; /* increment buffer_offset by the strlen from current string  */
				}
			}
		}

		sym_table.pstvr[sym_table.st_offset].plex = b_get_chmemloc(sym_table.plsBD, b_getmark(sym_table.plsBD)); /* set plex as the beginning of the lexeme from the Buffer */
		sym_table.pstvr[sym_table.st_offset].o_line = line; /* set line number */
		sym_table.pstvr[sym_table.st_offset].status_field = DEFAULT; /* set default status field */

		/* variable of type string */ 
		if (lexeme[strlen(lexeme) -1] == '#') {
			sym_table.pstvr[sym_table.st_offset].status_field |= STRING_MASK; /* set status field as string by performing a OR operation with the STRING_MASK */
			sym_table.pstvr[sym_table.st_offset].status_field |= UPDATE_MASK; /* Set update flag */
			sym_table.pstvr[sym_table.st_offset].i_value.str_offset = -1; /* set i_value */
		}
		/* variable of type int */ 
		else if (lexeme[0] == 'i' || lexeme[0] == 'o' || lexeme[0] == 'd' || lexeme[0] == 'n') {
			sym_table.pstvr[sym_table.st_offset].status_field |= INT_MASK; /* set status field as int by performing a OR operation with the INT_MASK*/
			sym_table.pstvr[sym_table.st_offset].i_value.int_val = 0; /* set i_value */
		}
		/* variable of type float */ 
		else {
			sym_table.pstvr[sym_table.st_offset].status_field |= FLOAT_MASK; /* set status field as float by performing a OR operation with the FLOAT_MASK*/
			sym_table.pstvr[sym_table.st_offset].i_value.fpl_val = 0.0f; /* set i_value */
		}

		st_incoffset(); /* increment global symbol table st_offset field */
		return sym_table.st_offset; /* The function returns the current offset of that entry from the beginning of the array of STVR (the array pointed by pstvr). */
	}

	return offset;
}
/*
 * Purpose: Loads an open input file.
 * Author: Jason Macfarlane
 * History/Versions: Created January 6, 2015, Last revised January 20, 2015 - Version 1.1
 * Called functions: fgetc(), feof(), b_addc(), fclose()
 * Parameters: FILE fi, Buffer* pBD
 * Return value: int
 * Algorithm: If run-time error is possible, return R_FAIL_1. Otherwise, get each character from
 the file and call b_addc() until the last character. Return the number of characters added to
 the buffer.
 */
int b_load(FILE * const fi, Buffer * const pBD) {
    char c; /* The character in the character buffer */
    int charNum = 0; /* The number of characters added to the buffer */
    
    if (!fi || !pBD)
        return R_FAIL_1;
    
    /*
     * For each character in the file, call b_addc() to add it to the character buffer.
     */
    while(1) { /* WARNING: constant in while-loop */
        c = (char)fgetc(fi);
        if(feof(fi))
            break;
        if(!b_addc(pBD, c))
            return LOAD_FAIL;
        ++charNum;
    }
    
    fclose(fi);
    
    return charNum;
}
Example #5
0
/**********************************************************************************************************
Purpose:			Set the proper token depending on the lexeme read from the buffer. 
Author:				Thom Palmer and Chris Whitten
History/Versions:	10.20.13
Called functions:	b_setmark(), b_getc(), b_getmark(), SEOF(), WHTSPACE(), is_assop(), strncmp(),
					b_set_getc_offset(), b_retract(), b_get_getc_offset(),b_eob(), isalnum(), b_addc()
					get_next_state(), b_create(), b_pack(), b_destroy() 
Parameters:			Buffer * const pBD
Return value:		Token t
Algorithm:			Validate parameters, read char from buffer, check the char to see if its a legal character.
					depending on the char peak forward to see what the following char is in order to 
					determine if it's part of the lexeme or if it's time to return. once a valid lexeme is
					found set the token and return. if a valid lexeme is not found set the token to error 
					state and return. 
**********************************************************************************************************/
Token mlwpar_next_token(Buffer * sc_buf)
{
	Token t;			/* token to return after recognition */
	unsigned char c;	/* input symbol */
	int state = 0;		/* initial state of the FSM */
	unsigned int retrCtr;
	short lexstart;		/* start offset of a lexeme in the input buffer */
	short lexend;		/* end offset of a lexeme in the input buffer */
	int accept = NOAS;	/* type of state - initially not accepting */  
	unsigned int i=0;	/* Used throughout the function as iterator */
   
	/* Ensure the buffer is not null before trying to access it */

	if(sc_buf == NULL)
	{	   
		scerrnum = BUFFNULL;  
	     t_set_err_t(RUNTIMERR, t);
	}     
                
	while (1) /* Endless loop broken by token returns it will generate a warning */
	{ 
                
		/* Set mark before getting the next character. This prevents the need for unneccessary decrements. */
		b_setmark(sc_buf, b_get_getc_offset(sc_buf));
		lexstart = b_getmark(sc_buf);
	
		/* Get the next char from the buffer. */
		c = b_getc(sc_buf); 	
	
		/* Ensure SEOF has not been read before processing any further. */
		if(SEOF(c))
		{
			t.code = SEOF_T;
			return t;
		}

		/* If it's whitespace ignore and return to the start of the loop. */
		if(WHTSPC(c))
		{
			continue;
		}

		/* Drop into switch statement to determine what the character can potentially represent and handle it appropriatly. */
		switch(c)
		{
			/* If c is '=' the token can either be a relation operatory or an assignment operator,  so peak forward */
			case EQSIGN:
				{ 
					c = b_getc(sc_buf);
					/* If the next character is '=' then we have found a relational operator */
					if(c == EQSIGN) 
					{
						/* Set the code and attribute and return t */
						t.code = REL_OP_T;
						t.attribute.rel_op = EQ;
						return t;
					}
					/* Otherwise retract and return an assignment operator token */
					b_retract(sc_buf);
					t.code = ASS_OP_T;
					return t;
				} 
			/* If the token starts with ! it can either be a comment or the != relational operator, so peak forward and act appropriatly. */
			case EXCLAMTN:
				c = b_getc(sc_buf);
				/* If the next token is < then we have a comment therfore ignore everything in the line.*/
				if(c == LESSTHN)
				{
					do
					{
						c = b_getc(sc_buf);
						if(SEOF(c))
						{ 
							t.code = ERR_T;
							t.attribute.err_lex[0] = EXCLAMTN;
							t.attribute.err_lex[1] = LESSTHN;
							t.attribute.err_lex[2] = c;
							t.attribute.err_lex[3] = STRTERM;
							b_retract(sc_buf);
							return t;
						}
					}while ( c != NEWLINE && c != CARRTRN);

					++line;
					continue;
				}
				/* If the next token we have the NE relational operator. */
				if(c == EQSIGN)
				{
					t.code = REL_OP_T;
					t.attribute.rel_op = NE ;
					return t;
				}
				/* if the next char is neither = or < we have an error set ERR_T*/
				t.code = ERR_T;
				t.attribute.err_lex[0] = EXCLAMTN;
				t.attribute.err_lex[1] = c;
				t.attribute.err_lex[2] = STRTERM;
	   
				/* We assume the error was meant to be a token so ignore everything in the line. */
				do
				{
					c = b_getc(sc_buf);
					/* If SEOF or b_eob is found retract the buffer and return t */
					if(SEOF(c))
					{
						b_retract(sc_buf);
						return t;
					}
				}while ( c != NEWLINE);
				++line;
				return t;

			/*If we have a plus sign '+' set the token and it's attirbute then return. */
			case POS:
				t.code = ART_OP_T;
				t.attribute.arr_op = PLUS;
				return t;

			/*If we have a minus sign '-' set the token and it's attirbute then return. */
			case NEG:
				t.code = ART_OP_T;
				t.attribute.arr_op = MINUS;
				return t;

			/*If we have a a period '.' it could be a logical operator or an error. */
			case PERIOD:
				retrCtr = 1;
				i = 0;
				c = b_getc(sc_buf);
				
				/* Switch on the first character read after the period '.' */
				switch (c) 
				{
				/* If its an 'A' we might have .AND. */
				case'A' :
					/* Compare the string the string read from the buffer to the string literal .AND.  */
					++retrCtr;
					if(b_getc(sc_buf) == 'N')
					{
						++retrCtr;
						if(b_getc(sc_buf) == 'D')
						{
							++retrCtr;
							if(b_getc(sc_buf) == PERIOD)
							{
								t.code = LOG_OP_T;
								t.attribute.log_op = AND;
								return t;
							}
						}
					}
					break;
				case'O':
					/* Comapre the string the string read from the buffer to the string literal .OR.  */
					++retrCtr;
					if(b_getc(sc_buf) == 'R')
					{
						++retrCtr;
						if(b_getc(sc_buf) == PERIOD)
						{
							t.code = LOG_OP_T;
							t.attribute.log_op = OR;
							return t;
						}
					}

					break;
				}

				while(i<retrCtr)
				{
					b_retract(sc_buf);
					i++;
				}
				t.code = ERR_T;
				/* Add char which caused the error to the err_lex */
				t.attribute.err_lex[0] = PERIOD;
				t.attribute.err_lex[1] = STRTERM;
				return t;

			/* If we have an astrix sign '*' set the token and it's attirbute then return. */
			case ASTRX:
				t.code = ART_OP_T;
				t.attribute.arr_op = MULT;
				return t;

			/* If c is a forward slash '/' set the token and it's attirbute then return. */
			case FWDSLSH:
				t.code = ART_OP_T;
				t.attribute.arr_op = DIV;
				return t;

			/* If c is a left brace '{' set the token and it's attirbute then return. */
			case LBRACE:
				t.code = LBR_T;
				return t;

			/* If c is a right brace '}' set the token and it's attirbute then return. */
			case RBRACE:
				t.code = RBR_T;
				return t;

			/* If c is a left parenthesis '(' set the token and it's attirbute then return. */
			case LPRNTHS:
				t.code = LPR_T;
				return t;

			/* If c is a right parenthesis ')' set the token and it's attirbute then return. */
			case RPRNTHS:
				t.code = RPR_T;
				return t;

			/* If c is a less than symbol '<' check the next char. */
			case LESSTHN:
				c = b_getc(sc_buf);

				/* If the next char is the greater than symbol '>' set the proper token and return. */
				if(c == GRTRTHN){
					t.code = SCC_OP_T;
					return t;
				}

				/* If the next char is not recognized restract the buffer and set the token */
				t.code = REL_OP_T;
				t.attribute.rel_op = LT;
				b_retract(sc_buf);
				return t;

			/* If c is a greater than symbol '>' set the proper token and return. */
			case GRTRTHN:
				t.code = REL_OP_T;
				t.attribute.rel_op = GT;
				return t;

			/* If c is a new line '\n' increment the line number and return to the start of the loop. */
			case CARRTRN:
				NEWLINE_TEST
				continue;
				
			/* If c is a NEWLINE character increment the line number and continue */
			case NEWLINE:
				++line;
				continue;

			/* If c is a comma ',' set the proper token and return. */
			case COMMA:
				t.code = COM_T;  
				return t;

			/* If c is a semi colon ';' set the proper token and return. */
			case SEMICLN:
				t.code = EOS_T;
				return t;

			/* If c is a quotation mark '"' we have the start of a string, analyze the next chars until '"' or SEOF is hit. */
			case QUOTE:
				/* read all the chars in from the input buffer until a '"' */
				do
				{
					c = b_getc(sc_buf);
					lexend = b_get_getc_offset(sc_buf);
					/* If eob has be set or SEOF is read in from the buffer prior to closing the string */
					/* Break into the error token setup. */
					if( SEOF(c))
					{	
						/* Set the getc_offset to the start of the string */
						b_set_getc_offset(sc_buf,lexstart);
						/* Iterate over the buffer and copy the contents of the error string into the err_lex */
						for( i = 0; i < lexend-lexstart; i++) /* Comparison of unsigned int and short will generate warning. 
															     lexend-lexstart will always be positive no need to cast */
						{				
							c = b_getc(sc_buf);
							/* For the first 20 characters */
							if(i<=ERR_LEN)
							{
								/* Copy c into the current index of err_lex for first 16 characters */
								if(i<=16)
								t.attribute.err_lex[i] = c;
								/* Copy a decimal into the indexes between 17 and ERR_LEN */
								if(i>16 && i<ERR_LEN)
								{
									t.attribute.err_lex[i] = PERIOD;
								}
								/* Copy a string terminator into the last index of err_lex */
								if (i==ERR_LEN)
								{
									t.attribute.err_lex[i]= STRTERM;
								}

							}
					
						}
						t.code = ERR_T;							
						return t;
					}
					/* Increment the line number each time a line terminator is found */
					if(c == NEWLINE)
					{
						++line;
					}
					if(c == CARRTRN)
					{
						NEWLINE_TEST
					}
				}while ( c != QUOTE );
			
				/* Closing quote found. Valid String */
				/* Set the getc_offset back to the start of the string */
				b_set_getc_offset(sc_buf,lexstart);
				/* Set the str_offset attribute to the location of the current getc_offset in the str_LTBL */
				t.attribute.str_offset = b_getsize(str_LTBL);

				/* Add the characters of the string into the str_LTBL */
				for(  i = 0; i< lexend-lexstart;i++) /* Comparison of unsigned int and short will generate warning. 
														lexend-lexstart will always be positive no need to cast */
				{			
					c = b_getc(sc_buf);
					/* Ensure that quotes are not added to the string */
					if(c != '"')
					{
						if(!b_addc(str_LTBL, c))
						{
							scerrnum = FAILADDC;
							t_set_err_t(RUNTIMERR, t);
						}
					}
				}
				/* Add the string terminator to the string and set the Token Code */
				if (!b_addc(str_LTBL,STRTERM))
				{
					scerrnum = FAILADDC;
					t_set_err_t(RUNTIMERR, t);
				}
				t.code = STR_T;
				return t;
			}
	
		/* Special symbol scanning completed. Now checking for lexeme type */
		if (isalnum(c))
		{
			/* Use for loop to iterate over the transition table based on the current state and character */
			/* Continue iterating until an accepting state has been found */
			for(state = get_next_state(state,c,&accept);accept==NOAS; state = get_next_state(state,c,&accept))
			{
				c = b_getc(sc_buf);
			}
		
			/* Retract the buffer if is is an accepting state with a retract */
			if(accept==ASWR)
			{
				b_retract(sc_buf);
			}
			/* Set the end of the lexeme at the current getc_offset */
			lexend = b_get_getc_offset(sc_buf);
			/* Create a temporary buffer to store the lexeme */
			lex_buf = b_create((lexend - lexstart +1),0,'f');
			/* If buffer creation was not successful. Set the error token for a runtime error. */
			if (!lex_buf)
			{
				scerrnum = BUFFNULL;
				t_set_err_t(RUNTIMERR, t);
			}

			
			
			/* Reset the getc_offset to the start of the lexeme */
			b_set_getc_offset(sc_buf,lexstart);
			/* Add the characters of the lexeme to lex_buf */
			for( i = 0;i<lexend-lexstart;i++) /* Comparison of unsigned int and short will generate warning. 
												 lexend-lexstart will always be positive no need to cast */
			{
				if (!b_addc(lex_buf,b_getc(sc_buf)))
				{
					scerrnum = FAILADDC;
					t_set_err_t(RUNTIMERR, t);
				}
			}
			/* Pack lex_buf and add the string terminator to it */
			b_pack(lex_buf);
			/* If b_addc fails set the token for a runtime error and return t  */
			if (!b_addc(lex_buf,STRTERM))
			{
				scerrnum = FAILADDC;
				t_set_err_t(RUNTIMERR, t);
			}
			/* Call the accepting function at the current state index and pass the lexeme */
			t = aa_table[state](b_get_chmemloc(lex_buf,0));
			b_destroy(lex_buf);
			return t;
		}
		/* This code will be executed if c was an invalid symbol*/
		/* Set error token and return t. */
		t.code = ERR_T;
		t.attribute.err_lex[0] = c;
		t.attribute.err_lex[1] = STRTERM; /*Probably a better way to do this.*/
		return t;             
   }
}
Example #6
0
/*  main function takes a PLATYPUS source file as
 *  an argument at the command line.
 *  usage: parser source_file_name [-stz size][-sts:A | -sts:D]
 */    
int main(int argc, char ** argv){

	FILE *fi;       /* input file handle */	
        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: ", "parser", "  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);
    }
    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_FAIL_1)
       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 buffer, scanner,symbol table and parser*/

/* Initialize scanner  */
	scanner_init(sc_buf);
/* Add SEOF to input buffer */ 
	b_addc(sc_buf, EOF);
/* Start parsing */
	printf("\nParsing the source file...\n\n");
	
        parser(sc_buf);
        
/* print Symbol Table */    
/* 
		if(sym_table.st_size && sort_st){   
           st_print(sym_table);
         if(sort_st){
           printf("\nSorting symbol table...\n");
           st_sort(sym_table,sort_st);
           st_print(sym_table);
         }
       }
*/       
	return (EXIT_SUCCESS); /* same effect as exit(0) */
}/*end of main */
Example #7
0
int main(int argc, char **argv){

	Buffer *ptr_Buffer;   /* pointer to Buffer structure */
	FILE *fi;             /* input file handle */
	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);
	}

	/* missing file name or/and mode parameter */
	if (argc <= 2){

		err_printf("\nDate: %s  Time: %s", __DATE__, __TIME__);
		err_printf("\nRuntime error at line %d in file %s\n", __LINE__, __FILE__);
		err_printf("%s\b\b\b\b%s%s", argv[0], ": ", "Missing parameters.");
		err_printf("Usage: platybt source_file_name mode");
		exit(1);
	}

	/* create a source code input buffer */
	switch (*argv[2]){ /*gets the first caracter of the mode argument*/
	case 'f': case 'a': case 'm': break;
	default:
		err_printf("%s%s%s", argv[0], ": ", "Wrong mode parameter.");
		exit(1);
	}
	/*create the input buffer */
	ptr_Buffer = b_create(INIT_CAPACITY, INC_FACTOR, *argv[2]);
	if (ptr_Buffer == NULL){
		err_printf("%s%s%s", argv[0], ": ", "Could not create buffer.");
		exit(1);
	}

	/* open the 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 a source file into the input buffer  */
	printf("Reading file %s ....Please wait\n", argv[1]);
	loadsize = b_load(fi, ptr_Buffer);
	if (loadsize == R_FAIL_1)
		err_printf("%s%s%s", argv[0], ": ", "Error in loading buffer.");

	/* close the 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]));
	}
	/* set a mark at the last char in the buffer*/
	b_setmark(ptr_Buffer, b_size(ptr_Buffer));

	/* display the contents of the input buffer */
	display(ptr_Buffer);

	/* pack the buffer
	* if possible, add end-of-file character (EOF) to the buffer
	* display again
	*/
	if (b_pack(ptr_Buffer)){
		if (!b_addc(ptr_Buffer, EOF))
			err_printf("%s%s%s", argv[0], ": ", "Error in writing to buffer.");
		display(ptr_Buffer);
	}


	/* destroy the buffer */
	b_destroy(ptr_Buffer);
	/* make the buffer invalid
	It is not necessary here because the function terminates anyway,
	but will prevent run-time errors and crashes in future expansions
	*/
	ptr_Buffer = NULL;
	/*return success */
	return (0);
}
Example #8
0
/*  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_FAIL_1)
       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= mlwpar_next_token(sc_buf);  
	  print_token(t);
	}while(t.code != SEOF_T);
  if(b_size(str_LTBL)) b_print(str_LTBL);
	b_destroy(sc_buf);
	b_destroy(str_LTBL);
	sc_buf = str_LTBL = NULL;
 
  return (0);
}
Example #9
0
/*******************************************************************************
* Purpose:			Add a new entry into the symbol table array of STVR at the 
*					next available element. 
* Author:			Skye Turriff
* History:			Version 1, 19 November 2015
* Called functions:	st_lookup(), b_setmark(), b_size(), b_addc(), b_rflag(),
*					st_incoffset()
* Parameters:		STD sym_table struct with valid st_size
*					char* lexeme pointer to VID name to be added to table
*					char type of VID
*					int line of first occurence of VID
* Return value:		int offset into STVR array where VID record is installed, 
*					-2 on bad parameters, or -1 if symbol table is full.
* Algorithm:		Check parameters, return -2 if bad. If lexeme already in
*					symbol table, return the offset. If symbol table is full,
*					return -1. Set plex for new STVR to point to the next space
*					available in CA. Add each character in the VID lexeme to 
*					this location and make a C-type string. Once the new lexeme
*					has been added, if at any time the location of the CA was 
*					moved, re-calculate plex for each STVR in the STVR array. 
*					Finally, initialize remaining members for new STVR, and
*					increment st_offset of global sym_table. Return offset of
*					new STVR in STVR array.
*******************************************************************************/
int st_install(STD sym_table, char* lexeme, char type, int line) {
	int offset;		/* Offset into array of STVR */
	char r_flag;	/* Memory reallocation flag for lexeme storage buffer */
	char* tplex;	/* Used to iterate through lexeme storage buffer */
	int i;			/* Loop counter for iteration through STVR array */

	/* Check for valid symbol table */
	if (sym_table.st_size == 0) 
		return ERR_FAIL2;	

	/* Check if lexeme already exists */
	if ((offset = st_lookup(sym_table, lexeme)) != ERR_FAIL1) 
		return offset;

	/* Ensure there is room for a new record */
	if (sym_table.st_offset >= sym_table.st_size) 
		return ERR_FAIL1;

	/* Set plex for new VID record */
	sym_table.pstvr[sym_table.st_offset].plex =
		b_setmark(sym_table.plsBD, b_size(sym_table.plsBD));

	/* Install new entry into STVR array, make C-type string */
	r_flag = 0;
	for (; *lexeme; lexeme++) {
		b_addc(sym_table.plsBD, *lexeme);
		if (b_rflag(sym_table.plsBD)) 
			r_flag = 1;
	}
	b_addc(sym_table.plsBD, '\0');
	if (b_rflag(sym_table.plsBD)) 
		r_flag = 1;

	/* If r_flag set, use tplex to interate through lexeme storage 
	until '\0'. Then set plex of the current STVR to tplex + 1 */
	if (r_flag) {
		sym_table.pstvr[0].plex = b_setmark(sym_table.plsBD, 0);
		tplex = sym_table.pstvr[0].plex;
		for (i = 1; i <= sym_table.st_offset; i++) {
			while (*tplex) { tplex++;  continue; }
			sym_table.pstvr[i].plex = ++tplex;
		}
	}

	/* Record source line number */
	sym_table.pstvr[sym_table.st_offset].o_line = line;

	/* Initialize status_field and i_value */
	sym_table.pstvr[sym_table.st_offset].status_field &= DEFAULTZ;
	sym_table.pstvr[sym_table.st_offset].status_field |= DEFAULT;
	if (type == 'I') { /* integer */
		sym_table.pstvr[sym_table.st_offset].status_field |= DT_INT;
		sym_table.pstvr[sym_table.st_offset].i_value.int_val = 0;
	}
	else if (type == 'F') {	/* float */
		sym_table.pstvr[sym_table.st_offset].status_field |= DT_FPL;
		sym_table.pstvr[sym_table.st_offset].i_value.fpl_val = 0.0F;
	}
	else { /* string */
		sym_table.pstvr[sym_table.st_offset].status_field |= DT_STR;
		sym_table.pstvr[sym_table.st_offset].status_field |= SET_FLG;
		sym_table.pstvr[sym_table.st_offset].i_value.str_offset = -1;
	}

	st_incoffset();	/* Increment offset into STVR array of global sym_table */

	return sym_table.st_offset;
}
Example #10
0
/********************************************************************
Function name:      st_install()
Purpose:            Install a new entry in the symbol table
Author:             Warren Rainey
History/Versions:   1.0
Called functions:   st_lookup(), b_setmark, b_get_r_flag(), b_addc(), b_get_chloc(), st_incoffset()
In parameters:      STD, char *, char, int
Return Value:       Int
Algorithm:			- Check if symbol table is valid
					- This function installs a new entry (VID record) in the symbol table.  
					First, It calls the st_lookup() function to search for the lexeme (variable name) in the symbol table. 
					- Add new record to symbol table and increment st_offest.
**********************************************************************/  
int st_install(STD sym_table, char *lexeme, char type, int line){
	int location = 0;
	int i = 0;
	int j = 0;
	STVR new_rec;
	
	/*intf("1lexeme: %s\n", lexeme);Test*/
	if(!sym_table.st_size){
		return R_FAIL_2;
	}

	location = st_lookup(sym_table,lexeme);

	if(location >= 0){/*lexeme found in symbol table*/  
		return location;
	}

	if(sym_table.st_offset == sym_table.st_size){
		return TABLE_FULL;
	}

	/*printf("2lexeme:%s\n", lexeme);Test*/
	/*sym_table.pstvr[sym_table.st_offset].plex = b_setmark(sym_table.plsBD,b_size(sym_table.plsBD));/*sym_table.st_offset*/
	new_rec.plex = b_setmark(sym_table.plsBD,b_size(sym_table.plsBD));/*sym_table.st_offset*/
	/*plex = b_setmark(sym_table.plsBD, getOffset(plsBD);
	b_setmark(sym_table.plsBD, 0); /*set to addc_offset*/
		for(i = 0; lexeme[i] != '\0'; i++){ /*add lexeme to lexeme storage*/
			b_addc(sym_table.plsBD, lexeme[i]);
			/*if plsBD has moves as result of realloc of buffer*/
			/*if( b_rflag(sym_table.plsBD)){/*Remove as it may creat p
				
				while(j < sym_table.st_offset){ 
					sym_table.pstvr[j].plex = temp;
					temp += strlen(temp) + 1; /* move temp to end of lexeme in buffer*
					j++;
				}
			}*/
		}
		b_addc(sym_table.plsBD, '\0');
		
	new_rec.status_field = DEFAULT;
	new_rec.o_line = line;
	
	
	/*Finding out if int, string or float*/
	if(type == 'I'){/*Is int*/
		new_rec.i_value.int_val = 0;
		new_rec.status_field |= SET_INTEGER;
	}else if(type == 'S'){/*Is string*/
		new_rec.i_value.str_offset = -1;
		new_rec.status_field |= SET_STRING;
		new_rec.status_field |= CHK_LSB;
	}else{/*Is float*/
		new_rec.i_value.fpl_val = 0.0f;
		new_rec.status_field |= SET_FLOAT;
	}
	/*printf("New plex: %s", new_rec.plex);Test*/
	sym_table.pstvr[sym_table.st_offset] = new_rec; /*add new record to table*/	
	st_incoffset();		
	return sym_table.st_offset;
}
Example #11
0
/**********************************************************************************************************
Purpose:				Add a new STVR into the symbol table
Author:					Thom Palmer
History/Versions:		10.18.13
Called functions:		macro-chk_sym_tbl(), st_lookup(), b_get_chmemloc(), b_getsize(), strlen(), b_addc(),
						b_get_r_flag(),st_incoffset()
Parameters:				STD sym_table,char *lexeme
Return value:			Offset of the STVR if it already exists -1 on failure.  
Algorithm:				Check for a valid symbol table, call st_lookup to find if the lexeme is already
						in the symbol table, if it is return the offset where it was found, otherwise
						point the current plex to the current size of the buffer, initialize o_line &
						status_field, store the lexeme in the buffer using a call to b_addc, 
						if a reallocation occurs at any point adjust all of the plex pointers, determine
						the default datatype of the lexeme and set it, increment the offset and return
						STD.st_offset
						* Assume that size_t is that same size as an int *
**********************************************************************************************************/
int st_install(STD sym_table, char *lexeme, int line)
{
	int vid_offset;							/* Stores the offset where lexeme is found */
	unsigned int i;									/* Used and an iterator*/
	short offset = 0;						/* Used to store the offset from the buffer head */
	int rFlag = 0;							/* Flag indicating if a reallocation occured in the buffer */

	/*Check for valid symbol table*/
	chk_sym_tbl(sym_table);	
	/* Call st_lookup to search for the lexeme in the table */
	vid_offset = st_lookup(sym_table, lexeme);
	/* If the lexeme was found. Return the offset where it was found */
	if(vid_offset != LEX_NOT_FND )
	{
		return vid_offset;
	}
	/* Check if symbol table is full */
	if(sym_table.st_size == sym_table.st_offset)
	{
		return SYM_TBL_FULL; 
	}
	/* Set the plex point using a call to b_get_chmemloc. This is the only buffer function that returns a pointer */
	sym_table.pstvr[sym_table.st_offset].plex  = b_get_chmemloc(sym_table.plsBD, b_getsize(sym_table.plsBD));
	/* Set o_line to the current line number */
	sym_table.pstvr[sym_table.st_offset].o_line = line;
	/* Clear the status filed berfore setting the default value*/
	sym_table.pstvr[sym_table.st_offset].status_field &= DEFAULTZ;
	/* Set the status field to default values using the default bitmask */
	sym_table.pstvr[sym_table.st_offset].status_field |= SETDFLT; 
	
	/* Iterate through the lexeme and store it as a c-type string within the symbol table buffer */ 
	for( i=0;i<=strlen(lexeme);i++)
	{
		/* Store each character including the string terminator */ 
		if(!b_addc(sym_table.plsBD, lexeme[i]))
		{
			/* Returning -1 on b_addc failure. Allows program to handle failure in this function correctly */
			return B_ADDC_FAIL; 
		}
		/* Increment rFlag if it is set*/
		if(b_get_r_flag(sym_table.plsBD))
		{			
			++rFlag;			
		}			
	}
	/*  According to language specs the VID is a string if its last character is a # */
	if(lexeme[strlen(lexeme) -1] == '#')
	{
		/* Set the data type field to a string using a bitmask and set i_value to -1 */
		sym_table.pstvr[sym_table.st_offset].status_field |= SET012_111; 
		sym_table.pstvr[sym_table.st_offset].i_value.str_offset = I_VAL_STR;
	}
	else
	{		
		switch(lexeme[0])
		{
		/*  According to language specs the  type of an VID is Integer if it's first character is i, o, d, or n */
		case 'd': case 'i': case 'n': case 'o':
			/* Set the data type field to an int using a bitmask and set i_value to 0 */
			sym_table.pstvr[sym_table.st_offset].status_field |= SET12_01; 
			sym_table.pstvr[sym_table.st_offset].i_value.int_val = I_VAL_INT;
			break;

		/* According to the language specs the default type for a VID is float */
		default:
			/* Set the data type field to a float using a bitmask and set i_value to 0 */
			sym_table.pstvr[sym_table.st_offset].status_field |= SET12_10; 
			sym_table.pstvr[sym_table.st_offset].i_value.fpl_val = I_VAL_FLT;
			break;
		}
	}
	/* If the rflag is set we will need to handle reallocating plex pointers */
	if(rFlag)
	{
		/* Iterate though the array of STVRs */
		/* Cast to unsigned because the offset is and index value which cannot be negative*/
		for(i=0; i<= (unsigned)sym_table.st_offset; i++)
		{							
			/* Correct the plex pointers of each STVR using the lengths of the previous lexemes cumulatively */
			sym_table.pstvr[i].plex  = b_get_chmemloc(sym_table.plsBD, offset);
			/* Casting to a short ebcause the plex is stored in the buffer which could never be larget that SHRT_MAX*/
			offset += (short)strlen(sym_table.pstvr[i].plex)+1;
		}	
	}

	/* Increment the current st_offset and return st_offset */
	st_incoffset();
	return sym_table.st_offset;
}