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

📄 parser.c

📁 guide and some example with visualC++
💻 C
📖 第 1 页 / 共 3 页
字号:
/* parser.c * *	(C) Copyright Apr 15 1995, Edmond J. Breen. *		   ALL RIGHTS RESERVED. * This code may be copied for personal, non-profit use only. * */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include "MachSet.h"#include "global.h"#include "lexer.h"#include "func.h"#include "typemod.h"#include "xalloc.h"#include "typesets.h"#include "cdecl.h"#include "error.h"#include "symbol.h"#include "parser.h"typedef struct {    val_t match, loc;} pair_t;static int STRUCT_MEMBER_TYPE =0;#define out_expr  Outexpr#define setInst(code,idx,mem,val)  do { code_t *C__C = code;\					    if(C__C->binst) \					C__C->inst[idx].mem = val;\				    } while(0)void EiC_reset_env_pointers(token_t *e1,int bp);/** PROTOTYPES parser.c **/static void correctit(code_t * C, eicstack_t * S, int nxt, int loc);static void fixcasestack(token_t * e1, int nxt, int loc);static void block(token_t * e1);static void addinlocals(token_t * e1,int n);static void label_stmt(token_t * e1);static void testfortype(token_t *e1, int NoVoid);static void genJump(token_t *e1, val_t *v, int t,int T);static void select_stmt(token_t * e1);static void iter_stmt(token_t * e1);static void jump_stmt(token_t * e1);static void Outexpr(token_t * e1);static void expr(token_t * e1);static void log_or_expr(token_t * e1);static void log_and_expr(token_t * e1);static void inc_or_expr(token_t * e1);static void xor_expr(token_t * e1);static void and_expr(token_t * e1);static void equal_expr(token_t * e1);static void rel_expr(token_t * e1);static void shift_expr(token_t * e1);static void add_expr(token_t * e1);static void mult_expr(token_t * e1);static void cast_expr(token_t * e1);static void f_cast_expr(token_t * e1);static void EiC_unary_expr(token_t * e1);static void postfix_expr(token_t * e1);static void EiC_r_postfix_expr(token_t * e1);static int arg_expr_list(token_t * E1, token_t * e1);static void primary_expr(token_t * e1);static void process_binary(void (*func) (token_t * e),		    token_t * e1, int op);static void assignop(void (*func) (token_t * e),	      token_t * e1, int op);static int findmem(type_expr * t, char *id);static int check4constmem(type_expr * t);int EiC_S_LEVEL;static int NoPTR = 0;static eicstack_t breakstack = {0, NULL};static eicstack_t contstack = {0, NULL};static eicstack_t *casestack;static int BREAK = 0, CONT = 0, CASEON;#if 1void EiCp_freeLabels(Label_t *lab){    if(lab) {	EiCp_freeLabels(lab->nxt);	xfree(lab->name);	xfree(lab);    }}Label_t * EiCp_addLabel(Label_t *lab, 			char *name, 			int loc, int chck){    Label_t *nlab;    if(chck) { /* check 4 duplicated labels */	nlab = lab;	while(nlab) {		    if(strcmp(name, nlab->name) == 0) 		EiC_error("Duplicate label %s",name);	    nlab = nlab->nxt;	}    }        nlab = xmalloc(sizeof(*nlab));    nlab->name = xmalloc(strlen(name)+1);    strcpy(nlab->name,name);    nlab->loc = loc;        nlab->nxt = lab;    return nlab;}#endif    void addoffset(eicstack_t * S, int nxt, int offset){    unsigned i;    val_t *v;    for (i = nxt, v = &S->val[nxt]; i < S->n; ++v, ++i)	v->ival += offset;}static void correctit(code_t * C, eicstack_t * S, int nxt, int loc){    val_t addr;    if(!C->binst)	return;    while (S->n > nxt) {	EiC_eicpop(S, &addr);	C->inst[addr.ival].val.ival =  loc-addr.ival;    }}static int comppair(const void * p1,const void * p2){    return ((pair_t*)p1)->match.ival - 	((pair_t*)p2)->match.ival;}void fixcasestack(token_t * e1, int nxt, int loc){    void qsort(void *base, size_t nm, size_t sz,	       int (*f)());    int i;    if (casestack->n > 0) {	correctit(&e1->Code, &breakstack, nxt, e1->Code.nextinst);	if (casestack->val[0].ival == 0)	    casestack->val[0].ival = e1->Code.nextinst - loc;	else	    casestack->val[0].ival -= loc;	for (i = 2; i < casestack->n; i += 2)	    casestack->val[i].ival -= loc;	qsort(&casestack->val[1],	      (casestack->n - 1) >> 1,	      sizeof(val_t) << 1,	      comppair);    } else	EiC_error("Illegal switch statement");}void EiC_initparser(){    extern int EiC_ErrorRecover;    EiC_work_tab = stand_tab;    EiC_ErrorRecover = 0;}void EiC_parse(environ_t * env){    void EiC_comm_switch(void);    token_t e1;    val_t v;    int t;    EiC_S_LEVEL = 1;    EiC_inittoken(&e1);    while ((t = EiC_lexan()) != DONE) {	EiC_freetoken(&e1);		if (t == ':') {		/* get an EiC command */	    int h;	    h = EiC_work_tab;	    EiC_work_tab = eic_tab;	    if (EiC_lexan() == ID) {		if (EiC_gettype(token->Val.sym->type) == t_eic)		    (*token->Val.sym->val.func) ();		else {		    EiC_remsym(token->Val.sym);		    EiC_error("Unknown EiC command");		}	    } else if(token->Tok == '-')		EiC_comm_switch();	    else		EiC_error("Expected an EiC command");	    EiC_work_tab = h;	    continue;	} else if(t == '?') {	  printf("\t If you want help, enter :help\n\n");	  continue;	}	  	retractlexan();#if 1	switch(t) {	  TYPEQUAL:	  STORECLASS:	  TYPESPEC:	    EiC_ext_decl(&e1);	    break;	  default:	    EiC_stmt(&e1);	}#else	block(&e1);#endif	EiC_concode(&env->CODE, &e1.Code);    }    EiC_concode(&env->CODE, &e1.Code);    if (e1.Type)	v.p.p = EiC_copytype(e1.Type);    else	v.p.p = EiC_addtype(t_void, NULL);    EiC_freetoken(&e1);    EiC_generate(&env->CODE, halt, &v, 0);}/* * Globals used for * local aggregate data */unsigned int EiC_ASPOT = 0;static unsigned int MASPOT = 0, ADDLOCALS = 0;    void EiC_updateLocals(void){        if (EiC_ASPOT > MASPOT)	MASPOT = EiC_ASPOT;    if (EiC_ENV->lsp > ADDLOCALS)	ADDLOCALS = EiC_ENV->lsp;}static void addinlocals(token_t * e1,int n){    val_t v;    token_t e2;        EiC_inittoken(&e2);    v.ival = n + (MASPOT>0);    EiC_generate(&e2.Code, checkar, &v, 0);    setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);    if (MASPOT) {	v.ival = MASPOT;	EiC_generate(&e2.Code, pushint, &v, 0);	setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);	v.ival = n;	{ /* correct for AAA location */	    int i, N;	    code_t *c = &e1->Code;	    N = nextinst(c);	    for(i = 0; i < N; ++i)		if(opcode(c,i) == lda && ivalcode(c,i) == -1)		    ivalcode(c,i) = n;	}	EiC_generate(&e2.Code, massign, &v, 1);	setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);	EiC_generate(&e1->Code, fmem, &v, 1);	setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);	v.ival = n;    }    EiC_generate(&e1->Code, reducear, &v, 0);    setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);    EiC_concode(&e2.Code, &e1->Code);    e1->Code = e2.Code;    ADDLOCALS = EiC_ASPOT = MASPOT = 0;}static void block(token_t * e1){    token_t e2;    EiC_inittoken(&e2);    while(EiC_ext_decl(&e2)) {	EiC_contoken(e1,&e2);	EiC_inittoken(&e2);    }    while (EiC_lexan() != '}' && token->Tok != DONE) {	retractlexan();	EiC_stmt(e1);    }    if (token->Tok == DONE)	EiC_error("Expected }");}static void stmt1(token_t * e1){    void EiC_clearTempories();    int bp;    unsigned aspot;    switch (EiC_lexan()) {    case '{':			/* compound statement */	EiC_S_LEVEL++;	bp = EiC_ENV->lsp;	aspot = EiC_ASPOT;	    block(e1);	EiC_updateLocals();	EiC_clearTempories();		EiC_ASPOT = aspot;	EiC_reset_env_pointers(e1, bp);	EiC_remlevel(EiC_S_LEVEL);	EiC_S_LEVEL--;	break;    case casesym:    case defaultsym:	label_stmt(e1);	break;    case gotosym:    case breaksym:    case continuesym:    case returnsym:	jump_stmt(e1);	break;    case ifsym:    case switchsym:	select_stmt(e1);	break;    case whilesym:    case dosym:    case forsym:	iter_stmt(e1);	break;    TYPEQUAL:    STORECLASS:    TYPESPEC:	    	EiC_error("Unexpected declaration");	retractlexan();	EiC_ext_decl(e1);	break;#if defined(ILOOKAHEAD) && (MAX_TOKENS > 1)	case ID: /* handle label statements */	    if(EiC_lexan() == ':') {		extern int EiC_INFUNC;		retractlexan();		if(!EiC_INFUNC) 		    EiC_error("Misplaced label statement");		else {		    e1->Code.labels = EiCp_addLabel(e1->Code.labels,						token->Val.sym->id,						e1->Code.nextinst, 1);		    EiC_lexan();		}		break;	    } else 		retractlexan();#endif	default:	    retractlexan();	    out_expr(e1);	    EiC_match(';', " ; ");	    return;    }    /* to get here a statement was executed, therefore */    e1->Type = EiC_addtype(t_void, e1->Type);        EiC_clearTempories();}void EiC_stmt(token_t *e1){    static int Stmts = 0;    Stmts++;        stmt1(e1);    Stmts--;    if (EiC_S_LEVEL == 1 && Stmts == 0) {	EiC_updateLocals();	if(ADDLOCALS > 0) 	    addinlocals(e1,ADDLOCALS);    }}static void label_stmt(token_t * e1){    if (!CASEON) {	EiC_error("Illegal label");	return;    }    if (token->Tok == casesym) {	token_t e2;	int t;	val_t v;	EiC_inittoken(&e2);	EiC_assign_expr(&e2);	EiC_match(':', " :");	if (isconst(e2.Type)) {	    t = EiC_gettype(e2.Type);	    if (t >= t_char && t <= t_uint) {		for (t = 1; t < casestack->n; t += 2)		    if (e2.Val.ival == casestack->val[t].ival)			EiC_error("Duplicate case in switch");		EiC_eicpush(casestack, e2.Val);		v.ival = e1->Code.nextinst;		EiC_eicpush(casestack, v);	    } else		EiC_error("Must be integer type");	} else	    EiC_error("Must be const_expr type");	EiC_stmt(e1);	EiC_freetoken(&e2);    } else {			/* default */	if (casestack->val[0].ival != 0)	    EiC_error("Duplicate default in switch");	EiC_match(':', " :");	casestack->val[0].ival = e1->Code.nextinst;	EiC_stmt(e1);    }}static void select_stmt(token_t * e1){    int t;    token_t e2;    val_t u1;    EiC_inittoken(&e2);    if (token->Tok == ifsym) {	EiC_match('(', " ( ");	out_expr(&e2);	testfortype(&e2,1);	t = EiC_gettype(e2.Type);		EiC_match(')', " ) ");	EiC_contoken(e1, &e2);	u1.ival = e1->Code.nextinst;	genJump(e1,&u1,t,0);	EiC_stmt(e1);	if (EiC_lexan() == elsesym) {	    setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival+1);	    u1.ival = e1->Code.nextinst;	    EiC_generate(&e1->Code, jmpu, &u1, 0);	    setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);	    EiC_stmt(e1);	    setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);	} else {	    setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);	    retractlexan();	}    } else {/* switchsym */	int nxtbreak, loc;	eicstack_t *hold;	BREAK++;	CASEON++;	nxtbreak = breakstack.n;	EiC_match('(', " (");	out_expr(&e2);	EiC_match(')', " )");	hold = casestack;	casestack = (eicstack_t *) xcalloc(1, sizeof(eicstack_t));	u1.ival = 0;	EiC_eicpush(casestack, u1);	/* push dummy for default */	EiC_contoken(e1, &e2);	u1.p.p = casestack;	loc = e1->Code.nextinst;	EiC_generate(&e1->Code, jmptab, &u1, 0);	EiC_stmt(e1);	fixcasestack(e1, nxtbreak, loc);	casestack = hold;	BREAK--;	CASEON--;    }}static void testfortype(token_t *e1, int NoVoid){    int t = EiC_gettype(e1->Type);    if(!isArithmetic(t) && t != t_pointer) {	if(t == t_void) {	    if(NoVoid)		EiC_error("Void expression");	}else 	    EiC_warningerror("Possible non relational operation");    }}static void genJump(token_t *e1, val_t *v, int t,int T){    /* 0 for false and 1 for True */    static int tab[2][5] = {{ jmpFint,jmpFlng,jmpFdbl,jmpFptr, jmpFllng},			    { jmpTint,jmpTlng,jmpTdbl,jmpTptr, jmpTllng}};    switch(t) {	default:	    EiC_error("Undefined type for relational operation");	case t_char: case t_uchar: 	case t_short:case t_ushort:	case t_int:  case t_uint:	    EiC_generate(&e1->Code, tab[T][0], v, 0);	    break;	case t_long: case t_ulong:	    EiC_generate(&e1->Code, tab[T][1], v, 0);	    break;	case t_float: case t_double:	    EiC_generate(&e1->Code, tab[T][2], v, 0);	    break;	case t_pointer:	    EiC_generate(&e1->Code, tab[T][3], v, 0);	    break;	case t_llong:	    EiC_generate(&e1->Code, tab[T][4], v, 0);	    break;        }}static void iter_stmt(token_t * e1){    int t, rt,nxtbreak, nxtcont;    val_t u1;    token_t e2, e3;    EiC_inittoken(&e2);    BREAK++, CONT++;    nxtbreak = breakstack.n;    nxtcont = contstack.n;    switch (token->Tok) {      case dosym:	u1.ival = e1->Code.nextinst;	EiC_stmt(e1);	if (EiC_lexan() != whilesym)	    EiC_error("Missing while in do while statement");	EiC_match('(', " (");	correctit(&e1->Code, &contstack, nxtcont, e1->Code.nextinst);	out_expr(&e2);	EiC_match(')', ")");	EiC_match(';', " ;");		testfortype(&e2,1);	rt = EiC_gettype(e2.Type);	EiC_contoken(e1, &e2);	u1.ival = u1.ival - e1->Code.nextinst;	genJump(e1,&u1,rt,1);	/*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/	correctit(&e1->Code, &breakstack, nxtbreak, e1->Code.nextinst);	break;      case whilesym:	u1.ival = e1->Code.nextinst;	EiC_generate(&e1->Code, jmpu, &u1, 0);	setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);	EiC_match('(', " ( ");	out_expr(&e2);		/* <expr> */	testfortype(&e2,1);	rt = EiC_gettype(e2.Type);	EiC_match(')', " ) ");	EiC_stmt(e1);		/* <stmt> */	setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);	t = e1->Code.nextinst;	EiC_contoken(e1, &e2);	u1.ival -= e1->Code.nextinst - 1;	genJump(e1,&u1,rt,1);	/*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/	setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);	correctit(&e1->Code, &breakstack, nxtbreak, e1->Code.nextinst);	correctit(&e1->Code, &contstack, nxtcont, t);	break;      case forsym:	EiC_inittoken(&e3);	EiC_match('(', " ( ");	out_expr(e1);		/* expr1 */	EiC_match(';', " ; ");	u1.ival = e1->Code.nextinst;	EiC_generate(&e1->Code, jmpu, &u1, 0);	out_expr(&e2);		/* expr2 */	testfortype(&e2,0);	rt = EiC_gettype(e2.Type);		EiC_match(';', " ; ");	out_expr(&e3);		/* expr3 */	EiC_match(')', " ; ");	EiC_stmt(e1);	correctit(&e1->Code, &contstack,		  nxtcont, e1->Code.nextinst);		EiC_contoken(e1, &e3);	setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);	EiC_contoken(e1, &e2);	u1.ival -= (e1->Code.nextinst - 1);	if (rt ==  t_void)	    EiC_generate(&e1->Code, jmpu, &u1, 0);	else	    genJump(e1,&u1,rt,1);	   /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/		setCodeLineNo(&e1->Code,e1->Code.nextinst -1, 0);		correctit(&e1->Code, &breakstack, nxtbreak,		  e1->Code.nextinst);	break;    }    BREAK--, CONT--;

⌨️ 快捷键说明

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