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 + -
显示快捷键?