📄 ccx.c
字号:
#include "ccx.h"
#include <stdlib.h>
#include <malloc.h>
#include <signal.h>
#include <stdio.h>
#ifndef NULL
#define NULL 0
#endif
//
// come from atexit.c
//
void p_exit(n)
int n;
{
fatalError=n;
return ;
}
//
// come from ccdata.c
//
/*
* parser suite - and / or / nothing / something parsers
*
* parser = [token] -> ([token],status)
*
* implemented as sideeffecting on [token], returns status.
*/
/* globals */
int p_argc;
char **p_argv;
TOKEN *buffer; /* where the pstr points to */
TOKEN *yybuffer; /* internal name for buffer */
VALUE *lvbuff; /* the parallel stack of yylvals */
int fatalError = 0; // flow control
int errorcount = 0; // to use counting errors
int dummy;
INSTRUCTION *program;
STACKVALUE *stack; /* the evaluation stack - either values or
* tokens */
STACKVALUE *value;
FRAME p_frame; /* all one needs to know for a rewind */
FRAME *fstack;
FRAME *fptr;
/* this IS a frame */
TOKEN *pstr; /* parsed stream */
int pc; /* program counter - counts up from 0 */
int passcount=0; /* input lines counted here */
/* end of frame */
INSTRUCTION instr; /* instruction cache */
TOKEN *maxp; /* maximum number parsed so far */
int call_mode = 0; /* flag for call convention. 1 = pascal
* (manual), 0 = C (auto) */
int optimize = 0; /* flag for flying program optimization */
PARSER *p_entry; /* entry point set by p_run & btck_error */
int p_enargs;
PARAM p_eargv[MAXARGS];
PRECC_DATA precc_data;
static VOID mkgen(void**, void**, int, int);
static VOID freegen(void**);
static VOID mkgen (s,v,n,m)
void **s, **v;
int n;
int m;
/* if *s, make a generic item of size n*m and put it in *v and *s */
{
if (*s != NULL)
return;
*s = (void *) p_calloc (n, m);
*v = *s;
}
VOID mkstack ()
/* make the attribute stack of the right sizes and install it */
{
mkgen ((void**)&stack, (void**)&value, precc_data.stacksize, sizeof(STACKVALUE));
}
static VOID freegen (s)
void **s;
{
if (*s == NULL)
return;
p_free (*s);
*s = NULL; /* so that we don't try freeing it twice */
}
VOID freestack ()
{
freegen ((void**)&stack);
}
VOID p_creat_data ()
/* we think one of the stacks at least is NULL, and we try and alloc it */
{
long bytesfree;
bytesfree = p_memleft ();
/* but which stack is it? */
/* compilation warnings for maybe losing digits from the args of
* p_calloc should always be ignored. The numbers can't be that big! */
mkgen ((void**)&buffer, (void**)&buffer, precc_data.readbuffersize,sizeof(TOKEN));
mkgen ((void**)&lvbuff, (void**)&lvbuff, precc_data.readbuffersize,sizeof(VALUE));
mkgen ((void**)&program, (void**)&program, precc_data.maxprogramsize,
sizeof(INSTRUCTION));
mkgen ((void**)&stack, (void**)&value, precc_data.stacksize, sizeof(STACKVALUE));
mkgen ((void**)&fstack, (void**)&fptr, precc_data.contextstacksize,sizeof(FRAME));
if (buffer == NULL || lvbuff == NULL ||
program == NULL || stack == NULL || fstack == NULL)
{
//fprintf (stderr,
//"error; not enough memory (%lu) for internal stacks\n", bytesfree);
p_exit (11);
}
return;
}
VOID p_destr_data ()
{
freegen ((void**)&buffer);
freegen ((void**)&lvbuff);
freegen ((void**)&program);
freegen ((void**)&stack);
freegen ((void**)&fstack);
}
//
// come from common.c
//
STATUS p_nothing0 ()
/*
p_parser succeeds without looking at any tokens from
the input stream.
*/
{
pushINCR;
return SUCCESS;
}
STATUS p_anything0 ()
/*
Parser which takes any token at all - except 0 - and places it as
a constant on the program stack. This p_parser only fails at EOS.
*/
{
TOKEN c;
VALUE v;
c = *pstr;
v = lvbuff[(int)(pstr-buffer)];
/*if (c) */
if (yytchar != EOF) /* need to be here by ..sang */
{
MOVEON;
pushVALUE(v);
return OK(v); /* so CAN'T use attribute 0 */
}
return FAILURE;
}
STATUS p_first0 ()
/*
This p_parser only succeeds at BOS and does nothing
*/
{ /* pstr CAN'T be < buffer. I am just being careful */
if ((void*)pstr <= (void*)buffer || pstr[-1]==(TOKEN)0) {
pushVALUE(SUCCESS);
return SUCCESS;
}
/* doesnt move on */
return FAILURE;
}
STATUS p_uerror0 (p)
/* return OK but set a frame boundary and an error handler parser p */
PARSER *p;
{
pushEXIT;
pc=0;
pc=p_evaluate ();
pc=0; /* we have to write the next program in the right place */
/* we can't reset the pstr at present. Only when we get a backtrack
can we seem to be able to do it, perhaps because that's like an escape to top level, where
we do reset the pstr every time. The problem is MAYBE that earlier
sequents are holding frame info which points into the pstr as
it is now. OK, we can't backtrack to them, but still ...
-- hmm. this may be past history now.
*/
/* why am I looking to skip the 0 token here? Surely it is
* just like any other token?
*/
/*printf("\n..");*/
{
realignbuffer();
}
passcount++; /* that means that a backtrack error will be
signalled if we try and backtrack through here */
p_enargs= 0;
p_entry = p; /* set the btck_error reentry pt */
/* Uh, not at all sure about the next, folks! - we won't backtrack
* but we are still inside various andparse things that will all
* try and pop the frame stack as they exit!!
*/
return (SUCCESS);
/* and don't reset STACKVALUE *value because we may later backtrack
* to earlier stack values - hey, that's past history now too!
* We don't have an attribute stack any more. */
}
STATUS p_uniq0 ()
{
return p_uerror0(0);
}
STATUS p_last0 ()
/* ** character mode only **
This p_parser only succeeds at EOS.
*/
{
if ((yytchar!=EOF) && (0 == *pstr)) /* does move on */
{
MOVEON;
pushVALUE(EOF);
/* the MOVEON did the pull of a token into the lookahead buff */
return OK(EOF);
}
return FAILURE;
}
STATUS p_exactly0 (c)
/*
this parser only succeeds when given token c.
It places the token's attribute as a literal on the program stack,
but not on the value stack. It gets put onto the latter at
runtime. It's also the return value, and a NULL attrib is changed
according to the OK macro to prevent a FAIL return in those cases.
*/
TOKEN c;
{
VALUE v;
if (*pstr == c)
{ /* read the attribute value */
v=lvbuff[(int)(pstr-buffer)];
MOVEON;
pushVALUE(v); /* save the attribute on the program stack */
return OK(v);
}
return FAILURE;
}
STATUS p_notexactly0 (c)
/*
this p_parser only succeds when given a TOKEN not equal to c.
It places the token's attribute as a literal on the program stack.
*/
TOKEN c;
{
VALUE v;
if (*pstr != c)
{
c=*pstr;
v=lvbuff[(int)(pstr-buffer)];
MOVEON;
pushVALUE(v);
return OK(v);
}
return FAILURE;
}
STATUS p_attach0 (p)
PARSER *p;
{
return (*p) ();
}
STATUS p_atch0 (v)
PARAM v;
/*
trivial parser which returns a fixed value
*/
{
return OK((VALUE)v);
}
VOID p_nop()
/*
a very trivial stack manipulation action
*/
{
}
/*
parser suite - and / or / nothing / something parsers
parser = [token] -> ([token],status)
implemented as sideeffecting on [token], returns status.
*/
//
// come from ccx.c
//
static PARAM a0[MAXARGS], *a=a0; /* holds parameters */
STATUS p_errparse0 ()
/* I'm just here to help detect errors */
{
//fprintf(stderr,"An unspecified parser has been called. Aborting.\n");
p_exit(12);
/* this is never called */
return FAILURE;
}
STATUS p_andparse0n (PARSER *p, ...)
/*
Serial composition of parsers. Does
first p then q. Put p's instructions on the
top of the program stack, then layer q's above
it.
This version has full rewind of the input stream on
failure, but this can be altered to single token
lookahead by deleting the line of code marked.
*/
{
static PARSER *q=p_errparse0;
va_list ap;
static int m;
static status tok;
MARK;
va_start(ap,p);
m=va_arg(ap,int);
a=(PARAM*)ap; /* very NON-PORTABLE, but it's fast */
ap=(va_list)&a[m];
m++;
switch(m-1) {
case 0: tok=(*p)();break;
case 1: tok=(*p)(a[0]);break;
case 2: tok=(*p)(a[0],a[1]);break;
case 3: tok=(*p)(a[0],a[1],a[2]);break;
case 4: tok=(*p)(a[0],a[1],a[2],a[3]);break;
case 5: tok=(*p)(a[0],a[1],a[2],a[3],a[4]);break;
case 6: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5]);break;
case 7: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);break;
case 8: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);break;
case 9: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);break;
case 10: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);break;
case 11: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10]);break;
case 12: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11]);
break;
case 13: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],
a[12]);break;
case 14: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],
a[12],a[13]);break;
case 15: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],
a[12],a[13],a[14]);break;
case 16: tok=(*p)(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],
a[12],a[13],a[14],a[15]);break;
default: p_exit(13);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -