prexpr.c

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

C
919
字号
#ifndef lintstatic	char	*sccsid = "@(#)prexpr.c	4.1	(ULTRIX)	7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * File: 	prexpr.c * * Pascal to C translator - Parser for expressions - getexpr() *			  - Also contains writestmt(), mainstmts(), myexit() *//*	Modification History * * 21-July-87 afd *	Added case 6 to "myexit()", for line to long (over 132 chars) * */#include <stdio.h>#include "ptoc.h"extern enum token    nexttoken;			/* next Pascal token obtained as input */extern int linecounter;		/* for myexit() */extern int lexlev;extern struct scaninfo scandata;extern int savecmt;			/* True when comment saved */extern char currfile[LINELENGTH];	/* file name for myexit() */extern int withindex;extern char withflag[WITHNEST];	/* WITHPTR: use "id->";  WITHREC: use "id." */extern struct stentry *withrecst[WITHNEST];extern char withvar[WITHNEST][LINELENGTH];struct stentry *findany();struct stentry *findlev();struct stentry *getstentry();char *getname();char *malloc();char *strchr();struct treenode *gettn();/* * getexpr.  Scan an expression, upto: a token that is not recognized * as part of an expression, or upto a ")" if not in a parenthesized sub expr. * * It calls itself recursively to pick up function parameters.  This is * so that the simple mechanism employed to handle `var' parameters will * work on nested function calls. */char mathop;			/* set true in getexpr if a mathop is encountered				 * This is used by writestmt() */getexpr(buf,cond)    char *buf;    int cond;			/* special conditions:				 *	1: stop after `]' (for "with" array id)				 *	2: in proc/func call (get var params)				 *	3: getting LHS of assignment stmt.				 *	   if funcvar occurs use the dummy				 *	   funcvar (to assign to).				 *	4: getting write stmt, stop on comma.				 */{    char inarray = 0;		/* @ `[' increm;  @ `]' decrem */    char inparen = 0;		/* @ `(' increm;  @ `)' decrem */    char gotptr = 0;    int i, j, wi;		/* loop indices */    int numenums;		/* number of entries an enum type has */    int nparams;		/* number of params a func/proc has */    int paramnum;		/* number of params obtained thus far */    struct stentry *st;    struct stentry *stparam;	/* pointer to current formal parameter */    char subbuf[EXPRLEN];	/* for recursize call to getexpr() */    int saveindex;		/* save index into buf of last "ident" */    char inset = 0;		/* set when processing "in" */    char setvar[LINELENGTH];	/* to hold set variable */    char setelement[LINELENGTH];/* to hold set element */    int setindex;		/* index in "buf" of start of possible setvar				       Reset on: and,or,!,(  */    int varindex;		/* index in "buf" of 1st char of a variable					Reset on: +,-,*,/,rel-ops,and,or,						  [,(,!,in  and  , */    int savemathop;		/* save mathop on recursive call for funct params */    char nowith;	/* set if "with" var not needed ("." already used) */    mathop = 0;    setindex = 0;    varindex = strlen(buf);    if (cond == 2)	{	/* Getting proc/func params, set up for it here.	 * Retrieve proc/func name from "buf": get st pointer to it, get	 * number of params it has, get pointer to first param.	 * (if we find a dummy function name variable used for returning	 * funtion value, then we search at lexlev-1.)	 */	st = findany(buf);		/* proc name stored in "buf" */	if (st != NULL)	    if (st->st_class == VARC)		st = findlev(buf,lexlev-1);	if (st != NULL)	    {	    buf[0] = '\0';	    nparams = st->st_nparams;	    if (nparams > 0)		{		paramnum = 0;		stparam = st->st_fparam;		}	    }	else	    myexit(1,buf);	}    for (; strlen(buf) < EXPRLEN - 10; )	{	if (gotptr)	    if (nexttoken != DOT)		if (inset)		    {		    strcpy(subbuf,setelement);		    strcpy(setelement,"*");		    strcat(setelement,subbuf);		    gotptr = 0;		    }		else		    {		    strcpy(subbuf, buf + saveindex);		    buf[saveindex] = '\0';		    strcat(buf, "*");		    strcat(buf, subbuf);		    gotptr = 0;		    }	switch(nexttoken)	    {	    case ANDT:		strcat(buf," && ");    		setindex = strlen(buf);		varindex = strlen(buf);		break;	    case CHARCONST:		if (inset)		    {		    strcpy(setelement,"'");		    strcat(setelement,scandata.si_name);		    strcat(setelement,"'");		    }		else		    {		    if (scandata.si_idlen > 1)			strcat(buf,"\"");		    else			strcat(buf,"'");		    strcat(buf, scandata.si_name);		    if (scandata.si_idlen > 1)			strcat(buf,"\"");		    else			strcat(buf,"'");		    }		break;	    case COLON:		/*		 * Legal in format of a write stmt		 */		strcat(buf,":");		break;	    case COMMA:		if (inarray)		    {		    strcat(buf,"][");		    varindex = strlen(buf);		    }		else		    if (cond == 4)			return;		else		    if (inset)			{			strcat(buf,setvar);			if (inset == 2)			    {			    strcat(buf, " <= ");			    inset = 1;			    }			else			    strcat(buf, " == ");			strcat(buf, setelement);			strcat(buf, ") || (");			}		else		    {		    strcat(buf,",");		    varindex = strlen(buf);		    if (cond == 2 && paramnum < nparams)			{			paramnum++;			stparam = stparam->st_link;			}		    }		break;	    case DOT:		if (gotptr)		    {		    if (inset)			strcat(setelement, "->");		    else			strcat(buf, "->");		    gotptr = 0;		    }		else		    if (inset)			strcat(setelement, ".");		    else			strcat(buf,".");		break;	    case DIVT:	    case INTDIVT:		if (!inarray && cond != 2)		    mathop = 1;		strcat(buf," / ");		varindex = strlen(buf);		break;	    case DOTDOT:		strcat(buf, setvar);		strcat(buf, " >= ");		strcat(buf, setelement);		strcat(buf, " && ");		inset = 2;		break;	    case FALSET:		strcat(buf,"0");		break;	    case IDENT:		if (inset)		    {		    st = findany(scandata.si_name);		    if (st != NULL && st->st_dstruct != SETS)			/* var in [constid..constid] (or [expr..expr]) */			strcpy(setelement,scandata.si_name);		    else			{  /* var in setid */			inset = 0;			strcat(buf, setvar);			strcat(buf, " == ");			strcat(buf,scandata.si_name);			strcat(buf, ")");			}		    break;		    }		/*		 * If a "." occured just before this ident, then we don't		 * want to look for a "with" varible to "dot" in front of		 * the ident.		 */		nowith = (char)strchr(buf + varindex,'.');		for (wi = withindex; nowith == 0 && wi >= 0; wi--)		    { /* get ptr to 1st field in record & see if id in record */		    st = 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, st->st_name))			    break;			/*			 * Skip over enumeration constants.			 */			if (st->st_dstruct == UDEFS && st->st_tipe == ENUMTY)			    {			    numenums = st->st_numdims;			    for (j = 0; j < numenums; j++)				st = st->st_link;			    }			st = st->st_link;			}		    if (nowith == 0 && i < withrecst[wi]->st_numdims)			{	/* ident is a record field of the 'with' var */			strcat(buf,withvar[wi]);			strcat(buf,scandata.si_name);			break;  /* from for loop */			}		    }		if (nowith != 0 || wi < 0)	/* id not in 'with' record */		    {		    st = findany(scandata.si_name);		    if (st == NULL)			    {		/* had "record." got "field" */			    strcat(buf,scandata.si_name);			    break;			    }		    if (cond == 3 && st->st_funcvar)			{	/* assignment to function use dummy name */			strcpy(subbuf, scandata.si_name);			strcpy(scandata.si_name, "v___");			strcat(scandata.si_name, subbuf);			}		    /*		     * if recursive function call find st entry for the func		     */		    if (cond != 3 && st->st_funcvar)			st = findlev(scandata.si_name, lexlev-1);		    /*		     * if calling a function that was passed as a parameter		     * find st entry for the func.		     */		    else if (cond != 3 && st->st_funcpar)			    st = findlev(scandata.si_name, lexlev-1);		    if (st != NULL)			{			/*			 * If we encounter a function name in an expression			 * we do not want to get its parameters if its			 * a function name parameter.			 */			if (st->st_class == FUNCC && stparam->st_funcpar == 0)			    {			    nparams = st->st_nparams;			    if (nparams > 0)				{				scanner(0);				if (nexttoken == LEFTPAREN)				    {				    /* Save func name and call getexpr()				     * recursively with it.  The recursive				     * call is used so that the simple				     * mechanism employed for handling `var'				     * params will work on nested function				     * calls.				     */				    strcpy(subbuf,scandata.si_name);				    if (st->st_funcpar)					strcat(buf, "(*");				    strcat(buf,scandata.si_name);				    if (st->st_funcpar)					strcat(buf, ")");				    strcat(buf, "(");				    scanner(0);		/* skip over '(' */				    savemathop = mathop;				    getexpr(subbuf,2);				    mathop = savemathop;				    strcat(buf,subbuf);				    strcat(buf,")");				    }				else				    myexit(2,"(");				break;				}			    else				{ /* func w/ no params, need "funcname()" */				if (st->st_funcpar)				    strcat(buf, "(*");				strcat(buf,scandata.si_name);				if (st->st_funcpar)				    strcat(buf, ")");				strcat(buf, "()");				break;				}			    }			else if (cond == 2 && paramnum < nparams)				{				if (stparam->st_byref && !(inarray) &&				    buf[strlen(buf)-1] != '.' &&				    buf[strlen(buf)-1] != '>')				    strcat(buf,"&");				}			else if (st->st_class == VARC && st->st_byref &&				 st->st_dstruct != ARRS)				/* accessing a parameter that was passed byref */				strcat(buf, "*");			saveindex = strlen(buf);			}		    strcat(buf,scandata.si_name);		    }		break;	    case IN:		/* Set "inset" flag & put "(" into "buf" in place of set id */		inset = 1;		strcpy(setvar, buf + setindex);		buf[setindex] = '\0';		strcat(buf,"(");		varindex = strlen(buf);		break;	    case LEFTPAREN:		/*		 * Special case of call to an undefinded proc, when		 * we were within a "with" stmt so we couldn't tell		 * until now if it was an assignment stmt or bad proc call		 */		if (cond == 3 && inarray == 0)		    myexit(1,scandata.si_name);		inparen++;		mathop = 1;		strcat(buf,"(");		if (!inarray)		    setindex = strlen(buf);		varindex = strlen(buf);		break;	    case LEFTBRACKET:		if (!inset)		    {		    strcat(buf,"[");		    inarray++;		    }		varindex = strlen(buf);		break;	    case MINUS:		if (!inarray && cond != 2)		    mathop = 1;		strcat(buf," - ");		varindex = strlen(buf);		break;	    case MODT:		if (!inarray && cond != 2)		    mathop = 1;		strcat(buf," % ");		varindex = strlen(buf);		break;	    case MULT:		if (!inarray && cond != 2)		    mathop = 1;		strcat(buf," * ");		varindex = strlen(buf);		break;	    case NOTT:		strcat(buf," ! ");    		setindex = strlen(buf);		varindex = strlen(buf);		mathop = 1;		break;	    case NUMCONST:		if (inset)		    strcpy(setelement,scandata.si_name);		else		    strcat(buf,scandata.si_name);		break;	    case ORT:		strcat(buf," || ");    		setindex = strlen(buf);		varindex = strlen(buf);

⌨️ 快捷键说明

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