Пример #1
0
Файл: lex1.c Проект: nicoUT/lex
/* Skip blanks and whitespace.  Expand this function to skip comments too. */
void skipblanks ()
  {
      int c;
      while ((c = peekchar()) != EOF && (c == ' ' || c == '\n' || c == '\t' || c == '{' || (c == '(' && peek2char() == '*'))){
		// { } comments
		if((c = peekchar()) == '{'){
			while((c = peekchar()) != '}'){
				getchar();
			}
		}
		// (* *) comments
		int loop = 1;
		if((c = peekchar()) == '(' && (c = peek2char()) == '*'){
			getchar();		// (
			while(loop){
				getchar(); 	// *
				if(peekchar() == '*' && peek2char() == ')'){		//exit
					getchar();	//grab *, then stop looping
					loop = 0;
				}
			}
		}
		getchar();	// will grab last ) and }
	  }
        
    }
Пример #2
0
/* Skip whitespace and comments. Moves the stream pointer
 * to right before the next valid character. */
void skipblanks () {
	int c, d;
	boolean done = FALSE;

	while ((c = peekchar()) != EOF &&
			(c == ' ' || c == '\n' || c == '\t' || c == 13 || c == '(' || c == '{')) {

		/* Comment is of the form {}; parse through it. */
		if (c == '{') {
			c = getchar();
			done = FALSE;

			while (!done) {
				c = getchar();
				if (c == EOF) {
					EOFFLG = 1;
					done = TRUE;
				}
				if (c == '}') {
					done = TRUE;
				}
			}
		}

		/* Comment is of the form (**). Check the next character to confirm
		 * that this is actually a comment before parsing through it. */
		if (c == '(' && (d = peek2char()) == '*') {
			getchar();
			getchar();
			done = FALSE;

			while (!done) {
				c = getchar();
				if (c == EOF) {
					EOFFLG = 1;
					done = TRUE;
				}
				if (c == '*' && (d = peekchar()) == ')') {
					getchar();
					done = TRUE;
				}
			}
		}
		else if (c == '(') {
			/* Not a comment. Break. */
			break;
		}

		getchar();
	}

}
Пример #3
0
Файл: lex1.c Проект: nicoUT/lex
TOKEN getstring (TOKEN tok){			//assuming no empty strings, no s := ''
	char string[16];
	int index = 0, loop = 1;
	int c;
	getchar();							//grab first apostrophe
	while(loop){
		c = getchar();					//first character of string, assuming at least length 1
		//escaped apostrophe
		if(peekchar() == '\''){
			if(peek2char() != '\''){
				getchar();
				//if not at max string
				if(index < 15){
					string[index] = c;
					string[index+1] = 0;		//not escaped, null terminate string
				}
				loop = 0;
			}
			else{						//escaped, grab one apostrophe
				getchar();
				string[index] = c;
				index++;
			}
		}
		else{							//normal character
			//if not at max string
			if(index < 15){
				string[index] = c;
				index++;
			}
		}
		string[15] = 0;					//null terminate, special condition where string is too large
	}
	strcpy(tok->stringval, string);
	tok->tokentype = STRINGTOK;
	tok->datatype = STRINGTYPE;
	
}
Пример #4
0
Файл: lex1.c Проект: nicoUT/lex
//capturing only 8 significant digits right now. double check this.
TOKEN number (TOKEN tok)
  { long num = 0;
    int  c, charval;
	char integ[100];
	char frac[100];	//null terminate these when done
	int decFound = 0, index = 0, decIndex = 0, integCount = 0, fracCount = 0, eFound = 0, i = 0;
	int tens = 0;		//num * 10^0 initially
	int sigOffset = 0;	//subtract from index to get number of significant digits
	int expo = 0;
	int startSig = 0;		//once a significant figure is foundm, set to 1
	int zerosAfterDec = 0;	//counts the number of zeros after the decimal. use when there are only 0's before decimal
	int zerosBeforeDec = 0; //counts the number of zeros skipped before the decimal point.
    while ((c = peekchar()) != EOF && ((CHARCLASS[c] == NUMERIC) || c == '.' || c == 'e')){ 
		while(((c = peekchar()) == '0' || c == '.') && !startSig){			//while(((c = peekchar()) == '0' || c == '.') && !startSig && CHARCLASS[c] == NUMERIC){	<- this does not work. dont try again
			c = getchar();
			if(c == '.' && peekchar() == '.'){
				//put back '.' and this number is done
				ungetc(c, stdin);
				tok->tokentype = NUMBERTOK;
				tok->datatype = INTEGER;
				tok->intval = num;
				return tok;						//special condition for 0 followed by .. delimiter
				
			}
			if(c == '.'){
				decFound = 1;
				decIndex = index;
			}
			else if(decFound && c == '0'){					//this is messing with frac[] array. something with decIndex i think...
				zerosAfterDec++;
			}
			else if(!decFound && c == '0'){
				zerosBeforeDec++;
			}
			index++;
		}
		//printf("zerosAfterDec = %d, zerosBeforeDec = %d\n", zerosAfterDec, zerosBeforeDec);
		if(c == '.' && peek2char() == '.')
			break;
		startSig = 1;
		sigOffset = index;
		c = getchar();
		if(c == 'e'){
			expo = exponent();
			eFound = 1;
		}
		else if(c == '.'){
			decIndex = index;
			decFound = 1;
		}
		else if(CHARCLASS[c] == NUMERIC){
			if(!decFound){					//adding integer part
			charval = (c - '0');
			num = num * 10 + charval;
			integ[index - zerosBeforeDec] = c;
			integCount++;
			}
			else if(decFound && c != '.'){
				frac[index - decIndex - zerosAfterDec - 1] = c;
				fracCount++;
			}
		}
		else						//special case for 0 and trimming non significant digits
			ungetc(c, stdin);
		index++;
    }
	
	//if integer, check for overflow
	char maxint[10] = "2147483647";
	int greater = 0;
	if(!decFound && integCount > 0){
		if(integCount > 10)
			printf("ERROR: INTEGER OVERFLOW FOR FOLLOWING TOKEN\n");
		if(integCount == 10){
			int i = 0;
			while(integ[i] == maxint[i] && i < integCount)
				i++;
			if(i != integCount){
				if(integ[i] > maxint[i])
					printf("ERROR: INTEGER OVERFLOW FOR FOLLOWING TOKEN\n");
			}
		}
	}
	
	//if decFound && integCount > 8. truncate and modify exponent
	char integ2[8];
	if(decFound && integCount > 8){	
		fracCount = 0;							//all 8 significant digits will be in integ[]
		expo += integCount - 8;
		integCount = 8;
		
		//recalculate num
		i = 0;
		num = 0;
		for(; i < 8; i++){
			charval = integ[i] - '0';
			num = num * 10 + charval;
		}
	}
	/* if(decFound && fracCount > 8){
		integCount = 0;
		expo -= fracCount - 8;
		fracCount = 8;
	} */

    tok->tokentype = NUMBERTOK;
	if(!decFound && !eFound){
		tok->datatype = INTEGER;
		tok->intval = num;
	}
	else{
		float mult = 0.1f;
		float fNum = num/1.0;
		int j = 0;
		for(; j < fracCount; j++){
			fNum = fNum + (frac[j] - '0')*mult;
			mult /= 10;
		}
		if((expo - zerosAfterDec) > 38 || (expo - zerosAfterDec) < -38)
			printf("ERROR: FLOAT OVERFLOW FOR FOLLOWING TOKEN\n");
		fNum = fNum * pow(10.0, expo/1.0) * pow(10.0, -zerosAfterDec/1.0);				//adding in multiplication by factor of 10
		tok->datatype = REAL;
		tok->realval = fNum;
	}
    return (tok);
}
Пример #5
0
/* Reads the number(s) starting from the current stream pointer location.
 * If the number is an integer, stores it in the argument TOKEN's intval
 * var. If it is a float, stores it in the argument TOKEN's realval var.
 *
 * Checks for overflow for (unsigned) integers and over-/underflow in floats.
 *
 * Returns the TOKEN given in the argument. */
TOKEN number(TOKEN tok) {
	int c, cclass, cint, d, dclass;
	double num = 0;
	boolean is_real = FALSE;	/* For real numbers (i.e., when the input token has a '.' in it). */
	boolean use_e = FALSE;		/* For when a token represents a number in (scientific) E notation. */
	boolean e_mult = FALSE;		/* Flag used to determine which direction to shift the decimal point. */

	double frac = 0;			/* For the numbers to the right of the decimal place. Is always < 1. */
	double counter = 1;

	int num_insig_figs = 0; 	/* Used when checking for over-/underflow. */

	while ((c = peekchar()) != EOF) {

		cclass = CHARCLASS[c];
		if (cclass != NUMERIC && c != '.' && c != 'e' && c != 'E') {
			break;
		}
		else if (c == 'e' || c == 'E') {
			d = peek2char();
			dclass = CHARCLASS[d];
			if (dclass != NUMERIC && d != '+' && d != '-') {
				break;		// should throw an error
			}

			if (d == '+') {
				getchar();
				e_mult = TRUE;
			}
			else if (d == '-') {
				getchar();
			}
			else if (dclass == NUMERIC) {
				e_mult = TRUE;
			}

//			getchar();
//			c = peek2char();
//			if ((cclass = CHARCLASS[c]) != NUMERIC) {
//printf("\tfuckles; curr d is %c, curr c is %c\n", d, c);
//				break;
//			}

			// CALL "PEEK3CHAR" TO SEE IF AT LEAST ONE DIGIT AFTER PLUS/MINUS SIGN?

			use_e = TRUE;

			/* The number being processed is a float. Since the value of everything
			 * to the right of the decimal point is not computed until after this
			 * loop, and its value is needed before that time, compute it now. */
			if (is_real) {
				double temp = 1;
//printf("hi\n");
				int i;
				for (i = 1; i < counter; i++) {
					temp *= 10;
				}

				num = num + (frac / temp);
				frac = 0;
				counter = 1;
				is_real = FALSE;
			}
		}
		else if (c == '.') {
			d = peek2char();
			if (d == EOF || d == '.' || (dclass = CHARCLASS[d]) != NUMERIC) {
				break;		// should throw an error
			}

			is_real = TRUE;
		}
		else {
			cint = (c - '0');

			if (use_e) {
				frac = frac * 10 + cint;
			}
			else if (is_real) {
				frac = frac * 10 + cint;
				counter++;
				if (num == 0) {
					num_insig_figs++;
				}
			}
			else {
				num = num * 10 + cint;
				num_insig_figs++;
			}

		}

		getchar();
	}

	tok->tokentype = NUMBERTOK;
//printf("frac is %f, num insig figs is %d, use_e is %d\n", frac, num_insig_figs, use_e);
	if (use_e) {
		tok->datatype = REAL;

		/* Ignore insignificant figures when checking for over-/underflow. */
		if ((num_insig_figs - frac) > FLT_MAX_10_EXP ||
				(num_insig_figs - frac) < FLT_MIN_10_EXP) {
//printf("\tin use_e: frac is %f, num insig figs is %d\n", frac, num_insig_figs);
			printf("Floating number out of range\n");
			tok->realval = 0;
		}
		else {
			int i;
			for (i = 0; i < frac; i++) {
				if (e_mult) {
					num *= 10;
				}
				else {
					num /= 10;
				}
			}
			tok->realval = num;
		}

	}
	else if (is_real) {
		tok->datatype = REAL;

		/* Ignore insignificant figures when checking for over-/underflow. */
		if ((num_insig_figs - counter) > FLT_MAX_10_EXP
				|| (num_insig_figs - counter) < FLT_MIN_10_EXP) {		// last test needed?
//printf("\tin is_real: frac is %f, num insig figs is %d\n", frac, num_insig_figs);
			printf("Floating number out of range\n");
			tok->realval = 0;
		}
		else {
			double temp = 1;

			int i;
			for (i = 1; i < counter; i++) {
				temp *= 10;
			}
			tok->realval = num + (frac / temp);
		}

	}
	else {
		tok->datatype = INTEGER;

		if (num > INT_UNSIGNED_MAX) {
			printf("Integer number out of range\n");
			tok->intval = INT_UNSIGNED_MAX;
//			return gettoken();		// enable if don't want out-of-range msg to be printed; disable prev line
		}
		else {
			tok->intval = num;
		}
	}

	return tok;
}
Пример #6
0
/* Reads the string starting from the current stream pointer
 * location. Stores the string in the argument TOKEN's
 * tokenstring[] var. Truncates strings if they are greater than
 * 15 characters in length. Returns the TOKEN given in the argument. */
TOKEN getstring (TOKEN tok) {
	int c, d, cclass;
	int counter = 0;

	c = peekchar();
	if (c == '\'') {	// consume the first apostrophe
		getchar();
	}
	else {
		// ????????????????????????????????
	}

	while ((c = peekchar()) != EOF && (d = peek2char()) != EOF && counter < 15) {

//		cclass = CHARCLASS[c];
//		if (c != '\'' && cclass != ALPHA && cclass != NUMERIC) {
//			break;
//		}

		/* Double apostrophe found. */
		if (c == '\'' && d == '\'') {
			getchar();
			getchar();
			tok->tokenval.tokenstring[counter] = '\'';
			counter++;
			continue;
		}
		else if (c == '\'' && d != '\'') {
			/* End of string reached. Break. */
			getchar();
			counter++;
			break;
		}
		else {
			tok->tokenval.tokenstring[counter] = c;
		}

		getchar();

		// should it be looping until it finds the last single apostrophe?
		/* Token may be longer than 15 characters; if it is, parse
		 * through the rest of it. */
		if (counter == 14) {
			c = peekchar();
			d = peek2char();
			while (c != '\'' && d != '\'' && d != EOF) {	// check c != eof?
				getchar();
				c = peekchar();
				d = peek2char();
			}

			// add eof check here?

			getchar();
			getchar();
		}

		counter++;
	}
	tok->tokenval.tokenstring[counter] = '\0';

	tok->tokentype = STRINGTOK;

	return tok;
}