⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scanner.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
/*#@(#)scanner.c	4.1	Ultrix	7/17/90*//* Copyright (c) 1982 Regents of the University of California */static char sccsid[] = "@(#)scanner.c 1.8 8/5/83";static char rcsid[] = "$Header: scanner.c,v 1.3 84/03/27 10:23:50 linton Exp $";/* * Debugger scanner. */#include "defs.h"#include "scanner.h"#include "main.h"#include "keywords.h"#include "tree.h"#include "symbols.h"#include "names.h"#include "y.tab.h"#ifndef publictypedef int Token;#endifpublic String initfile = ".dbxinit";typedef enum { WHITE, ALPHA, NUM, OTHER } Charclass;private Charclass class[256 + 1];private Charclass *lexclass = class + 1;#define isdigit(c) (lexclass[c] == NUM)#define isalnum(c) (lexclass[c] == ALPHA or lexclass[c] == NUM)#define ishexdigit(c) ( \    isdigit(c) or (c >= 'a' and c <= 'f') or (c >= 'A' and c <= 'F') \)#define MAXLINESIZE 1024private File in;private Char linebuf[MAXLINESIZE];private Char *curchar, *prevchar;#define MAXINCLDEPTH 10private struct {    File savefile;    Filename savefn;    int savelineno;} inclinfo[MAXINCLDEPTH];private unsigned int curinclindex;private Token getident();private Token getnum();private Token getstring();private Boolean eofinput();private Char charcon();private Char charlookup();private enterlexclass(class, s)Charclass class;String s;{    register char *p;    for (p = s; *p != '\0'; p++) {	lexclass[*p] = class;    }}public scanner_init(){    register Integer i;    for (i = 0; i < 257; i++) {	class[i] = OTHER;    }    enterlexclass(WHITE, " \t");    enterlexclass(ALPHA, "abcdefghijklmnopqrstuvwxyz");    enterlexclass(ALPHA, "ABCDEFGHIJKLMNOPQRSTUVWXYZ_$");    enterlexclass(NUM, "0123456789");    in = stdin;    errfilename = nil;    errlineno = 0;    curchar = linebuf;    linebuf[0] = '\0';}/* * Read a single token. * * Input is line buffered. * * There are two "modes" of operation:  one as in a compiler, * and one for reading shell-like syntax. */private Boolean shellmode;public Token yylex(){    register int c;    register char *p;    register Token t;    String line;    p = curchar;    if (*p == '\0') {	do {	    if (isterm(in)) {		printf("(%s) ", cmdname);		fflush(stdout);	    }	    line = fgets(linebuf, MAXLINESIZE, in);	} while (line == nil and not eofinput());	if (line == nil) {	    c = EOF;	} else {	    p = linebuf;	    while (lexclass[*p] == WHITE) {		p++;	    }	    shellmode = false;	}    } else {	while (lexclass[*p] == WHITE) {	    p++;	}    }    curchar = p;    prevchar = curchar;    c = *p;    if (lexclass[c] == ALPHA) {	t = getident();    } else if (lexclass[c] == NUM) {	if (shellmode) {	    t = getident();	} else {	    t = getnum();	}    } else {	++curchar;	switch (c) {	    case '\n':		t = '\n';		if (errlineno != 0) {		    errlineno++;		}		break;	    case '"':	    case '\'':		t = getstring();		break;	    case '.':		if (shellmode) {		    --curchar;		    t = getident();		} else if (isdigit(*curchar)) {		    --curchar;		    t = getnum();		} else {		    t = '.';		}		break;	    case '<':		if (not shellmode and *curchar == '<') {		    ++curchar;		    t = LFORMER;		} else {		    t = '<';		}		break;	    case '>':		if (not shellmode and *curchar == '>') {		    ++curchar;		    t = RFORMER;		} else {		    t = '>';		}		break;	    case '#':		if (*curchar == '^') {		    ++curchar;		    t = ABSTRACTION;		} else {		    t = '#';		}		break;	    case '-':		if (shellmode) {		    --curchar;		    t = getident();		} else if (*curchar == '>') {		    ++curchar;		    t = ARROW;		} else {		    t = '-';		}		break;	    case EOF:		t = 0;		break;	    default:		if (shellmode and index("!&*()[]", c) == nil) {		    --curchar;		    t = getident();		} else {		    t = c;		}		break;	}    }#   ifdef LEXDEBUG	if (lexdebug) {	    fprintf(stderr, "yylex returns ");	    print_token(stderr, t);	    fprintf(stderr, "\n");	}#   endif    return t;}/* * Parser error handling. */public yyerror(s)String s;{    register char *p;    register integer start;    if (streq(s, "syntax error")) {	beginerrmsg();	p = prevchar;	start = p - &linebuf[0];	if (p > &linebuf[0]) {	    while (lexclass[*p] == WHITE and p > &linebuf[0]) {		--p;	    }	}	fprintf(stderr, "%s", linebuf);	if (start != 0) {	    fprintf(stderr, "%*c", start, ' ');	}	if (p == &linebuf[0]) {	    fprintf(stderr, "^ unrecognized command");	} else {	    fprintf(stderr, "^ syntax error");	}	enderrmsg();    } else {	error(s);    }}/* * Eat the current line. */public gobble(){    curchar = linebuf;    linebuf[0] = '\0';}/* * Scan an identifier and check to see if it's a keyword. */private Token getident(){    char buf[256];    register Char *p, *q;    register Token t;    p = curchar;    q = buf;    if (shellmode) {	do {	    *q++ = *p++;	} while (index(" \t\n!&<>*[]()'\"", *p) == nil);    } else {	do {	    *q++ = *p++;	} while (isalnum(*p));    }    curchar = p;    *q = '\0';    yylval.y_name = identname(buf, false);    if (not shellmode) {	t = findkeyword(yylval.y_name);	if (t == nil) {	    t = NAME;	}    } else {	t = NAME;    }    return t;}/* * Scan a number. */private Token getnum(){    char buf[256];    register Char *p, *q;    register Token t;    Integer base;    p = curchar;    q = buf;    if (*p == '0') {	if (*(p+1) == 'x') {	    p += 2;	    base = 16;	} else {	    base = 8;	}    } else {	base = 10;    }    if (base == 16) {	do {	    *q++ = *p++;	} while (ishexdigit(*p));    } else {	do {	    *q++ = *p++;	} while (isdigit(*p));    }    if (*p == '.') {	do {	    *q++ = *p++;	} while (isdigit(*p));	if (*p == 'e' or *p == 'E') {	    p++;	    if (*p == '+' or *p == '-' or isdigit(*p)) {		*q++ = 'e';		do {		    *q++ = *p++;		} while (isdigit(*p));	    }	}	*q = '\0';	yylval.y_real = atof(buf);	t = REAL;    } else {	*q = '\0';	switch (base) {	    case 10:		yylval.y_int = atol(buf);		break;	    case 8:		yylval.y_int = octal(buf);		break;	    case 16:		yylval.y_int = hex(buf);		break;	    default:		badcaseval(base);	}	t = INT;    }    curchar = p;    return t;}/* * Convert a string of octal digits to an integer. */private int octal(s)String s;{    register Char *p;    register Integer n;    n = 0;    for (p = s; *p != '\0'; p++) {	n = 8*n + (*p - '0');    }    return n;}/* * Convert a string of hexadecimal digits to an integer. */private int hex(s)String s;{    register Char *p;    register Integer n;    n = 0;    for (p = s; *p != '\0'; p++) {	n *= 16;	if (*p >= 'a' and *p <= 'f') {	    n += (*p - 'a' + 10);	} else if (*p >= 'A' and *p <= 'F') {	    n += (*p - 'A' + 10);	} else {	    n += (*p - '0');	}    }    return n;}/* * Scan a string. */private Token getstring(){    char buf[256];    register Char *p, *q;    Boolean endofstring;    p = curchar;    q = buf;    endofstring = false;    while (not endofstring) {	if (*p == '\n' or *p == '\0') {	    error("non-terminated string");	    endofstring = true;	} else if (*p == '"' or *p == '\'') {	    if (*(p+1) != *p) {		endofstring = true;	    } else {		*q++ = *p;	    }	} else {	    curchar = p;	    *q++ = charcon(p);	    p = curchar;	}	p++;    }    curchar = p;    *q = '\0';    yylval.y_string = strdup(buf);    return STRING;}/* * Process a character constant. * Watch out for backslashes. */private Char charcon(p)char *p;{    char c, buf[10], *q;    if (*p == '\\') {	++p;	if (*p != '\\') {	    q = buf;	    do {		*q++ = *p++;	    } while (*p != '\\' and *p != '\'' and *p != '\n' and *p != '\0');	    *q = '\0';	    if (isdigit(buf[0])) {		c = (Char) octal(buf);	    } else {		c = charlookup(buf);	    }	    curchar = p - 1;	} else {	    c = '\\';	}    } else {	c = *p;    }    return c;}/* * Do a lookup for a ASCII character name. */private String ascii[] = {    "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",    "BS",  "HT",  "NL",  "VT",  "NP",  "CR",  "SO",  "SI",    "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",    "CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US",    "SP", nil};private char charlookup(s)String s;{    register int i;    for (i = 0; ascii[i] != NULL; i++) {	if (streq(s, ascii[i])) {	    return i;	}    }    if (streq(s, "DEL")) {	return 0177;    }    error("unknown ascii name \"%s\"", s);    return '?';}/* * Input file management routines. */public setinput(filename)Filename filename;{    File f;    f = fopen(filename, "r");    if (f == nil) {	error("can't open %s", filename);    } else {	if (curinclindex >= MAXINCLDEPTH) {	    error("unreasonable input nesting on \"%s\"", filename);	}	inclinfo[curinclindex].savefile = in;	inclinfo[curinclindex].savefn = errfilename;	inclinfo[curinclindex].savelineno = errlineno;	curinclindex++;	in = f;	errfilename = filename;	errlineno = 1;    }}private Boolean eofinput(){    register Boolean b;    if (curinclindex == 0) {	if (isterm(in)) {	    putchar('\n');	    clearerr(in);	    b = false;	} else {	    b = true;	}    } else {	fclose(in);	--curinclindex;	in = inclinfo[curinclindex].savefile;	errfilename = inclinfo[curinclindex].savefn;	errlineno = inclinfo[curinclindex].savelineno;	b = false;    }    return b;}/* * Pop the current input.  Return whether successful. */public Boolean popinput(){    Boolean b;    if (curinclindex == 0) {	b = false;    } else {	b = (Boolean) (not eofinput());    }    return b;}/* * Return whether we are currently reading from standard input. */public Boolean isstdin(){    return (Boolean) (in == stdin);}/* * Send the current line to the shell. */public shellline(){    register char *p;    p = curchar;    while (*p != '\0' and (*p == '\n' or lexclass[*p] == WHITE)) {	++p;    }    shell(p);    if (*p == '\0' and isterm(in)) {	putchar('\n');    }    erecover();}/* * Read the rest of the current line in "shell mode". */public beginshellmode(){    shellmode = true;}/* * Print out a token for debugging. */public print_token(f, t)File f;Token t;{    if (t == '\n') {	fprintf(f, "char '\\n'");    } else if (t == EOF) {	fprintf(f, "EOF");    } else if (t < 256) {	fprintf(f, "char '%c'", t);    } else {	fprintf(f, "\"%s\"", keywdstring(t));    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -