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

📄 scanner.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ *									* *			Copyright (c) 1986, 1989 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *									* *			Modification History				* *									* *	005 - Made # and \ work as expected in shellmode.		* *	      (Jon Reeves, January 21, 1989)				* *									* *      004 - Added a <cr> for the -x option for use with xdb           * *            (David Metsky, March 8, 1988)				* *									* *	003 - Merged in 4.3 changes.					* *	      (vjh, April 29, 1986)					* *									* *	002 - Update copyright.						* *	      (vjh, August 23, 1985)					* *									* *	001 - Added saved-command feature:  <cr> alone on a command 	* *	      line reexecutes previously entered command.		* *	      (Victoria Holt, April 9, 1985)				* *									* ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. *//* derived from: "@(#)scanner.c	5.1 (Berkeley) 5/31/85" */#ifndef lintstatic char sccsid[] = "@(#)scanner.c	4.2	ULTRIX	11/9/90";#endif not lintstatic char rcsid[] = "$Header: scanner.c,v 1.5 84/12/26 10:42:05 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;#define MAXLINESIZE 10240#endifpublic String initfile;public boolean xdb;		/* xdb specific features */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') \)public boolean chkalias;public char scanner_linebuf[MAXLINESIZE];private File in;private File recorded_input;private char *record_name = nil;private char *curchar, *prevchar;private char prevbuf[MAXLINESIZE];#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 enterlexclass(class, s)Charclass class;String s;{    register char *p;    for (p = s; *p != '\0'; p++) {	lexclass[*p] = class;    }}public set_record(string)char *string;{	if(record_name != nil) {		fclose(recorded_input);		record_name = nil;	}	if(strlen(string)) {		if((recorded_input = fopen(string, "w")) != nil) {			record_name = strdup(string);		} else {			error("unable to open %s for recording", string);		}	}}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 = scanner_linebuf;    scanner_linebuf[0] = '\0';    prevbuf[0] = '\n';    chkalias = true;}/* * Read a single token. * * The input is line buffered.  Tokens cannot cross line boundaries. * * There are two "modes" of operation:  one as in a compiler, * and one for reading shell-like syntax.  In the first mode * there is the additional choice of doing alias processing. */private Boolean shellmode;public Token yylex(){    register int c;    register char *p;    register Token t;    String line;    integer n;    p = curchar;    if (*p == '\0') {	do {	    if (isterm(in)) {		printf("(%s) ", cmdname);		if (xdb) {     /* 004 - DNM */		    printf("\n");		}	    }	    fflush(stdout);	    line = fgets(scanner_linebuf, MAXLINESIZE, in);	} while (line == nil and not eofinput());	if (line == nil) {	    c = EOF;	} else {	    p = scanner_linebuf;	    while (lexclass[*p] == WHITE) {		p++;	    }	    if (*p == '\n') {	        strcpy(scanner_linebuf, prevbuf);		p = scanner_linebuf;	    } else {	        strcpy(prevbuf, p);	    }	    shellmode = false;	}	Iline_alloc(p);	if(record_name != nil) {		fputs(p, recorded_input);    }	chkalias = true;    } else {	while (lexclass[*p] == WHITE) {	    p++;	}    }    curchar = p;    prevchar = curchar;    c = *p;    if (lexclass[c] == ALPHA) {	t = getident(chkalias);    } else if (lexclass[c] == NUM) {	if (shellmode) {	    t = getident(chkalias);	} else {	    t = getnum();	}    } else {	++curchar;	switch (c) {	    case '\n':		t = '\n';		if (errlineno != 0) {		    errlineno++;		}		break;	    case '"':	    case '\'':		t = getstring(c);		break;	    case '.':		if (shellmode) {		    --curchar;		    t = getident(chkalias);		} else if (isdigit(*curchar)) {		    --curchar;		    t = getnum();		} else {		    t = '.';		}		break;	    case '-':		if (shellmode) {		    --curchar;		    t = getident(chkalias);		} else if (*curchar == '>') {		    ++curchar;		    t = ARROW;		} else {		    t = '-';		}		break;	    case '#':		if (shellmode) {		    --curchar;		    t = getident(chkalias);		} else if (not isterm(in)) {		    *p = '\0';		    curchar = p;		    t = '\n';		    ++errlineno;		} else {		    t = '#';		}		break;	    case '\\':		if (*(p+1) == '\n') {		    n = MAXLINESIZE - (p - &scanner_linebuf[0]);		    if (n > 1) {			if (fgets(p, n, in) == nil) {			    t = 0;			} else {			    curchar = p;			    t = yylex();			}		    } else {			if (shellmode) {			    --curchar;			    t = getident(chkalias);			} else {			    t = '\\';			}		    }		} else {		    if (shellmode) {			--curchar;			t = getident(chkalias);		    } else {			t = '\\';		    }		}		break;	    case EOF:		t = 0;		break;	    default:		if (shellmode and index("!&*<>()[]", c) == nil) {		    --curchar;		    t = getident(chkalias);		} else {		    t = c;		}		break;	}    }    chkalias = false;#   ifdef LEXDEBUG	if (lexdebug) {	    fprintf(stderr, "yylex returns ");	    print_token(stderr, t);	    fprintf(stderr, "\n");	}#   endif	if(t == DELETE) {		char *tmp;				if(strncmp((tmp = (char *)strpbrk(line, "a")), "all", 3) == 0) {			tmp[0] = '*';			tmp[1] = ' ';			tmp[2] = ' ';		}	}    return t;}/* * Put the given string before the current character * in the current line, thus inserting it into the input stream. */public insertinput (s)String s;{    register char *p, *q;    int need, avail, shift;    q = s;    need = strlen(q);    avail = curchar - &scanner_linebuf[0];    if (need <= avail) {	curchar = &scanner_linebuf[avail - need];	p = curchar;	while (*q != '\0') {	    *p++ = *q++;	}    } else {	p = curchar;	while (*p != '\0') {	    ++p;	}	shift = need - avail;	if (p + shift >= &scanner_linebuf[MAXLINESIZE]) {	    error("alias expansion too large");	}	for (;;) {	    *(p + shift) = *p;	    if (p == curchar) {		break;	    }	    --p;	}	p = &scanner_linebuf[0];	while (*q != '\0') {	    *p++ = *q++;	}	curchar = &scanner_linebuf[0];    }}/* * Get the actuals for a macro call. */private String movetochar (str, c)String str;char c;{    register char *p;    while (*p != c) {	if (*p == '\0') {	    error("missing ')' in macro call");	} else if (*p == ')') {	    error("not enough parameters in macro call");	} else if (*p == ',') {	    error("too many parameters in macro call");	}	++p;    }    return p;}private String *getactuals (n)integer n;{    String *a;    register char *p;    int i;    a = newarr(String, n);    p = curchar;    while (*p != '(') {	if (lexclass[*p] != WHITE) {	    error("missing actuals for macro");	}	++p;    }    ++p;    for (i = 0; i < n - 1; i++) {	a[i] = p;	p = movetochar(p, ',');	*p = '\0';	++p;    }    a[n-1] = p;    p = movetochar(p, ')');    *p = '\0';    curchar = p + 1;    return a;}/* * Do command macro expansion, assuming curchar points to the beginning * of the actuals, and we are not in shell mode. */private expand (pl, str)List pl;String str;{    char buf[4096], namebuf[100];    register char *p, *q, *r;    String *actual;    Name n;    integer i;    boolean match;    if (pl == nil) {	insertinput(str);    } else {	actual = getactuals(list_size(pl));	p = buf;	q = str;	while (*q != '\0') {	    if (p >= &buf[4096]) {		error("alias expansion too large");	    }	    if (lexclass[*q] == ALPHA) {

⌨️ 快捷键说明

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