📄 preccx.y
字号:
# define TOKEN char# define VALUE char*# define STACKTOKENS 1# define STACKSIZE 2048# define BEGIN p_begin()# include "cc.h"# include "preccx.h"# undef UNSETNAME# include "preamble.h"char* p_infile, /* stdin name (eventually "-" if not a file) */ * p_outfile; /* stdout name (eventually "-" if not a file) */int p_begin(){ static int passes; /* no. of times re-entered MAIN */ int narg; /* no of command line args */ int nswitch; /* count of command line switches */ int switches; /* flag - when doing command line switches */ int dup2(); if(passes++==0){ /* print motto */ printf("\n\/* PRE-CC %.2f compiler-compiler \n\ * Copyright Peter Breuer 1989-1994\n\ * <ptb@eng.cam.ac.uk> Tel +44 (0)223 68682\n\ * <ptb@comlab.ox.ac.uk> <ptb@dit.upm.es>\n\ */\n\",__PRECC__); call_mode=1;/* set no-auto shift in value stack */ dup2(0,5); /* save stdin and stdout */ dup2(1,6); nswitch=0; /* begin command line processing */ switches=1; for (narg=1;narg<p_argc;narg++){ switch(p_argv[narg][0]){ case '-': if(!switches) /* mixed switches and files */ usage (1); nswitch++; switch(p_argv[narg][1]){ case 'r': /* read buffer size in Kb */ getkintarg(p_argv[narg]+2,&precc_data.readbuffersize, sizeof (TOKEN) + sizeof (VALUE)); break; case 'p': /* internal program length in Kb */ getkintarg(p_argv[narg]+2,&precc_data.maxprogramsize, sizeof (VALUE)); break; case 'v': /* internal VALUE stack size in Kb */ getkintarg(p_argv[narg]+2,&precc_data.stacksize, sizeof (STACKVALUE)); break; case 'f': /* internal FRAME stack size in Kb */ getkintarg(p_argv[narg]+2,&precc_data.contextstacksize, sizeof (FRAME)); case 'o': /* internal FRAME stack size in Kb */ if (0==strcmp(p_argv[narg]+1,"old")) precc_data.oldattributes=1; else precc_data.oldattributes=0; break; default: /* unknown option */ usage(3); } break; default: switches=0; /* end of switches */ break; } } /* now deal with redirects */ p_infile = p_outfile = "-"; /* in and out file names */ switch(p_argc-1-nswitch){ case 2: if (freopen(p_outfile=p_argv[nswitch+2], "w", stdout)==NULL) usage (2); case 1: if (freopen(p_infile=p_argv[nswitch+1], "r", stdin)==NULL) usage (5); case 0: break; default: /* too many files named */ usage (6); } } return 0; /* success */}char *envs[PSTACKLENGTH]; /*environment stack*/char *plvs[PSTACKLENGTH]; /*plainenv stack*/int ecount=0; /*pointer */int countstack[PSTACKLENGTH]; /*stack of number of sequents we have seen */int countcount =0; /*pointer */void pushenv()/* save the current environment and begin another */{ ecount++;}void popenv()/* release the current env and recall the old */{ ecount--;}void pushcount()/* save the current count of sequents and begin another */{ countcount++; /* the next line disambiguates references in blocks, but that is * probably not what is wanted. */ /* count = countcount*PSTACKLENGTH + 1; */ /* this next line does no disambiguation * and therefore causes warnings from C code, * but it doesn't matter. */ count = 1;}void popcount()/* release the current count of sequents and recall the old */{ countcount--;}int getcount()/* return the current count level for sequents */{ return countcount;} /* -- idens with params ------- */@ nameplusargs = IDENTIFIER [ rdbrktargs :VV(2)=V(1);:] @ nameplusvars = IDENTIFIER [ rdbrktvars :VV(2)=V(1);:] @ sqbrktargs = openbracket@ WHITESPACE someargs WHITESPACE@ closebracket :VV(5)=V(3);: @ rdbrktargs = openparen@ WHITESPACE theargs WHITESPACE@ closeparen :VV(5)=V(3);: @ rdbrktvars = openparen@ WHITESPACE thevars WHITESPACE@ closeparen :VV(5)=V(3);: /* these are token-driven writes */@ openparen = OPENPAREN : VV(1) = putchar(T(1)); :@ closeparen = CLOSEPAREN : VV(1) = putchar(T(1)); :@ openbracket = OPENBRACKET : VV(1) = putchar(T(1)); :@ closebracket = CLOSEBRACKET : VV(1) = putchar(T(1)); :@ theargs = someargs@ | : VV(0)=""; :@ thevars = somevars@ | : VV(0)=""; :@ comma = COMMA : VV(1)=putchar(','); :@ someargs =expr {WHITESPACE comma WHITESPACE expr :VV(5)=V(1);:}*@ somevars =var {WHITESPACE comma WHITESPACE var :VV(5)=V(1);:}*@ var = IDENTIFIER@ :if(*putargs(""))putargs(",");putargs("PARAM ");putargs(V(1));@ if(*putmeta(""))putmeta(",");putmeta(V(1));: /* -- parser identifiers --- *//* collect IDENTIFIERs from buffers */void SETENV()/* seal the current environment to be whats in the buffers now */{ environment=putargs(""); plainenv=putmeta(""); getargs(&environment); getmeta(&plainenv);}char *LASTVAR()/* last variable in the current environment */{char *s;if (ecount<0) return NULL;s = strchr(plainenv,',');if (!s) return plainenv;return s+1;}/* first item written in a declaration block */@ declname = nameplusvars :getname(&V(1));SETENV();:/* to make #line references to definitions immediately before the FIRST STATUS foo line in the emitted code, insert P_LINE; before the getname above *//* collect a domain IDENTIFIER in the same way */@ exprname = nameplusargs :getname(&V(1));: /* -- start of precc defn ---- */@ declaration = ^ AT !{declerr} WHITESPACE declname@ WHITESPACE EQUALS WHITESPACE@ expression WHITESPACE@ :VV(10) = P_REN(V(5),V(9));countcount=0;RESET;:void ADDVAR(char *x)/* make a new environment with one more var. save the old. */{ char *n; /* finish off current env */ getargs(&n); getmeta(&n); /* copy old to new - start by buffering it */ putargs(environment); putmeta(plainenv); /* increment env count */ pushenv(); /* point env at buffer */ environment=putargs(""); plainenv=putmeta(""); /* add new var */ if (is_in(x,plainenv)) return; /* unless already there */ if(*environment){ putargs(","); putmeta(","); } putargs("PARAM "); putargs(x); putmeta(x); /* note that the buffer is still unterminated */}/* to make #line references to definitions immediately before the STATUS foo line in the emitted code, insert P_LINE; before the VV above */@ declerr = printdeclerr@ passthrough :VV(2)=V(1);:@ printdeclerr = :VV(0)="@";@ printf("line %d error: malformed declaration\n@?",yylineno);: /* that was it. Now the top level (MAIN) parse. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -