prstmt.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,060 行 · 第 1/2 页
C
1,060 行
#ifndef lintstatic char *sccsid = "@(#)prstmt.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: prstmt.c * * Pascal to C translator - Parser for statements, Contains: * - statelist() - main routine for parsing stmts */#include <stdio.h>#include "ptoc.h"extern enum token nexttoken, /* next Pascal token obtained as input */ holdtoken; /* hold present token for look-ahead */extern char tokenahead;extern int lexlev;extern struct scaninfo scandata;extern int savecmt; /* True when comment saved */struct stentry *findany();struct stentry *findlev();struct stentry *getstentry();char *getname();char *malloc();char *strchr();struct treenode *gettn();struct treenode *writestmt();/* for "with" statements */int withindex = -1;char withflag[WITHNEST]; /* WITHPTR: use "id->"; WITHREC: use "id." */struct stentry *withrecst[WITHNEST];char withvar[WITHNEST][LINELENGTH];/* * Begin block */struct treenode *beginblock(parent,prev) struct treenode *parent, *prev;{ struct treenode * tn; tn = gettn(); tn->type = BEGINNODE; if (parent->type == WITHNODE) tn->blktype = WITHBLOCK; else tn->blktype = SEMIBLOCK; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; scanner(0); statelist(tn, BEGINLEVEL); return(tn);}/* * Assign stmt */struct treenode *assignstmt(parent,prev) struct treenode *parent, *prev;{ struct treenode * tn; char buf[EXPRLEN]; savecmt = 0; tn = gettn(); tn->type = ASSIGNNODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; buf[0] = '\0'; getexpr(buf,3); tn->storewhere = malloc(strlen(buf)+1); if (tn->storewhere == NULL) myexit(-1,""); strcpy(tn->storewhere,buf); scanner(0); /* get start of RHS of expr */ buf[0] = '\0'; getexpr(buf,0); /* * If assigning a character string in Pascal, use "strcpy" in C */ if (strchr(buf,'"') == buf) { tn->type = PCALLNODE; tn->stdecl = findany("strcpy"); tn->expression = malloc(strlen(tn->storewhere) + strlen(buf) + 2); if (tn->expression == NULL) myexit(-1,""); strcpy(tn->expression, tn->storewhere); strcat(tn->expression, ","); strcat(tn->expression, buf); } else { tn->storewhat = malloc(strlen(buf)+1); if (tn->storewhat == NULL) myexit(-1,""); strcpy(tn->storewhat,buf); } if (nexttoken == SEMICOLON) { savecmt = 1; scanner(0); /* get next token after SEMICOLEN */ } return(tn);}/* * call stmt. */struct treenode *callstmt(parent,prev,st) struct treenode *parent, *prev; struct stentry *st;{ struct treenode * tn; char buf[EXPRLEN]; savecmt = 0; tn = gettn(); tn->type = PCALLNODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; tn->stdecl = st; scanner(0); if (nexttoken == LEFTPAREN) { strcpy(buf,scandata.si_name); /* save proc name for getexpr() */ scanner(0); /* skip over '(' */ getexpr(buf,2); tn->expression = malloc(strlen(buf)+1); if (tn->expression == NULL) myexit(-1,""); strcpy(tn->expression,buf); scanner(0); /* get ';' */ } if (nexttoken == SEMICOLON) { savecmt = 1; scanner(0); /* get nexttoken */ } return(tn);}/* * case stmt */struct treenode *casestmt(parent,prev) struct treenode *parent, *prev;{ struct treenode *tn, *casetn; struct treenode *labelparent, *labelprev; char buf[EXPRLEN]; char other = 0; /* set true if "otherwise" found */ char o_or_x[4]; savecmt = 0; tn = gettn(); casetn = tn; tn->type = CASENODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; /* get case expression */ buf[0] = '\0'; scanner(0); /* get 1st char of expression */ getexpr(buf,0); tn->expression = malloc(strlen(buf)+1); if (tn->expression == NULL) myexit(-1,""); strcpy(tn->expression,buf); scanner(0); /* get nexttoken after 'OF' */ prev = NULL; parent = tn; /* case is parent to listheads */ /* * Loop until 'end' of case stmt is found */ for (; nexttoken != ENDT; ) { tn = gettn(); tn->type = LISTHEADNODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; prev = tn; /* * get case labels for one case */ labelparent = tn; labelprev = NULL; for (; nexttoken != COLON; ) { tn = gettn(); tn->type = LABELNODE; if (labelparent->firstc == NULL) labelparent->firstc = tn; labelparent->lastc = tn; if (labelprev != NULL) labelprev->next = tn; /* * Get constant set up in scandata.si_name */ switch (nexttoken) { case CHARCONST: strcpy(buf,scandata.si_name); strcpy(scandata.si_name,"'"); strcat(scandata.si_name,buf); strcat(scandata.si_name,"'"); break; case MINUS: scanner(0); strcpy(buf,scandata.si_name); strcpy(scandata.si_name, "-"); strcat(scandata.si_name, buf); break; case PLUS: scanner(0); strcpy(buf,scandata.si_name); strcpy(scandata.si_name, "+"); strcat(scandata.si_name, buf); break; case IDENT: case NUMCONST: break; /* do nothing: already set up */ case TRUET: strcpy(scandata.si_name, "1"); break; case FALSET: strcpy(scandata.si_name, "0"); break; case PERCENT: scanner(0); if (nexttoken != IDENT) myexit(2,"constant"); if ((strcmp(scandata.si_name,"o") == 0) || (strcmp(scandata.si_name,"O") == 0)) strcpy(o_or_x,"0"); else if ((strcmp(scandata.si_name,"x") == 0) || (strcmp(scandata.si_name,"X") == 0)) strcpy(o_or_x,"0x"); else myexit(2,"constant"); /* * Call scanner to get octal or hex const within * apostrophes. */ scanner(0); if (nexttoken != CHARCONST) myexit(2,"constant"); strcpy(buf,scandata.si_name); strcpy(scandata.si_name, o_or_x); strcat(scandata.si_name, buf); break; case OTHERWISE: strcpy(scandata.si_name, "default"); other = 1; break; default: /* * Assume its correct syntax (like +/- constant) */ break; } /* end switch on nexttoken */ tn->expression = malloc(strlen(scandata.si_name)+1); if (tn->expression == NULL) myexit(-1,""); strcpy(tn->expression,scandata.si_name); labelprev = tn; if (other) nexttoken = COLON; else scanner(0); if (nexttoken == COMMA) scanner(0); if (nexttoken == SEMICOLON || nexttoken == ENDT) myexit(2,"case label"); } savecmt = 1; scanner(0); /* get nexttoken after ":" @ end of case label */ statelist(tn, SINGLESTMT); /* tn = last label node in this group */ } savecmt = 1; scanner(0); /* get nexttoken after case 'end' */ if (nexttoken == SEMICOLON) scanner(0); return(casetn);}/* * Cmt stmt. Create a tree node for it. */struct treenode *cmtstmt(parent,prev) struct treenode *parent, *prev;{ struct treenode * tn; tn = gettn(); tn->type = COMMENTNODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; tn->blkcmt = scandata.si_cmtptr; scanner(0); /* get next token after comment */ return(tn);}/* * for stmt */struct treenode *forstmt(parent,prev) struct treenode *parent, *prev;{ struct treenode * tn; char buf[EXPRLEN]; savecmt = 0; tn = gettn(); tn->type = FORNODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; scanner(0); /* get 1st token of for loop var */ buf[0] = '\0'; getexpr(buf,0); tn->variable = malloc(strlen(buf)+1); if (tn->variable == NULL) myexit(-1,""); strcpy(tn->variable,buf); scanner(0); /* get next token after ':=' */ buf[0] = '\0'; getexpr(buf,0); tn->initvalue = malloc(strlen(buf)+1); if (tn->initvalue == NULL) myexit(-1,""); strcpy(tn->initvalue,buf); if (nexttoken == TOT) tn->to = 1; else tn->to = 0; scanner(0); /* get next token after 'to/downto' */ buf[0] = '\0'; getexpr(buf,0); tn->finalvalue = malloc(strlen(buf)+1); if (tn->finalvalue == NULL) myexit(-1,""); strcpy(tn->finalvalue,buf); if (nexttoken != LOOPDO) myexit(2,"do"); savecmt = 1; scanner(0); /* get next token after 'do' */ statelist(tn, SINGLESTMT); return(tn);}/* * goto stmt */struct treenode *gotostmt(parent,prev) struct treenode *parent, *prev;{ struct treenode * tn; char buf[EXPRLEN]; savecmt = 0; tn = gettn(); tn->type = GOTONODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; scanner(0); /* get 1st token of goto label */ buf[0] = '\0'; getexpr(buf,0); tn->expression = malloc(strlen(buf)+1); if (tn->expression == NULL) myexit(-1,""); strcpy(tn->expression,buf); if (nexttoken == SEMICOLON) { savecmt = 1; scanner(0); } return(tn);}/* * label stmt */struct treenode *labelstmt(parent,prev) struct treenode *parent, *prev;{ struct treenode * tn; char buf[EXPRLEN]; savecmt = 0; tn = gettn(); tn->type = LABELNODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; tn->expression = malloc(strlen(scandata.si_name)+1); if (tn->expression == NULL) myexit(-1,""); strcpy(tn->expression,scandata.si_name); scanner(0); if (nexttoken != COLON) myexit(2,":"); savecmt = 1; scanner(0); return(tn);}/* * if stmt. */struct treenode *ifstmt(parent,prev) struct treenode *parent, *prev;{ struct treenode *tn; /* ptr to 'if' tree node */ struct treenode *elsetn; /* ptr to 'else block' tree node */ char buf[EXPRLEN]; savecmt = 0; tn = gettn(); tn->type = IFNODE; if (parent->firstc == NULL) parent->firstc = tn; parent->lastc = tn; if (prev != NULL) prev->next = tn; scanner(0); /* get 1st token of if 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 != THENT) myexit(2,"then"); savecmt = 1; scanner(0); /* get next token after 'then' */ statelist(tn, SINGLESTMT); /* 'then' part goes under firstc */ if (nexttoken == ELSET) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?