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

📄 parser.c

📁 微软的基于HMM的人脸识别原代码, 非常经典的说
💻 C
📖 第 1 页 / 共 3 页
字号:
}

static void jump_stmt(token_t * e1)
{
    extern int EiC_INFUNC;
    extern int EiC_RETURNON;
    extern token_t *EiC_RETURNEXPR;
    val_t v;
    v.ival = e1->Code.nextinst;
    switch (token->Tok) {
	case gotosym:
	    if(!EiC_INFUNC) 
		EiC_error("Misplaced goto statement");
	    else {
		if(EiC_lexan() != ID)
		    EiC_error("expected goto label");
		else {
		    EiC_generate(&e1->Code, jmpu, &v, 0);
		    e1->Code.gotos = EiCp_addLabel(e1->Code.gotos,
						    token->Val.sym->id,
						   v.ival, 0);
		    if(EiC_gettype(token->Val.sym->type) == ID)
			EiC_remsym(token->Val.sym);
		}
	    }
	    break;

	    
	case breaksym:
	    if (!BREAK)
		EiC_error("Misplaced break statement");
	    else
		EiC_eicpush(&breakstack, v);
	    EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
	    EiC_match(';', " ;");
	    break;
	case continuesym:
	    if (!CONT)
		EiC_error("Misplaced continue statement");
	    else
		EiC_eicpush(&contstack, v);
	    EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
	    EiC_match(';', " ;");
	    break;
	case returnsym:
	    if (!EiC_RETURNON)
		EiC_error("Misplaced return statement");
	    else {
		token_t e2;
		if (EiC_lexan() != ';') {
		    retractlexan();
		    EiC_inittoken(&e2);
		    expr(&e2);
		    /* catch dangling pointers */
		    if(EiC_gettype(e2.Type) == t_pointer && e2.Sym) 
			if((EiC_gettype(e2.Sym->type) != t_pointer &&
			    EiC_gettype(e2.Sym->type) != t_array)  && EiC_GI(&e2)) 
			    EiC_warningerror("Possible dangling pointer");
		    EiC_match(';', " ;");
		    if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) == t_void &&
		       EiC_gettype(e2.Type) != t_void)
			EiC_error("Illegal return type, expected void");
		    
		    if (isconst(e2.Type)) {
			EiC_castconst(&e2, EiC_RETURNEXPR, 1);
			EiC_output(&e2);
		    } else {
			EiC_output(&e2);
			EiC_castvar(&e2, EiC_RETURNEXPR, 0);
		    }
		    if(EiC_HasHiddenParm(EiC_RETURNEXPR->Type)) {
			val_t v;
			v.ival = -1;
			EiC_generate(&e1->Code,rvalptr,&v,1);
			v.ival = 1;
			EiC_generate(&e1->Code,bump,&v,0);
			EiC_contoken(e1, &e2);
			v.ival = EiC_get_sizeof(nextType(EiC_RETURNEXPR->Type));
			EiC_generate(&e1->Code,refmem,&v,0);
		    } else
			EiC_contoken(e1, &e2);
		} else
		    if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) != t_void)
			EiC_warningerror("missing return value");
		EiC_generate(&e1->Code, eicreturn, &e1->Val, 0);
	    }
	    break;
    }
}

static void generatePtr(token_t * e1)
{
    if(!NoPTR && EiC_gettype(e1->Type) == t_array && !e1->Pflag) {
	EiC_exchtype(t_pointer, e1->Type);
	if(!EiC_GI(e1)) { /* static of global variable */
	    setConst(e1->Type);
	    e1->Val.p = EiC_ENV->AR[e1->Val.ival].v.p;
	}
    }
}

static void expr(token_t * e1)  
{
    /* really a comma expression */
    token_t e2;
    int c = 0;
    do {
	EiC_inittoken(&e2);
	EiC_assign_expr(&e2);
	if(nextinst(&e1->Code))
	    EiC_output(e1);
	EiC_concode(&e1->Code,&e2.Code);
	EiC_freetype(e1->Type);	
	e1->Type = EiC_copytype(e2.Type);
	e1->Pflag = e2.Pflag;
	EiC_freetoken(&e2);
	c++;

    } while (EiC_lexan() == ',');
    retractlexan();
    e1->Pflag = e2.Pflag;
    e1->Sym = e2.Sym;
    e1->Val = e2.Val;
    if(c > 1)
	setConstp(e1->Type);
}

static void Outexpr(token_t * e1) 
{
    /* really a comma expression */
    token_t e2;
    int c = 0;
    do {
	EiC_inittoken(&e2);
	EiC_assign_expr(&e2);
	EiC_output(&e2);
	EiC_freetype(e1->Type);
	EiC_concode(&e1->Code,&e2.Code);
	e1->Type = EiC_copytype(e2.Type);
	EiC_freetoken(&e2);
	c++;

    } while (EiC_lexan() == ',');
    retractlexan();
    e1->Pflag = e2.Pflag;
    e1->Sym = e2.Sym;
    e1->Val = e2.Val;
    if(c > 1)
	setConstp(e1->Type);
}


void EiC_assign_expr(token_t * e1)
{

#if 1
    int t = EiC_lexan();
    
    /* handle longjmp and setjmp */

    if(t == eiclongjmpsym) {
	EiC_generate(&e1->Code, __eiclongjmp, &e1->Val, EiC_GI(e1));
	e1->Type = EiC_freetype(e1->Type);
	e1->Type = EiC_addtype(t_void, e1->Type);
	e1->Pflag = 1;
	return;

    } else if (t == eicsetjmpsym) {
	EiC_generate(&e1->Code, __eicsetjmp, &e1->Val, EiC_GI(e1));
	e1->Type = EiC_freetype(e1->Type);
	e1->Type = EiC_addtype(t_int, e1->Type);
	e1->Pflag = 1;
	return;
    } else
	retractlexan();

#endif

    cond_expr(e1);
    while (1)
	switch (EiC_lexan()) {
	  case ASS:		/* = */
	  case ADDEQ:		/* += */
	  case SUBEQ:		/* -= */
	  case DIVEQ:		/* /= */
	  case MULEQ:		/* *= */
	  case MODEQ:		/* %= */
	  case RSHTEQ:		/* >>= */
	  case LSHTEQ:		/* <<= */
	  case ANDEQ:		/* &= */
	  case BOREQ:		/* |= */
	  case XOREQ:		/* ^= */
	    assignop(EiC_assign_expr, e1, token->Tok);
	    break;
	  default:
	    retractlexan();
	    generatePtr(e1);
	    return;
	}
}

extern void cond_expr(token_t * e1)
{
    log_or_expr(e1);
    if (EiC_lexan() == '?') {
	val_t v;
	int rt;
	token_t e2, e3;
	EiC_inittoken(&e2);
	out_expr(&e2);
	EiC_match(':', " :");
	EiC_inittoken(&e3);
	cond_expr(&e3);
	if(!isconst(e3.Type))
	    EiC_output(&e3);
	EiC_cast2comm(&e2, &e3);
	EiC_output(&e3);
	EiC_output(e1);
	rt = EiC_gettype(e1->Type);
	e1->Type = EiC_freetype(e1->Type);
	e1->Type = EiC_copytype(e2.Type);
	v.ival = e2.Code.nextinst + 2;
#if 0
	  EiC_generate(&e1->Code, jmpFint, &v, 0);
#else
	  genJump(e1,&v,rt,0);

#endif
	EiC_contoken(e1, &e2);

	v.ival = e1->Code.nextinst;
	EiC_generate(&e1->Code, jmpu, &v, 0);
	setInst(&e1->Code,v.ival,val.ival,e3.Code.nextinst+1);
	EiC_contoken(e1, &e3);
	 /* conditional's  can't form lvalues */
	setConstp(e1->Type);
    } else
	retractlexan();
}

static void fixit(code_t *C, int s)
{
    int i;
    for(i = s; i < C->nextinst;i++)
	switch(C->inst[i].opcode) {
	  case jmpFint:
	  case jmpFlng:
	  case jmpFdbl:
	  case jmpFptr:
	  case jmpTint:
	  case jmpTlng:
	  case jmpTdbl:
	  case jmpTptr:
	    if(C->inst[i].val.ival == INT_MAX)
		C->inst[i].val.ival = C->nextinst - i;
	}
}

static void log_or_expr(token_t * e1)
{
    void EiC_do_lor(token_t *, int);
    log_and_expr(e1);
    if(EiC_lexan() == LOR) {
	token_t e2;
	int nxt = e1->Code.nextinst;
	EiC_do_lor(e1, INT_MAX);
	do {
	    EiC_inittoken(&e2);
	    log_and_expr(&e2);
	    EiC_do_lor(&e2,INT_MAX);
	    EiC_contoken(e1,&e2);
	} while (EiC_lexan() == LOR);
	fixit(&e1->Code,nxt);
    }
    retractlexan();
}

static void log_and_expr(token_t * e1)
{
    void EiC_do_land(token_t *, int);
    inc_or_expr(e1);
    if(EiC_lexan() == LAND) {
	token_t e2;
	int nxt = e1->Code.nextinst;
	EiC_do_land(e1, INT_MAX);
	do {
	    EiC_inittoken(&e2);
	    inc_or_expr(&e2);
	    EiC_do_land(&e2,INT_MAX);
	    EiC_contoken(e1,&e2);
	} while (EiC_lexan() == LAND);
	fixit(&e1->Code,nxt);
    }
    retractlexan();
}

static void inc_or_expr(token_t * e1)
{
    xor_expr(e1);
    while (EiC_lexan() == BOR)
	process_binary(xor_expr, e1, BOR);
    retractlexan();
}

static void xor_expr(token_t * e1)
{
    and_expr(e1);
    while (EiC_lexan() == XOR)
	process_binary(and_expr, e1, XOR);
    retractlexan();
}

static void and_expr(token_t * e1)
{
    equal_expr(e1);
    while (EiC_lexan() == AND)
	process_binary(equal_expr, e1, AND);
    retractlexan();
}

static void equal_expr(token_t * e1)
{
    rel_expr(e1);
    while (1)
	switch (EiC_lexan()) {
	  case EQ:
	  case NE:
	    process_binary(rel_expr, e1, token->Tok);
	    break;
	  default:
	    retractlexan();
	    return;
	}
}

static void rel_expr(token_t * e1)
{
    shift_expr(e1);
    while (1)
	switch (EiC_lexan()) {
	  case LT:
	  case LE:
	  case GT:
	  case GE:
	    process_binary(shift_expr, e1, token->Tok);
	    break;
	  default:
	    retractlexan();
	    return;
	}
}

static void shift_expr(token_t * e1)
{
    add_expr(e1);
    while (1)
	switch (EiC_lexan()) {
	  case LSHT:
	  case RSHT:
	    process_binary(add_expr, e1, token->Tok);
	    break;
	  default:
	    retractlexan();
	    return;
	}
}

static void add_expr(token_t * e1)
{
    mult_expr(e1);
    while (1)
	switch (EiC_lexan()) {
	  case '+':
	  case '-':
	    process_binary(mult_expr, e1, token->Tok);
	    break;
	  default:
	    retractlexan();
	    return;
	}
}

static void mult_expr(token_t * e1)
{
    cast_expr(e1);
    while (1)
	switch (EiC_lexan()) {
	  case '*':
	  case '/':
	  case '%':
	    process_binary(cast_expr, e1, token->Tok);
	    break;
	  default:
	    retractlexan();
	    return;
	}
}

static void cast_expr(token_t * e1)
{
    if (EiC_lexan() != '(') {
	retractlexan();
	EiC_unary_expr(e1);
    } else {
	f_cast_expr(e1);
    }
}

static void f_cast_expr(token_t * e1)
{
    token_t e2;
    switch (EiC_lexan()) {
      TYPESPEC:
      TYPEQUAL:
	EiC_inittoken(&e2);
	retractlexan();
	EiC_type_name(e1);
	EiC_match(')', " )");
	cast_expr(&e2);
	if (isconst(e2.Type)) {
	    setConst(e1->Type);
	    EiC_castconst(&e2, e1, 1);
	    e1->Val = e2.Val;
	} else {
	    EiC_output(&e2);
	    EiC_castvar(&e2, e1, 1);
	    e1->Pflag = e2.Pflag;
	    e1->Sym = e2.Sym;
	    /*e1->Val = e2.Val;*/
	}
	EiC_contoken(e1, &e2);
	break;
	/* cast can't form lvalues */
	setConstp(e1->Type);
      default:
	retractlexan();
	expr(e1);
	EiC_match(')', " )");
	EiC_r_postfix_expr(e1);
	break;
    }
}


static void EiC_unary_expr(token_t * e1)
{
    int t;
    
    t = EiC_lexan();
    switch (t) {
      case '+':			/* unary - */
      case '-':			/* unary + */
      case '*':			/* indirection */
      case '~':			/* ones complement */
      case NOT:			/* */
	cast_expr(e1);
	EiC_unaryop(e1, t);
	return;
      case INC:			/* ++ lval */
      case DEC:			/* -- lval */
	EiC_unary_expr(e1);
	EiC_unaryop(e1, t);
	return;
      case sizeofsym:
	NoPTR++;
	if(EiC_lexan() == '(') {
	    switch(EiC_lexan()) {
	      TYPESPEC:
	      TYPEQUAL:
		retractlexan();
		e1->Type = EiC_freetype(e1->Type);
		EiC_type_name(e1);
		break;
	      default: /* must be unary expr, i.e. ( expr ) */
		retractlexan();
		expr(e1);
	    }
	    EiC_match(')', " )");
	} else {
	    retractlexan();
	    EiC_unary_expr(e1);
	}
	EiC_freecode(&e1->Code);
	if(isconst(e1->Type)  && 
	   EiC_gettype(e1->Type) == t_pointer &&
	   EiC_gettype(e1->Type->nxt) == t_char) /* hack for char */
	                                          /* constants */
		e1->Val.uival = strlen(e1->Val.p.p) + 1;
	    else
		e1->Val.uival = EiC_get_sizeof(e1->Type);
   
	if(!e1->Val.uival || !e1->Type)
	    EiC_error("Invalid argument to sizeof");
	    
	e1->Type = EiC_freetype(e1->Type);
	
	e1->Type = EiC_addtype(t_uint, e1->Type);
	setConst(e1->Type);
	e1->Pflag = 0;
	NoPTR--;
	return;

    case AND:
#if 0
	/* this section of code is an attempt to
	 * to have constant addresses determined
	 * at compile time (not finished)
	 */
	NoPTR++;
	cast_expr(e1);
	t = EiC_gettype(e1->Type);
	if(e1->Sclass == c_register)
	    EiC_error("Cannot apply & to a register variable");
	/* check for global or static variable class */
	if(EiC_GI(e1) == 0 && !isconst(e1->Type) && t != t_lval) {
	    void * EiC_getaddress(token_t * e1);
	    ptr_t *p;
	    if(t == t_union || t == t_struct)
		e1->Type = EiC_addtype(t_pointer,e1->Type);
	    p = EiC_getaddress(e1);
	    e1->Val.p.sp = e1->Val.p.p = p;
	    e1->Val.p.ep = (char *) p + SIZEOFTHETYPE;
	    setConst(e1->Type);
	}
	
	if(!isconst(e1->Type)) {
	    switch (t) {
	    case t_char:
	    case t_uchar:
	    case t_short:
	    case t_ushort:
	    case t_int:
	    case t_uint:
	    CASE_LONG:
	    CASE_ULONG:
	    CASE_FLOAT:
	    case t_pointer:
		if (e1->Pflag)
		    EiC_error("Must have lvalue");
		else {
		  if(isUnSafe(e1->Type))
		    e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
		  EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
		}
		break;
	    case t_lval:
		e1->Type = EiC_succType(e1->Type);
		break;
	    case t_struct:
	    case t_union:
	    case t_array:
		EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
		break;
	    case t_funcdec:
		EiC_exchtype(t_func, e1->Type);
	    case t_func:
		v.p.p = e1->Sym;
		EiC_generate(&e1->Code, pushptr, &v, 0);
		break;
	    default:
		EiC_error("Must have lvalue");
	    }
	    e1->Type = EiC_addtype(t_pointer, e1->Type);
	    e1->Pflag = 1;
	} else  /* nothing much to do */
	    if(EiC_gettype(e1->Type) != t_pointer)
		EiC_error("Must have lvalue");
	NoPTR--;
	return;
    }

#else
	NoPTR++;
	cast_expr(e1);
	NoPTR--;
	if(e1->Sclass == c_register)
	    EiC_error("Cannot apply & to a register variable");
	switch (EiC_gettype(e1->Type)) {
	    case t_char:
	    case t_uchar:
	    case t_short:
	    case t_ushort:
	    case t_int:
	    case t_uint:
	CASE_LONG:
	CASE_ULONG:
	CASE_FLOAT:
	    case t_pointer:
		if (e1->Pflag)
		    EiC_error("Must have lvalue");
		else {
		    e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
		    EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
		}	
		break;
	    case t_lval:
		e1->Type = EiC_succType(e1->Type);
		break;
	    case t_struct:
	    case t_union:
	    case t_array:
		EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
		break;

	    case t_funcdec:
	    case t_func:
	    case t_builtin:
		EiC_output(e1);
		return;

	    default:
		EiC_error("Must have lvalue");
	}
	e1->Type = EiC_addtype(t_pointer, e1->Type);
	e1->Pflag = 1;
	return;
    }
#endif

    retractlexan();
    postfix_expr(e1);
}

static void postfix_expr(token_t * e1)
{
    primary_expr(e1);
    EiC_r_postfix_expr(e1);
}

static void EiC_r_postfix_expr(token_t * e1)
{
    void derefConst(token_t *);
    void EiC_binhlval(int, token_t *, token_t *);
    
    int t,c = 0;
    switch ((t = EiC_lexan())) {
      case INC:

⌨️ 快捷键说明

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