예제 #1
0
파일: token.c 프로젝트: pauley/pcc
/*
 * Scan quickly the input file searching for:
 *	- '#' directives
 *	- keywords (if not flslvl)
 *	- comments
 *
 *	Handle strings, numbers and trigraphs with care.
 *	Only data from pp files are scanned here, never any rescans.
 *	TODO: Only print out strings before calling other functions.
 */
static void
fastscan(void)
{
	struct symtab *nl;
	int ch, i;

	goto run;
	for (;;) {
		ch = NXTCH();
xloop:		if (ch == -1)
			return;
		if ((spechr[ch] & C_SPEC) == 0) {
			PUTCH(ch);
			continue;
		}
		switch (ch) {
		case '/': /* Comments */
			if ((ch = inch()) == '/') {
				if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
				do {
					if (Cflag) PUTCH(ch);
					ch = inch();
				} while (ch != -1 && ch != '\n');
				goto xloop;
			} else if (ch == '*') {
				if (Cflag) { PUTCH('/'); PUTCH('*'); }
				for (;;) {
					ch = inch();
					if (ch == '\n') {
						ifiles->lineno++;
						PUTCH('\n');
					}
					if (ch == -1)
						return;
					if (ch == '*') {
						ch = inch();
						if (ch == '/') {
							if (Cflag) {
								PUTCH('*');
								PUTCH('/');
							} else
								PUTCH(' ');
							break;
						}
						unch(ch);
						ch = '*';
					}
					if (Cflag) PUTCH(ch);
				}
			} else {
				PUTCH('/');
				goto xloop;
			}
			break;

		case '?':  /* trigraphs */
			if ((ch = chktg()))
				goto xloop;
			PUTCH('?');
			break;

		case '\\':
			if ((ch = NXTCH()) == '\n') {
				ifiles->lineno++;
				continue;
			} else {
				PUTCH('\\');
			}
			goto xloop;

		case '\n': /* newlines, for pp directives */
			ifiles->lineno++;
			do {
				PUTCH(ch);
run:				ch = NXTCH();
			} while (ch == ' ' || ch == '\t');
			if (ch == '#') {
				ppdir();
				continue;
			} else if (ch == '%') {
				ch = NXTCH();
				if (ch == ':') {
					ppdir();
					continue;
				} else {
					unch(ch);
					ch = '%';
				}
			}
			goto xloop;

		case '\"': /* strings */
str:			PUTCH(ch);
			while ((ch = inch()) != '\"') {
				PUTCH(ch);
				if (ch == '\\') {
					ch = inch();
					PUTCH(ch);
				}
				if (ch < 0)
					return;
			}
			PUTCH(ch);
			break;

		case '.':  /* for pp-number */
			PUTCH(ch);
			ch = NXTCH();
			if (ch < '0' || ch > '9')
				goto xloop;
			/* FALLTHROUGH */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			do {
				PUTCH(ch);
				ch = NXTCH();
				if (spechr[ch] & C_EP) {
					PUTCH(ch);
					ch = NXTCH();
					if (ch == '-' || ch == '+')
						continue;
				}
			} while ((spechr[ch] & C_ID) || (ch == '.'));
			goto xloop;

		case '\'': /* character literal */
con:			PUTCH(ch);
			if (tflag)
				continue; /* character constants ignored */
			while ((ch = NXTCH()) != '\'') {
				PUTCH(ch);
				if (ch == '\\') {
					ch = NXTCH();
					PUTCH(ch);
				} else if (ch < 0)
					return;
				else if (ch == '\n')
					goto xloop;
			}
			PUTCH(ch);
			break;

		case 'L':
			ch = NXTCH();
			if (ch == '\"') {
				PUTCH('L');
				goto str;
			}
			if (ch == '\'') {
				PUTCH('L');
				goto con;
			}
			unch(ch);
			ch = 'L';
			/* FALLTHROUGH */
		default:
			if ((spechr[ch] & C_ID) == 0)
				error("fastscan");
			if (flslvl) {
				while (spechr[ch] & C_ID)
					ch = NXTCH();
				goto xloop;
			}
			i = 0;
			do {
				yytext[i++] = (usch)ch;
				ch = NXTCH();
				if (ch == '\\') {
					ch = NXTCH();
					if (ch != '\n') {
						unch('\n');
						ch = '\\';
					} else {
						ifiles->lineno++;
						ch = NXTCH();
					}
				}
				if (ch < 0)
					return;
			} while (spechr[ch] & C_ID);
			yytext[i] = 0;
			unch(ch);
			if ((nl = lookup((usch *)yytext, FIND)) != 0) {
				usch *op = stringbuf;
				putstr(gotident(nl));
				stringbuf = op;
			} else
				putstr((usch *)yytext);
			break;
		}
	}
}
예제 #2
0
파일: token.c 프로젝트: enukane/netbsd-src
/*
 * Scan quickly the input file searching for:
 *	- '#' directives
 *	- keywords (if not flslvl)
 *	- comments
 *
 *	Handle strings, numbers and trigraphs with care.
 *	Only data from pp files are scanned here, never any rescans.
 *	TODO: Only print out strings before calling other functions.
 */
static void
fastscan(void)
{
	struct symtab *nl;
	int ch, i = 0;
	int nnl = 0;
	usch *cp;

	goto run;
	for (;;) {
		ch = NXTCH();
xloop:		if (ch == -1)
			return;
#ifdef PCC_DEBUG
		if (dflag>1)
			printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@');
#endif
		if ((spechr[ch] & C_SPEC) == 0) {
			PUTCH(ch);
			continue;
		}
		switch (ch) {
		case EBLOCK:
		case WARN:
		case CONC:
			error("bad char passed");
			break;

		case '/': /* Comments */
			if ((ch = inch()) == '/') {
cppcmt:				if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
				do {
					if (Cflag) PUTCH(ch);
					ch = inch();
				} while (ch != -1 && ch != '\n');
				goto xloop;
			} else if (ch == '*') {
				if (eatcmnt())
					return;
			} else {
				PUTCH('/');
				goto xloop;
			}
			break;

		case '?':  /* trigraphs */
			if ((ch = chktg()))
				goto xloop;
			PUTCH('?');
			break;

		case '\\':
			if ((ch = NXTCH()) == '\n') {
				ifiles->lineno++;
				continue;
			} else {
				PUTCH('\\');
			}
			goto xloop;

		case '\n': /* newlines, for pp directives */
			while (nnl > 0) { PUTCH('\n'); nnl--; }
run2:			ifiles->lineno++;
			do {
				PUTCH(ch);
run:				ch = NXTCH();
				if (ch == '/') {
					ch = NXTCH();
					if (ch == '/')
						goto cppcmt;
					if (ch == '*') {
						if (eatcmnt())
							return;
						goto run;
					} 
					unch(ch);
					ch = '/';
				}
			} while (ch == ' ' || ch == '\t');
			if (ch == '\\') {
				ch = NXTCH();
				if (ch == '\n')
					goto run2;
				unch(ch);
				ch = '\\';
			}
			if (ch == '#') {
				ppdir();
				continue;
			} else if (ch == '%') {
				ch = NXTCH();
				if (ch == ':') {
					ppdir();
					continue;
				} else {
					unch(ch);
					ch = '%';
				}
			} else if (ch == '?') {
				if ((ch = chktg()) == '#') {
					ppdir();
					continue;
				} else if (ch == 0) 
					ch = '?';
			}
			goto xloop;

		case '\"': /* strings */
str:			PUTCH(ch);
			while ((ch = NXTCH()) != '\"') {
				if (ch == '\n')
					goto xloop;
				if (ch == '\\') {
					if ((ch = NXTCH()) != '\n') {
						PUTCH('\\');
						PUTCH(ch);
					} else
						nnl++;
					continue;
                                }
				if (ch < 0)
					return;
				PUTCH(ch);
			}
			PUTCH(ch);
			break;

		case '.':  /* for pp-number */
			PUTCH(ch);
			ch = NXTCH();
			if (ch < '0' || ch > '9')
				goto xloop;
			/* FALLTHROUGH */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			do {
				PUTCH(ch);
nxt:				ch = NXTCH();
				if (ch == '\\') {
					ch = NXTCH();
					if (ch == '\n') {
						goto nxt;
					} else {
						unch(ch);
						ch = '\\';
					}
				}
				if (spechr[ch] & C_EP) {
					PUTCH(ch);
					ch = NXTCH();
					if (ch == '-' || ch == '+')
						continue;
				}
			} while ((spechr[ch] & C_ID) || (ch == '.'));
			goto xloop;

		case '\'': /* character literal */
con:			PUTCH(ch);
			if (tflag)
				continue; /* character constants ignored */
			while ((ch = NXTCH()) != '\'') {
				if (ch == '\n')
					goto xloop;
				if (ch == '\\') {
					if ((ch = NXTCH()) != '\n') {
						PUTCH('\\');
						PUTCH(ch);
					} else
						nnl++;
					continue;
				}
				if (ch < 0)
					return;
				PUTCH(ch);
			}
			PUTCH(ch);
			break;

		case 'L':
			ch = NXTCH();
			if (ch == '\"') {
				PUTCH('L');
				goto str;
			}
			if (ch == '\'') {
				PUTCH('L');
				goto con;
			}
			unch(ch);
			ch = 'L';
			/* FALLTHROUGH */
		default:
			if ((spechr[ch] & C_ID) == 0)
				error("fastscan");
			if (flslvl) {
				while (spechr[ch] & C_ID)
					ch = NXTCH();
				goto xloop;
			}
			i = 0;
			do {
				yytext[i++] = (usch)ch;
				ch = NXTCH();
				if (ch == '\\') {
					ch = NXTCH();
					if (ch != '\n') {
						unch(ch);
						ch = '\\';
					} else {
						putch('\n');
						ifiles->lineno++;
						ch = NXTCH();
					}
				}
				if (ch < 0)
					return;
			} while (spechr[ch] & C_ID);

			yytext[i] = 0;
			unch(ch);

			cp = stringbuf;
			if ((nl = lookup((usch *)yytext, FIND)) && kfind(nl)) {
				putstr(stringbuf);
			} else
				putstr((usch *)yytext);
			stringbuf = cp;

			break;
		}
	}
}