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