⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gen.c

📁 SRI international 发布的OAA框架软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * gen.c
 *
 * Generate C code (ANSI, K&R, C++)
 *
 * SOFTWARE RIGHTS
 *
 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
 * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
 * company may do whatever they wish with source code distributed with
 * PCCTS or the code generated by PCCTS, including the incorporation of
 * PCCTS, or its output, into commerical software.
 *
 * We encourage users to develop software with PCCTS.  However, we do ask
 * that credit is given to us for developing PCCTS.  By "credit",
 * we mean that if you incorporate our source code into one of your
 * programs (commercial product, research project, or otherwise) that you
 * acknowledge this fact somewhere in the documentation, research report,
 * etc...  If you like PCCTS and have developed a nice tool with the
 * output, please mention that you developed it using PCCTS.  In
 * addition, we ask that this header remain intact in our source code.
 * As long as these guidelines are kept, we expect to continue enhancing
 * this system and expect to make other tools available as they are
 * completed.
 *
 * ANTLR 1.33
 * Terence Parr
 * Parr Research Corporation
 * with Purdue University and AHPCRC, University of Minnesota
 * 1989-2001
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "pcctscfg.h"
#include "set.h"
#include "syn.h"
#include "hash.h"
#include "generic.h"
#include "dlgdef.h"

#define NumExprPerLine	4
static int on1line=0;
static set tokensRefdInBlock;

					/* T r a n s l a t i o n  T a b l e s */

/* C_Trans[node type] == pointer to function that knows how to translate that node. */
#ifdef __cplusplus
void (*C_Trans[NumNodeTypes+1])(...) = {
	NULL,
	NULL,					/* See next table.
Junctions have many types */
	(void (*)(...)) genRuleRef,
	(void (*)(...)) genToken,
	(void (*)(...)) genAction
 };
#else
void (*C_Trans[NumNodeTypes+1])() = {
	NULL,
	NULL,					/* See next table.
Junctions have many types */
	genRuleRef,
	genToken,
	genAction
 };
#endif

/* C_JTrans[Junction type] == pointer to function that knows how to translate that
 * kind of junction node.
 */
#ifdef __cplusplus
void (*C_JTrans[NumJuncTypes+1])(...) = {
	NULL,
	(void (*)(...)) genSubBlk,
	(void (*)(...)) genOptBlk,
	(void (*)(...)) genLoopBlk,
	(void (*)(...)) genEndBlk,
	(void (*)(...)) genRule,
	(void (*)(...)) genJunction,
	(void (*)(...)) genEndRule,
	(void (*)(...)) genPlusBlk,
	(void (*)(...)) genLoopBegin
 };
#else
void (*C_JTrans[NumJuncTypes+1])() = {
	NULL,
	genSubBlk,
	genOptBlk,
	genLoopBlk,
	genEndBlk,
	genRule,
	genJunction,
	genEndRule,
	genPlusBlk,
	genLoopBegin
 };
#endif

#define PastWhiteSpace(s)	while (*(s) == ' ' || *(s) == '\t') {s++;}

static int tabs = 0;

/* MR6	Got tired of text running off page when using standard tab stops */

#define TAB { int i; 					                		\
	      if (TabWidth==0) { 					                \
	         for (i=0; i<tabs; i++) fputc('\t', output);		                \
	      } else {           							\
		 for (i=0; i<tabs*TabWidth; i++) fputc(' ',output);     	        \
	      };	                						\
	    }

static void
#ifdef __USE_PROTOS
tab( void )
#else
tab( )
#endif
TAB

#ifdef __USE_PROTOS
static char *tokenFollowSet(TokNode *);
static ActionNode *findImmedAction( Node * );
static void dumpRetValAssign(char *, char *, RuleRefNode *);		/* MR30 */
static void dumpAfterActions(FILE *output);
static set ComputeErrorSet(Junction *, int, int);
static void makeErrorClause(Junction *, set, int, int);
static void DumpFuncHeader( Junction *, RuleEntry * );
static int has_guess_block_as_first_item(Junction *);
static int genExprSets(set *, int);
static void genExprTree( Tree *t, int k );
static void genExprTreeOriginal( Tree *t, int k );                  /* MR10 */
static char * findOuterHandlerLabel(ExceptionGroup *eg);            /* MR7 */
static void OutLineInfo(FILE *file,int line,char *fileName);        /* MR14 */
#else
static char *tokenFollowSet();
static ActionNode *findImmedAction();
static void dumpRetValAssign();
static void dumpAfterActions();
static set ComputeErrorSet();
static void makeErrorClause();
static void DumpFuncHeader();
static int has_guess_block_as_first_item();
static int genExprSets();
static void genExprTree();
static void genExprTreeOriginal();                                  /* MR10 */
static char * findOuterHandlerLabel();                              /* MR7 */
static void OutLineInfo();                                          /* MR14 */
#endif

#define gen(s)			{tab(); fprintf(output, s);}
#define gen1(s,a)		{tab(); fprintf(output, s,a);}
#define gen2(s,a,b)		{tab(); fprintf(output, s,a,b);}
#define gen3(s,a,b,c)	{tab(); fprintf(output, s,a,b,c);}
#define gen4(s,a,b,c,d)	{tab(); fprintf(output, s,a,b,c,d);}
#define gen5(s,a,b,c,d,e)	{tab(); fprintf(output, s,a,b,c,d,e);}
#define gen6(s,a,b,c,d,e,f)	{tab(); fprintf(output, s,a,b,c,d,e,f);}
#define gen7(s,a,b,c,d,e,f,g)	{tab(); fprintf(output, s,a,b,c,d,e,f,g);}

#define _gen(s)			{fprintf(output, s);}
#define _gen1(s,a)		{fprintf(output, s,a);}
#define _gen2(s,a,b)	{fprintf(output, s,a,b);}
#define _gen3(s,a,b,c)	{fprintf(output, s,a,b,c);}
#define _gen4(s,a,b,c,d){fprintf(output, s,a,b,c,d);}
#define _gen5(s,a,b,c,d,e){fprintf(output, s,a,b,c,d,e);}
#define _gen6(s,a,b,c,d,e,f){fprintf(output, s,a,b,c,d,e,f);}
#define _gen7(s,a,b,c,d,e,f,g){fprintf(output, s,a,b,c,d,e,f,g);}


/* MR11 a convenient place to set a break point */

#ifdef __USE_PROTOS
void MR_break(void) 
#else
void MR_break() 
#endif
{
  return;
}

/* MR10 genTraceOut(Junction *)      */

#ifdef __USE_PROTOS
static void genTraceOut(Junction *q)
#else
static void genTraceOut(q)
  Junction  *q;
#endif
{
  if ( TraceGen ) {
		if ( GenCC ) {gen1("zzTRACEOUT(\"%s\");\n", q->rname);}
    		else gen1("zzTRACEOUT((ANTLRChar *)\"%s\");\n", q->rname);
  }
}

static void
#ifdef __USE_PROTOS
warn_about_using_gk_option(void)
#else
warn_about_using_gk_option()
#endif
{
	static int warned_already=0;

	if ( !DemandLookahead || warned_already ) return;
	warned_already = 1;
	warnNoFL("-gk option could cause trouble for <<...>>? predicates");
}

void
#ifdef __USE_PROTOS
freeBlkFsets( Junction *q )
#else
freeBlkFsets( q )
Junction *q;
#endif
{
	int i;
	Junction *alt;
	require(q!=NULL, "freeBlkFsets: invalid node");

	for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
	{
		for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]);
	}
}

/*
 * Generate a local variable allocation for each token references
 * in this block.
 */
static void
#ifdef __USE_PROTOS
genTokenPointers( Junction *q )
#else
genTokenPointers( q )
Junction *q;
#endif
{
	/* Rule refs are counted and can be referenced, but their
	 * value is not set to anything useful ever.
	 *
     * The ptrs are to be named _tij where i is the current level
	 * and j is the element number within an alternative.
	 */
	int first=1, t=0;
	set a;
	tokensRefdInBlock = q->tokrefs;

	if ( set_deg(q->tokrefs) == 0 ) return;
	a = set_dup(q->tokrefs);
	gen("ANTLRTokenPtr ");
	for (; !set_nil(a); set_rm(t, a))
	{
		t = set_int(a);
		if ( first ) first = 0;
		else _gen(",");
		if ( !DontCopyTokens ) _gen2("_tv%d%d,", BlkLevel, t);
		_gen2("_t%d%d", BlkLevel, t);
		if ( !DontCopyTokens ) {_gen2("= &_tv%d%d", BlkLevel, t);}
		else _gen("=NULL");
	}
	_gen(";\n");
	set_free(a);
}

static int
#ifdef __USE_PROTOS
hasDefaultException(ExceptionGroup *eg)
#else
hasDefaultException(eg)
ExceptionGroup *eg;
#endif
{
    ListNode *q;

    for (q = eg->handlers->next; q!=NULL; q=q->next)
    {
        ExceptionHandler *eh = (ExceptionHandler *)q->elem;
        if ( strcmp("default", eh->signalname)==0 ) {
            return 1;
        }
    }
    return 0;
}
static void
#ifdef __USE_PROTOS
dumpException(ExceptionGroup *eg, int no_default_case)
#else
dumpException(eg, no_default_case)
ExceptionGroup *eg;
int no_default_case;
#endif
{
    char    *outerLabel;                                             /* MR7 */
    int     altHandler=0;                                            /* MR7 */
    int     namedHandler=0;                                          /* MR7 */

    outerLabel=findOuterHandlerLabel(eg);                            /* MR7 */

    if (eg->label != NULL) {                                         /* MR7 */
      namedHandler=1;                                                /* MR7 */
    } else if (eg->forRule) {                                        /* MR7 */
      /* nothing */                                                  /* MR20 */
    } else {                                                         /* MR7 */
      altHandler=1;                                                  /* MR7 */
    };                                                               /* MR7 */

#if 0
**     if (! eg->used) {                                             /* MR7 */
**     	warnFL("exception group never used",                         /* MR7 */
**             FileStr[eg->altstart->file],eg->altstart->line);      /* MR7 */
**     };                                                            /* MR7 */
#endif

    if (namedHandler) {                                              /* MR7 */
	  gen1("switch ( _signal ) {  /* [%s] */\n",eg->label);          /* MR7 */
    } else {                                                         /* MR7 */
	  gen("switch ( _signal ) {\n");                                 /* MR7 */
      gen("case NoSignal: break;  /* MR7 */\n");                     /* MR7 */
    };                                                               /* MR7 */
	{
		ListNode *q;
		for (q = eg->handlers->next; q!=NULL; q=q->next)
		{
			ExceptionHandler *eh = (ExceptionHandler *)q->elem;
			if ( strcmp("default", eh->signalname)==0 ) {
				gen("default :\n");
				tabs++;
				dumpAction(eh->action, output, tabs, -1, 1, 1);
                gen("_signal=NoSignal;  /* MR7 */\n");                  /* MR7 */
                gen("break;  /* MR7 */\n");                             /* MR7 */
				tabs--;
				gen("}\n");

                /* copied from later code in dumpException */        /* MR7 */

                if (namedHandler) {                                  /* MR7 */
                  gen("if (_signal != NoSignal)");                   /* MR7 */
                  _gen1(" goto %s_handler;  /* MR7 */\n",outerLabel);/* MR7 */
                } else if (altHandler) {                             /* MR7 */
                  gen1("goto %s_handler;  /* MR7 */\n",outerLabel);  /* MR7 */
                };
				return;
			}
			gen1("case %s :\n", eh->signalname);
			tabs++;
			if ( eh->action != NULL )
			{
				dumpAction(eh->action, output, tabs, -1, 1, 1);
                gen("break;  /* MR7 */\n");                          /* MR7 */
			}
			tabs--;
		}
	}
	if ( no_default_case ) return;

	gen("default :\n");
    tabs++;                                                         /* MR7 */
    gen("break;  /* MR7 */\n");                                     /* MR7 */
    tabs--;                                                         /* MR7 */

	tabs++;
/*****	gen("*_retsignal = _signal;\n"); *****/

	tabs--;
	gen("}\n");

    if (namedHandler) {                                             /* MR7 */
      gen("if (_signal != NoSignal)");                              /* MR7 */
      _gen1(" goto %s_handler;  /* MR7 */\n",outerLabel);           /* MR7 */
    } else if (altHandler) {                                        /* MR7 */
      gen1("goto %s_handler;  /* MR7 */\n",outerLabel);             /* MR7 */
    };

}

static void
#ifdef __USE_PROTOS
dumpExceptions(ListNode *list)
#else
dumpExceptions(list)
ListNode *list;
#endif
{
	ListNode *p;

	for (p = list->next; p!=NULL; p=p->next)
	{
		ExceptionGroup *eg = (ExceptionGroup *) p->elem;
		_gen2("%s%s_handler:\n",
			  eg->label==NULL?"":eg->label,
			  eg->altID==NULL?"":eg->altID);
		if ( eg->altID!=NULL ) dumpException(eg, 0);
		else {
			/* This must be the rule exception handler */
			dumpException(eg, 1);
			if ( !hasDefaultException(eg) )
            {
                gen("default :\n");
                tabs++;
                gen("zzdflthandlers(_signal,_retsignal);\n");
                tabs--;
                gen("}\n");
            }
		}
	}
}

/* For each element label that is found in a rule, generate a unique
 * Attribute (and AST pointer if GenAST) variable.
 */
void
#ifdef __USE_PROTOS
genElementLabels(ListNode *list)
#else
genElementLabels(list)
ListNode *list;
#endif
{
	int first=1;
	ListNode *p;

	if ( GenCC ) {gen("ANTLRTokenPtr");}
	else {gen("Attrib");}
	for (p = list->next; p!=NULL; p=p->next)
	{
		char *ep = (char *)p->elem;
		if ( first ) first = 0;
		else _gen(",");
		if ( GenCC ) {_gen1(" %s=NULL",ep);}
		else {_gen1(" %s",ep);}
	}
	_gen(";\n");

	if ( !GenAST ) return;

	first = 1;
	gen("AST");
	for (p = list->next; p!=NULL; p=p->next)
	{
		char *ep = (char *)p->elem;
		if ( first ) first = 0;
		else _gen(",");
		_gen1(" *%s_ast=NULL",ep);
	}
	_gen(";\n");
}

/*
 * Generate a local variable allocation for each token or rule reference
 * in this block.
 */
static void
#ifdef __USE_PROTOS
genASTPointers( Junction *q )
#else
genASTPointers( q )
Junction *q;
#endif
{
	int first=1, t;
	set a;

	a = set_or(q->tokrefs, q->rulerefs);
	if ( set_deg(a) > 0 )
	{
		gen("AST ");
		for (; !set_nil(a); set_rm(t, a))
		{
			t = set_int(a);
			if ( first ) first = 0;
			else _gen(",");
			_gen2("*_ast%d%d=NULL", BlkLevel, t);

⌨️ 快捷键说明

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