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

📄 vtc.y

📁 Unix下的MUD客户端程序
💻 Y
📖 第 1 页 / 共 2 页
字号:
%{/* vtc.y: VTC compiler and lexical analyzer */#include "vt.h"String ptext;int debug = 0;extern int iwidth[];#define ERR_PRMTNAME	"Primitive name used as function name"#define ERR_RESERVED	"Reserved word used as identifier"#define ERR_DUPGOTO	"Duplicate goto label"#define ERR_MISBREAK	"Misplaced break statement"#define ERR_MISCONT	"Misplaced continue statement"#define ERR_DUPTAG	"Duplicate parameter or local variable name"#define ERR_UDGOTO	"One or more goto labels not defined"#define ERR_TOOMANY	"Too many parameters or local variables"#define ERR_UNTERMCHAR	"Unterminated character constant"#define ERR_UNTERMSTR	"Unterminated string constant"#define ERR_BADBRACE	"Illegal placement of right brace"#define ERR_ILLFUNC	"Illegal placement of reserved word func"/* The intermediate program */#define INIT_CODE 256static Instr *icode;static int loc = 0, codesize;#define Check_code(n) Check(icode, Instr, codesize, loc + (n))#define Hexdigitvalue(a) (isdigit(a) ? a - '0' : ucase(a) - 'A' + 10)#define Code(t) if (1) { Check_code(1); icode[loc++].type = t; } else#define Code2(t, elem, val) if (1) { Check_code(2); icode[loc++].type = t; \				     icode[loc++].elem = val; } else#define Code_iconst(val) Code2(I_ICONST, iconst, val)#define Code_pcall(pn, ac) if (1) { Check_code(2); \				    icode[loc++].type = I_PCALL; \				    icode[loc].pc.pnum = pn; \				    icode[loc++].pc.argc = ac; } else#define Code_fcall(id, ac) if (1) { Check_code(2); \				    icode[loc++].type = I_FCALL; \				    icode[loc++].argc = ac; \				    icode[loc++].ident = id; } elsetypedef struct label {	char *name;	int offset;	struct label *next;} Label;#define MAXILEN 32static Label *lhead = NULL;#ifdef PROTOTYPESstatic void code_var(char *);static void code_goto(char *, int);static void free_labels(void);static void add_tag(char **, int *, char *);static int find_tag(char **, int, char *);static char *parse_token(char *);static int read_char(char **);static int enter_sconst(Cstr);static char *read_string(char *);static char *read_comment(char *);static void compile(void);static void scan(void);static void cleanup_parse();static void lexerror(char *);static void yyerror(char *);static int yylex(void);#elsestatic void compile(), scan(), cleanup_parse(), lexerror(), yyerror();static void code_var(), free_labels(), add_tag(), code_goto();static char *parse_token(), *read_string(), *read_comment();#endif#define INIT_JMP 64#define INIT_COND 16int *jmptab, jmpsize, jmppos;int *condstack, condsize, condpos;int *loopstack, loopsize, looppos;#define Incjmp(n)	Check(jmptab, int, jmpsize, jmppos += (n))#define Pushcond(x)	Push(condstack, int, condsize, condpos, x)#define Pushloop(x)	Push(loopstack, int, loopsize, looppos, x)#define Peekloop	(loopstack[looppos - 1])#define Incloop(n)	if (1) { Pushloop(jmppos); Incjmp(n); } else#define Decloop		looppos--#define Ljmp(l, t)	Code2(t, offset, Peekloop + (l))#define Ldest(l)	(jmptab[Peekloop + (l)] = loc)#define Break		if (looppos) Code2(I_JMP, offset, Peekloop + 1); \			else yyerror(ERR_MISBREAK)#define Continue	if (looppos) Code2(I_JMP, offset, Peekloop); \			else yyerror(ERR_MISCONT)#define Jmp(t)		if (1) { Pushcond(jmppos); Code2(t, offset, jmppos); \				 Incjmp(1); } else#define Dest		(jmptab[condstack[--condpos]] = loc)#define Destnext	(jmptab[condstack[--condpos]] = loc + 2)#define Return		Code2(I_JMP, offset, 0)/* Local vars and array vars */#define MAX_TAGS 32static char *lvars[MAX_TAGS], *avars[MAX_TAGS];static int lvarc = 0, avarc = 0, reqargs = 0;static int lexline = -1;		/* Line being analyzed	     */static int parseline = -1;		/* Line being parsed	     */static int errflag;			/* Error flag		     */static char *curfunc = "";		/* Name of current function  */static char *curfile = "";		/* Name of current file	     */extern Prmt prmtab[];#define OP_BOR	     0#define OP_BXOR	     1#define OP_BAND	     2#define OP_EQ	     3#define OP_NE	     4#define OP_LT	     5#define OP_LE	     6#define OP_GT	     7#define OP_GE	     8#define OP_SL	     9#define OP_SR	    10#define OP_ADD	    11#define OP_SUB	    12#define OP_MULT	    13#define OP_DIV	    14#define OP_MOD	    15#define OP_POSTINC  16#define OP_POSTDEC  17#define OP_PREINC   18#define OP_PREDEC   19#define OP_NOT	    20#define OP_COMPL    21#define OP_NEG	    22#define OP_ASN	    23#define PR_LOOKUP   102%}%union {	int num;	int index;	void (*bobj)();	int str;	char *s;}%token <num>	ICONST%token <str>	SCONST%token <bobj>	BOBJ%token <s>	IDENT%token		FUNC FASSIGN DO WHILE IF ELSE FOR GOTO BREAK CONTINUE RETURN%type  <num>	exprv args asn_op%type  <s>	unreserved%left ';'%left ','%right '=' TA DA MA AA SA SLA SRA BAA BXA BOA CONDA%right '?' ':'%right DEREF%left OR%left AND%left '|'%left '^'%left '&'%left EQ NE%left '<' LE '>' GE%left SL SR%left '+' '-'%left '*' '/' '%'%right '!' '~' INC DEC%left '(' ')' '[' ']'%%directive	: fdecl FASSIGN expr		| fdecl tdecl compound	{ Code(I_NULL); }		| tdecl command		{ Code(I_NULL); }		;command : stmt	| command stmt	;fdecl	: FUNC unreserved adecl		{ curfunc = $2;					  if (find_prmt($2) != -1)						  yyerror(ERR_PRMTNAME); }	;adecl	: '(' optargs ')'	| '(' params { reqargs = avarc; } optargs ')'tdecl	: /* nothing */	| '[' ']'	| '[' locals ']'	;optargs : /* nothing */	| '/' params	;params	: unreserved			{ add_tag(avars, &avarc, $1); }	| params ',' unreserved		{ add_tag(avars, &avarc, $3); }	;locals	: unreserved			{ add_tag(lvars, &lvarc, $1); }	| locals ',' unreserved		{ add_tag(lvars, &lvarc, $3); }	;post	: postlval			{ Code(I_EVAL); }	| postfix	;postlval: IDENT				{ code_var($1); }	| BOBJ				{ Code2(I_BOBJ, bobj, $1); }	| post DEREF IDENT		{ Code2(I_SCONST, sindex,						enter_sconst(cstr_s($3)));					  Code_pcall(PR_LOOKUP, 2); }	| post '[' expr ']'		{ Code_pcall(OP_ADD, 2); }	| post '[' ICONST ']'		{ if ($3) { Code_iconst($3);						    Code_pcall(OP_ADD, 2); } }	| '(' lval ')'	;lval	: postlval	| '*' unary	;atom	: ICONST			{ Code_iconst($1); }	| SCONST			{ Code2(I_SCONST, sindex, $1); }	| '.' unreserved		{ int ind = find_prmt($2);					  if (ind != -1)					       Code2(I_PPTR, pnum, ind);					  else Code2(I_FPTR, ident, $2); }	| IDENT '(' args ')'		{ int ind = find_prmt($1);					  if (ind != -1)					       Code_pcall(ind, $3);					  else Code_fcall($1, $3); }	| '(' lval ')' '(' args ')'	{ Code2(I_EXEC, argc, $5); }	| '(' expr ')'	;/* Can occur before [] */postfix : atom	| postlval INC			{ Code_pcall(OP_POSTINC, 1); }	| postlval DEC			{ Code_pcall(OP_POSTDEC, 1); }	;unary	: postfix	| lval				{ Code(I_EVAL); }	| INC lval			{ Code_pcall(OP_PREINC, 1); }	| DEC lval			{ Code_pcall(OP_PREDEC, 1); }	| '!' unary			{ Code_pcall(OP_NOT, 1); }	| '~' unary			{ Code_pcall(OP_COMPL, 1); }	| '-' unary			{ Code_pcall(OP_NEG, 1); }	| '+' unary	| '&' lval	;binary	: unary	| binary OR			{ Code(I_CVTB); Jmp(I_JMPPT); }	  binary			{ Code(I_CVTB); Dest; }	| binary AND			{ Code(I_CVTB); Jmp(I_JMPPF); }	  binary			{ Code(I_CVTB); Dest; }	| binary '|' binary		{ Code_pcall(OP_BOR, 2); }	| binary '^' binary		{ Code_pcall(OP_BXOR, 2); }	| binary '&' binary		{ Code_pcall(OP_BAND, 2); }	| binary EQ binary		{ Code_pcall(OP_EQ, 2); }	| binary NE binary		{ Code_pcall(OP_NE, 2); }	| binary '<' binary		{ Code_pcall(OP_LT, 2); }	| binary LE binary		{ Code_pcall(OP_LE, 2); }	| binary '>' binary		{ Code_pcall(OP_GT, 2); }	| binary GE binary		{ Code_pcall(OP_GE, 2); }	| binary SL binary		{ Code_pcall(OP_SL, 2); }	| binary SR binary		{ Code_pcall(OP_SR, 2); }	| binary '+' binary		{ Code_pcall(OP_ADD, 2); }	| binary '-' binary		{ Code_pcall(OP_SUB, 2); }	| binary '*' binary		{ Code_pcall(OP_MULT, 2); }	| binary '/' binary		{ Code_pcall(OP_DIV, 2); }	| binary '%' binary		{ Code_pcall(OP_MOD, 2); }	| binary '?'			{ Jmp(I_JMPF); }	  binary ':'			{ Destnext; Jmp(I_JMP); }	  binary			{ Dest; }	| binary '?' ':' { Jmp(I_JMPPT); } binary { Dest; }	;assign	: binary	| lval '=' assign		{ Code_pcall(OP_ASN, 2); }	| lval asn_op			{ Code(I_DUP); Code(I_EVAL); }	  assign			{ Code_pcall($2, 2);					  Code_pcall(OP_ASN, 2); }	| lval CONDA			{ Code(I_DUP); Code(I_EVAL);					  Jmp(I_JMPPT); }	  assign			{ Dest; Code_pcall(OP_ASN, 2); }	;asn_op	: TA	{ $$ = OP_MULT; }	| DA	{ $$ = OP_DIV; }	| MA	{ $$ = OP_MOD; }	| AA	{ $$ = OP_ADD; }	| SA	{ $$ = OP_SUB; }	| SLA	{ $$ = OP_SL; }	| SRA	{ $$ = OP_SR; }		| BAA	{ $$ = OP_BAND; }	| BXA	{ $$ = OP_BXOR; }	| BOA	{ $$ = OP_BOR; }	;/* Expression, value equal to last assignment-expression */expr	: assign	| expr ',' { Code(I_POP); } assign	;/* List of assignment-expressions, retaining values (arg list) */exprv	: assign			{ $$ = 1; }	| exprv ',' assign		{ $$ = $1 + 1; }	;args	: /* nothing */			{ $$ = 0; }	| exprv	;/* Optional expression, no value */oexprn	: /* nothing */	| expr				{ Code(I_POP); }	;/* Optional expression with value */oexprv	: /* nothing */			{ Code_iconst(1); }	| expr	;compound: '{' stmtlist '}' ;stmtlist: /* nothing */	| stmtlist stmt	;ifcond	: IF '(' expr ')'		{ Jmp(I_JMPF); } ;stmt	: compound	| oexprn ';'	| ifcond stmt			{ Dest; }	| ifcond stmt ELSE { Destnext; Jmp(I_JMP); } stmt { Dest; }	| WHILE				{ Incloop(2); Ldest(0); }	  '(' expr ')'			{ Ljmp(1, I_JMPF); }	  stmt				{ Ljmp(0, I_JMP); Ldest(1); Decloop; }	| DO				{ Incloop(3); Ldest(2); }	  stmt				{ Ldest(0); }	  WHILE '(' expr ')'		{ Ljmp(2, I_JMPT); Ldest(1); Decloop; }	| FOR '(' oexprn ';'		{ Incloop(4); Ldest(3); }	  oexprv ';'			{ Ljmp(1, I_JMPF); Ljmp(2, I_JMP);					  Ldest(0); }	  oexprn ')'			{ Ljmp(3, I_JMP); Ldest(2); }	  stmt				{ Ljmp(0, I_JMP); Ldest(1); Decloop; }	| IDENT ':' { code_goto($1, 0); } stmt	| GOTO IDENT ';'		{ code_goto($2, 1); }	| BREAK ';'			{ Break; }	| CONTINUE ';'			{ Continue; }	| RETURN ';'			{ Code(I_NULL); Return; }	| RETURN expr ';'		{ Return; }	;/* Error if identifier is reserved */unreserved	: IDENT		| reserved		{ yyerror(ERR_RESERVED); $$ = ""; }		;reserved	: BOBJ | DO | WHILE | IF | ELSE | FOR | FUNC | GOTO		| BREAK | CONTINUE | RETURN | ICONST ;%%/* Auxiliary compiler functions */static void code_var(ident)	char *ident;{	int tag;	if ((tag = find_tag(avars, avarc, ident)) != -1)		Code2(I_AVAR, tnum, tag);	else if ((tag = find_tag(lvars, lvarc, ident)) != -1)		Code2(I_LVAR, tnum, tag);	else		Code2(I_GVAR, ident, ident);}static void code_goto(name, to)	char *name;	int to;{	Label *label;	for (label = lhead; label; label = label->next) {		if (streq(label->name, name)) {			if (to)				Code2(I_JMP, offset, label->offset);			else if (jmptab[label->offset] == -1)				jmptab[label->offset] = loc;			else				yyerror(ERR_DUPGOTO);			return;		}	}	label = New(Label);	label->name = name;	label->offset = jmppos;	Push(jmptab, int, jmpsize, jmppos, to ? -1 : loc);	if (to)		Code2(I_JMP, offset, label->offset);	label->next = lhead;	lhead = label;}static void free_labels(){	Label *label = lhead, *next;	for (label = lhead; label; label = next) {		next = label->next;		if (jmptab[label->offset] == -1)			yyerror(ERR_UDGOTO);		Discard(label, Label);	}	lhead = NULL;}static void add_tag(table, pos, tag)	char *table[], *tag;	int *pos;{	int i;	for (i = 0; i < *pos; i++) {		if (!strcmp(table[i], tag)) {			yyerror(ERR_DUPTAG);			return;		}	}	if (*pos == MAX_TAGS)		yyerror(ERR_TOOMANY);	else		table[(*pos)++] = tag;}static int find_tag(table, num, ident)	char *table[], *ident;	int num;{	int i;	for (i = 0; i < num; i++) {		if (streq(table[i], ident))			return i;	}	return -1;}/* The lexical analyzer */typedef struct token {	int type;	YYSTYPE val;

⌨️ 快捷键说明

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