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

📄 parse.c

📁 把pascal程序转成C语言程序 把pascal程序转成C语言程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (line_start()) {	    if (opts & BR_FUNCTION)		singleindent(funccloseindent);	    else		singleindent(closebraceindent);	}        output("}");	i = 1;	cmt = findcomment(curcomments, CMT_ONEND, serial);	if (!(opts & BR_REPEAT) && commentvisible(cmt)) {	    out_spaces(bracecommentindent, commentoverindent,		       commentlen(cmt), 0);	    output("\001");	    outcomment(cmt);	    i = 0;	}	if (i) {	    outspnl((opts & BR_REPEAT) ||		    ((opts & BR_THENPART) && (braceelseline & 1) == 0 &&		     !findcomment(curcomments, -1, serial)));	}    }    if (gotcomments) {	outcontext->comments = curcomments;	curcomments = savecurcmt;    }}/* Should have a way to convert GOTO's to the end of the function to RETURN's *//* Convert "_RETV = foo;" at end of function to "return foo" */Static int checkreturns(spp, nearret)Stmt **spp;int nearret;{    Stmt *sp;    Expr *rvar, *ex;    Meaning *mp;    int spnearret, spnextreturn;    int result = 0;    if (debug>2) { fprintf(outf, "checkreturns on:\n"); dumpstmt(*spp, 5); }    while ((sp = *spp)) {        spnextreturn = (sp->next &&                        sp->next->kind == SK_RETURN && sp->next->exp1 &&                        isretvar(sp->next->exp1) == curctx->cbase);        spnearret = (nearret && !sp->next) || spnextreturn;        result = 0;        switch (sp->kind) {            case SK_ASSIGN:                ex = sp->exp1;                if (ex->kind == EK_ASSIGN || structuredfunc(ex)) {                    rvar = ex->args[0];                    mp = isretvar(rvar);                    if (mp == curctx->cbase && spnearret) {                        if (ex->kind == EK_ASSIGN) {                            if (mp->kind == MK_VARPARAM) {                                ex = makeexpr_comma(ex, makeexpr_var(mp));                            } else {                                ex = grabarg(ex, 1);                                mp->refcount--;                            }                        }                        sp->exp1 = ex;                        sp->kind = SK_RETURN;                        if (spnextreturn) {                            mp->refcount--;                            sp->next = sp->next->next;                        }                        result = 1;                    }                }                break;            case SK_RETURN:            case SK_GOTO:                result = 1;                break;            case SK_IF:                result = checkreturns(&sp->stm1, spnearret) &    /* NOT && */                         checkreturns(&sp->stm2, spnearret);                break;            case SK_TRY:                (void) checkreturns(&sp->stm1, 0);                (void) checkreturns(&sp->stm2, spnearret);                break;            /* should handle CASE statements as well */            default:                (void) checkreturns(&sp->stm1, 0);                (void) checkreturns(&sp->stm2, 0);                break;        }        spp = &sp->next;    }    return result;}/* Replace all occurrences of one expression with another expression */Expr *replaceexprexpr(ex, oldex, newex, keeptype)Expr *ex, *oldex, *newex;int keeptype;{    int i;    Type *type;    for (i = 0; i < ex->nargs; i++)        ex->args[i] = replaceexprexpr(ex->args[i], oldex, newex, keeptype);    if (exprsame(ex, oldex, 2)) {        if (ex->val.type->kind == TK_POINTER &&            ex->val.type->basetype == oldex->val.type) {            freeexpr(ex);            return makeexpr_addr(copyexpr(newex));        } else if (oldex->val.type->kind == TK_POINTER &&                   oldex->val.type->basetype == ex->val.type) {            freeexpr(ex);            return makeexpr_hat(copyexpr(newex), 0);        } else {	    type = ex->val.type;            freeexpr(ex);            ex = copyexpr(newex);	    if (keeptype)		ex->val.type = type;	    return ex;        }    }    return resimplify(ex);}void replaceexpr(sp, oldex, newex)Stmt *sp;Expr *oldex, *newex;{    while (sp) {        replaceexpr(sp->stm1, oldex, newex);        replaceexpr(sp->stm2, oldex, newex);        if (sp->exp1)            sp->exp1 = replaceexprexpr(sp->exp1, oldex, newex, 1);        if (sp->exp2)            sp->exp2 = replaceexprexpr(sp->exp2, oldex, newex, 1);        if (sp->exp3)            sp->exp3 = replaceexprexpr(sp->exp3, oldex, newex, 1);        sp = sp->next;    }}Stmt *mixassignments(sp, mp)Stmt *sp;Meaning *mp;{    if (!sp)        return NULL;    sp->next = mixassignments(sp->next, mp);    if (sp->next &&	 sp->kind == SK_ASSIGN &&         sp->exp1->kind == EK_ASSIGN &&         sp->exp1->args[0]->kind == EK_VAR &&         (!mp || mp == (Meaning *)sp->exp1->args[0]->val.i) &&         ord_type(sp->exp1->args[0]->val.type)->kind == TK_INTEGER &&         nodependencies(sp->exp1->args[1], 0) &&         sp->next->kind == SK_ASSIGN &&         sp->next->exp1->kind == EK_ASSIGN &&         (exprsame(sp->exp1->args[0], sp->next->exp1->args[0], 1) ||          (mp && mp->istemporary)) &&         exproccurs(sp->next->exp1->args[1], sp->exp1->args[0]) == 1) {        sp->next->exp1->args[1] = replaceexprexpr(sp->next->exp1->args[1],                                                  sp->exp1->args[0],                                                  sp->exp1->args[1], 1);        if (mp && mp->istemporary)            canceltempvar(mp);        return sp->next;    }    return sp;}/* Do various simple (sometimes necessary) massages on the statements */Static Stmt bogusreturn = { SK_RETURN, NULL, NULL, NULL, NULL, NULL, NULL };Static int isescape(ex)Expr *ex;{    if (ex->kind == EK_BICALL && (!strcmp(ex->val.s, name_ESCAPE) ||                                  !strcmp(ex->val.s, name_ESCIO) ||                                  !strcmp(ex->val.s, name_ESCIO2) ||				  !strcmp(ex->val.s, name_OUTMEM) ||				  !strcmp(ex->val.s, name_CASECHECK) ||				  !strcmp(ex->val.s, name_NILCHECK) ||                                  !strcmp(ex->val.s, "_exit") ||                                  !strcmp(ex->val.s, "exit")))        return 1;    if (ex->kind == EK_CAST)        return isescape(ex->args[0]);    return 0;}/* check if a block can never exit by falling off the end */Static int deadendblock(sp, breaks)Stmt *sp;int breaks;{    if (!sp)        return 0;    while (sp->next)        sp = sp->next;    return (sp->kind == SK_RETURN ||            sp->kind == SK_CASECHECK ||            ((sp->kind == SK_GOTO || sp->kind == SK_BREAK ||	      sp->kind == SK_CONTINUE) && breaks) ||            (sp->kind == SK_IF && deadendblock(sp->stm1, breaks) &&                                  deadendblock(sp->stm2, breaks)) ||            (sp->kind == SK_ASSIGN && isescape(sp->exp1)));}int expr_is_bool(ex, want)Expr *ex;int want;{    long val;    if (ex->val.type == tp_boolean && isconstexpr(ex, &val))        return (val == want);    return 0;}/* Returns 1 if c1 implies c2, 0 otherwise *//* If not1 is true, then checks if (!c1) implies c2; similarly for not2 *//* Identities used:        c1 -> (c2a && c2b)      <=>     (c1 -> c2a) && (c1 -> c2b)        c1 -> (c2a || c2b)      <=>     (c1 -> c2a) || (c1 -> c2b)        (c1a && c1b) -> c2      <=>     (c1a -> c2) || (c1b -> c2)        (c1a || c1b) -> c2      <=>     (c1a -> c2) && (c1b -> c2)        (!c1) -> (!c2)          <=>     c2 -> c1        (a == b) -> c2(b)       <=>     c2(a)        !(c1 && c2)             <=>     (!c1) || (!c2)        !(c1 || c2)             <=>     (!c1) && (!c2)*//* This could be smarter about, e.g., (a>5) -> (a>0) */int implies(c1, c2, not1, not2)Expr *c1, *c2;int not1, not2;{    Expr *ex;    int i;    if (c1->kind == EK_EQ && c1->args[0]->val.type == tp_boolean) {        if (checkconst(c1->args[0], 1)) {     /* things like "flag = true" */            return implies(c1->args[1], c2, not1, not2);        } else if (checkconst(c1->args[1], 1)) {            return implies(c1->args[0], c2, not1, not2);        } else if (checkconst(c1->args[0], 0)) {            return implies(c1->args[1], c2, !not1, not2);        } else if (checkconst(c1->args[1], 0)) {            return implies(c1->args[0], c2, !not1, not2);        }    }    if (c2->kind == EK_EQ && c2->args[0]->val.type == tp_boolean) {        if (checkconst(c2->args[0], 1)) {            return implies(c1, c2->args[1], not1, not2);        } else if (checkconst(c2->args[1], 1)) {            return implies(c1, c2->args[0], not1, not2);        } else if (checkconst(c2->args[0], 0)) {            return implies(c1, c2->args[1], not1, !not2);        } else if (checkconst(c2->args[1], 0)) {            return implies(c1, c2->args[0], not1, !not2);        }    }    switch (c2->kind) {        case EK_AND:            if (not2)               /* c1 -> (!c2a || !c2b) */                return (implies(c1, c2->args[0], not1, 1) ||                        implies(c1, c2->args[1], not1, 1));            else                    /* c1 -> (c2a && c2b) */                return (implies(c1, c2->args[0], not1, 0) &&                        implies(c1, c2->args[1], not1, 0));        case EK_OR:            if (not2)               /* c1 -> (!c2a && !c2b) */                return (implies(c1, c2->args[0], not1, 1) &&                        implies(c1, c2->args[1], not1, 1));            else                    /* c1 -> (c2a || c2b) */                return (implies(c1, c2->args[0], not1, 0) ||                        implies(c1, c2->args[1], not1, 0));        case EK_NOT:                /* c1 -> (!c2) */            return (implies(c1, c2->args[0], not1, !not2));        case EK_CONST:            if ((c2->val.i != 0) != not2)  /* c1 -> true */                return 1;            break;	default:	    break;    }    switch (c1->kind) {        case EK_AND:            if (not1)               /* (!c1a || !c1b) -> c2 */                return (implies(c1->args[0], c2, 1, not2) &&                        implies(c1->args[1], c2, 1, not2));            else                    /* (c1a && c1b) -> c2 */                return (implies(c1->args[0], c2, 0, not2) ||                        implies(c1->args[1], c2, 0, not2));        case EK_OR:            if (not1)               /* (!c1a && !c1b) -> c2 */                return (implies(c1->args[0], c2, 1, not2) ||                        implies(c1->args[1], c2, 1, not2));            else                    /* (c1a || c1b) -> c2 */                return (implies(c1->args[0], c2, 0, not2) &&                        implies(c1->args[1], c2, 0, not2));        case EK_NOT:                /* (!c1) -> c2 */            return (implies(c1->args[0], c2, !not1, not2));        case EK_CONST:            if ((c1->val.i != 0) == not1)  /*  false -> c2 */                return 1;            break;        case EK_EQ:                 /* (a=b) -> c2 */        case EK_ASSIGN:             /* (a:=b) -> c2 */        case EK_NE:                 /* (a<>b) -> c2 */            if ((c1->kind == EK_NE) == not1) {                if (c1->args[0]->kind == EK_VAR) {                    ex = replaceexprexpr(copyexpr(c2), c1->args[0], c1->args[1], 1);                    i = expr_is_bool(ex, !not2);                    freeexpr(ex);                    if (i)                        return 1;                }                if (c1->args[1]->kind == EK_VAR) {                    ex = replaceexprexpr(copyexpr(c2), c1->args[1], c1->args[0], 1);                    i = expr_is_bool(ex, !not2);                    freeexpr(ex);                    if (i)                        return 1;                }            }            break;	default:	    break;    }    if (not1 == not2 && exprequiv(c1, c2)) {    /* c1 -> c1 */        return 1;    }    return 0;}void infiniteloop(sp)Stmt *sp;{    switch (infloopstyle) {        case 1:      /* write "for (;;) ..." */            sp->kind = SK_FOR;            freeexpr(sp->exp1);            sp->exp1 = NULL;            break;        case 2:      /* write "while (1) ..." */            sp->kind = SK_WHILE;            freeexpr(sp->exp1);            sp->exp1 = makeexpr_val(make_ord(tp_boolean, 1));            break;        case 3:      /* write "do ... while (1)" */            sp->kind = SK_REPEAT;            freeexpr(sp->exp1);            sp->exp1 = makeexpr_val(make_ord(tp_boolean, 1));            break;        default:     /* leave it alone */            break;    }}Expr *print_func(ex)Expr *ex;{    if (!ex || ex->kind != EK_BICALL)	return NULL;    if ((!strcmp(ex->val.s, "printf") &&	 ex->args[0]->kind == EK_CONST) ||	!strcmp(ex->val.s, "putchar") ||	!strcmp(ex->val.s, "puts"))	return ex_output;    if ((!strcmp(ex->val.s, "fprintf") ||	 !strcmp(ex->val.s, "sprintf")) &&	ex->args[1]->kind == EK_CONST)	return ex->args[0];    if (!strcmp(ex->val.s, "putc") ||	!strcmp(ex->val.s, "fputc") ||	!strcmp(ex->val.s, "fputs"))	return ex->args[1];    return NULL;}int printnl_func(ex)Expr *ex;{    char *cp, ch;    int i, len;    if

⌨️ 快捷键说明

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