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

📄 cc.y

📁 一个用flex、bison和vc开发的堆栈机
💻 Y
字号:
%{
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include "symbol.h" 
#include "conio.h"
#include "stkmach.h"

jmp_buf begin;
char *progname;
char *infile;
FILE *yyin;
char **gargv;
int gargc;

extern yylex();
extern int lineno;
extern Inst progp, progbase;
extern indef;
/* 
%token GT GE LT LE EQ NE OR AND NOT
%token PLUS MINUS MUL DIV
%token AS
*/
#define code2(c1,c2)	code(c1); code(c2)
#define code3(c1,c2,c3)	code(c1); code(c2); code(c3)
%}
%union {
	Inst *inst;    /* 指令 */
	symrec *tptr;  /* 符号表指针 */
	int narg;      /* 参数 */
	int delim;     /* 分界符(不存入符号表中) */
	int op;		   /* 操作符(不存入符号表中) */
	char *str;	   /* 字符串(不存入符号表中) */
}

%token <delim> NL COMMA
%token <delim> LP RP LB RB
%token <op> MINUSMINUS PLUSPLUS PLUSMINUS MINUSPLUS

%token <tptr> NUMBER CONST VAR BLTIN UNDEF PRINT WHILE IF ELSE
%token <tptr> FUNCTION PROCEDURE RETURN FUNC PROC READ 
%token <narg> ARG
%token <str> STRING
%type <inst> stmt asgn expr stmtlist cond while if begin end 
%type <inst> prlist
%type <narg> arglist
%type <tptr> procname

%right AS
%left OR
%left AND
%left GT GE LT LE EQ NE
%left PLUS MINUS
%left MUL DIV
%left NEG POS NOT
%right POW
%%
list:	
	| list NL
	| list defn NL
	| list asgn NL		{ code2(pop,STOP); return 1; }
	| list expr NL		{ code2(print,STOP); return 1; }
	| list stmt NL		{ code(STOP); return 1; }
	| list error NL		{ yyerrok; }
	;
asgn: VAR AS expr			{ $$ = $3; code3(varpush, (Inst)$1, assign); }
	| ARG AS expr			
		{ defnonly("$"); code2(argassign, (Inst)$1); $$ = $3; }
	;
stmt: expr				{ code(pop); }
	| RETURN { defnonly("return"); code(procret); }
	| RETURN expr
		{ defnonly("return"); $$ = $2; code(funcret); }
	| PROCEDURE begin LP arglist RP
		{ $$ = $2; code3(call, (Inst)$1, (Inst)$4); }
	| PRINT prlist		=
		{ $$ = $2; }
	| while cond stmt end	{
								($1)[1] = (Inst)$3;     /* body of loop */
								($1)[2] = (Inst)$4;		/* end, if cond fails */
							}						
	| if cond stmt end	{	/* else-less if */
							($1)[1] = (Inst)$3;		/* thenpart*/
							($1)[3] = (Inst)$4;		/* end, if cond fails */
						}
	| if cond stmt end	ELSE stmt end {	/* if with else */
							($1)[1] = (Inst)$3;		/* thenpart*/
							($1)[2] = (Inst)$6;		/* elsepart*/
							($1)[3] = (Inst)$7;		/* end, if cond fails */
						}
	| LB stmtlist RB	{ $$ = $2; }
	;
cond:	LP expr RP		{ code(STOP); $$ = $2; }
	;
while:	WHILE	{ $$ = code3(whilecode, STOP, STOP); }
	;
if:		IF		{ $$ = code(ifcode); code3(STOP,STOP,STOP); }
	;
begin: /*nothing*/	{ $$ = progp; }
	;
end:	/* nothing */	{ code(STOP); $$ = progp; }
	;
stmtlist: /* nothing */	{ $$ = progp; }
	| stmtlist NL
	| stmtlist stmt
	;
expr:NUMBER					{ $$ = code2(constpush, (Inst)$1); }
	| CONST					{ $$ = code2(constpush, (Inst)$1); }
	| VAR					{ $$ = code3(varpush, (Inst)$1, eval); }
	| ARG					{ defnonly("$"); $$ = code2(arg, (Inst)$1); } 
	| asgn
	| FUNCTION begin LP arglist RP
							{ $$ = $2, code3(call, (Inst)$1, (Inst)$4); }
	| READ LP VAR RP		{ $$ = code2(varread, (Inst)$3); }
	| BLTIN LP expr RP		{ $$ = $3; code2(bltin, (Inst)$1->value.fnctptr); } 
	| LP expr RP			{ $$ = $2; }
	| PLUS expr %prec POS	{ $$ = $2; }
	| expr PLUS expr		{ code(add); }
	| expr MINUS expr		{ code(sub); }
	| expr MUL expr			{ code(mul); }
	| expr DIV expr			{ code(divi); }
	| expr POW expr			{ code(power); }
	| MINUS expr %prec NEG	{ $$ = $2; code(neg); }
	| expr GT expr { code(gt); }
	| expr GE expr { code(ge); }
	| expr LT expr { code(lt); }
	| expr LE expr { code(le); }
	| expr EQ expr { code(eq); }
	| expr NE expr { code(ne); }
	| expr AND expr { code(and); }
	| expr OR expr { code(or); }
	| NOT expr     { $$ = $2; code(not); }
	;
prlist: expr		{ code(prexpr); }
	| STRING		{ $$ = code2(prstr, (Inst)$1); }
	| prlist COMMA expr		{ code(prexpr); }
	| prlist COMMA STRING	{ code2(prstr, (Inst)$3); }
defn:	FUNC procname { $2->type = FUNCTION; indef = 1; }
		LP RP stmt { define($2); indef = 0; }  /*code(funcret);*/
	|	PROC procname { $2->type = PROCEDURE; indef = 1; }
		LP RP stmt { define($2); indef = 0; } /*code(procret);*/
	;
procname: VAR
	| FUNCTION
	| PROCEDURE
	;
arglist: /*nothing*/		{ $$ = 0; }
	| expr					{ $$ = 1; }
	| arglist COMMA expr	{ $$ = $1 + 1; }
	;
%%
enum TOK {
	$DIM=1,$IF
};
main(int argc, char *argv[])
{
	int fpecatch();
	progname = argv[0];

	if (argc == 1) 
	{
		static char *stdinonly[] = { "-" };
		gargv = stdinonly;
		gargc = 1; 
	} 
	else	
	{
		gargv = argv + 1;
		gargc = argc - 1;
	}
	init_table();
	while (moreinput())
		run();
	return 0;
}

moreinput()
{
	if (gargc-- <= 0)
		return 0;
	infile = *gargv++;
	lineno = 1;
	if (strcmp(infile, "-") == 0)
	{
		yyin = stdin;
		infile = 0;
	}
	else if ((yyin = fopen(infile, "r")) == NULL)
	{
		fprintf(stderr, "%s: cant't open %s\n", progname, infile);
		return moreinput();
	}
	return 1;
}

run()
{
	setjmp(begin);
	signal(SIGFPE, fpecatch);
	
	for (initcode(); yyparse(); initcode())
		excute(progbase);	
}
warning(char *s, char *t)
{
	fprintf(stderr, "%s: %s", progname, s);
	if (t)
		fprintf(stderr, " %s", t);
	fprintf(stderr, " near line %d\n", lineno);
}
yyerror(char *s)
{
	warning(s,(char*) 0);
}

execerror(char *s, char *t)
{
	warning(s, t);
	longjmp(begin, 0);
}

fpecatch()
{
	execerror("floating point exception", (char *) 0);
}

⌨️ 快捷键说明

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