Пример #1
0
/*
 * Purpose: Implement the panic recovery mode.
 * Author: Jason Macfarlane
 * History/Versions: 1.0
 * Called functions: syn_printe(), mlwpar_next_token(), exit()
 * Parameters: int sync_token_code
 * Return value: STD
 * Algorithm: Print an error message and increment the number of errors.
 * If the token code is not SEOF, advance it to the next token. If the
 * new token matches the required token (sync_token_code), attempt to
 * advance the current token once more and return. Otherwise, exit the
 * program.
 */
void syn_eh(int sync_token_code) {
    /* Print an error and increment the error counter. */
    syn_printe();
    ++synerrno;
    
    /*
     * While the current token code is not equal to SEOF_T, advance
     * the current token and validate it. Repeat until the current
     * token code is equal to the required token code.
     */
    while (lookahead.code != SEOF_T) {
        lookahead = mlwpar_next_token(sc_buf);
        
        if (lookahead.code == sync_token_code) {
            
            /* If the current token code is not SEOF_T, advance it to the next token. */
            if (lookahead.code != SEOF_T)
                lookahead = mlwpar_next_token(sc_buf);
            
            return;
        }
    }
    
    /*
     * If the loop exists without returning, check if the
     * required token code is SEOF_T. If not, no match was
     * found. Exit with the number of errors.
     */
    if (sync_token_code != SEOF_T)
        exit(synerrno);
}
Пример #2
0
/*
Purpose: Error handling function implementing simple panic mode.
Author: Kyle Hinskens, Kwok Hong Kelvin Chan
Version: 13.12.6
Called functions: syn_printe, mlwpar_next_token
Parameters: int sync_token_code The token code
Return value: None
*/
void syn_eh(int sync_token_code) {

	/* First, the function calls syn_printe() and increments the error counter. Then the
		function implements a panic mode error recovery: the function advances the input token
		(lookahead_token) until it finds a token code matching the one required by the parser
		(pr_token_code passed to the function as sync_token_code). */
	syn_printe();
	++synerrno;

	/* It is possible, when advancing, that the function can reach the end of the source file
		without finding the matching token. To prevent from overrunning the input buffer, before
		every move the function checks if the end of the file is reached. If the function looks for
		sync_token_code different from SEOF_T and reaches the end of the source file, the
		function calls exit(synerrno). */
	while (sync_token_code != lookahead_token.code) {
		if (sync_token_code != SEOF_T && lookahead_token.code == SEOF_T) {
			exit(synerrno);
		}

		lookahead_token = mlwpar_next_token(sc_buf);
	}

	/* If a matching token is found and the matching token is not SEOF_T, the function
		advances the input token one more time and returns. If a matching token is found and
		the matching token is SEOF_T, the function returns. */
	if (sync_token_code != SEOF_T) {	
		lookahead_token = mlwpar_next_token(sc_buf);
	}
}
Пример #3
0
/*
 * Purpose: Start the parser.
 * Author: Jason Macfarlane
 * History/Versions: 1.0
 * Called functions: mlwpar_next_token(), program(), match(), gen_incode()
 * Parameters: Buffer* in_buf
 */
void parser(Buffer* in_buf) {
    sc_buf = in_buf; /* Copy the passed buffer pointer location to the scanner buffer. */
    lookahead = mlwpar_next_token(sc_buf); /* Advance lookahead to the first token. */
    program(); /* Start the parser. */
    match(SEOF_T,NO_ATTR); /* Match the end of the PLATYPUS file. */
    gen_incode("PLATY: Source file parsed");
}
Пример #4
0
/* Provided by S.Ranev */
void parser(Buffer *in_buf) {
	sc_buf = in_buf;
	lookahead_token = mlwpar_next_token(sc_buf);
	program();
	match(SEOF_T, NO_ATTR);
	gen_incode("Source file parsed");
}
Пример #5
0
/*
 * Purpose: Match two tokens: the current input token and the required token.
 * Author: Jason Macfarlane
 * History/Versions: 1.0
 * Called functions: syn_printe(), mlwpar_next_token(), syn_eh()
 * Parameters: int pr_token_code, int pr_token_attribute
 * Algorithm: If the required token code matches the current code, check the types.
 * If the required token code is ART_OP_T, KW_T, LOG_OP_T or REL_OP_T, check if
 * the attributes from both token codes match. If not, break. Otherwise, advance
 * the input token (lookahead). Check for errors and invalid codes.
 */
void match(int pr_token_code, int pr_token_attribute) {
    /* If the required token code matches the current code, enter panic mode and return. */
    if (pr_token_code != lookahead.code) {
        syn_eh(pr_token_code);
        return;
    }
    
    /* Verify the token code. */
    switch (pr_token_code) {
        case ART_OP_T: /* Arithmetic operator token */
        case KW_T: /* Keyword token */
        case LOG_OP_T: /* Logical operator token */
        case REL_OP_T: /* Relational operator token */
            
            /*
             * If the required token attribute doesn't match the
             * current attribute, enter panic more and return.
             */
            if (pr_token_attribute != lookahead.attribute.get_int) {
                syn_eh(pr_token_code);
                return;
            }
            
        default:
            /* If the current token code matches SEOF, return. */
            if (lookahead.code == SEOF_T)
                return;
            
            /* Advance to the next token. */
            lookahead = mlwpar_next_token(sc_buf);
            
            /*
             * If the current token code matches ERR_T, print an error, advance
             * the token and increment the error counter.
             */
            if (lookahead.code == ERR_T) {
                syn_printe();
                lookahead = mlwpar_next_token(sc_buf);
                ++synerrno;
            }
            
            return;
    }
}
Пример #6
0
/*
Purpose: Matches two tokens: the current input token (lookahead_token) 
		and the token required by the parser. 
Author: Kyle Hinskens, Kwok Hong Kelvin Chan
Version: 13.12.6
Called functions: syn_eh, mlwpar_next_token
Parameters: 
			int pr_token_code The token code
			int pr_token_attribute The token attribute
Return value: None
*/
void match(int pr_token_code, int pr_token_attribute) {
	int matched = 0;

	/* The attribute code is used only when the token code is one of
		the following codes: KW_T, LOG_OP_T, ART_OP_T, REL_OP_T. In all other cases
		the token code is matched only. */
	if (lookahead_token.code == pr_token_code) {
		switch(pr_token_code) {
		case KW_T:
		case LOG_OP_T:
		case ART_OP_T:
		case REL_OP_T:
			if (lookahead_token.attribute.get_int == pr_token_attribute) matched = 1;
			break;
		default:
			matched = 1;
			break;
		}
	}

	/* If the match is successful and the lookahead_token is SEOF_T, the function returns. */
	if (matched) {
		if (lookahead_token.code == SEOF_T) return;

		/* If the match is successful and the lookahead_token is not SEOF_T, the function
			advances to the next input token */
		lookahead_token = mlwpar_next_token(sc_buf);

		/* If the new lookahead token is ERR_T, the function calls the error printing function */
		if (lookahead_token.code == ERR_T) {
			syn_printe();
			lookahead_token = mlwpar_next_token(sc_buf); /* Advance to the next input token */
			++synerrno;
			return;
		}
	}
	else {
		/* If the match is unsuccessful, the function calls the error handler and returns. */
		syn_eh(pr_token_code);
		return;
	}
}
Пример #7
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);
}
Пример #8
0
/*  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_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 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= mlwpar_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) */
}