prstmt.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,060 行 · 第 1/2 页

C
1,060
字号
	/*	 * Create an 'else-block' for the else clause.	 * The 'if' tree node's lastchild points to the else-block.	 */	elsetn = gettn();	elsetn->type = BEGINNODE;	elsetn->blktype = ELSEBLOCK;	tn->lastc = elsetn;	savecmt = 1;	scanner(0);			/* next token after 'else' */	statelist(elsetn,SINGLESTMT);	/* 'else' part goes under elseblock */	}    else	tn->lastc = NULL;		/* no else clause */    return(tn);}/* * Read/Readln stmts */struct treenode *readstmt(parent, prev, ln)    struct treenode *parent;    struct treenode *prev;    char ln;			/* true if its readLN */{    struct stentry *st;    struct treenode *tn;    char filevar[WORDLENGTH];    char inputvar[LINELENGTH];    char lit[EXPRLEN];    char buf[EXPRLEN];    savecmt = 0;    tn = gettn();    tn->type = READNODE;    if (parent->firstc == NULL)	parent->firstc = tn;    parent->lastc = tn;    if (prev != NULL)	prev->next = tn;    filevar[0] = '\0';    lit[0] = '\0';    buf[0] = '\0';    scanner();    if (nexttoken == LEFTPAREN)	{	scanner();	for (;;)	    {	    if (strcmp(buf,""))		strcat(buf,", ");    	    inputvar[0] = '\0';	    getexpr(inputvar,4);	    st = findany(scandata.si_name);	    while (st->st_dstruct == UDEFS)		st = st->st_uptr;	    switch (st->st_dstruct)		{		case FILESTR:		    strcpy(filevar, scandata.si_name);		    break;		case ARRS:		    strcat(lit, "%s");		    strcat(buf,inputvar);		    break;		default:		    strcat(buf,"&");		    strcat(buf,inputvar);		    switch (st->st_tipe)			{			case CHARTY:			    strcat(lit, "%c");			    break;			case REALTY:			    strcat(lit, "%f");			    break;			default:			    strcat(lit, "%d");			    break;			}   /* end switch st_tipe */		}  /* end switch st_dstruct */	    if (nexttoken == RIGHTPAREN)		break;	    scanner();	    }  /* end for */	}   /* end if (nexttoken == LEFTPAREN) */    strcat(lit, "\"");    if (ln)	tn->expression = malloc(strlen(buf) + strlen(lit) + strlen(filevar) + 35);    else	tn->expression = malloc(strlen(buf) + strlen(lit) + strlen(filevar) + 15);    if (tn->expression == NULL)	myexit(-1,"");    tn->expression[0] = '\0';    if (strcmp(filevar, ""))	{	strcat(tn->expression, "fscanf(");			/* + 7 */	strcat(tn->expression, filevar);	strcat(tn->expression, ", ");		    		/* + 2 */	}    else	strcat(tn->expression, "scanf(");    strcat(tn->expression, "\"");				/* + 1 */    strcat(tn->expression, lit);    if (strcmp(buf,""))	strcat(tn->expression, ", ");		    		/* + 2 */    strcat(tn->expression, buf);    strcat(tn->expression,");");		    		/* + 2 */    if (ln)	strcat(tn->expression," gets(readln_dummy);");		/* + 20 */    scanner();    if (nexttoken == SEMICOLON)	{	savecmt = 1;	scanner();	}    return(tn);}/* * repeat stmt */struct treenode *repeatstmt(parent,prev)    struct treenode *parent, *prev;{    struct treenode * tn;    char buf[EXPRLEN];    tn = gettn();    tn->type = REPEATNODE;    if (parent->firstc == NULL)	parent->firstc = tn;    parent->lastc = tn;    if (prev != NULL)	prev->next = tn;    savecmt = 1;    scanner(0);    statelist(tn, FUNCLEVEL);	/* get multiple stmts w/out begin..end */    buf[0] = '\0';    savecmt = 0;    scanner(0);				/* get 1st token of expr */    getexpr(buf,0);    tn->expression = malloc(strlen(buf)+4);    if (tn->expression == NULL)	myexit(-1,"");    /*     * repeat-until (cond)   <translates to>   do-while (not cond)     */    strcpy(tn->expression,"!(");    strcat(tn->expression,buf);    strcat(tn->expression,")");    if (nexttoken == SEMICOLON)	{	savecmt = 1;	scanner(0);				/* get nexttoken */	}    return(tn);}/* * semistmt. */struct treenode *semistmt(parent,prev)    struct treenode *parent, *prev;{    struct treenode * tn;    tn = gettn();    tn->type = SEMINODE;    if (parent->firstc == NULL)	parent->firstc = tn;    parent->lastc = tn;    if (prev != NULL)	prev->next = tn;    savecmt = 1;    scanner(0);				/* get next token */    return(tn);}/* * While stmt. */struct treenode *whilestmt(parent,prev)    struct treenode *parent, *prev;{    struct treenode * tn;    char buf[EXPRLEN];    savecmt = 0;    tn = gettn();    tn->type = WHILENODE;    if (parent->firstc == NULL)	parent->firstc = tn;    parent->lastc = tn;    if (prev != NULL)	prev->next = tn;    scanner(0);				/* get 1st token of while expression */    buf[0] = '\0';    getexpr(buf,0);    tn->expression = malloc(strlen(buf)+1);    if (tn->expression == NULL)	myexit(-1,"");    strcpy(tn->expression,buf);    if (nexttoken != LOOPDO)	myexit(2,"do");    savecmt = 1;    scanner(0);				/* get next token after 'do' */    statelist(tn, SINGLESTMT);    return(tn);}/* * With stmt */struct treenode *withstmt(parent,prev)    struct treenode *parent, *prev;{    struct treenode *tn;    struct stentry *st, *wist;    int i, j, wi;			/* loop indices */    int numenums;			/* number of entries an enum type has */    char buf[EXPRLEN];    char first;    savecmt = 0;    tn = gettn();    tn->type = WITHNODE;    if (parent->firstc == NULL)	parent->firstc = tn;    parent->lastc = tn;    if (prev != NULL)	prev->next = tn;      do {    scanner(0);		/* get 'with' var */    if (nexttoken != IDENT)	myexit(2,"identifier");    st = findany(scandata.si_name);    if (st == NULL && withindex < 0)	myexit(1,scandata.si_name);    for (wi = withindex; wi >= 0; wi--)	{ /* get ptr to 1st field in record & see if id in record */	wist = withrecst[wi]->st_next;	for (i = 0; i < withrecst[wi]->st_numdims; i++)	    {	/* see if ident matches a record field */	    if (!strcmp(scandata.si_name, wist->st_name))		break;	    /*	     * Skip over enumeration constants.	     */	    if (wist->st_dstruct == UDEFS && wist->st_tipe == ENUMTY)		{		numenums = wist->st_numdims;		for (j = 0; j < numenums; j++)		    wist = wist->st_link;		}	    wist = wist->st_link;	    }	if (i < withrecst[wi]->st_numdims)	    {	/* ident is a record field of the 'with' var */	    strcpy(withvar[withindex+1], withvar[wi]);	    strcat(withvar[withindex+1],scandata.si_name);	    st = wist;	    break;	    }	}    if (wi < 0)	/* id not in 'with' record */	strcpy(withvar[withindex+1], scandata.si_name);    /*     * Loop to get all of "with" variable.     */    first = 1;    for (; nexttoken == IDENT ;)	{	for (; st->st_dstruct == UDEFS ||	    (st->st_dstruct == ARRS && st->st_tipe == USERTYPE) ; )	    st = st->st_uptr;	/*	 * If id is an array id, call getexpr() to get array subscripts.	 */	scanner(0);	if (nexttoken == LEFTBRACKET)	    {	    buf[0] = '\0';	    getexpr(buf,1);	    if (nexttoken != RIGHTBRACKET)		myexit(2,"]");	    strcat(withvar[withindex+1], buf);	    scanner(0);		/* nexttoken after ']' */	    }	if (nexttoken == UPARROW)	    if (st->st_dstruct != PTRS)		myexit(3,"bad 'with' variable");	    else		{withflag[withindex+1] = WITHPTR;		scanner(0);		if (nexttoken == DOT)		    {		    strcat(withvar[withindex+1], "->");		    /*		     * Can't trust st->uptr directly, since object pointed to		     * could have been defined later.		     */		    st = findany(st->st_uptr->st_name);		    if (st == NULL)			myexit(3,"bad 'with' variable");		    withrecst[withindex+1] = st;		    scanner(0);		    if (nexttoken != IDENT)			myexit(3,"bad 'with' variable");	    	    first = 0;		    }		}	else if (nexttoken == DOT)	    if (st->st_dstruct != RECORDS)		myexit(3,"bad 'with' variable");	    else		{withflag[withindex+1] = WITHREC;		strcat(withvar[withindex+1], ".");		withrecst[withindex+1] = st;		scanner(0);		if (nexttoken != IDENT)		    myexit(3,"bad 'with' variable");		first = 0;		}	else if (nexttoken != LOOPDO && nexttoken != COMMA)		myexit(3,"bad 'with' variable");	if (nexttoken == IDENT && (!first))	    {	    /*	     * Get ptr to first field in record & find field name	     */	    wist = st->st_next;	    for (i = 0; i < wist->st_numdims; i++)		{	/* see if ident matches a record field */		if (!strcmp(scandata.si_name, wist->st_name))		    break;		/*		 * Skip over enumeration constants.		 */		if (wist->st_dstruct == UDEFS && wist->st_tipe == ENUMTY)		    {		    numenums = wist->st_numdims;		    for (j = 0; j < numenums; j++)			wist = wist->st_link;		    }		wist = wist->st_link;		}	    if (i < st->st_numdims)		{	/* ident is a record field of the 'with' var */		strcat(withvar[withindex+1],scandata.si_name);		st = wist;		}	    else		myexit(3,"bad 'with' variable");	    }	/* if (nexttoken == IDENT && !first) */	}	/* for (nexttoken == IDENT) */    /*     * Now update "withrecst" to point to last record structure     * referenced by the last ident part of the "with" variable.     */    if (st->st_dstruct == PTRS)	{	/*	 * Can't trust st->uptr directly, since object pointed to	 * could have been defined later.	 */	st = findany(st->st_uptr->st_name);	if (st == NULL)	    myexit(3,"bad 'with' variable");	withrecst[withindex+1] = st;	strcat(withvar[withindex+1], "->");	}    else if (st->st_dstruct == RECORDS)	{	withrecst[withindex+1] = st;	strcat(withvar[withindex+1], ".");	}    /*     * Now done getting the "with" variable so     * its safe to increment "withindex".     */    withindex++;  } while (nexttoken == COMMA);    savecmt = 1;    scanner(0);		/* get nexttoken after 'do' */    statelist(tn,SINGLESTMT);    withflag[withindex] = 0;    withindex--;    return(tn);}/* * Statement list. * BNF: *	<statelist> ::= (<statement> | begin <statelist> end) ^+ *	<statement> ::= (<label>: | SEMICOLON | <assignstmt> | <callstmt> | *			<casestmt> | <forstmt> | <ifstmt> | <whilestmt> | *			<repeatstmt> | <withstmt> | <gotostmt>) */statelist(parent, state)    struct treenode *parent;    char state;		/* 0 = SINGLESTMT, 1 = FUNCLEVEL, 2 = BEGINLEVEL */{    struct stentry *st;    struct treenode *tn, *prev;    char stmt;			/* set to 0 when we don't recognize a stmt */    char cont;			/* set to 1 when we get a comment or label */    prev = NULL;    stmt = 1;    do {	cont = 0;	switch (nexttoken)	    {	    case BEGINT:		prev = beginblock(parent, prev);		break;	    case ENDT:		stmt = 0;		/*		 * This is neccessary so that the 'end' of a case stmt		 * is not scanned here.		 */		if (state != SINGLESTMT)		    {		    scanner(0);		    if (nexttoken == SEMICOLON)			scanner(0);		    }		break;	    case IDENT:		st = findany(scandata.si_name);		if (st != NULL && (st->st_funcpar == 2))		    st = findlev(scandata.si_name,lexlev-1);		if (st == NULL)		    if (withindex < 0)			myexit(1,scandata.si_name);		if (st != NULL && (st->st_class == PROCC || st->st_class == FUNCC))		    prev = callstmt(parent,prev,st);		else		    prev = assignstmt(parent,prev);		break;	    case CASET:		prev = casestmt(parent, prev);		break;	    case COMMENT:		prev = cmtstmt(parent, prev);		/* can always have another stmt after a comment so continue */		cont = 1;		break;	    case FORT:		prev = forstmt(parent, prev);		break;	    case GOTOT:		prev = gotostmt(parent, prev);		break;	    case IFT:		prev = ifstmt(parent, prev);		break;	    case NUMCONST:		prev = labelstmt(parent, prev);		/* can always have another stmt after a label so continue */		cont = 1;		break;	    case READT:		prev = readstmt(parent, prev, 0);		break;	    case READLNT:		prev = readstmt(parent, prev, 1);		break;	    case REPEATT:		prev = repeatstmt(parent, prev);		break;	    case UNTILT:		stmt = 0;	/* repeatstmt() will get the expression */		break;	    case WHILET:		prev = whilestmt(parent, prev);		break;	    case WITHT:		prev = withstmt(parent, prev);		break;	    case WRITET:		prev = writestmt(parent, prev, 0);		break;	    case WRITELNT:		prev = writestmt(parent, prev, 1);		break;	    case SEMICOLON:		prev = semistmt(parent, prev);		break;	    default:		stmt = 0;		break;	    }   /* end switch on nexttoken */    } while (cont || (stmt && state));    /*     * Get any trailing comments and any between procs     */    while (nexttoken == COMMENT)	prev = cmtstmt(parent, prev);}

⌨️ 快捷键说明

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