Add in the 1st version of ECP.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2832 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qwang12
2007-06-28 07:00:39 +00:00
parent 30d4a0c7ec
commit 3eb9473ea9
1433 changed files with 266617 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
=======================================================
Known Problems In PCCTS - Last revised 14 November 1998
=======================================================
#14. Parsing bug in dlg
THM: I have been unable to reproduce this problem.
Reported by Rick Howard Mijenix Corporation (rickh@mijenix.com).
The regular expression parser (in rexpr.c) fails while
trying to parse the following regular expression:
{[a-zA-Z]:}(\\\\[a-zA-Z0-9]*)+
See my comment in the following excerpt from rexpr.c:
/*
* <regExpr> ::= <andExpr> ( '|' {<andExpr>} )*
*
* Return -1 if syntax error
* Return 0 if none found
* Return 1 if a regExrp was found
*/
static
regExpr(g)
GraphPtr g;
{
Graph g1, g2;
if ( andExpr(&g1) == -1 )
{
return -1;
}
while ( token == '|' )
{
int a;
next();
a = andExpr(&g2);
if ( a == -1 ) return -1; /* syntax error below */
else if ( !a ) return 1; /* empty alternative */
g1 = BuildNFA_AorB(g1, g2);
}
if ( token!='\0' ) return -1;
*****
***** It appears to fail here becuause token is 125 - the closing '}'
***** If I change it to:
***** if ( token!='\0' && token!='}' && token!= ')' ) return -1;
*****
***** It succeeds, but I'm not sure this is the corrrect approach.
*****
*g = g1;
return 1;
}
#13. dlg reports an invalid range for: [\0x00-\0xff]
Diagnosed by Piotr Eljasiak (eljasiak@no-spam.zt.gdansk.tpsa.pl):
Fixed in MR16.
#12. Strings containing comment actions
Sequences that looked like C style comments appearing in string
literals are improperly parsed by antlr/dlg.
<< fprintf(out," /* obsolete */ ");
For this case use:
<< fprintf(out," \/\* obsolete \*\/ ");
Reported by K.J. Cummings (cummings@peritus.com).
#11. User hook for deallocation of variables on guess fail
The mechanism outlined in Item #108 works only for
heap allocated variables.
#10. Label re-initialization in ( X {y:Y} )*
If a label assignment is optional and appears in a
(...)* or (...)+ block it will not be reset to NULL
when it is skipped by a subsequent iteration.
Consider the example:
( X { y:Y })* Z
with input:
X Y X Z
The first time through the block Y will be matched and
y will be set to point to the token. On the second
iteration of the (...)* block there is no match for Y.
But y will not be reset to NULL, as the user might
expect, it will contain a reference to the Y that was
matched in the first iteration.
The work-around is to manually reset y:
( X << y = NULL; >> { y:Y } )* Z
or
( X ( y:Y | << y = NULL; >> /* epsilon */ ) )* Z
Reported by Jeff Vincent (JVincent@novell.com).
#9. PCCTAST.h PCCTSAST::setType() is a noop
#8. #tokdefs with ~Token and .
THM: I have been unable to reproduce this problem.
When antlr uses #tokdefs to define tokens the fields of
#errclass and #tokclass do not get properly defined.
When it subsequently attempts to take the complement of
the set of tokens (using ~Token or .) it can refer to
tokens which don't have names, generating a fatal error.
#7. DLG crashes on some invalid inputs
THM: In MR20 have fixed the most common cases.
The following token defintion will cause DLG to crash.
#token "()"
Reported by Mengue Olivier (dolmen@bigfoot.com).
#6. On MS systems \n\r is treated as two new lines
Fixed.
#5. Token expressions in #tokclass
#errclass does not support TOK1..TOK2 or ~TOK syntax.
#tokclass does not support ~TOKEN syntax
A workaround for #errclass TOK1..TOK2 is to use a
#tokclass.
Reported by Dave Watola (dwatola@amtsun.jpl.nasa.gov)
#4. A #tokdef must appear "early" in the grammar file.
The "early" section of the grammar file is the only
place where the following directives may appear:
#header
#first
#tokdefs
#parser
Any other kind of statement signifiies the end of the
"early" section.
#3. Use of PURIFY macro for C++ mode
Item #93 of the CHANGES_FROM_1.33 describes the use of
the PURIFY macro to zero arguments to be passed by
upward inheritance.
#define PURIFY(r, s) memset((char *) &(r), '\0', (s));
This may not be the right thing to do for C++ objects that
have constructors. Reported by Bonny Rais (bonny@werple.net.au).
For those cases one should #define PURIFY to be an empty macro
in the #header or #first actions.
#2. Fixed in 1.33MR10 - See CHANGES_FROM_1.33 Item #80.
#1. The quality of support for systems with 8.3 file names leaves
much to be desired. Since the kit is distributed using the
long file names and the make file uses long file names it requires
some effort to generate. This will probably not be changed due
to the large number of systems already written using the long
file names.

View File

@@ -0,0 +1,171 @@
---------------------------------------------------------------------------------
README for pccts 1.33mr20 (Maintenance Release #20) release date 5 August 1999
---------------------------------------------------------------------------------
Parr Research Corporation
with
Purdue University Electrical Engineering
and
University of Minnesota, AHPCRC
Terence Parr
Russell Quong
Will Cohen
Hank Dietz
A central place for information about PCCTS 1.33 is:
http://www.polhode.com/pccts.html
The maintenance release is available from:
http://www.polhode.com/pccts133mr.zip
There is a ready-to-run version for win32 for Microsoft Visual Studio
at the same site. It is available from:
http://www.polhode.com/win32.zip
There is a newsgroup dedicated to pccts 1.33 and related topics:
comp.compilers.tools.pccts
You may also want to register for the antlr-interest mailing list
which is provided gratis by the following service:
http://www.onesite.com
New users should visit http://www.polhode.com/pccts.html in
order to get the following document:
"Notes For New Users of PCCTS"
This is a Postscript file of about 40 pages which is extremely
useful for someone starting out. It is a based on 1.33mr7 so is a
little bit out-of-date. The section on semantic predicates is
very out of date, but I have not had time to revise it.
When you have a little more experience, be sure to review the
following documents in the distribution kit:
CHANGES_FROM_133.txt
CHANGES_FROM_133_BEFORE_MR13.txt
KNOWN_PROBLEMS.txt
-------------------------------------------------------------------------
INSTALLATION (Unix)
-------------------------------------------------------------------------
0. Download http://www.polhode.com/pccts133mr.zip
1. Unzip the distribution kit to your preferred location.
2. cd to the main pccts directory.
3. make
This will create:
antlr.exe
dlg.exe
sorcerer.exe
genmk.exe
4. Add pccts/bin to your path.
5. To get an up-to-date list of program options execute the
program with no command line options. To get up-to-date
documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt
at:
http://www.polhode.com/pccts.html.
6. You need not create a library. The makefile created by genmk
assumes that the files are not part of a library.
If you wish to create a library from elements of pccts/h:
If the first letter of the filename is lowercase (uppercase) it is
related to the code generated using the pccts C mode (C++ mode).
Some of the .c and .cpp files in the h directory are not meant to
be placed in a library and will not compile because they are meant
to be #include in pccts generated files which are grammar specific.
For C++ users place the following elements in the library:
AParser.cpp
ASTBase.cpp
ATokenBuffer.cpp
BufFileInput.cpp (optional)
DLexerBase.cpp
PCCTSAST.cpp
SList.cpp
-------------------------------------------------------------------------
INSTALLATION (Win32)
-------------------------------------------------------------------------
I've tried to keep the win32 kit to the minimum necessary to get
up and running. The complete kit contains additional information
(some historical), source code, and DevStudio projects for
rebuilding pccts from the source code.
The kit is now distributed with both MSVC 5 and MSVC6 style projects.
0. Download http://www.polhode.com/win32.zip.
You may also wish to download:
http://www.polhode.com/CHANGES_FROM_133.txt
http://www.polhode.com/CHANGES_FROM_133_BEFORE_MR13.txt
http://www.polhode.com/KNOWN_PROBLEMS.txt
1. Unzip the distribution kit to your preferred location.
This will create:
a pccts directory tree
pccts/bin/*.exe
pccts/lib/*.lib
pccts/h/*
sorcerer/lib/*
sorcerer/h/*
an example directory tree
example\calcAST\*
example\simple\*
2. Define the environment variable PCCTS to point to the main
pccts directory.
3. Try building the simple project: example\simple\simple50.dsw
or simple60.dsw.
4. Try building the complex project: example\calcAST\calcAST50.dsw
or calcAST60.dsw.
-------------------------------------------------------------------------
INSTALLATION (DEC/VMS)
-------------------------------------------------------------------------
DEC/VMS support added by Pi<50>ronne Jean-Fran<61>ois (jfp@altavista.net)
0. Download http://www.polhode.com/pccts133mr.zip
1. Unzip the distribution kit to your preferred location.
2. set default to the main pccts directory.
3. @makefile.vms
This will create in directory [.bin]:
antlr.exe
dlg.exe
sorcerer.exe
genmk.exe
5. To get an up-to-date list of program options execute the
program with no command line options. To get up-to-date
documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt
at http://www.polhode.com/pccts.html.

View File

@@ -0,0 +1,815 @@
/* ANTLRParser.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-1998
*/
#include "pcctscfg.h"
#include "pccts_stdlib.h"
#include "pccts_stdarg.h"
#include "pccts_string.h"
#include "pccts_stdio.h"
PCCTS_NAMESPACE_STD
/* I have to put this here due to C++ limitation
* that you can't have a 'forward' decl for enums.
* I hate C++!!!!!!!!!!!!!!!
* Of course, if I could use real templates, this would go away.
*/
// MR1
// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the
// MR1 ANTLRTokenType enum
// MR1
enum ANTLRTokenType { TER_HATES_CPP=0, ITS_TOO_COMPLICATED=9999}; // MR1
#define ANTLR_SUPPORT_CODE
#include ATOKEN_H
#include ATOKENBUFFER_H
#include APARSER_H
static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000; /* MR14 */
static const int zzINF_BUFFER_TOKEN_CHUNK_SIZE = 1000; /* MR14 */
/* L o o k a h e a d M a c r o s */
/* maximum of 32 bits/unsigned int and must be 8 bits/byte;
* we only use 8 bits of it.
*/
SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = {
0x00000001, 0x00000002, 0x00000004, 0x00000008,
0x00000010, 0x00000020, 0x00000040, 0x00000080
};
char ANTLRParser::eMsgBuffer[500] = "";
ANTLRParser::
~ANTLRParser()
{
delete [] token_type;
delete [] zzFAILtext; // MR16 Manfred Kogler
}
ANTLRParser::
ANTLRParser(ANTLRTokenBuffer *_inputTokens,
int k,
int use_inf_look,
int dlook,
int ssize)
{
LLk = k;
can_use_inf_look = use_inf_look;
/* MR14 */ if (dlook != 0) {
/* MR14 */ panic("ANTLRParser::ANTLRParser - Demand lookahead not supported in C++ mode");
/* MR14 */
/* MR14 */ };
demand_look = 0; /* demand_look = dlook; */
bsetsize = ssize;
guessing = 0;
token_tbl = NULL;
eofToken = (ANTLRTokenType)1;
// allocate lookahead buffer
token_type = new ANTLRTokenType[LLk];
lap = 0;
labase = 0;
#ifdef ZZDEFER_FETCH
stillToFetch = 0; // MR19
#endif
dirty = 0;
inf_labase = 0; // MR7
inf_last = 0; // MR7
/* prime lookahead buffer, point to inputTokens */
this->inputTokens = _inputTokens;
this->inputTokens->setMinTokens(k);
_inputTokens->setParser(this); // MR1
resynchConsumed=1; // MR8
zzFAILtext=NULL; // MR9
traceOptionValueDefault=0; // MR10
traceReset(); // MR10
zzGuessSeq=0; // MR10
syntaxErrCount=0; // MR11
}
void ANTLRParser::init()
{
prime_lookahead();
resynchConsumed=1; // MR8
traceReset(); // MR10
}
void ANTLRParser::traceReset()
{
traceOptionValue=traceOptionValueDefault;
traceGuessOptionValue=1;
traceCurrentRuleName=NULL;
traceDepth=0;
}
int ANTLRParser::
guess(ANTLRParserState *st)
{
saveState(st);
guessing = 1;
return setjmp(guess_start.state);
}
void ANTLRParser::
saveState(ANTLRParserState *buf)
{
buf->guess_start = guess_start;
buf->guessing = guessing;
buf->inf_labase = inf_labase;
buf->inf_last = inf_last;
buf->dirty = dirty;
buf->traceOptionValue=traceOptionValue; /* MR10 */
buf->traceGuessOptionValue=traceGuessOptionValue; /* MR10 */
buf->traceCurrentRuleName=traceCurrentRuleName; /* MR10 */
buf->traceDepth=traceDepth; /* MR10 */
}
void ANTLRParser::
restoreState(ANTLRParserState *buf)
{
int i;
int prevTraceOptionValue;
guess_start = buf->guess_start;
guessing = buf->guessing;
inf_labase = buf->inf_labase;
inf_last = buf->inf_last;
dirty = buf->dirty;
// restore lookahead buffer from k tokens before restored TokenBuffer position
// if demand_look, then I guess we don't look backwards for these tokens.
for (i=1; i<=LLk; i++) token_type[i-1] =
inputTokens->bufferedToken(i-LLk)->getType();
lap = 0;
labase = 0;
/* MR10 */
prevTraceOptionValue=traceOptionValue;
traceOptionValue=buf->traceOptionValue;
if ( (prevTraceOptionValue > 0) !=
(traceOptionValue > 0)) {
if (traceCurrentRuleName != NULL) { /* MR21 */
if (traceOptionValue > 0) {
fprintf(stderr,
"trace enable restored in rule %s depth %d\n",
traceCurrentRuleName,
traceDepth);
};
if (traceOptionValue <= 0) {
fprintf(stderr,
"trace disable restored in rule %s depth %d\n",
traceCurrentRuleName, /* MR21 */
traceDepth);
};
}
};
traceGuessOptionValue=buf->traceGuessOptionValue;
traceCurrentRuleName=buf->traceCurrentRuleName;
traceDepth=buf->traceDepth;
traceGuessDone(buf);
}
/* Get the next symbol from the input stream; put it into lookahead buffer;
* fill token_type[] fast reference cache also. NLA is the next place where
* a lookahead ANTLRAbstractToken should go.
*/
void ANTLRParser::
consume()
{
#ifdef ZZDEBUG_CONSUME_ACTION
zzdebug_consume_action();
#endif
// MR19 V.H. Simonis
// Defer Fetch feature
// Moves action of consume() into LA() function
#ifdef ZZDEFER_FETCH
stillToFetch++;
#else
NLA = inputTokens->getToken()->getType();
dirty--;
lap = (lap+1)&(LLk-1);
#endif
}
_ANTLRTokenPtr ANTLRParser::
LT(int i)
{
// MR19 V.H. Simonis
// Defer Fetch feature
// Moves action of consume() into LA() function
#ifdef ZZDEFER_FETCH
undeferFetch();
#endif
#ifdef DEBUG_TOKENBUFFER
if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */
{
char buf[2000]; /* MR20 Was "static" */
sprintf(buf, "The minimum number of tokens you requested that the\nANTLRTokenBuffer buffer is not enough to satisfy your\nLT(%d) request; increase 'k' argument to constructor for ANTLRTokenBuffer\n", i);
panic(buf);
}
#endif
return inputTokens->bufferedToken(i-LLk);
}
void
ANTLRParser::
look(int k)
{
int i, c = k - (LLk-dirty);
for (i=1; i<=c; i++) consume();
}
/* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK);
*/
void
ANTLRParser::
prime_lookahead()
{
int i;
for(i=1;i<=LLk; i++) consume();
dirty=0;
// lap = 0; // MR14 Sinan Karasu (sinan.karasu@boeing.com)
// labase = 0; // MR14
labase=lap; // MR14
}
/* check to see if the current input symbol matches '_t'.
* During NON demand lookahead mode, dirty will always be 0 and
* hence the extra code for consuming tokens in _match is never
* executed; the same routine can be used for both modes.
*/
int ANTLRParser::
_match(ANTLRTokenType _t, ANTLRChar **MissText,
ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
SetWordType **MissSet)
{
if ( dirty==LLk ) {
consume();
}
if ( LA(1)!=_t ) {
*MissText=NULL;
*MissTok= _t; *BadTok = LT(1);
*MissSet=NULL;
return 0;
}
dirty++;
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
return 1;
}
/* check to see if the current input symbol matches '_t'.
* Used during exception handling.
*/
int ANTLRParser::
_match_wsig(ANTLRTokenType _t)
{
if ( dirty==LLk ) {
consume();
}
if ( LA(1)!=_t ) return 0;
dirty++;
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
return 1;
}
/* check to see if the current input symbol matches any token in a set.
* During NON demand lookahead mode, dirty will always be 0 and
* hence the extra code for consuming tokens in _match is never
* executed; the same routine can be used for both modes.
*/
int ANTLRParser::
_setmatch(SetWordType *tset, ANTLRChar **MissText,
ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
SetWordType **MissSet)
{
if ( dirty==LLk ) {
consume();
}
if ( !set_el(LA(1), tset) ) {
*MissText=NULL;
*MissTok= (ANTLRTokenType)0; *BadTok=LT(1);
*MissSet=tset;
return 0;
}
dirty++;
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
return 1;
}
int ANTLRParser::
_setmatch_wsig(SetWordType *tset)
{
if ( dirty==LLk ) {
consume();
}
if ( !set_el(LA(1), tset) ) return 0;
dirty++;
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
return 1;
}
/* Exception handling routines */
//
// 7-Apr-97 133MR1
// Change suggested by Eli Sternheim (eli@interhdl.com)
//
void ANTLRParser::
consumeUntil(SetWordType *st)
{
ANTLRTokenType tmp; // MR1
const int Eof=1; // MR1
while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); } // MR1
}
//
// 7-Apr-97 133MR1
// Change suggested by Eli Sternheim (eli@interhdl.com)
//
void ANTLRParser::
consumeUntilToken(int t)
{
int tmp; // MR1
const int Eof=1; // MR1
while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); } // MR1
}
/* Old error stuff */
void ANTLRParser::
resynch(SetWordType *wd,SetWordType mask)
{
/* MR8 S.Bochnak@microtool.com.pl */
/* MR8 Change file scope static "consumed" to instance var */
/* if you enter here without having consumed a token from last resynch
* force a token consumption.
*/
/* MR8 */ if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;}
/* if current token is in resynch set, we've got what we wanted */
/* MR8 */ if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;}
/* scan until we find something in the resynch set */
while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();}
/* MR8 */ resynchConsumed=1;
}
/* standard error reporting function that assumes DLG-based scanners;
* you should redefine in subclass to change it or if you use your
* own scanner.
*/
void ANTLRParser::
syn(_ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
ANTLRTokenType etok, int k)
{
int line;
line = LT(1)->getLine();
syntaxErrCount++; /* MR11 */
fprintf(stderr, "line %d: syntax error at \"%s\"",
line,
(LA(1)==eofToken && LT(1)->getText()[0] == '@')?
"<eof>":LT(1)->getText() /* MR21a */);
if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
if ( k==1 ) fprintf(stderr, " missing");
else
{
fprintf(stderr, "; \"%s\" not", LT(1)->getText());
if ( set_deg(eset)>1 ) fprintf(stderr, " in");
}
if ( set_deg(eset)>0 ) edecode(eset);
else fprintf(stderr, " %s", token_tbl[etok]);
if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup);
fprintf(stderr, "\n");
}
/* is b an element of set p? */
int ANTLRParser::
set_el(ANTLRTokenType b, SetWordType *p)
{
return( p[DIVWORD(b)] & bitmask[MODWORD(b)] );
}
int ANTLRParser::
set_deg(SetWordType *a)
{
/* Fast compute degree of a set... the number
of elements present in the set. Assumes
that all word bits are used in the set
*/
register SetWordType *p = a;
register SetWordType *endp = &(a[bsetsize]);
register int degree = 0;
if ( a == NULL ) return 0;
while ( p < endp )
{
register SetWordType t = *p;
register SetWordType *b = &(bitmask[0]);
do {
if (t & *b) ++degree;
} while (++b < &(bitmask[sizeof(SetWordType)*8]));
p++;
}
return(degree);
}
void ANTLRParser::
edecode(SetWordType *a)
{
register SetWordType *p = a;
register SetWordType *endp = &(p[bsetsize]);
register unsigned e = 0;
if ( set_deg(a)>1 ) fprintf(stderr, " {");
do {
register SetWordType t = *p;
register SetWordType *b = &(bitmask[0]);
do {
if ( t & *b ) fprintf(stderr, " %s", token_tbl[e]);
e++;
} while (++b < &(bitmask[sizeof(SetWordType)*8]));
} while (++p < endp);
if ( set_deg(a)>1 ) fprintf(stderr, " }");
}
/* input looks like:
* zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk)
* where the zzMiss stuff is set here to the token that did not match
* (and which set wasn't it a member of).
*/
// MR9 29-Sep-97 Stan Bochnak (S.Bochnak@microTool.com.pl)
// MR9 Original fix to static allocated text didn't
// MR9 work because a pointer to it was passed back
// MR9 to caller. Replace with instance variable.
const int SETWORDCOUNT=20;
void
ANTLRParser::FAIL(int k, ...)
{
//
// MR1 10-Apr-97
//
if (zzFAILtext == NULL) zzFAILtext=new char [1000]; // MR9
SetWordType **f=new SetWordType *[SETWORDCOUNT]; // MR1 // MR9
SetWordType **miss_set;
ANTLRChar **miss_text;
_ANTLRTokenPtr *bad_tok;
ANTLRChar **bad_text;
//
// 7-Apr-97 133MR1
// err_k is passed as a "int *", not "unsigned *"
//
int *err_k; // MR1
int i;
va_list ap;
va_start(ap, k);
zzFAILtext[0] = '\0';
if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer");
for (i=1; i<=k; i++) /* collect all lookahead sets */
{
f[i-1] = va_arg(ap, SetWordType *);
}
for (i=1; i<=k; i++) /* look for offending token */
{
if ( i>1 ) strcat(zzFAILtext, " ");
strcat(zzFAILtext, LT(i)->getText());
if ( !set_el(LA(i), f[i-1]) ) break;
}
miss_set = va_arg(ap, SetWordType **);
miss_text = va_arg(ap, ANTLRChar **);
bad_tok = va_arg(ap, _ANTLRTokenPtr *);
bad_text = va_arg(ap, ANTLRChar **);
err_k = va_arg(ap, int *); // MR1
if ( i>k )
{
/* bad; lookahead is permutation that cannot be matched,
* but, the ith token of lookahead is valid at the ith position
* (The old LL sub 1 (k) versus LL(k) parsing technique)
*/
*miss_set = NULL;
*miss_text = LT(1)->getText();
*bad_tok = LT(1);
*bad_text = (*bad_tok)->getText();
*err_k = k;
//
// MR4 20-May-97 erroneously deleted contents of f[]
// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)
// MR1 10-Apr-97 release temporary storage
//
delete [] f; // MR1
return; // MR1
}
/* fprintf(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/
*miss_set = f[i-1];
*miss_text = zzFAILtext;
*bad_tok = LT(i);
*bad_text = (*bad_tok)->getText();
if ( i==1 ) *err_k = 1;
else *err_k = k;
//
// MR4 20-May-97 erroneously deleted contents of f[]
// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)
// MR1 10-Apr-97 release temporary storage
//
delete [] f; // MR1
return; // MR1
}
int ANTLRParser::
_match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows)
{
if ( dirty==LLk ) consume();
if ( LA(1)!=tokenWanted )
{
syntaxErrCount++; /* MR11 */
fprintf(stderr,
"line %d: syntax error at \"%s\" missing %s\n",
LT(1)->getLine(),
(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
token_tbl[tokenWanted]);
consumeUntil( whatFollows );
return 0;
}
else {
dirty++;
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
/* if ( !demand_look ) consume(); */
return 1;
}
}
int ANTLRParser::
_setmatch_wdfltsig(SetWordType *tokensWanted,
ANTLRTokenType tokenTypeOfSet,
SetWordType *whatFollows)
{
if ( dirty==LLk ) consume();
if ( !set_el(LA(1), tokensWanted) )
{
syntaxErrCount++; /* MR11 */
fprintf(stderr,
"line %d: syntax error at \"%s\" missing %s\n",
LT(1)->getLine(),
(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
token_tbl[tokenTypeOfSet]);
consumeUntil( whatFollows );
return 0;
}
else {
dirty++;
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
/* if ( !demand_look ) consume(); */
return 1;
}
}
char *ANTLRParser::
eMsgd(char *err,int d)
{
sprintf(eMsgBuffer, err, d); // dangerous, but I don't care
return eMsgBuffer;
}
char *ANTLRParser::
eMsg(char *err, char *s)
{
sprintf(eMsgBuffer, err, s);
return eMsgBuffer;
}
char *ANTLRParser::
eMsg2(char *err,char *s, char *t)
{
sprintf(eMsgBuffer, err, s, t);
return eMsgBuffer;
}
void ANTLRParser::
panic(const char *msg) // MR20 const
{
fprintf(stderr, "ANTLR panic: %s\n", msg);
exit(PCCTS_EXIT_FAILURE); // MR1
}
const ANTLRChar *ANTLRParser:: // MR1
parserTokenName(int tok) { // MR1
return token_tbl[tok]; // MR1
} // MR1
void ANTLRParser::traceGuessDone(const ANTLRParserState *state) {
int doIt=0;
if (traceCurrentRuleName == NULL) return;
if (traceOptionValue <= 0) {
doIt=0;
} else if (traceGuessOptionValue <= 0) {
doIt=0;
} else {
doIt=1;
};
if (doIt) {
fprintf(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",
state->traceCurrentRuleName,
LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
state->traceDepth);
if (state->guessing != 0) {
fprintf(stderr," (guess mode continues - an enclosing guess is still active)");
} else {
fprintf(stderr," (guess mode ends)");
};
fprintf(stderr,"\n");
};
}
void ANTLRParser::traceGuessFail() {
int doIt=0;
if (traceCurrentRuleName == NULL) return; /* MR21 */
if (traceOptionValue <= 0) {
doIt=0;
} else if (guessing && traceGuessOptionValue <= 0) {
doIt=0;
} else {
doIt=1;
};
if (doIt) {
fprintf(stderr,"guess failed\n");
};
}
/* traceOption:
zero value turns off trace
*/
void ANTLRParser::tracein(const ANTLRChar * rule) {
int doIt=0;
traceDepth++;
traceCurrentRuleName=rule;
if (traceOptionValue <= 0) {
doIt=0;
} else if (guessing && traceGuessOptionValue <= 0) {
doIt=0;
} else {
doIt=1;
};
if (doIt) {
fprintf(stderr,"enter rule %s {\"%s\"} depth %d",
rule,
LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
traceDepth);
if (guessing) fprintf(stderr," guessing");
fprintf(stderr,"\n");
};
return;
}
void ANTLRParser::traceout(const ANTLRChar * rule) {
int doIt=0;
traceDepth--;
if (traceOptionValue <= 0) {
doIt=0;
} else if (guessing && traceGuessOptionValue <= 0) {
doIt=0;
} else {
doIt=1;
};
if (doIt) {
fprintf(stderr,"exit rule %s {\"%s\"} depth %d",
rule,
LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
traceDepth+1);
if (guessing) fprintf(stderr," guessing");
fprintf(stderr,"\n");
};
}
int ANTLRParser::traceOption(int delta) {
int prevValue=traceOptionValue;
traceOptionValue=traceOptionValue+delta;
if (traceCurrentRuleName != NULL) {
if (prevValue <= 0 && traceOptionValue > 0) {
fprintf(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
};
if (prevValue > 0 && traceOptionValue <= 0) {
fprintf(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
};
};
return prevValue;
}
int ANTLRParser::traceGuessOption(int delta) {
int prevValue=traceGuessOptionValue;
traceGuessOptionValue=traceGuessOptionValue+delta;
if (traceCurrentRuleName != NULL) {
if (prevValue <= 0 && traceGuessOptionValue > 0) {
fprintf(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
};
if (prevValue > 0 && traceGuessOptionValue <= 0) {
fprintf(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
};
};
return prevValue;
}
// MR19 V.H. Simonis Defer Fetch feature
void ANTLRParser::undeferFetch()
{
#ifdef ZZDEFER_FETCH
if (stillToFetch) {
for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) {
NLA = inputTokens->getToken()->getType();
dirty--;
lap = (lap+1)&(LLk-1);
}
stillToFetch = 0;
}
#else
return;
#endif
}
int ANTLRParser::isDeferFetchEnabled()
{
#ifdef ZZDEFER_FETCH
return 1;
#else
return 0;
#endif
}

View File

@@ -0,0 +1,358 @@
/* ANTLRParser.h
*
* Define the generic ANTLRParser superclass, which is subclassed to
* define an actual parser.
*
* Before entry into this file: ANTLRTokenType must be set.
*
* 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-1998
*/
#ifndef APARSER_H_GATE
#define APARSER_H_GATE
#include "pcctscfg.h"
#include "pccts_stdio.h"
#include "pccts_setjmp.h"
PCCTS_NAMESPACE_STD
#include ATOKEN_H
#include ATOKENBUFFER_H
#ifdef ZZCAN_GUESS
#ifndef ZZINF_LOOK
#define ZZINF_LOOK
#endif
#endif
#define NLA (token_type[lap&(LLk-1)])/* --> next LA */
typedef unsigned char SetWordType;
/* Define external bit set stuff (for SetWordType) */
#define EXT_WORDSIZE (sizeof(char)*8)
#define EXT_LOGWORDSIZE 3
/* s y n t a c t i c p r e d i c a t e s t u f f */
#ifndef zzUSER_GUESS_HOOK
#define zzUSER_GUESS_HOOK(seqFrozen,zzrv)
#endif
#ifndef zzUSER_GUESS_DONE_HOOK
#define zzUSER_GUESS_DONE_HOOK(seqFrozen)
#endif
/* MR14 Add zzUSER_GUESS_FAIL_HOOK and related code */
#define zzUSER_GUESS_FAIL_HOOK_INTERNAL zzUSER_GUESS_FAIL_HOOK(SeqFrozen)
#ifndef zzUSER_GUESS_FAIL_HOOK
#define zzUSER_GUESS_FAIL_HOOK(zzGuessSeq)
#endif
typedef struct _zzjmp_buf {
jmp_buf state;
} zzjmp_buf;
/* these need to be macros not member functions */
#define zzGUESS_BLOCK ANTLRParserState zzst; int zzrv; int _marker; int zzGuessSeqFrozen;
#define zzNON_GUESS_MODE if ( !guessing )
#define zzGUESS_FAIL guess_fail();
/* Note: zzGUESS_DONE does not execute longjmp() */
#define zzGUESS_DONE {zzrv=1; inputTokens->rewind(_marker); guess_done(&zzst);zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) }
#define zzGUESS saveState(&zzst); \
guessing = 1; \
zzGuessSeqFrozen = ++zzGuessSeq; \
_marker = inputTokens->mark(); \
zzrv = setjmp(guess_start.state); \
zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \
if ( zzrv ) zzGUESS_DONE
#define zzTRACEdata const ANTLRChar *zzTracePrevRuleName = NULL;
#ifndef zzTRACEIN
#define zzTRACEIN(r) zzTracePrevRuleName=traceCurrentRuleName;tracein(r);
#endif
#ifndef zzTRACEOUT
#define zzTRACEOUT(r) traceout(r);traceCurrentRuleName=zzTracePrevRuleName;
#endif
/* a n t l r p a r s e r d e f */
struct ANTLRParserState {
/* class variables */
zzjmp_buf guess_start;
int guessing;
int inf_labase;
int inf_last;
int dirty;
int traceOptionValue; // MR10
int traceGuessOptionValue; // MR10
const ANTLRChar *traceCurrentRuleName; // MR10
int traceDepth; // MR10
};
/* notes:
*
* multiple inheritance is a cool way to include what stuff is needed
* in this structure (like guess stuff). however, i'm not convinced that
* multiple inheritance works correctly on all platforms. not that
* much space is used--just include all possibly useful members.
*
* the class should also be a template with arguments for the lookahead
* depth and so on. that way, more than one parser can be defined (as
* each will probably have different lookahead requirements). however,
* am i sure that templates work? no, i'm not sure.
*
* no attributes are maintained and, hence, the 'asp' variable is not
* needed. $i can still be referenced, but it refers to the token
* associated with that rule element. question: where are the token's
* stored if not on the software stack? in local variables created
* and assigned to by antlr.
*/
class ANTLRParser {
protected:
/* class variables */
static SetWordType bitmask[sizeof(SetWordType)*8];
static char eMsgBuffer[500];
protected:
int LLk; // number of lookahead symbols (old LL_K)
int demand_look;
ANTLRTokenType eofToken; // when do I stop during resynch()s
int bsetsize; // size of bitsets created by ANTLR in
// units of SetWordType
ANTLRTokenBuffer *inputTokens; //place to get input tokens
zzjmp_buf guess_start; // where to jump back to upon failure
int guessing; // if guessing (using (...)? predicate)
// infinite lookahead stuff
int can_use_inf_look; // set by subclass (generated by ANTLR)
int inf_lap;
int inf_labase;
int inf_last;
int *_inf_line;
const ANTLRChar **token_tbl; // pointer to table of token type strings MR20 const
int dirty; // used during demand lookahead
ANTLRTokenType *token_type; // fast reference cache of token.getType()
// ANTLRLightweightToken **token; // the token with all its attributes
int lap;
int labase;
#ifdef ZZDEFER_FETCH
int stillToFetch; // MR19 V.H. Simonis
#endif
private:
void fill_inf_look();
protected:
virtual void guess_fail() { // MR9 27-Sep-97 make virtual
traceGuessFail(); // MR10
longjmp(guess_start.state, 1); } // MR9
virtual void guess_done(ANTLRParserState *st) { // MR9 27-Sep-97 make virtual
restoreState(st); } // MR9
virtual int guess(ANTLRParserState *); // MR9 27-Sep-97 make virtual
void look(int);
int _match(ANTLRTokenType, ANTLRChar **, ANTLRTokenType *,
_ANTLRTokenPtr *, SetWordType **);
int _setmatch(SetWordType *, ANTLRChar **, ANTLRTokenType *,
_ANTLRTokenPtr *, SetWordType **);
int _match_wsig(ANTLRTokenType);
int _setmatch_wsig(SetWordType *);
virtual void consume();
virtual void resynch(SetWordType *wd,SetWordType mask); // MR21
void prime_lookahead();
virtual void tracein(const ANTLRChar *r); // MR10
virtual void traceout(const ANTLRChar *r); // MR10
static unsigned MODWORD(unsigned x) {return x & (EXT_WORDSIZE-1);} // x % EXT_WORDSIZE // MR9
static unsigned DIVWORD(unsigned x) {return x >> EXT_LOGWORDSIZE;} // x / EXT_WORDSIZE // MR9
int set_deg(SetWordType *);
int set_el(ANTLRTokenType, SetWordType *);
virtual void edecode(SetWordType *); // MR1
virtual void FAIL(int k, ...); // MR1
int traceOptionValue; // MR10
int traceGuessOptionValue; // MR10
const ANTLRChar *traceCurrentRuleName; // MR10
int traceDepth; // MR10
void traceReset(); // MR10
virtual void traceGuessFail(); // MR10
virtual void traceGuessDone(const ANTLRParserState *); // MR10
int zzGuessSeq; // MR10
public:
ANTLRParser(ANTLRTokenBuffer *,
int k=1,
int use_inf_look=0,
int demand_look=0,
int bsetsize=1);
virtual ~ANTLRParser();
virtual void init();
ANTLRTokenType LA(int i)
{
//
// MR14 demand look will always be 0 for C++ mode
//
//// return demand_look ? token_type[(labase+(i)-1)&(LLk-1)] :
//// token_type[(lap+(i)-1)&(LLk-1)];
// MR19 V.H. Simonis Defer fetch feature
#ifdef ZZDEFER_FETCH
undeferFetch();
#endif
return token_type[(lap+(i)-1)&(LLk-1)];
}
_ANTLRTokenPtr LT(int i);
void setEofToken(ANTLRTokenType t) { eofToken = t; }
ANTLRTokenType getEofToken() const { return eofToken; } // MR14
void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); }
void garbageCollectTokens() { inputTokens->garbageCollectTokens(); }
virtual void syn(_ANTLRTokenPtr tok, ANTLRChar *egroup,
SetWordType *eset, ANTLRTokenType etok, int k);
virtual void saveState(ANTLRParserState *); // MR9 27-Sep-97 make virtual
virtual void restoreState(ANTLRParserState *); // MR9 27-Sep-97 make virtual
virtual void panic(const char *msg); // MR20 const
static char *eMsgd(char *,int);
static char *eMsg(char *,char *);
static char *eMsg2(char *,char *,char *);
void consumeUntil(SetWordType *st);
void consumeUntilToken(int t);
virtual int _setmatch_wdfltsig(SetWordType *tokensWanted,
ANTLRTokenType tokenTypeOfSet,
SetWordType *whatFollows);
virtual int _match_wdfltsig(ANTLRTokenType tokenWanted,
SetWordType *whatFollows);
const ANTLRChar * parserTokenName(int tok); // MR1
int traceOptionValueDefault; // MR11
int traceOption(int delta); // MR11
int traceGuessOption(int delta); // MR11
// MR8 5-Aug-97 S.Bochnak@microtool.com.pl
// MR8 Move resynch static local variable
// MR8 to class instance
int syntaxErrCount; // MR12
ANTLRTokenStream *getLexer() const { // MR12
return inputTokens ? inputTokens->getLexer() : 0; } // MR12
protected: // MR8
int resynchConsumed; // MR8
char *zzFAILtext; // workarea required by zzFAIL // MR9
void undeferFetch(); // MR19 V.H. Simonis
int isDeferFetchEnabled(); // MR19 V.H. Simonis
};
#define zzmatch(_t) \
if ( !_match((ANTLRTokenType)_t, &zzMissText, &zzMissTok, \
(_ANTLRTokenPtr *) &zzBadTok, &zzMissSet) ) goto fail;
#define zzmatch_wsig(_t,handler) \
if ( !_match_wsig((ANTLRTokenType)_t) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}
#define zzsetmatch(_ts) \
if ( !_setmatch(_ts, &zzMissText, &zzMissTok, \
(_ANTLRTokenPtr *) &zzBadTok, &zzMissSet) ) goto fail;
#define zzsetmatch_wsig(_ts, handler) \
if ( !_setmatch_wsig(_ts) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}
/* For the dflt signal matchers, a FALSE indicates that an error occurred
* just like the other matchers, but in this case, the routine has already
* recovered--we do NOT want to consume another token. However, when
* the match was successful, we do want to consume hence _signal=0 so that
* a token is consumed by the "if (!_signal) consume(); _signal=NoSignal;"
* preamble.
*/
#define zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) \
if ( !_setmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) ) \
_signal = MismatchedToken;
#define zzmatch_wdfltsig(tokenWanted, whatFollows) \
if ( !_match_wdfltsig(tokenWanted, whatFollows) ) _signal = MismatchedToken;
// MR1 10-Apr-97 zzfailed_pred() macro does not backtrack
// MR1 in guess mode.
// MR1 Identification and correction due to J. Lilley
#ifndef zzfailed_pred
#define zzfailed_pred(_p) \
if (guessing) { \
zzGUESS_FAIL; \
} else { \
fprintf(stdout,"line %d: semantic error; failed predicate: '%s'\n", \
LT(1)->getLine(), _p); \
}
#endif
#define zzRULE \
SetWordType *zzMissSet=NULL; ANTLRTokenType zzMissTok=(ANTLRTokenType)0; \
_ANTLRTokenPtr zzBadTok=NULL; ANTLRChar *zzBadText=(ANTLRChar *)""; \
int zzErrk=1,zzpf=0; \
zzTRACEdata \
ANTLRChar *zzMissText=(ANTLRChar *)"";
#endif
/* S t a n d a r d E x c e p t i o n S i g n a l s */
#define NoSignal 0
#define MismatchedToken 1
#define NoViableAlt 2
#define NoSemViableAlt 3
/* MR7 Allow more control over signalling */
/* by adding "Unwind" and "SetSignal" */
#define Unwind 4
#define setSignal(newValue) *_retsignal=_signal=(newValue)
#define suppressSignal *_retsignal=_signal=0
#define exportSignal *_retsignal=_signal

View File

@@ -0,0 +1,244 @@
/* Abstract syntax tree manipulation functions
*
* 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-1998
*/
#include "pcctscfg.h"
#include "pccts_stdio.h"
#include "pccts_stdarg.h"
PCCTS_NAMESPACE_STD
#define ANTLR_SUPPORT_CODE
#include "ASTBase.h"
/* ensure that tree manipulation variables are current after a rule
* reference
*/
void
ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
{
if ( *_sibling == NULL ) return;
if ( *_root == NULL ) *_root = *_sibling;
else if ( *_root != *_sibling ) (*_root)->_down = *_sibling;
if ( *_tail==NULL ) *_tail = *_sibling;
while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right;
}
/* add a child node to the current sibling list */
void
ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
{
if ( *_tail != NULL ) (*_tail)->_right = this;
else {
*_sibling = this;
if ( *_root != NULL ) (*_root)->_down = *_sibling;
}
*_tail = this;
if ( *_root == NULL ) *_root = *_sibling;
}
/* make a new AST node. Make the newly-created
* node the root for the current sibling list. If a root node already
* exists, make the newly-created node the root of the current root.
*/
void
ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
{
if ( *_root != NULL )
if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root;
*_root = this;
(*_root)->_down = *_sibling;
}
/* Apply preorder_action(), etc.. to root then each sibling */
//
// 7-Apr-97 133MR1
// Fix suggested by Ron House (house@helios.usq.edu.au)
//
void
ASTBase::preorder()
{
ASTBase *tree = this;
while ( tree!= NULL )
{
if ( tree->_down != NULL ) {
tree->preorder_before_action(); // MR1
};
tree->preorder_action();
if ( tree->_down!=NULL )
{
tree->_down->preorder();
tree->preorder_after_action(); // MR1
}
tree = tree->_right;
}
}
/* free all AST nodes in tree; apply func to each before freeing */
void
ASTBase::destroy()
{
ASTBase* tree = this;
while (tree) {
if (tree->_down) tree->_down->destroy();
ASTBase* cur = tree;
tree = tree->_right;
delete cur;
}
}
/* build a tree (root child1 child2 ... NULL)
* If root is NULL, simply make the children siblings and return ptr
* to 1st sibling (child1). If root is not single node, return NULL.
*
* Siblings that are actually siblins lists themselves are handled
* correctly. For example #( NULL, #( NULL, A, B, C), D) results
* in the tree ( NULL A B C D ).
*
* Requires at least two parameters with the last one being NULL. If
* both are NULL, return NULL.
*/
ASTBase *
ASTBase::tmake(ASTBase *root, ...)
{
va_list ap;
register ASTBase *child, *sibling=NULL, *tail, *w;
va_start(ap, root);
if ( root != NULL )
if ( root->_down != NULL ) {
root->reportOverwriteOfDownPointer(); /* MR21 Report problem which almost always an error */
return NULL;
}
child = va_arg(ap, ASTBase *);
while ( child != NULL )
{
for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */
if ( sibling == NULL ) {sibling = child; tail = w;}
else {tail->_right = child; tail = w;}
child = va_arg(ap, ASTBase *);
}
if ( root==NULL ) root = sibling;
else root->_down = sibling;
va_end(ap);
return root;
}
#ifndef PCCTS_NOT_USING_SOR
/* tree duplicate */
// forgot to check for NULL this (TJP July 23,1995)
ASTBase *
ASTBase::dup()
{
ASTBase *u, *t=this;
if ( t == NULL ) return NULL;
/*
u = new ASTBase;
*u = *t;
*/
u = (ASTBase *)this->shallowCopy();
if ( t->_right!=NULL ) u->_right = t->_right->dup();
else u->_right = NULL;
if ( t->_down!=NULL ) u->_down = t->_down->dup();
else u->_down = NULL;
return u;
}
#endif
//
// 7-Apr-97 133MR1
// Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com)
//
/* tree duplicate */
#ifndef PCCTS_NOT_USING_SOR
ASTBase *
ASTDoublyLinkedBase::dup()
{
ASTDoublyLinkedBase *u, *t=this;
if ( t == NULL ) return NULL;
u = (ASTDoublyLinkedBase *)this->shallowCopy();
u->_up = NULL; /* set by calling invocation */
u->_left = NULL;
if (t->_right!=NULL) { // MR1
u->_right=t->_right->dup(); // MR1
((ASTDoublyLinkedBase *)u->_right)->_left = u; // MR1
} else { // MR1
u->_right = NULL; // MR1
}; // MR1
if (t->_down!=NULL) { // MR1
u->_down = t->_down->dup(); // MR1
((ASTDoublyLinkedBase *)u->_down)->_up = u; // MR1
} else { // MR1
u->_down = NULL; // MR1
}; // MR1
return u;
}
#endif
/*
* Set the 'up', and 'left' pointers of all nodes in 't'.
* Initial call is double_link(your_tree, NULL, NULL).
*/
void
ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up)
{
ASTDoublyLinkedBase *t = this;
t->_left = (ASTDoublyLinkedBase *) left;
t->_up = (ASTDoublyLinkedBase *) up;
if (t->_down != NULL)
((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t);
if (t->_right != NULL)
((ASTDoublyLinkedBase *)t->_right)->double_link(t, up);
}
// MR21 ASTBase::reportOverwriteOfDownPointer
void ASTBase::reportOverwriteOfDownPointer()
{
panic("Attempt to overwrite down pointer in ASTBase::tmake");
}
// MR21 ASTBase::panic
void ASTBase::panic(const char *msg)
{
fprintf(stderr,"ASTBase panic: %s\n", msg);
exit(PCCTS_EXIT_FAILURE);
}

View File

@@ -0,0 +1,119 @@
/* Abstract syntax tree
*
* 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-1998
*/
#ifndef ASTBase_H
#define ASTBase_H
#include "pcctscfg.h"
#include "pccts_stdio.h"
#include "pccts_stdlib.h"
PCCTS_NAMESPACE_STD
#ifndef PCCTS_NOT_USING_SOR
#include "PCCTSAST.h"
#endif
/*
* Notes:
*
* To specify a copy constructor, subclass one of these classes and
* give the copy constructor. To use dup(), you must define shallowCopy().
* shallowCopy() can use either a copy constructor or just copy the node
* itself.
*/
#ifdef PCCTS_NOT_USING_SOR
class DllExportPCCTS ASTBase {
#else
class DllExportPCCTS ASTBase : public PCCTS_AST {
#endif
protected:
ASTBase *_right, *_down;
public:
#ifdef PCCTS_NOT_USING_SOR
ASTBase *right() { return _right; }
ASTBase *down() { return _down; }
void setRight(ASTBase *t) { _right = (ASTBase *)t; }
void setDown(ASTBase *t) { _down = (ASTBase *)t; }
#else
PCCTS_AST *right() { return _right; } // define the SORCERER interface
PCCTS_AST *down() { return _down; }
void setRight(PCCTS_AST *t) { _right = (ASTBase *)t; }
void setDown(PCCTS_AST *t) { _down = (ASTBase *)t; }
#endif
ASTBase() { _right = _down = NULL; }
virtual ~ASTBase() { ; }
#ifndef PCCTS_NOT_USING_SOR
virtual ASTBase *dup();
#endif
void destroy();
void preorder();
static ASTBase *tmake(ASTBase *, ...);
static void link(ASTBase **, ASTBase **, ASTBase **);
void subchild(ASTBase **, ASTBase **, ASTBase **);
void subroot(ASTBase **, ASTBase **, ASTBase **);
virtual void preorder_action() { ; }
virtual void preorder_before_action() { printf(" ("); }
virtual void preorder_after_action() { printf(" )"); }
virtual void panic(const char *msg); /* MR21 */
virtual void reportOverwriteOfDownPointer(); /* MR21 */
};
class DllExportPCCTS ASTDoublyLinkedBase : public ASTBase {
protected:
ASTDoublyLinkedBase *_left, *_up;
public:
void double_link(ASTBase *left, ASTBase *up);
#ifndef PCCTS_NOT_USING_SOR
virtual ASTBase *dup();
#endif
#ifdef PCCTS_NOT_USING_SOR
ASTBase *left() { return _left; }
ASTBase *up() { return _up; }
void setLeft(ASTBase *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6
void setUp(ASTBase *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6
#else
PCCTS_AST *left() { return _left; }
PCCTS_AST *up() { return _up; }
void setLeft(PCCTS_AST *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6
void setUp(PCCTS_AST *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6
#endif
};
class AST; // announce that this class will be coming along shortly
#endif

View File

@@ -0,0 +1,82 @@
/* ATokPtr.C
*
* ANTLRToken MUST be defined before entry to this file.
*
* 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
* Written by Russell Quong June 30, 1995
* Adapted by Terence Parr to ANTLR stuff
* Parr Research Corporation
* with Purdue University and AHPCRC, University of Minnesota
* 1989-1998
*/
#include "pcctscfg.h"
PCCTS_NAMESPACE_STD
#include "ATokPtr.h"
void ANTLRTokenPtr::ref() const
{
if (ptr_ != NULL) {
ptr_->ref();
}
}
void ANTLRTokenPtr::deref()
{
if (ptr_ != NULL)
{
ptr_->deref();
if ( ptr_->nref()==0 )
{
delete ptr_;
ptr_ = NULL;
}
}
}
ANTLRTokenPtr::~ANTLRTokenPtr()
{
deref();
}
//
// 8-Apr-97 MR1 Make operator -> a const member function
// as weall as some other member functions
//
void ANTLRTokenPtr::operator = (const ANTLRTokenPtr & lhs) // MR1
{
lhs.ref(); // protect against "xp = xp"; ie same underlying object
deref();
ptr_ = lhs.ptr_;
}
void ANTLRTokenPtr::operator = (ANTLRAbstractToken *addr)
{
if (addr != NULL) {
addr->ref();
}
deref();
ptr_ = addr;
}

View File

@@ -0,0 +1,88 @@
/* ATokPtr.h
*
* 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
* Written by Russell Quong June 30, 1995
* Adapted by Terence Parr to ANTLR stuff
* Parr Research Corporation
* with Purdue University and AHPCRC, University of Minnesota
* 1989-1998
*/
#ifndef ATokPtr_h
#define ATokPtr_h
#include "pcctscfg.h"
#include "pccts_stdio.h"
PCCTS_NAMESPACE_STD
// pointer to a reference counted object
// robust in that an unused ANTLRTokenPtr can point to NULL.
class ANTLRAbstractToken;
class DllExportPCCTS ANTLRTokenPtr {
public:
ANTLRTokenPtr(ANTLRAbstractToken *addr=NULL){ptr_ = addr; ref();}
ANTLRTokenPtr(const ANTLRTokenPtr &lhs) {ptr_ = lhs.ptr_; lhs.ref();}
~ANTLRTokenPtr();
// use ANTLRTokenPtr as a pointer to ANTLRToken
//
// 8-Apr-97 MR1 Make operator -> a const member function
// as well as some other member functions
//
ANTLRAbstractToken *operator-> () const { return ptr_; } // MR1
//
// 7-Apr-97 133MR1
// Fix suggested by Andreas Magnusson
// (Andreas.Magnusson@mailbox.swipnet.se)
void operator = (const ANTLRTokenPtr & lhs); // MR1
void operator = (ANTLRAbstractToken *addr);
int operator != (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int
{ return this->ptr_ != q.ptr_; }
int operator == (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int
{ return this->ptr_ == q.ptr_; }
int operator == (const ANTLRAbstractToken *addr) const // MR11
{ return this->ptr_ == addr; }
int operator != (const ANTLRAbstractToken *addr) const // MR11
{ return this->ptr_ != addr; }
void ref() const;
void deref();
protected:
ANTLRAbstractToken *ptr_;
};
//typedef ANTLRTokenPtr _ANTLRTokenPtr;
/*
* Since you cannot redefine operator->() to return one of the user's
* token object types, we must down cast. This is a drag. Here's
* a macro that helps. template: "mytoken(a-smart-ptr)->myfield".
*/
#define mytoken(tk) ((ANTLRToken *)(tk.operator->()))
#endif

View File

@@ -0,0 +1,305 @@
/* ANTLRToken.h
*
* 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-1998
*/
#ifndef ATOKEN_H_GATE
#define ATOKEN_H_GATE
#include "pcctscfg.h"
#include "pccts_string.h"
#include "pccts_stdio.h"
#include "pccts_stdlib.h"
PCCTS_NAMESPACE_STD
// MR9 RJV (JVincent@novell.com) Not needed for variable length strings
//// MR9 #ifndef ANTLRCommonTokenTEXTSIZE
//// MR9 #define ANTLRCommonTokenTEXTSIZE 100
//// MR9 #endif
/* must define what a char looks like; can make this a class too */
typedef char ANTLRChar;
/* D E F I N E S M A R T P O I N T E R S */
//#include ATOKPTR_H not tested yet, leave out
class ANTLRAbstractToken;
typedef ANTLRAbstractToken *_ANTLRTokenPtr;
class ANTLRAbstractToken {
public:
virtual ~ANTLRAbstractToken() {;}
virtual ANTLRTokenType getType() const = 0;
virtual void setType(ANTLRTokenType t) = 0;
virtual int getLine() const = 0;
virtual void setLine(int line) = 0;
virtual ANTLRChar *getText() const = 0;
virtual void setText(const ANTLRChar *) = 0;
/* This function will disappear when I can use templates */
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *text,
int line) = 0;
/* define to satisfy ANTLRTokenBuffer's need to determine whether or
not a token object can be destroyed. If nref()==0, no one has
a reference, and the object may be destroyed. This function defaults
to 1, hence, if you use deleteTokens() message with a token object
not derived from ANTLRCommonRefCountToken, the parser will compile
but will not delete objects after they leave the token buffer.
*/
virtual unsigned nref() const { return 1; } // MR11
virtual void ref() {;}
virtual void deref() {;}
virtual void panic(const char *msg) // MR20 const
{
fprintf(stderr, "ANTLRAbstractToken panic: %s\n", msg);
exit(PCCTS_EXIT_FAILURE);
}
};
/* This class should be subclassed. It cannot store token type or text */
class ANTLRRefCountToken : public ANTLRAbstractToken {
public:
#ifdef DBG_REFCOUNTTOKEN
static int ctor;
static int dtor;
#endif
protected:
unsigned refcnt_;
#ifdef DBG_REFCOUNTTOKEN
char object[200];
#endif
public:
ANTLRRefCountToken(ANTLRTokenType t, const ANTLRChar *s)
#ifndef DBG_REFCOUNTTOKEN
{
refcnt_ = 0;
}
#else
{
ctor++;
refcnt_ = 0;
if ( t==1 ) sprintf(object,"tok_EOF");
else sprintf(object,"tok_%s",s);
fprintf(stderr, "ctor %s #%d\n",object,ctor);
}
#endif
ANTLRRefCountToken()
#ifndef DBG_REFCOUNTTOKEN
{ refcnt_ = 0; }
#else
{
ctor++;
refcnt_ = 0;
sprintf(object,"tok_blank");
fprintf(stderr, "ctor %s #%d\n",object,ctor);
}
virtual ~ANTLRRefCountToken()
{
dtor++;
if ( dtor>ctor ) fprintf(stderr, "WARNING: dtor>ctor\n");
fprintf(stderr, "dtor %s #%d\n", object, dtor);
object[0]='\0';
}
#endif
// reference counting stuff needed by ANTLRTokenPtr.
// User should not access these; for C++ language reasons, we had
// to make these public. Yuck.
void ref() { refcnt_++; }
void deref() { refcnt_--; }
unsigned nref() const { return refcnt_; } // MR11
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *txt,
int line)
{
panic("call to ANTLRRefCountToken::makeToken()\n");
return NULL;
}
};
class ANTLRCommonNoRefCountToken : public ANTLRAbstractToken {
protected:
ANTLRTokenType _type;
int _line;
ANTLRChar *_text; // MR9 RJV
public:
ANTLRCommonNoRefCountToken(ANTLRTokenType t, const ANTLRChar *s)
{ setType(t); _line = 0; _text = NULL; setText(s); }
ANTLRCommonNoRefCountToken()
{ setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); }
~ANTLRCommonNoRefCountToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string
ANTLRTokenType getType() const { return _type; }
void setType(ANTLRTokenType t) { _type = t; }
virtual int getLine() const { return _line; }
void setLine(int line) { _line = line; }
ANTLRChar *getText() const { return _text; }
int getLength() const { return strlen(getText()); } // MR11
// MR9 RJV: Added code for variable length strings to setText()
void setText(const ANTLRChar *s)
{ if (s != _text) {
if (_text) delete [] _text;
if (s != NULL) {
_text = new ANTLRChar[strlen(s)+1];
if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed");
strcpy(_text,s);
} else {
_text = new ANTLRChar[1];
if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed");
strcpy(_text,"");
};
};
}
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *txt,
int line)
{
ANTLRAbstractToken *t = new ANTLRCommonNoRefCountToken;
t->setType(tt); t->setText(txt); t->setLine(line);
return t;
}
// MR9 THM Copy constructor required when heap allocated string is used with copy semantics
ANTLRCommonNoRefCountToken (const ANTLRCommonNoRefCountToken& from) :
ANTLRAbstractToken(from) {
setType(from._type);
setLine(from._line);
_text=NULL;
setText(from._text);
};
// MR9 THM operator =() required when heap allocated string is used with copy semantics
virtual ANTLRCommonNoRefCountToken& operator =(const ANTLRCommonNoRefCountToken& rhs) {
////// MR15 WatCom can't hack use of operator =()
////// Use this: *( (ANTRLAbstractToken *) this)=rhs;
*( (ANTLRAbstractToken *) this ) = rhs;
setType(rhs._type);
setLine(rhs._line);
setText(rhs._text);
return *this;
};
};
class ANTLRCommonToken : public ANTLRRefCountToken {
protected:
ANTLRTokenType _type;
int _line;
ANTLRChar *_text; // MR9 RJV:Added
public:
ANTLRCommonToken(ANTLRTokenType t, const ANTLRChar *s) : ANTLRRefCountToken(t,s)
{ setType(t); _line = 0; _text = NULL; setText(s); } // MR9
ANTLRCommonToken()
{ setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); } // MR9
virtual ~ANTLRCommonToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string
ANTLRTokenType getType() const { return _type; }
void setType(ANTLRTokenType t) { _type = t; }
virtual int getLine() const { return _line; }
void setLine(int line) { _line = line; }
ANTLRChar *getText() const { return _text; }
int getLength() const { return strlen(getText()); } // MR11
// MR9 RJV: Added code for variable length strings to setText()
void setText(const ANTLRChar *s)
{ if (s != _text) {
if (_text) delete [] _text;
if (s != NULL) {
_text = new ANTLRChar[strlen(s)+1];
if (_text == NULL) panic("ANTLRCommonToken::setText new failed");
strcpy(_text,s);
} else {
_text = new ANTLRChar[1];
if (_text == NULL) panic("ANTLRCommonToken::setText new failed");
strcpy(_text,"");
};
};
}
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *txt,
int line)
{
ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt);
t->setLine(line);
return t;
}
// MR9 THM Copy constructor required when heap allocated string is used with copy semantics
ANTLRCommonToken (const ANTLRCommonToken& from) :
ANTLRRefCountToken(from) {
setType(from._type);
setLine(from._line);
_text=NULL;
setText(from._text);
};
// MR9 THM operator =() required when heap allocated string is used with copy semantics
virtual ANTLRCommonToken& operator =(const ANTLRCommonToken& rhs) {
////// MR15 WatCom can't hack use of operator =()
////// Use this instead: *( (ANTRLRRefCountToken *) this)=rhs;
*( (ANTLRRefCountToken *) this) = rhs;
setType(rhs._type);
setLine(rhs._line);
setText(rhs._text);
return *this;
};
};
// used for backward compatibility
typedef ANTLRCommonToken ANTLRCommonBacktrackingToken;
#endif

View File

@@ -0,0 +1,345 @@
/* ANTLRTokenBuffer.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-1998
*/
typedef int ANTLRTokenType; // fool AToken.h into compiling
class ANTLRParser; /* MR1 */
#define ANTLR_SUPPORT_CODE
#include "pcctscfg.h"
#include ATOKENBUFFER_H
typedef ANTLRAbstractToken *_ANTLRTokenPtr;
#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
static unsigned char test[1000];
#endif
#ifdef DBG_REFCOUNTTOKEN
int ANTLRCommonToken::ctor = 0;
int ANTLRCommonToken::dtor = 0;
#endif
ANTLRTokenBuffer::
ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _chunk_size_formal) /* MR14 */
{
this->input = _input;
this->k = _k;
buffer_size = chunk_size = _chunk_size_formal;
buffer = (_ANTLRTokenPtr *)
calloc(chunk_size+1,sizeof(_ANTLRTokenPtr ));
if ( buffer == NULL ) {
panic("cannot alloc token buffer");
}
buffer++; // leave the first elem empty so tp-1 is valid ptr
tp = &buffer[0];
last = tp-1;
next = &buffer[0];
num_markers = 0;
end_of_buffer = &buffer[buffer_size-1];
// BUGBUG -- threshold = &buffer[(int)(buffer_size*(1.0/2.0))];
threshold = &buffer[(int)(buffer_size / 2)];
_deleteTokens = 1; // assume we delete tokens
parser=NULL; // MR5 - uninitialized reference
}
static void f() {;}
ANTLRTokenBuffer::
~ANTLRTokenBuffer()
{
f();
// Delete all remaining tokens (from 0..last inclusive)
if ( _deleteTokens )
{
_ANTLRTokenPtr *z;
for (z=buffer; z<=last; z++)
{
(*z)->deref();
// z->deref();
#ifdef DBG_REFCOUNTTOKEN
fprintf(stderr, "##########dtor: deleting token '%s' (ref %d)\n",
((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
#endif
if ( (*z)->nref()==0 )
{
delete (*z);
}
}
}
if ( buffer!=NULL ) free((char *)(buffer-1));
}
#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
#include "pccts_stdio.h"
PCCTS_NAMESPACE_STD
#endif
_ANTLRTokenPtr ANTLRTokenBuffer::
getToken()
{
if ( tp <= last ) // is there any buffered lookahead still to be read?
{
return *tp++; // read buffered lookahead
}
// out of buffered lookahead, get some more "real"
// input from getANTLRToken()
if ( num_markers==0 )
{
if( next > threshold )
{
#ifdef DBG_TBUF
fprintf(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer);
#endif
makeRoom();
}
}
else {
if ( next > end_of_buffer )
{
#ifdef DBG_TBUF
fprintf(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size);
#endif
extendBuffer();
}
}
*next = getANTLRToken();
(*next)->ref(); // say we have a copy of this pointer in buffer
last = next;
next++;
tp = last;
return *tp++;
}
void ANTLRTokenBuffer::
rewind(int pos)
{
#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
fprintf(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]);
test[pos]--;
#endif
tp = &buffer[pos];
num_markers--;
}
/*
* This function is used to specify that the token pointers read
* by the ANTLRTokenBuffer should be buffered up (to be reused later).
*/
int ANTLRTokenBuffer::
mark()
{
#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
test[tp-buffer]++;
fprintf(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]);
#endif
num_markers++;
return tp - buffer;
}
/*
* returns the token pointer n positions ahead.
* This implies that bufferedToken(1) gets the NEXT symbol of lookahead.
* This is used in conjunction with the ANTLRParser lookahead buffer.
*
* No markers are set or anything. A bunch of input is buffered--that's all.
* The tp pointer is left alone as the lookahead has not been advanced
* with getToken(). The next call to getToken() will find a token
* in the buffer and won't have to call getANTLRToken().
*
* If this is called before a consume() is done, how_many_more_i_need is
* set to 'n'.
*/
_ANTLRTokenPtr ANTLRTokenBuffer::
bufferedToken(int n)
{
// int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1;
int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1;
// Make sure that at least n tokens are available in the buffer
#ifdef DBG_TBUF
fprintf(stderr, "bufferedToken(%d)\n", n);
#endif
for (int i=1; i<=how_many_more_i_need; i++)
{
if ( next > end_of_buffer ) // buffer overflow?
{
extendBuffer();
}
*next = getANTLRToken();
(*next)->ref(); // say we have a copy of this pointer in buffer
last = next;
next++;
}
return tp[n - 1];
}
/* If no markers are set, the none of the input needs to be saved (except
* for the lookahead Token pointers). We save only k-1 token pointers as
* we are guaranteed to do a getANTLRToken() right after this because otherwise
* we wouldn't have needed to extend the buffer.
*
* If there are markers in the buffer, we need to save things and so
* extendBuffer() is called.
*/
void ANTLRTokenBuffer::
makeRoom()
{
#ifdef DBG_TBUF
fprintf(stderr, "in makeRoom.................\n");
fprintf(stderr, "num_markers==%d\n", num_markers);
#endif
/*
if ( num_markers == 0 )
{
*/
#ifdef DBG_TBUF
fprintf(stderr, "moving lookahead and resetting next\n");
_ANTLRTokenPtr *r;
fprintf(stderr, "tbuf = [");
for (r=buffer; r<=last; r++)
{
if ( *r==NULL ) fprintf(stderr, " xxx");
else fprintf(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText());
}
fprintf(stderr, " ]\n");
fprintf(stderr,
"before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer);
#endif
// Delete all tokens from 0..last-(k-1) inclusive
if ( _deleteTokens )
{
_ANTLRTokenPtr *z;
for (z=buffer; z<=last-(k-1); z++)
{
(*z)->deref();
// z->deref();
#ifdef DBG_REFCOUNTTOKEN
fprintf(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n",
((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
#endif
if ( (*z)->nref()==0 )
{
delete (*z);
}
}
}
// reset the buffer to initial conditions, but move k-1 symbols
// to the beginning of buffer and put new input symbol at k
_ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1;
// ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1;
#ifdef DBG_TBUF
fprintf(stderr, "lookahead buffer = [");
#endif
for (int i=1; i<=(k-1); i++)
{
*p++ = *q++;
#ifdef DBG_TBUF
fprintf(stderr,
" '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());
#endif
}
#ifdef DBG_TBUF
fprintf(stderr, " ]\n");
#endif
next = &buffer[k-1];
tp = &buffer[k-1]; // tp points to what will be filled in next
last = tp-1;
#ifdef DBG_TBUF
fprintf(stderr,
"after: tp=%d, last=%d, next=%d\n",
tp-buffer, last-buffer, next-buffer);
#endif
/*
}
else {
extendBuffer();
}
*/
}
/* This function extends 'buffer' by chunk_size and returns with all
* pointers at the same relative positions in the buffer (the buffer base
* address could have changed in realloc()) except that 'next' comes
* back set to where the next token should be stored. All other pointers
* are untouched.
*/
void
ANTLRTokenBuffer::
extendBuffer()
{
int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;
#ifdef DBG_TBUF
fprintf(stderr, "extending physical buffer\n");
#endif
buffer_size += chunk_size;
buffer = (_ANTLRTokenPtr *)
realloc((char *)(buffer-1),
(buffer_size+1)*sizeof(_ANTLRTokenPtr ));
if ( buffer == NULL ) {
panic("cannot alloc token buffer");
}
buffer++; // leave the first elem empty so tp-1 is valid ptr
tp = buffer + save_tp; // put the pointers back to same relative position
last = buffer + save_last;
next = buffer + save_next;
end_of_buffer = &buffer[buffer_size-1];
// BUGBUG -- threshold = &buffer[(int)(buffer_size*(1.0/2.0))];
threshold = &buffer[(int)(buffer_size / 2)];
/*
// zero out new token ptrs so we'll know if something to delete in buffer
ANTLRAbstractToken **p = end_of_buffer-chunk_size+1;
for (; p<=end_of_buffer; p++) *p = NULL;
*/
}
ANTLRParser * ANTLRTokenBuffer:: // MR1
setParser(ANTLRParser *p) { // MR1
ANTLRParser *old=parser; // MR1
parser=p; // MR1
input->setParser(p); // MR1
return old; // MR1
} // MR1
// MR1
ANTLRParser * ANTLRTokenBuffer:: // MR1
getParser() { // MR1
return parser; // MR1
} // MR1
/* to avoid having to link in another file just for the smart token ptr
* stuff, we include it here. Ugh.
*/
#include ATOKPTR_C

View File

@@ -0,0 +1,106 @@
/* ANTLRTokenBuffer.h
*
* 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-1998
*/
#ifndef ATOKENBUFFER_H_GATE
#define ATOKENBUFFER_H_GATE
#include "pcctscfg.h"
#include "pccts_stdlib.h"
PCCTS_NAMESPACE_STD
#include ATOKEN_H
#include ATOKENSTREAM_H
/*
* The parser is "attached" to an ANTLRTokenBuffer via interface
* functions: getToken() and bufferedToken(). The object that actually
* consumes characters and constructs tokens is connected to the
* ANTLRTokenBuffer via interface function ANTLRTokenStream::getToken();
* where ANTLRTokenStream is really just a behavior (class with no data).
* C++ does not have this abstraction and hence we simply have come up
* with a fancy name for "void *". See the note in ANTLRTokenStream.h on
* the "behavior" of ANTLRTokenStream.
*/
class ANTLRParser; // MR1
class DllExportPCCTS ANTLRTokenBuffer {
protected:
ANTLRTokenStream *input; // where do I get tokens
int buffer_size;
int chunk_size;
int num_markers;
int k; // Need at least this many tokens in buffer
_ANTLRTokenPtr *buffer; // buffer used for arbitrary lookahead
_ANTLRTokenPtr *tp; // pts into buffer; current token ptr
_ANTLRTokenPtr *last; // pts to last valid token in buffer
_ANTLRTokenPtr *next; // place to put token from getANTLRToken()
_ANTLRTokenPtr *end_of_buffer;
/* when you try to write a token past this and there are no markers
set, then move k-1 tokens back to the beginning of the buffer.
We want to stay away from the end of the buffer because we have
to extend it if a marker is set and we reach the end (we cannot
move tokens to the beginning of the buffer in this case).
*/
_ANTLRTokenPtr *threshold;
unsigned char _deleteTokens;
// This function is filled in by the subclass; it initiates fetch of input
virtual _ANTLRTokenPtr getANTLRToken() { return input->getToken(); }
void makeRoom();
void extendBuffer();
public:
ANTLRTokenBuffer(ANTLRTokenStream *in, int k=1, int chksz=50);
virtual ~ANTLRTokenBuffer();
virtual _ANTLRTokenPtr getToken();
virtual void rewind(int pos);
virtual int mark();
virtual _ANTLRTokenPtr bufferedToken(int i);
void noGarbageCollectTokens() { _deleteTokens=0; }
void garbageCollectTokens() { _deleteTokens=1; }
virtual int bufferSize() { return buffer_size; }
virtual int minTokens() { return k; }
virtual void setMinTokens(int k_new) { k = k_new; }
virtual void panic(const char *msg) { exit(PCCTS_EXIT_FAILURE); } /* MR20 const */
protected: // MR1
ANTLRParser *parser; // MR1
public: // MR1
ANTLRParser *setParser(ANTLRParser *p); // MR1
ANTLRParser *getParser(); // MR1
ANTLRTokenStream *getLexer() const { // MR12
return input;} // MR12
};
#endif

View File

@@ -0,0 +1,51 @@
/* ANTLRTokenStream.h
*
* 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-1998
*/
#ifndef ATOKENSTREAM_H_GATE
#define ATOKENSTREAM_H_GATE
#include "pcctscfg.h"
/* This is really a behavior or protocol; it merely indicates the behavior
* required of the input and output of an ANTLRTokenBuffer. You could
* subclass it, but you can also just pass any old pointer to ANTLRTokenBuffer
* with a type cast (in which case, your getANTLRToken() would have to
* explicitly cast the input pointer to your REAL type (typically your lexer)).
*/
class ANTLRParser; // MR1
class DllExportPCCTS ANTLRTokenStream {
public:
virtual _ANTLRTokenPtr getToken() = 0;
virtual ANTLRParser * setParser(ANTLRParser *p) {return 0; }; // MR12
virtual ANTLRParser * getParser() { return 0; }; // MR12
};
#endif

View File

@@ -0,0 +1,215 @@
/* ANTLRToken.h
*
* 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-1998
*/
#ifndef ATOKEN_H_GATE
#define ATOKEN_H_GATE
#include "pcctscfg.h"
#include "pccts_string.h"
#include "pccts_stdio.h"
#include "pccts_stdlib.h"
PCCTS_NAMESPACE_STD
#ifndef ANTLRCommonTokenTEXTSIZE
#define ANTLRCommonTokenTEXTSIZE 100
#endif
/* must define what a char looks like; can make this a class too */
typedef char ANTLRChar;
/* D E F I N E S M A R T P O I N T E R S */
#include "pcctscfg.h"
//#include ATOKPTR_H not tested yet, leave out
class ANTLRAbstractToken;
typedef ANTLRAbstractToken *_ANTLRTokenPtr;
class DllExportPCCTS ANTLRAbstractToken {
public:
virtual ~ANTLRAbstractToken() {;}
virtual ANTLRTokenType getType() = 0;
virtual void setType(ANTLRTokenType t) = 0;
virtual int getLine() = 0;
virtual void setLine(int line) = 0;
virtual ANTLRChar *getText() = 0;
virtual void setText(ANTLRChar *) = 0;
/* This function will disappear when I can use templates */
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *text,
int line) = 0;
/* define to satisfy ANTLRTokenBuffer's need to determine whether or
not a token object can be destroyed. If nref()==0, no one has
a reference, and the object may be destroyed. This function defaults
to 1, hence, if you use deleteTokens() message with a token object
not derived from ANTLRCommonRefCountToken, the parser will compile
but will not delete objects after they leave the token buffer.
*/
virtual unsigned nref() { return 1; }
virtual void ref() {;}
virtual void deref() {;}
virtual void panic(char *msg)
{
fprintf(stderr, "ANTLRAbstractToken panic: %s\n", msg);
exit(PCCTS_EXIT_FAILURE);
}
};
/* This class should be subclassed. It cannot store token type or text */
class DllExportPCCTS ANTLRRefCountToken : public ANTLRAbstractToken {
public:
#ifdef DBG_REFCOUNTTOKEN
static int ctor;
static int dtor;
#endif
protected:
unsigned refcnt_;
#ifdef DBG_REFCOUNTTOKEN
char object[200];
#endif
public:
ANTLRRefCountToken(ANTLRTokenType t, ANTLRChar *s)
#ifndef DBG_REFCOUNTTOKEN
{
refcnt_ = 0;
}
#else
{
ctor++;
refcnt_ = 0;
if ( t==1 ) sprintf(object,"tok_EOF");
else sprintf(object,"tok_%s",s);
fprintf(stderr, "ctor %s #%d\n",object,ctor);
}
#endif
ANTLRRefCountToken()
#ifndef DBG_REFCOUNTTOKEN
{ refcnt_ = 0; }
#else
{
ctor++;
refcnt_ = 0;
sprintf(object,"tok_blank");
fprintf(stderr, "ctor %s #%d\n",object,ctor);
}
virtual ~ANTLRRefCountToken()
{
dtor++;
if ( dtor>ctor ) fprintf(stderr, "WARNING: dtor>ctor\n");
fprintf(stderr, "dtor %s #%d\n", object, dtor);
object[0]='\0';
}
#endif
// reference counting stuff needed by ANTLRTokenPtr.
// User should not access these; for C++ language reasons, we had
// to make these public. Yuck.
void ref() { refcnt_++; }
void deref() { refcnt_--; }
unsigned nref() { return refcnt_; }
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *txt,
int line)
{
panic("call to ANTLRRefCountToken::makeToken()\n");
return NULL;
}
};
class DllExportPCCTS ANTLRCommonNoRefCountToken : public ANTLRAbstractToken {
protected:
ANTLRTokenType _type;
int _line;
ANTLRChar _text[ANTLRCommonTokenTEXTSIZE+1];
public:
ANTLRCommonNoRefCountToken(ANTLRTokenType t, ANTLRChar *s)
{ setType(t); _line = 0; setText(s); }
ANTLRCommonNoRefCountToken()
{ setType((ANTLRTokenType)0); _line = 0; setText(""); }
ANTLRTokenType getType() { return _type; }
void setType(ANTLRTokenType t) { _type = t; }
virtual int getLine() { return _line; }
void setLine(int line) { _line = line; }
ANTLRChar *getText() { return _text; }
void setText(ANTLRChar *s)
{ strncpy((char *)_text, (char *)s, ANTLRCommonTokenTEXTSIZE); }
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *txt,
int line)
{
ANTLRAbstractToken *t = new ANTLRCommonNoRefCountToken;
t->setType(tt); t->setText(txt); t->setLine(line);
return t;
}
};
class DllExportPCCTS ANTLRCommonToken : public ANTLRRefCountToken {
protected:
ANTLRTokenType _type;
int _line;
ANTLRChar _text[ANTLRCommonTokenTEXTSIZE+1];
public:
ANTLRCommonToken(ANTLRTokenType t, ANTLRChar *s) : ANTLRRefCountToken(t,s)
{ setType(t); _line = 0; setText(s); }
ANTLRCommonToken()
{ setType((ANTLRTokenType)0); _line = 0; setText(""); }
virtual ~ANTLRCommonToken() {;}
ANTLRTokenType getType() { return _type; }
void setType(ANTLRTokenType t) { _type = t; }
virtual int getLine() { return _line; }
void setLine(int line) { _line = line; }
ANTLRChar *getText() { return _text; }
void setText(ANTLRChar *s)
{ strncpy((char *)_text, (char *)s, ANTLRCommonTokenTEXTSIZE); }
virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
ANTLRChar *txt,
int line)
{
ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt);
t->setLine(line);
return t;
}
};
// used for backward compatibility
typedef ANTLRCommonToken ANTLRCommonBacktrackingToken;
#endif

View File

@@ -0,0 +1,100 @@
// FILE: BufFileInput.cpp
// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru
// CREATION: 26-JAN-1998
// DESCRIPTION: File Input Stream with lookahead for Scanner.
// See file BufFileInput.h for details
// Change History:
//
// 22-Jun-1998 assert.h -> PCCTS_ASSERT_H
// string.h -> PCCTS_STRING_H
//
// 28-May-1998 Add virtual destructor to release buffer.
//
// Add dummy definition for ANTLRTokenType
// to allow compilation without knowing
// token type codes.
//
// Manfred Kogler (km@cast.uni-linz.ac.at)
// (1.33MR14)
//
// 20-Jul-1998 MR14a - Reorder initialization list for ctor.
//
enum ANTLRTokenType {TER_HATES_CPP=0, SO_DO_OTHERS=9999 };
#include "pcctscfg.h"
#include "pccts_assert.h"
#include "pccts_string.h"
PCCTS_NAMESPACE_STD
#include "BufFileInput.h"
BufFileInput::BufFileInput( FILE *f, int buf_size )
: input( f ),
buf( new int[buf_size] ),
size( buf_size ),
start( 0 ),
len( 0 )
{
}
BufFileInput::~BufFileInput()
{
delete [] buf;
}
int BufFileInput::nextChar( void )
{
if( len > 0 )
{
// get char from buffer
int c = buf[start];
if( c != EOF )
{
start++; start %= size;
len--;
}
return c;
} else {
// get char from file
int c = getc( input );
if( c == EOF )
{
// if EOF - put it in the buffer as indicator
buf[start] = EOF;
len++;
}
return c;
}
}
int BufFileInput::lookahead( char* s )
{
int l = strlen( s );
assert( 0 < l && l <= size );
while( len < l )
{
int c = getc( input );
buf[ (start+len) % size ] = c;
len++;
if( c == EOF ) return 0;
}
for( int i = 0; i < l; i++ )
{
if( s[i] != buf[ (start+i) % size ] ) return 0;
}
return 1;
}
// End of file BufFileInput.cpp

View File

@@ -0,0 +1,53 @@
// FILE: BufFileInput.h
// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru
// CREATION: 26-JAN-1998
// DESCRIPTION: File Input Stream with lookahead for Scanner
// Tested under Win32 with ANTLR 1.33 MR10 and MSVC 5.0
// Change History:
//
// 28-May-1998 Add virtual destructor to release buffer
// Manfred Kogler (km@cast.uni-linz.ac.at)
// (1.33MR14)
#ifndef BufFileInput_h
#define BufFileInput_h
#include "pcctscfg.h"
#include "pccts_stdio.h"
PCCTS_NAMESPACE_STD
#include "DLexerBase.h"
class DllExportPCCTS BufFileInput : public DLGInputStream
{
public:
// constructor
// f - input stream
// buf_size - size of buffer (maximal length for string in is_in)
BufFileInput(FILE *f, int buf_size = 8 );
virtual ~BufFileInput();
// gets next char from stream
virtual int nextChar( void );
// looks in stream and compares next l characters with s
// returns the result of comparision
int lookahead( char* s );
private:
FILE *input; // input stream;
int* buf; // buffer
int size; // size of buffer
int start; // position of the first symbol in buffer
int len; // count of characters in buffers
};
#endif
// end of file BufFileInput.h

View File

@@ -0,0 +1,98 @@
/************************************************************/
/* */
/* Predefined char stream: Input from (c++) stream. */
/* */
/* By Hubert Holin (Hubert.Holin@Bigfoot.com), 1998. */
/* */
/* This is completely free stuff, do whatever you want with */
/* it (but then, I will take no responsability for whatever */
/* may happen if you do either... caveat emptor!). */
/* */
/************************************************************/
#ifndef _DLG_STREAM_INPUT_H
#define _DLG_STREAM_INPUT_H
#include "pccts_istream.h"
PCCTS_NAMESPACE_STD
#ifndef DLGX_H
#include "DLexerBase.h"
#endif
// NOTES: The semantics of the copy constructor
// and the affectation operator may be unwaranted...
// and the stream may not be reset.
//
// It would have been so much nicer for nextChar()
// to throw (of for the DLGInputStream to change status)
// upon hiting EOF than to return an "int"...
template <
class E,
class T = ::std::char_traits<E>
>
class DLG_stream_input : public DLGInputStream
{
public:
DLG_stream_input(::std::basic_istream<E,T> * p_input_stream)
: input(p_input_stream)
{
// nothing to do!
};
DLG_stream_input(const DLG_stream_input & a_recopier)
: input(a_recopier.input)
{
// nothing to do!
};
virtual ~DLG_stream_input()
{
this->purge(); // bloody templarized lookup...
};
DLG_stream_input operator = (const DLG_stream_input & a_affecter)
{
if (this != &a_affecter)
{
input = a_affecter.input;
}
return(*this);
};
virtual int nextChar()
{
E extracted_stuff;
input->get(extracted_stuff);
if (*input)
{
return(int(extracted_stuff));
}
else
{
return(EOF);
}
};
protected:
::std::basic_istream<E,T> * input;
private:
void purge()
{
// nothing to do!
};
};
#endif /* _DLG_STREAM_INPUT_H */

View File

@@ -0,0 +1,188 @@
/* DLexer.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-1998
*/
#define ZZINC {if ( track_columns ) (++_endcol);}
#define ZZGETC {ch = input->nextChar(); cl = ZZSHIFT(ch);}
#define ZZNEWSTATE (newstate = dfa[state][cl])
#ifndef ZZCOPY
#define ZZCOPY \
/* Truncate matching buffer to size (not an error) */ \
if (nextpos < lastpos){ \
*(nextpos++) = ch; \
}else{ \
bufovf = 1; \
}
#endif
void DLGLexer::
mode( int m )
{
/* points to base of dfa table */
if (m<MAX_MODE){
automaton = m;
/* have to redo class since using different compression */
cl = ZZSHIFT(ch);
}else{
sprintf((char *)ebuf,"Invalid automaton mode = %d ",m);
errstd(ebuf);
}
}
ANTLRTokenType DLGLexer::
nextTokenType(void)
{
register int state, newstate;
/* last space reserved for the null char */
register DLGChar *lastpos;
ANTLRTokenType tk;
skip:
bufovf = 0;
lastpos = &_lextext[_bufsize-1];
nextpos = _lextext;
_begcol = _endcol+1;
more:
_begexpr = nextpos;
if ( interactive ) {
/* interactive version of automaton */
/* if there is something in ch, process it */
state = newstate = dfa_base[automaton];
if (charfull){
ZZINC;
ZZCOPY;
ZZNEWSTATE;
}
while (alternatives[newstate]){
state = newstate;
ZZGETC;
ZZINC;
ZZCOPY;
ZZNEWSTATE;
}
/* figure out if last character really part of token */
if ((state != dfa_base[automaton]) && (newstate == DfaStates)){
charfull = 1;
--nextpos;
}else{
charfull = 0;
state = newstate;
}
*(nextpos) = '\0';
/* Able to transition out of start state to some non err state?*/
if ( state == dfa_base[automaton] ){
/* make sure doesn't get stuck */
advance();
}
}
else { /* non-interactive version of automaton */
if (!charfull)
advance();
else
ZZINC;
state = dfa_base[automaton];
while (ZZNEWSTATE != DfaStates) {
state = newstate;
ZZCOPY;
ZZGETC;
ZZINC;
}
charfull = 1;
if ( state == dfa_base[automaton] ){
if (nextpos < lastpos){
*(nextpos++) = ch;
}else{
bufovf = 1;
}
*nextpos = '\0';
/* make sure doesn't get stuck */
advance();
}else{
*nextpos = '\0';
}
}
if ( track_columns ) _endcol -= charfull;
_endexpr = nextpos -1;
add_erase = 0;
#ifdef OLD
tk = (ANTLRTokenType)
(*actions[accepts[state]])(this); // must pass this manually
// actions is not a [] of pointers
// to member functions.
#endif
tk = (this->*actions[accepts[state]])();
// MR1
// MR1 11-Apr-97 Help for tracking DLG results
// MR1
#ifdef DEBUG_LEXER
/* MR1 */ if (debugLexerFlag) {
/* MR1 */ if (parser != NULL) {
/* MR1 */ printf("\ntoken name=%s",parser->parserTokenName(tk));
/* MR1 */ } else {
/* MR1 */ printf("\ntoken nnumber=%d",tk);
/* MR1 */ };
/* MR1 */ printf(" lextext=(%s) mode=%d",
/* MR1 */ (_lextext[0]=='\n' && _lextext[1]==0) ?
/* MR1 */ "newline" : _lextext,
/* MR1 */ automaton);
/* MR1 */ if (interactive && !charfull) {
/* MR1 */ printf(" char=empty");
/* MR1 */ } else {
/* MR1 */ if (ch=='\n') {
/* MR1 */ printf(" char=newline");
/* MR1 */ } else {
/* MR1 */ printf(" char=(%c)",ch);
/* MR1 */ };
/* MR1 */ };
/* MR1 */ printf(" %s\n",
/* MR1 */ (add_erase==1 ? "skip()" :
/* MR1 */ add_erase==2 ? "more()" :
/* MR1 */ ""));
/* MR1 */ };
#endif
switch (add_erase) {
case 1: goto skip;
case 2: goto more;
}
return tk;
}
void DLGLexer::
advance()
{
if ( input==NULL ) err_in();
ZZGETC; charfull = 1; ZZINC;
}

View File

@@ -0,0 +1,268 @@
/* DLGLexerBase.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-1998
*/
#include "pcctscfg.h"
#include "pccts_stdio.h"
#include "pccts_stdlib.h"
PCCTS_NAMESPACE_STD
/* I have to put this here due to C++ limitation
* that you can't have a 'forward' decl for enums.
* I hate C++!!!!!!!!!!!!!!!
*/
// MR1
// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the
// MR1 ANTLRTokenType enum
// MR1
enum ANTLRTokenType { TER_HATES_CPP=0, ITS_UTTER_GARBAGE, // MR1
WITH_SOME_GOOD_IDEAS=9999}; // MR1
#define ANTLR_SUPPORT_CODE
#include "pcctscfg.h"
#include DLEXERBASE_H
DLGLexerBase::
DLGLexerBase(DLGInputStream *in,
unsigned bufsize,
int _interactive,
int _track_columns)
{
this->_bufsize = bufsize;
this->_lextext = new DLGChar[_bufsize];
if ( this->_lextext==NULL ) {
panic("text buffer is NULL");
}
this->_begexpr = this->_endexpr = NULL;
this->ch = this->bufovf = 0;
this->nextpos = NULL;
this->cl = 0;
this->add_erase = 0;
this->input = in;
this->_begcol = 0;
this->_endcol = 0;
this->_line = 1;
this->charfull = 0;
this->automaton = 0;
this->token_to_fill = NULL;
this->interactive = _interactive;
this->track_columns = _track_columns;
this->debugLexerFlag = 0; // MR1
this->parser = NULL; // MR1
this->lexErrCount=0; // MR11
}
// MR19 THM
void DLGLexerBase::reset()
{
this->charfull = 0;
this->_begcol = 0;
this->_endcol = 0;
this->automaton = 0;
this->_line=1;
this->lexErrCount=0;
}
void DLGLexerBase::
setInputStream( DLGInputStream *in )
{
this->input = in;
_line = 1;
charfull = 0;
}
/* saves dlg state, but not what feeds dlg (such as file position) */
void DLGLexerBase::
saveState(DLGState *state)
{
state->input = input;
state->interactive = interactive;
state->track_columns = track_columns;
state->auto_num = automaton;
state->add_erase = add_erase;
state->lookc = ch;
state->char_full = charfull;
state->begcol = _begcol;
state->endcol = _endcol;
state->line = _line;
state->lextext = _lextext;
state->begexpr = _begexpr;
state->endexpr = _endexpr;
state->bufsize = _bufsize;
state->bufovf = bufovf;
state->nextpos = nextpos;
state->class_num = cl;
state->debugLexerFlag = debugLexerFlag; // MR1
state->parser = parser; // MR1
}
void DLGLexerBase::
restoreState(DLGState *state)
{
input = state->input;
interactive = state->interactive;
track_columns = state->track_columns;
automaton = state->auto_num;
add_erase = state->add_erase;
ch = state->lookc;
charfull = state->char_full;
_begcol = state->begcol;
_endcol = state->endcol;
_line = state->line;
_lextext = state->lextext;
_begexpr = state->begexpr;
_endexpr = state->endexpr;
_bufsize = state->bufsize;
bufovf = state->bufovf;
nextpos = state->nextpos;
cl = state->class_num;
debugLexerFlag = state->debugLexerFlag; // MR1
parser = state->parser; // MR1
}
/* erase what is currently in the buffer, and get a new reg. expr */
void DLGLexerBase::
skip()
{
add_erase = 1;
}
/* don't erase what is in the lextext buffer, add on to it */
void DLGLexerBase::
more()
{
add_erase = 2;
}
/* substitute c for the reg. expr last matched and is in the buffer */
void DLGLexerBase::
replchar(DLGChar c)
{
/* can't allow overwriting null at end of string */
if (_begexpr < &_lextext[_bufsize-1]){
*_begexpr = c;
*(_begexpr+1) = '\0';
}
_endexpr = _begexpr;
nextpos = _begexpr + 1;
}
/* replace the string s for the reg. expr last matched and in the buffer */
void DLGLexerBase::
replstr(const DLGChar *s) /* MR20 const */
{
register DLGChar *l= &_lextext[_bufsize -1];
nextpos = _begexpr;
if (s){
while ((nextpos <= l) && (*(nextpos++) = *(s++))){
/* empty */
}
/* correct for NULL at end of string */
nextpos--;
}
if ((nextpos <= l) && (*(--s) == 0)){
bufovf = 0;
}else{
bufovf = 1;
}
*(nextpos) = '\0';
_endexpr = nextpos - 1;
}
void DLGLexerBase::
errstd(const char *s) /* MR20 const */
{
lexErrCount++; /* MR11 */
fprintf(stderr,
"%s near line %d (text was '%s')\n",
((s == NULL) ? "Lexical error" : s),
_line,_lextext);
}
int DLGLexerBase::
err_in()
{
fprintf(stderr,"No input stream, function, or string\n");
/* return eof to get out gracefully */
return EOF;
}
ANTLRTokenType DLGLexerBase::
erraction()
{
errstd("invalid token");
advance();
skip();
return (ANTLRTokenType) 0; // bogus, but satisfies compiler
}
_ANTLRTokenPtr DLGLexerBase::
getToken()
{
if ( token_to_fill==NULL ) panic("NULL token_to_fill");
ANTLRTokenType tt = nextTokenType();
_ANTLRTokenPtr tk = token_to_fill->makeToken(tt, _lextext,_line);
return tk;
}
void DLGLexerBase::
panic(const char *msg) /* MR20 const */
{
fprintf(stderr, "DLG panic: %s\n", msg);
//
// 7-Apr-97 133MR1
//
exit(PCCTS_EXIT_FAILURE); // MR1
}
ANTLRParser * DLGLexerBase:: // MR1
setParser(ANTLRParser *p) { // MR1
ANTLRParser *oldValue=parser; // MR1
parser=p; // MR1
return oldValue; // MR1
} // MR1
// MR1
ANTLRParser * DLGLexerBase:: // MR1
getParser() { // MR1
return parser; // MR1
} // MR1
// MR1
int DLGLexerBase:: // MR1
debugLexer(int newValue) { // MR1
int oldValue=debugLexerFlag; // MR1
debugLexerFlag=newValue; // MR1
return oldValue; // MR1
} // MR1

View File

@@ -0,0 +1,197 @@
/* DLGLexerBase.h
*
* 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-1998
*/
#ifndef DLGX_H
#define DLGX_H
#include "pcctscfg.h"
#include "pccts_stdio.h"
PCCTS_NAMESPACE_STD
#include ATOKEN_H
#include ATOKENSTREAM_H
class ANTLRParser; // MR1
/* must define what a char looks like; can make this a class too */
typedef char DLGChar;
/* Can have it as a class too: (ack this looks weird; is it right?)
class DllExportPCCTS DLGChar {
private:
int c;
public:
DLGChar(int ch) { c = ch; }
int atom() { return c; }
};
*/
/* user must subclass this */
class DllExportPCCTS DLGInputStream {
public:
virtual int nextChar() = 0;
};
/* Predefined char stream: Input from FILE */
class DllExportPCCTS DLGFileInput : public DLGInputStream {
private:
int found_eof;
FILE *input;
public:
DLGFileInput(FILE *f) { input = f; found_eof = 0; }
int nextChar() {
int c;
if ( found_eof ) return EOF;
else {
c=getc(input);
if ( c==EOF ) found_eof = 1;
return c;
}
}
void DLGFileReset(FILE *f) {input=f; found_eof = 0; }; // MR11
};
// MR9 Suggested by Bruce Guenter (bruceg@qcc.sk.ca)
// MR9 Make DLGStringInput const correct
/* Predefined char stream: Input from string */
class DllExportPCCTS DLGStringInput : public DLGInputStream {
private:
const DLGChar *input; // MR9
const DLGChar *p; // MR9
public:
DLGStringInput(const DLGChar *s) { input = s; p = &input[0];} // MR9
int nextChar()
{
if (*p) return (int) (unsigned char) *p++; // MR14
else return EOF;
}
void DLGStringReset(const DLGChar *s) {input=s; p= &input[0]; }; // MR11 // MR16
};
class DllExportPCCTS DLGState {
public:
DLGInputStream *input;
int interactive;
int track_columns;
int auto_num;
int add_erase;
int lookc;
int char_full;
int begcol, endcol;
int line;
DLGChar *lextext, *begexpr, *endexpr;
int bufsize;
int bufovf;
DLGChar *nextpos;
int class_num;
int debugLexerFlag; // MR1
ANTLRParser *parser; // MR1
};
/* user must subclass this */
class DllExportPCCTS DLGLexerBase : public ANTLRTokenStream {
public:
virtual ANTLRTokenType erraction();
protected:
DLGInputStream *input;
int interactive;
int track_columns;
DLGChar *_lextext; /* text of most recently matched token */
DLGChar *_begexpr; /* beginning of last reg expr recogn. */
DLGChar *_endexpr; /* beginning of last reg expr recogn. */
int _bufsize; /* number of characters in lextext */
int _begcol; /* column that first character of token is in*/
int _endcol; /* column that last character of token is in */
int _line; /* line current token is on */
int ch; /* character to determine next state */
int bufovf; /* indicates that buffer too small for text */
int charfull;
DLGChar *nextpos; /* points to next available position in lextext*/
int cl;
int automaton;
int add_erase;
DLGChar ebuf[70];
_ANTLRTokenPtr token_to_fill;
int debugLexerFlag; // MR1
ANTLRParser *parser; // MR1
public:
virtual _ANTLRTokenPtr getToken(); // MR12 public
virtual void advance(void) = 0;
void skip(void); /* erase lextext, look for antoher token */
void more(void); /* keep lextext, look for another token */
void mode(int k); /* switch to automaton 'k' */
void saveState(DLGState *);
void restoreState(DLGState *);
virtual ANTLRTokenType nextTokenType(void)=0;/* get next token */
void replchar(DLGChar c); /* replace last recognized reg. expr. with
a character */
void replstr(const DLGChar *s); /* replace last recognized reg. expr. with
a string */ /* MR20 const */
virtual int err_in(); // MR1
virtual void errstd(const char *); // MR1 MR20 const
int line() { return _line; }
void set_line(int newValue) { _line=newValue; }; // MR1
virtual void newline() { _line++; }
DLGChar *lextext() { return _lextext; }
int begcol() { return _begcol; }
int endcol() { return _endcol; }
void set_begcol(int a) { _begcol=a; }
void set_endcol(int a) { _endcol=a; }
DLGChar *begexpr() { return _begexpr; }
DLGChar *endexpr() { return _endexpr; }
int bufsize() { return _bufsize; }
void setToken(ANTLRAbstractToken *t) { token_to_fill = t; }
void setInputStream(DLGInputStream *);
DLGLexerBase(DLGInputStream *in,
unsigned bufsize=2000,
int interactive=0,
int track_columns=0);
void reset(); // MR19
virtual ~DLGLexerBase() { delete [] _lextext; }
virtual void panic(const char *msg); // MR1 MR20 const
void trackColumns() {
track_columns = 1;
this->_begcol = 0;
this->_endcol = 0;
};
virtual ANTLRParser *setParser(ANTLRParser *p); // MR1
virtual ANTLRParser *getParser(); // MR1
virtual int debugLexer(int value); // MR1
int lexErrCount; // MR12
};
#endif

View File

@@ -0,0 +1,104 @@
#ifndef PBLACKBOX_H
#define PBLACKBOX_H
/*
* 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-1998
*/
#include "pcctscfg.h"
#include "pccts_iostream.h"
PCCTS_NAMESPACE_STD
// MR20 Added #include for "DLexerBase.h"
#include "DLexerBase.h"
//
// The default buffer size of the lexer is given by the
// second argument of the lexer's ctor. It is optional
// and defaults to 2000
//
template<class Lexer, class Parser, class Token>
class DllExportPCCTS ParserBlackBox {
protected:
DLGFileInput *in;
Lexer *scan;
_ANTLRTokenPtr tok;
ANTLRTokenBuffer *pipe;
Parser *_parser;
FILE *file;
int openByBlackBox; /* MR21 Don't close what we haven't opened */
public:
ParserBlackBox(FILE *f)
{
openByBlackBox = 0; /* MR21a */
file = f;
in = new DLGFileInput(f);
scan = new Lexer(in);
pipe = new ANTLRTokenBuffer(scan);
tok = new Token;
scan->setToken(tok);
_parser = new Parser(pipe);
_parser->init();
}
ParserBlackBox(char *fname)
{
FILE *f = fopen(fname, "r");
if ( f==NULL ) {
openByBlackBox = 0;
cerr << "cannot open " << fname << "\n"; return;
}
else {
openByBlackBox = 1;
file = f;
in = new DLGFileInput(f);
scan = new Lexer(in);
pipe = new ANTLRTokenBuffer(scan);
tok = new Token;
scan->setToken(tok);
_parser = new Parser(pipe);
_parser->init();
}
}
~ParserBlackBox()
{
delete in; delete scan; delete pipe; delete _parser; delete tok;
if (1 == openByBlackBox) {
fclose(file);
}
}
Parser *parser() { return _parser; }
Lexer *getLexer() { return scan; }
};
#endif

View File

@@ -0,0 +1,662 @@
/*
* PCCTSAST.C
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B14 and ANTLR 1.33
* Terence Parr
* Parr Research Corporation
* AHPCRC, University of Minnesota
* 1992-1998
*/
#define ANTLR_SUPPORT_CODE
#include "pcctscfg.h"
#include "PCCTSAST.h"
#include "pccts_stdarg.h"
PCCTS_NAMESPACE_STD
#include <ctype.h>
//#include "SList.h"
/* String Scanning/Parsing Stuff */
const char *PCCTS_AST::scan_token_tbl[] = { /* MR20 const */
"invalid", /* 0 */
"LPAREN", /* 1 */
"RPAREN", /* 2 */
"PERCENT", /* 3 */
"INT", /* 4 */
"COLON", /* 5 */
"POUND", /* 6 */
"PERIOD", /* 7 */
};
void PCCTS_AST::
addChild(PCCTS_AST *t)
{
if ( t==NULL ) return;
PCCTS_AST *s = down();
if ( s!=NULL )
{
while ( s->right()!=NULL ) s = s->right();
s->setRight(t);
}
else
this->setDown(t);
}
void PCCTS_AST::
lisp(FILE *f)
{
if ( down() != NULL ) fprintf(f," (");
lisp_action(f);
if ( down()!=NULL ) down()->lisp(f);
if ( down() != NULL ) fprintf(f," )");
if ( right()!=NULL ) right()->lisp(f);
}
/* build a tree (root child1 child2 ... NULL)
* If root is NULL, simply make the children siblings and return ptr
* to 1st sibling (child1). If root is not single node, return NULL.
*
* Siblings that are actually sibling lists themselves are handled
* correctly. For example #( NULL, #( NULL, A, B, C), D) results
* in the tree ( NULL A B C D ).
*
* Requires at least two parameters with the last one being NULL. If
* both are NULL, return NULL.
*
* The down() and right() down/right pointers are used to make the tree.
*/
PCCTS_AST *PCCTS_AST::
make(PCCTS_AST *rt, ...)
{
va_list ap;
register PCCTS_AST *child, *sibling=NULL, *tail, *w;
PCCTS_AST *root;
va_start(ap, rt);
root = rt;
if ( root != NULL )
if ( root->down() != NULL ) return NULL;
child = va_arg(ap, PCCTS_AST *);
while ( child != NULL )
{
/* find end of child */
for (w=child; w->right()!=NULL; w=w->right()) {;}
if ( sibling == NULL ) {sibling = child; tail = w;}
else {tail->setRight(child); tail = w;}
child = va_arg(ap, PCCTS_AST *);
}
if ( root==NULL ) root = sibling;
else root->setDown(sibling);
va_end(ap);
return root;
}
/* The following push and pop routines are only used by ast_find_all() */
void PCCTS_AST::
_push(PCCTS_AST **st, int *sp, PCCTS_AST *e)
{
(*sp)--;
require((*sp)>=0, "stack overflow");
st[(*sp)] = e;
}
PCCTS_AST *PCCTS_AST::
_pop(PCCTS_AST **st, int *sp)
{
PCCTS_AST *e = st[*sp];
(*sp)++;
require((*sp)<=MaxTreeStackDepth, "stack underflow");
return e;
}
/* Find all occurrences of u in t.
* 'cursor' must be initialized to 't'. It eventually
* returns NULL when no more occurrences of 'u' are found.
*/
PCCTS_AST *PCCTS_AST::
ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor)
{
PCCTS_AST *sib;
static PCCTS_AST *template_stack[MaxTreeStackDepth];
static int tsp = MaxTreeStackDepth;
static int nesting = 0;
if ( *cursor == NULL ) return NULL;
if ( *cursor!=this ) sib = *cursor;
else {
/* else, first time--start at top of template 't' */
tsp = MaxTreeStackDepth;
sib = this;
/* bottom of stack is always a NULL--"cookie" indicates "done" */
_push(template_stack, &tsp, NULL);
}
keep_looking:
if ( sib==NULL ) /* hit end of sibling list */
{
sib = _pop(template_stack, &tsp);
if ( sib == NULL ) { *cursor = NULL; return NULL; }
}
if ( sib->type() != u->type() )
{
/* look for another match */
if ( sib->down()!=NULL )
{
if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
sib=sib->down();
goto keep_looking;
}
/* nothing below to try, try next sibling */
sib=sib->right();
goto keep_looking;
}
/* found a matching root node, try to match what's below */
if ( match_partial(sib, u) )
{
/* record sibling cursor so we can pick up next from there */
if ( sib->down()!=NULL )
{
if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
*cursor = sib->down();
}
else if ( sib->right()!=NULL ) *cursor = sib->right();
else *cursor = _pop(template_stack, &tsp);
return sib;
}
/* no match, keep searching */
if ( sib->down()!=NULL )
{
if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
sib=sib->down();
}
else sib = sib->right(); /* else, try to right if zip below */
goto keep_looking;
}
/* are two trees exactly alike? */
int PCCTS_AST::
match(PCCTS_AST *u)
{
PCCTS_AST *t = this;
PCCTS_AST *sib;
if ( u==NULL ) return 0;
for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
{
if ( sib->type() != u->type() ) return 0;
if ( sib->down()!=NULL )
if ( !sib->down()->match(u->down()) ) return 0;
}
return 1;
}
/* Is 'u' a subtree of 't' beginning at the root? */
int PCCTS_AST::
match_partial(PCCTS_AST *t, PCCTS_AST *u)
{
PCCTS_AST *sib;
if ( u==NULL ) return 1;
if ( t==NULL ) if ( u!=NULL ) return 0; else return 1;
for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
{
if ( sib->type() != u->type() ) return 0;
if ( sib->down()!=NULL )
if ( !match_partial(sib->down(), u->down()) ) return 0;
}
return 1;
}
/* Walk the template tree 't' (matching against 'this'), filling in the
* 'labels' array, and setting 'n' according to how many labels were matched.
*/
int PCCTS_AST::
scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n)
{
ScanAST *sib;
PCCTS_AST *u = this;
if ( u==NULL ) return 0;
for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
{
/* make sure tokens match; token of '0' means wildcard match */
if ( sib->type() != u->type() && sib->type()!=0 ) return 0;
/* we have a matched token here; set label pointers if exists */
if ( sib->label_num>0 )
{
require(labels!=NULL, "label found in template, but no array of labels");
(*n)++;
*(labels[sib->label_num-1]) = u;
}
/* match what's below if something there and current node is not wildcard */
if ( sib->down()!=NULL && sib->type()!=0 )
{
if ( sib->down()==NULL ) if ( u->down()!=NULL ) return 0; else return 1;
if ( !u->down()->scanmatch(sib->down(), labels, n) ) return 0;
}
}
return 1;
}
void PCCTS_AST::
insert_after(PCCTS_AST *b)
{
PCCTS_AST *end;
if ( b==NULL ) return;
/* find end of b's child list */
for (end=b; end->right()!=NULL; end=end->right()) {;}
end->setRight(this->right());
this->setRight(b);
}
void PCCTS_AST::
append(PCCTS_AST *b)
{
PCCTS_AST *end;
require(b!=NULL, "append: NULL input tree");
/* find end of child list */
for (end=this; end->right()!=NULL; end=end->right()) {;}
end->setRight(b);
}
PCCTS_AST *PCCTS_AST::
tail()
{
PCCTS_AST *end;
/* find end of child list */
for (end=this; end->right()!=NULL; end=end->right()) {;}
return end;
}
PCCTS_AST *PCCTS_AST::
bottom()
{
PCCTS_AST *end;
/* find end of child list */
for (end=this; end->down()!=NULL; end=end->down()) {;}
return end;
}
PCCTS_AST *PCCTS_AST::
cut_between(PCCTS_AST *a, PCCTS_AST *b)
{
PCCTS_AST *end, *ret;
if (a==NULL||b==NULL) return NULL;
/* find node pointing to b */
for (end=a; end->right()!=NULL&&end->right()!=b; end=end->right())
{;}
if (end->right()==NULL) return NULL; //ast_cut_between: a,b not connected
end->setRight(NULL); /* don't want it point to 'b' anymore */
ret = a->right();
a->setRight(b);
return ret;
}
#ifdef NOT_YET
SList *PCCTS_AST::
to_slist()
{
SList *list = new SList;
PCCTS_AST *p;
for (p=this; p!=NULL; p=p->right())
{
list->add(p);
}
return list;
}
#endif
void PCCTS_AST::
tfree()
{
PCCTS_AST *t = this;
if ( t->down()!=NULL ) t->down()->tfree();
if ( t->right()!=NULL ) t->right()->tfree();
delete t;
}
int PCCTS_AST::
nsiblings()
{
PCCTS_AST *t = this;
int n=0;
while ( t!=NULL )
{
n++;
t = t->right();
}
return n;
}
PCCTS_AST *PCCTS_AST::
sibling_index(int i)
{
PCCTS_AST *t = this;
int j=1;
require(i>0, "sibling_index: i<=0");
while ( t!=NULL )
{
if ( j==i ) return t;
j++;
t = t->right();
}
return NULL;
}
/* Assume this is a root node of a tree--
* duplicate that node and what's below; ignore siblings of root node.
*/
// MR9 23-Sep-97 RJV
// MR9
// MR9 RJV: Original version only duplicated the node and down elements.
// MR9 Made copies of the pointers to sibling.
// MR9 Changed call "down()->deepCopy()" to "down()->deepCopyBushy()"
// MR9
PCCTS_AST *PCCTS_AST::
deepCopy()
{
PCCTS_AST *u = this->shallowCopy();
if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());
u->setRight(NULL);
return u;
}
/* Copy all nodes including siblings of root. */
PCCTS_AST *PCCTS_AST::
deepCopyBushy()
{
PCCTS_AST *u = this->shallowCopy();
/* copy the rest of the tree */
if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());
if ( right()!=NULL ) u->setRight(right()->deepCopyBushy());
return u;
}
void PCCTS_AST::
scanast_free(ScanAST *t)
{
if ( t == NULL ) return;
scanast_free( t->down() );
scanast_free( t->right() );
free( (char *) t ); // MR1
}
/*
* scan
*
* This function is like scanf(): it attempts to match a template
* against an input tree. A variable number of tree pointers
* may be set according to the '%i' labels in the template string.
* For example:
*
* t->ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )",
* &w, &x, &y, &z);
*
* Naturally, you'd want this converted from
*
* t->ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )",
* &w, &x, &y, &z);
*
* by SORCERER.
*
* This function call must be done withing a SORCERER file because SORCERER
* must convert the token references to the associated token number.
*
* This functions parses the template and creates trees which are then
* matched against the input tree. The labels are set as they are
* encountered; hence, partial matches may leave some pointers set
* and some NULL. This routines initializes all argument pointers to NULL
* at the beginning.
*
* This function returns the number of labels matched.
*/
int PCCTS_AST::
ast_scan(char *templ, ...)
{
va_list ap;
ScanAST *tmpl;
int n, i, found=0;
PCCTS_AST ***label_ptrs=NULL;
va_start(ap, templ);
/* make a ScanAST tree out of the template */
tmpl = stringparser_parse_scanast(templ, &n);
/* make an array out of the labels */
if ( n>0 )
{
label_ptrs = (PCCTS_AST ***) calloc(n, sizeof(PCCTS_AST **));
require(label_ptrs!=NULL, "scan: out of memory");
for (i=1; i<=n; i++)
{
label_ptrs[i-1] = va_arg(ap, PCCTS_AST **);
*(label_ptrs[i-1]) = NULL;
}
}
/* match the input tree against the template */
scanmatch(tmpl, label_ptrs, &found);
scanast_free(tmpl);
free( (char *) label_ptrs); // MR1
return found;
}
ScanAST *PCCTS_AST::
new_scanast(int tok)
{
ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST));
//
// 7-Apr-97 133MR1
//
if ( p == NULL ) { // MR1
fprintf(stderr, "out of mem\n"); // MR1
exit(PCCTS_EXIT_FAILURE); // MR1
}; // MR1
p->_token = tok;
return p;
}
ScanAST *PCCTS_AST::
stringparser_parse_scanast(char *templ, int *num_labels)
{
StringLexer lex;
StringParser parser;
ScanAST *t;
stringlexer_init(&lex, templ);
stringparser_init(&parser, &lex);
t = stringparser_parse_tree(&parser);
*num_labels = parser.num_labels;
return t;
}
void PCCTS_AST::
stringparser_match(StringParser *parser, int token)
{
if ( parser->token != token ) panic("bad tree in scan()");
}
/*
* Match a tree of the form:
* (root child1 child2 ... childn)
* or,
* node
*
* where the elements are integers or labeled integers.
*/
ScanAST *PCCTS_AST::
stringparser_parse_tree(StringParser *parser)
{
ScanAST *t=NULL, *root, *child, *last;
if ( parser->token != __POUND )
{
return stringparser_parse_element(parser);
}
stringparser_match(parser,__POUND);
parser->token = stringscan_gettok(parser->lexer);
stringparser_match(parser,__LPAREN);
parser->token = stringscan_gettok(parser->lexer);
root = stringparser_parse_element(parser);
while ( parser->token != __RPAREN )
{
child = stringparser_parse_element(parser);
if ( t==NULL ) { t = child; last = t; }
else { last->_right = child; last = child; }
}
stringparser_match(parser,__RPAREN);
parser->token = stringscan_gettok(parser->lexer);
root->_down = t;
return root;
}
ScanAST *PCCTS_AST::
stringparser_parse_element(StringParser *parser)
{
static char ebuf[100];
int label = 0;
if ( parser->token == __POUND )
{
return stringparser_parse_tree(parser);
}
if ( parser->token == __PERCENT )
{
parser->token = stringscan_gettok(parser->lexer);
stringparser_match(parser,__INT);
label = atoi(parser->lexer->text);
parser->num_labels++;
if ( label==0 ) panic("%%0 is an invalid label");
parser->token = stringscan_gettok(parser->lexer);
stringparser_match(parser,__COLON);
parser->token = stringscan_gettok(parser->lexer);
/* can label tokens and wildcards */
if ( parser->token != __INT && parser->token != __PERIOD )
panic("can only label tokens");
}
if ( parser->token == __INT )
{
ScanAST *p = new_scanast(atoi(parser->lexer->text));
parser->token = stringscan_gettok(parser->lexer);
p->label_num = label;
return p;
}
if ( parser->token == __PERIOD )
{
ScanAST *p = new_scanast(0); /* token of 0 is wildcard */
parser->token = stringscan_gettok(parser->lexer);
p->label_num = label;
return p;
}
sprintf(ebuf, "mismatch token in scan(): %s", scan_token_str(parser->token));
panic(ebuf);
return NULL;
}
void PCCTS_AST::
stringparser_init(StringParser *parser, StringLexer *input)
{
parser->lexer = input;
parser->token = stringscan_gettok(parser->lexer);
parser->num_labels = 0;
}
void PCCTS_AST::
stringlexer_init(StringLexer *scanner, char *input)
{
scanner->text[0]='\0';
scanner->input = input;
scanner->p = input;
stringscan_advance(scanner);
}
void PCCTS_AST::
stringscan_advance(StringLexer *scanner)
{
if ( *(scanner->p) == '\0' ) scanner->c = __StringScanEOF;
scanner->c = *(scanner->p)++;
}
int PCCTS_AST::
stringscan_gettok(StringLexer *scanner)
{
char *index = &scanner->text[0];
static char ebuf[100];
while ( isspace(scanner->c) ) { stringscan_advance(scanner); }
if ( isdigit(scanner->c) )
{
int tok = __INT;
while ( isdigit(scanner->c) ) {
*index++ = scanner->c;
stringscan_advance(scanner);
}
*index = '\0';
return tok;
}
switch ( scanner->c )
{
case '#' : stringscan_advance(scanner); return __POUND;
case '(' : stringscan_advance(scanner); return __LPAREN;
case ')' : stringscan_advance(scanner); return __RPAREN;
case '%' : stringscan_advance(scanner); return __PERCENT;
case ':' : stringscan_advance(scanner); return __COLON;
case '.' : stringscan_advance(scanner); return __PERIOD;
case '\0' : return __StringScanEOF;
case __StringScanEOF : return __StringScanEOF;
default :
sprintf(ebuf, "invalid char in scan: '%c'", scanner->c);
panic(ebuf);
}
return __StringScanEOF; // never reached
}
const char *PCCTS_AST:: /* MR20 const */
scan_token_str(int t)
{
if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t];
else if ( t==__StringScanEOF ) return "<end-of-string>";
else return "<invalid-token>";
}

View File

@@ -0,0 +1,142 @@
/* Abstract syntax tree
*
* 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-1998
*/
#ifndef PCCTSAST_H
#define PCCTSAST_H
#include "pcctscfg.h"
#include "pccts_stdio.h"
#include "pccts_stdlib.h"
PCCTS_NAMESPACE_STD
//class SList;
#define StringScanMaxText 50
#define MaxTreeStackDepth 400
//
// 7-Apr-97 133MR1 signed int not accepted by AT&T cfront
//
typedef struct stringlexer {
int c; // MR1
char *input;
char *p;
char text[StringScanMaxText];
} StringLexer;
/* Define the structures needed for ast_scan() */
typedef struct stringparser {
int token;
StringLexer *lexer;
int num_labels;
} StringParser;
typedef struct _scanast {
struct _scanast *_right, *_down;
int _token;
int label_num;
int type() { return _token; }
struct _scanast *right() { return _right; }
struct _scanast *down() { return _down; }
} ScanAST;
#define VALID_SCAN_TOKEN(t) (t>=__LPAREN && t<=__PERIOD)
class DllExportPCCTS PCCTS_AST {
protected:
static const char *scan_token_tbl[]; /* MR20 const */
enum {
__LPAREN=1,
__RPAREN=2,
__PERCENT=3,
__INT=4,
__COLON=5,
__POUND=6,
__PERIOD=7,
__StringScanEOF=-1};
protected:
const char *scan_token_str(int t); /* MR20 const */
void stringlexer_init(StringLexer *scanner, char *input);
void stringparser_init(StringParser *, StringLexer *);
ScanAST *stringparser_parse_scanast(char *templ, int *n);
ScanAST *stringparser_parse_tree(StringParser *parser);
ScanAST *stringparser_parse_element(StringParser *parser);
void stringscan_advance(StringLexer *scanner);
int stringscan_gettok(StringLexer *scanner);
void _push(PCCTS_AST **st, int *sp, PCCTS_AST *e);
PCCTS_AST *_pop(PCCTS_AST **st, int *sp);
int match_partial(PCCTS_AST *t, PCCTS_AST *u);
int scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n);
void scanast_free(ScanAST *t);
ScanAST *new_scanast(int tok);
void stringparser_match(StringParser *parser, int type);
virtual PCCTS_AST *deepCopyBushy();
public:
PCCTS_AST() {;}
virtual ~PCCTS_AST() {;}
/* This group must be defined for SORCERER to work correctly */
virtual PCCTS_AST *right() = 0;
virtual PCCTS_AST *down() = 0;
virtual void setRight(PCCTS_AST *t) = 0;
virtual void setDown(PCCTS_AST *t) = 0;
// we define these so ANTLR doesn't have to
virtual int type() { return 0; }
virtual void setType(int t) {;}
virtual PCCTS_AST *shallowCopy() {panic("no shallowCopy() defined"); return NULL;}
/* These are not needed by ANTLR, but are support functions */
virtual PCCTS_AST *deepCopy(); // used by SORCERER in transform mode
virtual void addChild(PCCTS_AST *t);
virtual void lisp_action(FILE *f) {;}
virtual void lisp(FILE *f);
static PCCTS_AST *make(PCCTS_AST *rt, ...);
virtual PCCTS_AST *ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor);
virtual int match(PCCTS_AST *u);
virtual void insert_after(PCCTS_AST *b);
virtual void append(PCCTS_AST *b);
virtual PCCTS_AST *tail();
virtual PCCTS_AST *bottom();
static PCCTS_AST *cut_between(PCCTS_AST *a, PCCTS_AST *b);
// virtual SList *to_slist();
virtual void tfree();
int ast_scan(char *templ, ...);
virtual int nsiblings();
virtual PCCTS_AST *sibling_index(int i);
void require(int e,const char *err){ if ( !e ) panic(err); } /* MR20 const */
virtual void panic(const char *err) // MR20 const
{ fprintf(stderr, "PCCTS_AST: %s\n", err); exit(PCCTS_EXIT_FAILURE); }
};
#endif /* PCCTSAST_H */

View File

@@ -0,0 +1,71 @@
#ifndef SList_h
#define SList_h
/*
* SList.h
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* PCCTS 1.33
* Terence Parr
* Parr Research Corporation
* with Purdue University and AHPCRC, University of Minnesota
* 1992-1998
*/
#include "pcctscfg.h"
#include "pccts_stdio.h"
#include "pccts_stdlib.h"
PCCTS_NAMESPACE_STD
#include "PCCTSAST.h"
class PCCTS_AST;
class SListNode {
protected:
void *_elem; /* pointer to any kind of element */
SListNode *_next;
public:
SListNode() {_elem=_next=NULL;}
virtual ~SListNode() {_elem=_next=NULL;}
void *elem() { return _elem; }
void setElem(void *e) { _elem = e; }
void setNext(SListNode *t) { _next = t; }
SListNode *next() { return _next; }
};
class SList {
SListNode *head, *tail;
public:
SList() {head=tail=NULL;}
virtual ~SList() {head=tail=NULL;}
virtual void *iterate(SListNode **);
virtual void add(void *e);
virtual void lfree();
virtual PCCTS_AST *to_ast(SList list);
virtual void require(int e,char *err){ if ( !e ) panic(err); }
virtual void panic(char *err){ fprintf(stderr, "SList panic: %s\n", err); exit(PCCTS_EXIT_FAILURE); }
};
#endif

View File

@@ -0,0 +1,788 @@
/* antlr.h
*
* 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-1998
*/
#ifndef ANTLR_H
#define ANTLR_H
#include "pcctscfg.h"
#include "pccts_stdio.h"
/* turn off warnings for unreferenced labels */
#ifdef _MSC_VER
#pragma warning(disable:4102)
#endif
/*
* Define all of the stack setup and manipulation of $i, #i variables.
*
* Notes:
* The type 'Attrib' must be defined before entry into this .h file.
*/
#ifdef __USE_PROTOS
#include "pccts_stdlib.h"
#else
#ifdef VAXC
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#endif
#include "pccts_string.h"
#if 0
#include "set.h"
#endif
typedef int ANTLRTokenType;
typedef unsigned char SetWordType;
typedef char ANTLRChar;
/* G u e s s S t u f f */
#ifdef ZZCAN_GUESS
#ifndef ZZINF_LOOK
#define ZZINF_LOOK
#endif
#endif
#ifdef ZZCAN_GUESS
typedef struct _zzjmp_buf {
jmp_buf state;
} zzjmp_buf;
#endif
/* can make this a power of 2 for more efficient lookup */
#ifndef ZZLEXBUFSIZE
#define ZZLEXBUFSIZE 8000 /* MR22 raise from 2k to 8k */
#endif
#define zzOvfChk \
if ( zzasp <= 0 ) \
{ \
fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \
exit(PCCTS_EXIT_FAILURE); \
}
#ifndef ZZA_STACKSIZE
#define ZZA_STACKSIZE 400
#endif
#ifndef ZZAST_STACKSIZE
#define ZZAST_STACKSIZE 400
#endif
#ifndef zzfailed_pred
#ifdef ZZCAN_GUESS
#define zzfailed_pred(_p) \
if (zzguessing) { \
zzGUESS_FAIL; \
} else { \
fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p); \
}
#else
#define zzfailed_pred(_p) \
fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p)
#endif
#endif
/* MR19 zzchar_t additions */
#ifdef LL_K
#define LOOKAHEAD \
int zztokenLA[LL_K]; \
zzchar_t zztextLA[LL_K][ZZLEXBUFSIZE]; \
int zzlap = 0, zzlabase=0; /* labase only used for DEMAND_LOOK */
#else
#define LOOKAHEAD \
int zztoken;
#endif
#ifndef zzcr_ast
#define zzcr_ast(ast,attr,tok,text)
#endif
#ifdef DEMAND_LOOK
#define DemandLookData int zzdirty=1;
#else
#define DemandLookData
#endif
#ifndef zzUSER_GUESS_HOOK
#define zzUSER_GUESS_HOOK(seqFrozen,zzrv)
#endif
#ifndef zzUSER_GUESS_DONE_HOOK
#define zzUSER_GUESS_DONE_HOOK(seqFrozen)
#endif
/* S t a t e S t u f f */
#ifdef ZZCAN_GUESS
#define zzGUESS_BLOCK zzantlr_state zzst; int zzrv; int zzGuessSeqFrozen;
/* MR10 change zzGUESS: do zzGUESS_DONE when zzrv==1 after longjmp as in C++ mode */
#define zzGUESS zzsave_antlr_state(&zzst); \
zzguessing = 1; \
zzGuessSeqFrozen=++zzGuessSeq; \
zzrv = setjmp(zzguess_start.state); \
zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \
if (zzrv) zzGUESS_DONE;
#ifdef zzTRACE_RULES
#define zzGUESS_FAIL { zzTraceGuessFail(); longjmp(zzguess_start.state, 1); }
#else
#define zzGUESS_FAIL longjmp(zzguess_start.state, 1)
#endif
/* MR10 change zzGUESS_DONE: zzrv=1 to simulate longjmp() return value as in C++ mode */
#define zzGUESS_DONE { zzrestore_antlr_state(&zzst); zzrv=1; zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) }
#define zzNON_GUESS_MODE if ( !zzguessing )
#define zzGuessData \
zzjmp_buf zzguess_start; \
int zzguessing;
#else
#define zzGUESS_BLOCK
#define zzGUESS
#define zzGUESS_FAIL
#define zzGUESS_DONE
#define zzNON_GUESS_MODE
#define zzGuessData
#endif
typedef struct _zzantlr_state {
#ifdef ZZCAN_GUESS
zzjmp_buf guess_start;
int guessing;
#endif
int asp;
int ast_sp;
#ifdef ZZINF_LOOK
int inf_lap; /* not sure we need to save this one */
int inf_labase;
int inf_last;
/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */
/* MR6 Additional state needs to be saved/restored */
/* MR6 Matching changes in err.h */
int *inf_tokens; /* MR6 */
char **inf_text; /* MR6 */
char *inf_text_buffer; /* MR6 */
int *inf_line; /* MR6 */
#endif
#ifdef DEMAND_LOOK
int dirty;
#endif
#ifdef LL_K
int tokenLA[LL_K];
char textLA[LL_K][ZZLEXBUFSIZE];
int lap;
int labase;
#else
int token;
char text[ZZLEXBUFSIZE];
#endif
#ifdef zzTRACE_RULES
int traceOptionValue; /* MR10 */
int traceGuessOptionValue; /* MR10 */
char *traceCurrentRuleName; /* MR10 */
int traceDepth; /* MR10 */
#endif
} zzantlr_state;
#ifdef zzTRACE_RULES
extern int zzTraceOptionValueDefault;
extern int zzTraceOptionValue;
extern int zzTraceGuessOptionValue;
extern char *zzTraceCurrentRuleName;
extern int zzTraceDepth;
#endif
extern int zzGuessSeq; /* MR10 */
extern int zzSyntaxErrCount; /* MR11 */
extern int zzLexErrCount; /* MR11 */
/* I n f i n i t e L o o k a h e a d */
#ifdef ZZINF_LOOK
#define InfLookData \
int *zzinf_tokens; \
char **zzinf_text; \
char *zzinf_text_buffer; \
int *zzinf_line; \
int zzinf_labase; \
int zzinf_last;
#else
#define InfLookData
#endif
#ifdef ZZINF_LOOK
#ifndef ZZINF_DEF_TEXT_BUFFER_SIZE
#define ZZINF_DEF_TEXT_BUFFER_SIZE 20000
#endif
#ifndef ZZINF_DEF_TOKEN_BUFFER_SIZE
#define ZZINF_DEF_TOKEN_BUFFER_SIZE 2000
#endif
/* WARNING!!!!!!
* ZZINF_BUFFER_TEXT_CHUNK_SIZE must be > sizeof(text) largest possible token.
*/
#ifndef ZZINF_BUFFER_TEXT_CHUNK_SIZE
#define ZZINF_BUFFER_TEXT_CHUNK_SIZE 5000
#endif
#ifndef ZZINF_BUFFER_TOKEN_CHUNK_SIZE
#define ZZINF_BUFFER_TOKEN_CHUNK_SIZE 1000
#endif
#if ZZLEXBUFSIZE > ZZINF_BUFFER_TEXT_CHUNK_SIZE
#define ZZINF_BUFFER_TEXT_CHUNK_SIZE ZZLEXBUFSIZE+5
#endif
/* make inf_look user-access macros */
#ifdef LL_K
#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)-LL_K+1) <= zzinf_last)
#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)-LL_K+1]
#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)-LL_K+1]
/* MR6 In 1.33 vanilla the #define ZZINF_LINE(i) is was commented out */
#define ZZINF_LINE(i) zzinf_line[(zzinf_labase+i-1)-LL_K+1]
#else
#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)) <= zzinf_last)
#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)]
#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)]
#endif
#define inf_zzgettok _inf_zzgettok()
extern void _inf_zzgettok();
#endif /* ZZINF_LOOK */
#ifdef LL_K
#ifdef __USE_PROTOS
#define ANTLR_INFO \
Attrib zzempty_attr(void) {static Attrib a; return a;} \
Attrib zzconstr_attr(int _tok, char *_text) \
{Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
int zzasp=ZZA_STACKSIZE; \
char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
InfLookData \
zzGuessData
#else
#define ANTLR_INFO \
Attrib zzempty_attr() {static Attrib a; return a;} \
Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \
{Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
int zzasp=ZZA_STACKSIZE; \
char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
InfLookData \
zzGuessData
#endif
#else
#ifdef __USE_PROTOS
#define ANTLR_INFO \
Attrib zzempty_attr(void) {static Attrib a; return a;} \
Attrib zzconstr_attr(int _tok, char *_text) \
{Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
int zzasp=ZZA_STACKSIZE; \
char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
InfLookData \
zzGuessData
#else
#define ANTLR_INFO \
Attrib zzempty_attr() {static Attrib a; return a;} \
Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \
{Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
int zzasp=ZZA_STACKSIZE; \
char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
InfLookData \
zzGuessData
#endif
#endif /* LL_k */
#ifdef ZZINF_LOOK
#ifdef LL_K
#ifdef DEMAND_LOOK
#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;}
#else
#define zzPrimeLookAhead {zzlap = zzlabase = 0; zzfill_inf_look();\
{int _i; for(_i=1;_i<=LL_K; _i++) \
{zzCONSUME;} zzlap = zzlabase = 0;}}
#endif
#else /* LL_K */
#ifdef DEMAND_LOOK
#define zzPrimeLookAhead zzfill_inf_look(); zzdirty=1
#else
#define zzPrimeLookAhead zzfill_inf_look(); inf_zzgettok
#endif
#endif /* LL_K */
#else /* ZZINF_LOOK */
#ifdef LL_K
#ifdef DEMAND_LOOK
#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;}
#else
#define zzPrimeLookAhead {int _i; zzlap = 0; for(_i=1;_i<=LL_K; _i++) \
{zzCONSUME;} zzlap = 0;}
#endif
#else
#ifdef DEMAND_LOOK
#define zzPrimeLookAhead zzdirty=1
#else
#define zzPrimeLookAhead zzgettok()
#endif
#endif /* LL_K */
#endif /* ZZINF_LOOK */
#ifdef LL_K
#define zzenterANTLRs(s) \
zzlextext = &(zztextLA[0][0]); zzrdstr( s ); zzPrimeLookAhead;
#define zzenterANTLRf(f) \
zzlextext = &(zztextLA[0][0]); zzrdfunc( f ); zzPrimeLookAhead;
#define zzenterANTLR(f) \
zzlextext = &(zztextLA[0][0]); zzrdstream( f ); zzPrimeLookAhead;
#ifdef ZZINF_LOOK
#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
#else
#define zzleaveANTLR(f)
#define zzleaveANTLRf(f)
#define zzleaveANTLRs(f)
#endif
#else
#define zzenterANTLRs(s) \
{static char zztoktext[ZZLEXBUFSIZE]; \
zzlextext = zztoktext; zzrdstr( s ); zzPrimeLookAhead;}
#define zzenterANTLRf(f) \
{static char zztoktext[ZZLEXBUFSIZE]; \
zzlextext = zztoktext; zzrdfunc( f ); zzPrimeLookAhead;}
#define zzenterANTLR(f) \
{static char zztoktext[ZZLEXBUFSIZE]; \
zzlextext = zztoktext; zzrdstream( f ); zzPrimeLookAhead;}
#ifdef ZZINF_LOOK
#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
#else
#define zzleaveANTLR(f)
#define zzleaveANTLRf(f)
#define zzleaveANTLRs(f)
#endif
#endif
/* MR19 Paul D. Smith (psmith@baynetworks.com)
Need to adjust AST stack pointer at exit.
Referenced in ANTLRx macros.
*/
#ifdef GENAST
#define ZZAST_ADJUST ++zzast_sp;
#else
#define ZZAST_ADJUST
#endif
#define ANTLR(st, f) zzbufsize = ZZLEXBUFSIZE; \
zzenterANTLR(f); \
{ \
zzBLOCK(zztasp1); \
st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
/* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
/* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
zzEXIT_ANTLR(zztasp1 + 1); \
} \
zzleaveANTLR(f);
#define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE; \
zzmode(_m); \
zzenterANTLR(f); \
{ \
zzBLOCK(zztasp1); \
st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
/* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
/* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
zzEXIT_ANTLR(zztasp1 + 1); \
} \
zzleaveANTLR(f);
#define ANTLRf(st, f) zzbufsize = ZZLEXBUFSIZE; \
zzenterANTLRf(f); \
{ \
zzBLOCK(zztasp1); \
st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
/* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
/* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
zzEXIT_ANTLR(zztasp1 + 1); \
} \
zzleaveANTLRf(f);
#define ANTLRs(st, s) zzbufsize = ZZLEXBUFSIZE; \
zzenterANTLRs(s); \
{ \
zzBLOCK(zztasp1); \
st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
/* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
/* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
zzEXIT_ANTLR(zztasp1 + 1); \
} \
zzleaveANTLRs(s);
#ifdef LL_K
#define zztext (&(zztextLA[zzlap][0]))
#else
#define zztext zzlextext
#endif
/* A r g u m e n t A c c e s s */
#define zzaCur (zzaStack[zzasp])
#define zzaRet (*zzaRetPtr)
#define zzaArg(v,n) zzaStack[v-n]
#define zzMakeAttr { zzNON_GUESS_MODE {zzOvfChk; --zzasp; zzcr_attr(&(zzaStack[zzasp]),LA(1),LATEXT(1));}}
#ifdef zzdef0
#define zzMake0 { zzOvfChk; --zzasp; zzdef0(&(zzaStack[zzasp]));}
#else
#define zzMake0 { zzOvfChk; --zzasp;}
#endif
#define zzaPush(_v) { zzOvfChk; zzaStack[--zzasp] = _v;}
#ifndef zzd_attr
#define zzREL(t) zzasp=(t); /* Restore state of stack */
#else
#define zzREL(t) for (; zzasp<(t); zzasp++) \
{ zzd_attr(&(zzaStack[zzasp])); }
#endif
#define zzsetmatch(_es) \
if ( !_zzsetmatch(_es, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail;
#ifdef ZZCAN_GUESS
#define zzsetmatch_wsig(_es, handler) \
if ( !_zzsetmatch_wsig(_es) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;}
#else
#define zzsetmatch_wsig(_es, handler) \
if ( !_zzsetmatch_wsig(_es) ) {_signal=MismatchedToken; goto handler;}
#endif
#ifdef __USE_PROTOS
extern int _zzsetmatch(SetWordType *, char **, char **, int *, int *, SetWordType **);
extern int _zzsetmatch_wsig(SetWordType *);
#else
extern int _zzsetmatch();
extern int _zzsetmatch_wsig();
#endif
#define zzmatch(_t) \
if ( !_zzmatch(_t, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail;
#ifdef ZZCAN_GUESS
#define zzmatch_wsig(_t,handler) \
if ( !_zzmatch_wsig(_t) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;}
#else
#define zzmatch_wsig(_t,handler) \
if ( !_zzmatch_wsig(_t) ) {_signal=MismatchedToken; goto handler;}
#endif
#ifdef __USE_PROTOS
extern int _zzmatch(int, char **, char **, int *, int *, SetWordType **);
extern int _zzmatch_wsig(int);
#else
extern int _zzmatch();
extern int _zzmatch_wsig();
#endif
#define zzmatch_wdfltsig(_t,_f) \
if ( !_zzmatch_wdfltsig(_t,_f) ) _signal=MismatchedToken;
#define zzsetmatch_wdfltsig(tw,tt,wf) \
if ( !_zzsetmatch_wdfltsig(tw,tt,wf) ) _signal=MismatchedToken;
#ifdef __USE_PROTOS
extern int _zzmatch_wdfltsig(int, SetWordType *);
extern int _zzsetmatch_wdfltsig(SetWordType *tokensWanted,
int tokenTypeOfSet,
SetWordType *whatFollows);
#else
extern int _zzmatch_wdfltsig();
extern int _zzsetmatch_wdfltsig();
#endif
#ifdef GENAST
#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \
SetWordType *zzMissSet=NULL; int zzMissTok=0; \
int zzBadTok=0; char *zzBadText=""; \
int zzErrk=1,zzpf=0; \
zzTRACEdata \
char *zzMissText=""; zzASTVars
#else
#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \
int zzBadTok=0; char *zzBadText=""; \
int zzErrk=1,zzpf=0; \
zzTRACEdata \
SetWordType *zzMissSet=NULL; int zzMissTok=0; char *zzMissText=""
#endif
#ifdef GENAST
#define zzBLOCK(i) int i = zzasp - 1; int zztsp = zzast_sp
#define zzEXIT(i) zzREL(i); zzastREL; zzNON_GUESS_MODE { zzastPush(*_root); }
#define zzEXIT_ANTLR(i) zzREL(i); zzastREL /* [i_a] added as we want this for the ANTLRx() macros */
#define zzLOOP(i) zzREL(i); zzastREL
#else
#define zzBLOCK(i) int i = zzasp - 1
#define zzEXIT(i) zzREL(i)
#define zzEXIT_ANTLR(i) zzREL(i) /* [i_a] added as we want this for the ANTLRx() macros */
#define zzLOOP(i) zzREL(i)
#endif
#ifdef LL_K
#ifdef DEMAND_LOOK
#define LOOK(_k) {int i,stop=_k-(LL_K-zzdirty); for (i=1; i<=stop; i++) \
zzCONSUME;}
#define zzCONSUME {zzgettok(); zzdirty--; \
zzlap = (zzlap+1)&(LL_K-1); \
zzlextext = &(zztextLA[zzlap][0]);}
#else
#ifdef ZZINF_LOOK
#define zzCONSUME {inf_zzgettok; \
zzlap = (zzlap+1)&(LL_K-1); \
zzlextext = &(zztextLA[zzlap][0]); \
}
#else
#define zzCONSUME {zzgettok(); \
zzlap = (zzlap+1)&(LL_K-1); \
zzlextext = &(zztextLA[zzlap][0]);}
#endif /* ZZINF_LOOK */
#endif /* DEMAND_LOOK */
#else /* LL_K */
#ifdef DEMAND_LOOK
#define LOOK(_k) if ( zzdirty) zzCONSUME;
#ifdef ZZINF_LOOK
#define zzCONSUME inf_zzgettok; zzdirty=0;
#else
#define zzCONSUME zzgettok(); zzdirty=0;
#endif /* ZZINF_LOOK */
#else /* DEMAND_LOOK */
#ifdef ZZINF_LOOK
#define zzCONSUME inf_zzgettok
#else
#define zzCONSUME zzgettok();
#endif
#endif /* DEMAND_LOOK */
#endif /* LL_K */
#ifdef LL_K
#define NLA zztokenLA[zzlap&(LL_K-1)] /* --> next LA */
#define NLATEXT zztextLA[zzlap&(LL_K-1)] /* --> next text of LA */
#ifdef DEMAND_LOOK
#define LA(i) zztokenLA[(zzlabase+(i)-1)&(LL_K-1)]
#define LATEXT(i) (&(zztextLA[(zzlabase+(i)-1)&(LL_K-1)][0]))
#else
#define LA(i) zztokenLA[(zzlap+(i)-1)&(LL_K-1)]
#define LATEXT(i) (&(zztextLA[(zzlap+(i)-1)&(LL_K-1)][0]))
#endif
#else
#define NLA zztoken
#define NLATEXT zztext
#define LA(i) zztoken
#define LATEXT(i) zztext
#endif
/* S t a n d a r d S i g n a l s */
#define NoSignal 0
#define MismatchedToken 1
#define NoViableAlt 2
#define NoSemViableAlt 3
/* MR7 Allow more control over signalling */
/* by adding "Unwind" and "zzsetSignal" */
#define Unwind 4
#define zzsetSignal(newValue) *_retsignal=_signal=(newValue)
#define zzsuppressSignal *_retsignal=_signal=0
#define zzexportSignal *_retsignal=_signal
/* F u n c t i o n T r a c i n g */
#ifndef zzTRACE_RULES
#define zzTRACEdata
#else
#ifndef zzTRACEdata
#define zzTRACEdata ANTLRChar *zzTracePrevRuleName = NULL;
#endif
#endif
#ifndef zzTRACEIN
#define zzTRACEIN(r) zzTracePrevRuleName=zzTraceCurrentRuleName;zzTraceIn(r);
#endif
#ifndef zzTRACEOUT
#define zzTRACEOUT(r) zzTraceOut(r);zzTraceCurrentRuleName=zzTracePrevRuleName;
#endif
/* MR19 zzchar_t additions */
#ifndef zzchar_t
#ifdef ZZWCHAR_T
#define zzchar_t wchar_t
#else
#define zzchar_t char
#endif
#endif
/* E x t e r n D e f s */
#ifdef __USE_PROTOS
extern Attrib zzempty_attr(void);
extern Attrib zzconstr_attr(int, char *);
extern void zzsyn(char *, int, char *, SetWordType *, int, int, char *);
extern int zzset_el(unsigned, SetWordType *);
extern int zzset_deg(SetWordType *);
extern void zzedecode(SetWordType *);
extern void zzFAIL(int k, ...);
extern void zzresynch(SetWordType *, SetWordType);
extern void zzsave_antlr_state(zzantlr_state *);
extern void zzrestore_antlr_state(zzantlr_state *);
extern void zzfill_inf_look(void);
extern void zzconsumeUntil(SetWordType *st); /* MR7 */
extern void zzconsumeUntilToken(int t); /* MR7 */
extern void zzTraceIn(char * ruleName); /* MR10 */
extern void zzTraceOut(char * ruleName); /* MR10 */
extern int zzTraceOption(int delta); /* MR10 */
extern int zzTraceGuessOption(int delta); /* MR10 */
extern void zzTraceReset(void); /* MR10 */
extern void zzTraceGuessFail(void); /* MR10 */
#ifdef EXCEPTION_HANDLING
extern void zzdflthandlers(int, int *);
#endif
#else
extern Attrib zzempty_attr();
extern Attrib zzconstr_attr();
extern void zzsyn();
extern int zzset_el();
extern int zzset_deg();
extern void zzedecode();
extern void zzFAIL();
extern void zzresynch();
extern void zzsave_antlr_state();
extern void zzrestore_antlr_state();
extern void zzfill_inf_look();
extern void zzconsumeUntil(); /* MR7 */
extern void zzconsumeUntilToken(); /* MR7 */
extern void zzTraceIn(); /* MR10 */
extern void zzTraceOut(); /* MR10 */
extern int zzTraceOption(); /* MR10 */
extern int zzTraceGuessOption(); /* MR10 */
extern void zzTraceReset(); /* MR10 */
extern void zzTraceGuessFail(); /* MR10 */
#ifdef EXCEPTION_HANDLING
extern void zzdflthandlers();
#endif
#endif
/* G l o b a l V a r i a b l e s */
/* Define a parser; user should do a "#parser myname" in their grammar file */
/*extern struct pccts_parser zzparser;*/
extern char *zztokens[];
#ifdef LL_K
extern int zztokenLA[];
extern zzchar_t zztextLA[][ZZLEXBUFSIZE];
extern int zzlap;
extern int zzlabase;
#else
extern int zztoken;
#endif
extern char zzStackOvfMsg[];
extern int zzasp;
extern Attrib zzaStack[];
#ifdef ZZINF_LOOK
extern int *zzinf_tokens;
extern char **zzinf_text;
extern char *zzinf_text_buffer;
extern int *zzinf_line;
extern int zzinf_labase;
extern int zzinf_last;
#endif
#ifdef DEMAND_LOOK
extern int zzdirty;
#endif
#ifdef ZZCAN_GUESS
extern int zzguessing;
extern zzjmp_buf zzguess_start;
#endif
/* Define global veriables that refer to values exported by the scanner.
* These declarations duplicate those in dlgdef.h, but are needed
* if ANTLR is not to generate a .dlg file (-gx); PS, this is a hack.
*/
extern zzchar_t *zzlextext; /* text of most recently matched token */
extern int zzbufsize; /* how long zzlextext is */
#endif

View File

@@ -0,0 +1,345 @@
/* Abstract syntax tree manipulation functions
*
* 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-1998
*/
#include "pcctscfg.h"
#ifdef PCCTS_USE_STDARG
#include "pccts_stdarg.h"
#else
#include <varargs.h>
#endif
/* ensure that tree manipulation variables are current after a rule
* reference
*/
void
#ifdef __USE_PROTOS
zzlink(AST **_root, AST **_sibling, AST **_tail)
#else
zzlink(_root, _sibling, _tail)
AST **_root, **_sibling, **_tail;
#endif
{
if ( *_sibling == NULL ) return;
if ( *_root == NULL ) *_root = *_sibling;
else if ( *_root != *_sibling ) (*_root)->down = *_sibling;
if ( *_tail==NULL ) *_tail = *_sibling;
while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right;
}
AST *
#ifdef __USE_PROTOS
zzastnew(void)
#else
zzastnew()
#endif
{
AST *p = (AST *) calloc(1, sizeof(AST));
if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST node\n",__FILE__,__LINE__);
return p;
}
/* add a child node to the current sibling list */
void
#ifdef __USE_PROTOS
zzsubchild(AST **_root, AST **_sibling, AST **_tail)
#else
zzsubchild(_root, _sibling, _tail)
AST **_root, **_sibling, **_tail;
#endif
{
AST *n;
zzNON_GUESS_MODE {
n = zzastnew();
#ifdef DEMAND_LOOK
zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
#else
zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
#endif
zzastPush( n );
if ( *_tail != NULL ) (*_tail)->right = n;
else {
*_sibling = n;
if ( *_root != NULL ) (*_root)->down = *_sibling;
}
*_tail = n;
if ( *_root == NULL ) *_root = *_sibling;
}
}
/* make a new AST node. Make the newly-created
* node the root for the current sibling list. If a root node already
* exists, make the newly-created node the root of the current root.
*/
void
#ifdef __USE_PROTOS
zzsubroot(AST **_root, AST **_sibling, AST **_tail)
#else
zzsubroot(_root, _sibling, _tail)
AST **_root, **_sibling, **_tail;
#endif
{
AST *n;
zzNON_GUESS_MODE {
n = zzastnew();
#ifdef DEMAND_LOOK
zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
#else
zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
#endif
zzastPush( n );
if ( *_root != NULL )
if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root;
*_root = n;
(*_root)->down = *_sibling;
}
}
/* Apply function to root then each sibling
* example: print tree in child-sibling LISP-format (AST has token field)
*
* void show(tree)
* AST *tree;
* {
* if ( tree == NULL ) return;
* printf(" %s", zztokens[tree->token]);
* }
*
* void before() { printf(" ("); }
* void after() { printf(" )"); }
*
* LISPdump() { zzpre_ast(tree, show, before, after); }
*
*/
void
#ifdef __USE_PROTOS
zzpre_ast(
AST *tree,
void (*func)(AST *), /* apply this to each tree node */
void (*before)(AST *), /* apply this to root of subtree before preordering it */
void (*after)(AST *)) /* apply this to root of subtree after preordering it */
#else
zzpre_ast(tree, func, before, after)
AST *tree;
void (*func)(), /* apply this to each tree node */
(*before)(), /* apply this to root of subtree before preordering it */
(*after)(); /* apply this to root of subtree after preordering it */
#endif
{
while ( tree!= NULL )
{
if ( tree->down != NULL ) (*before)(tree);
(*func)(tree);
zzpre_ast(tree->down, func, before, after);
if ( tree->down != NULL ) (*after)(tree);
tree = tree->right;
}
}
/* free all AST nodes in tree; apply func to each before freeing */
#if 0
////void
////#ifdef __USE_PROTOS
////zzfree_ast(AST *tree)
////#else
////zzfree_ast(tree)
////AST *tree;
////#endif
////{
//// if ( tree == NULL ) return;
//// zzfree_ast( tree->down );
//// zzfree_ast( tree->right );
//// zztfree( tree );
////}
#endif
/*
MR19 Optimize freeing of the following structure to limit recursion
SAKAI Kiyotaka (ksakai@isr.co.jp)
*/
/*
NULL o
/ \
NULL o
/ \
NULL NULL
*/
/*
MR21 Another refinement to replace recursion with iteration
NAKAJIMA Mutsuki (muc@isr.co.jp).
*/
void
#ifdef __USE_PROTOS
zzfree_ast(AST *tree)
#else
zzfree_ast(tree)
AST *tree;
#endif
{
AST *otree;
if (tree == NULL) return;
while (tree->down == NULL || tree->right == NULL) {
if (tree->down == NULL && tree->right == NULL) {
zztfree(tree);
return;
}
otree = tree;
if (tree->down == NULL) {
tree = tree->right;
} else {
tree = tree->down;
}
zztfree( otree );
}
while (tree != NULL) {
zzfree_ast(tree->down);
otree = tree;
tree = otree->right;
zztfree(otree);
}
}
/* build a tree (root child1 child2 ... NULL)
* If root is NULL, simply make the children siblings and return ptr
* to 1st sibling (child1). If root is not single node, return NULL.
*
* Siblings that are actually siblins lists themselves are handled
* correctly. For example #( NULL, #( NULL, A, B, C), D) results
* in the tree ( NULL A B C D ).
*
* Requires at least two parameters with the last one being NULL. If
* both are NULL, return NULL.
*/
#ifdef PCCTS_USE_STDARG
AST *zztmake(AST *rt, ...)
#else
AST *zztmake(va_alist)
va_dcl
#endif
{
va_list ap;
register AST *child, *sibling=NULL, *tail=NULL /* MR20 */, *w;
AST *root;
#ifdef PCCTS_USE_STDARG
va_start(ap, rt);
root = rt;
#else
va_start(ap);
root = va_arg(ap, AST *);
#endif
if ( root != NULL )
if ( root->down != NULL ) return NULL;
child = va_arg(ap, AST *);
while ( child != NULL )
{
for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */
if ( sibling == NULL ) {sibling = child; tail = w;}
else {tail->right = child; tail = w;}
child = va_arg(ap, AST *);
}
if ( root==NULL ) root = sibling;
else root->down = sibling;
va_end(ap);
return root;
}
/* tree duplicate */
AST *
#ifdef __USE_PROTOS
zzdup_ast(AST *t)
#else
zzdup_ast(t)
AST *t;
#endif
{
AST *u;
if ( t == NULL ) return NULL;
u = zzastnew();
*u = *t;
#ifdef zzAST_DOUBLE
u->up = NULL; /* set by calling invocation */
u->left = NULL;
#endif
u->right = zzdup_ast(t->right);
u->down = zzdup_ast(t->down);
#ifdef zzAST_DOUBLE
if ( u->right!=NULL ) u->right->left = u;
if ( u->down!=NULL ) u->down->up = u;
#endif
return u;
}
void
#ifdef __USE_PROTOS
zztfree(AST *t)
#else
zztfree(t)
AST *t;
#endif
{
#ifdef zzd_ast
zzd_ast( t );
#endif
free( t );
}
#ifdef zzAST_DOUBLE
/*
* Set the 'up', and 'left' pointers of all nodes in 't'.
* Initial call is double_link(your_tree, NULL, NULL).
*/
void
#ifdef __USE_PROTOS
zzdouble_link(AST *t, AST *left, AST *up)
#else
zzdouble_link(t, left, up)
AST *t, *left, *up;
#endif
{
if ( t==NULL ) return;
t->left = left;
t->up = up;
zzdouble_link(t->down, NULL, t);
zzdouble_link(t->right, t, up);
}
#endif

View File

@@ -0,0 +1,115 @@
/* Abstract syntax tree
*
* Macros, definitions
*
* 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-1998
*/
#ifndef ZZAST_H
#define ZZAST_H
#define zzastOvfChk \
if ( zzast_sp <= 0 ) \
{ \
fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \
exit(PCCTS_EXIT_FAILURE); \
}
#ifndef USER_DEFINED_AST
#ifndef AST_FIELDS
#define AST_FIELDS
#endif
typedef struct _ast {
struct _ast *right, *down;
#ifdef zzAST_DOUBLE
struct _ast *left, *up;
#endif
AST_FIELDS
} AST;
#else
#ifdef zzAST_DOUBLE
#define AST_REQUIRED_FIELDS struct _ast *right, *down, *left, *up;
#else
#define AST_REQUIRED_FIELDS struct _ast *right, *down;
#endif
#endif
/* N o d e a c c e s s m a c r o s */
#define zzchild(t) (((t)==NULL)? (AST *) NULL:(t->down)) /* MR19 */
#define zzsibling(t) (((t)==NULL)? (AST *) NULL:(t->right)) /* MR19 */
/* define global variables needed by #i stack */
#define zzASTgvars \
AST *zzastStack[ZZAST_STACKSIZE]; \
int zzast_sp = ZZAST_STACKSIZE;
#define zzASTVars AST *_ast = NULL, *_sibling = NULL, *_tail = NULL
#define zzSTR ( (_tail==NULL)?(&_sibling):(&(_tail->right)) )
#define zzastCur (zzastStack[zzast_sp])
#define zzastArg(i) (zzastStack[zztsp-i])
#define zzastPush(p) zzastOvfChk; zzastStack[--zzast_sp] = p;
#define zzastDPush --zzast_sp
#define zzastMARK zztsp=zzast_sp; /* Save state of stack */
#define zzastREL zzast_sp=zztsp; /* Return state of stack */
#define zzrm_ast {zzfree_ast(*_root); _tail = _sibling = (*_root)=NULL;}
extern int zzast_sp;
extern AST *zzastStack[];
#ifdef __USE_PROTOS
void zzlink(AST **, AST **, AST **);
void zzsubchild(AST **, AST **, AST **);
void zzsubroot(AST **, AST **, AST **);
void zzpre_ast(AST *, void (*)(AST *), void (*)(AST *), void (*)(AST *));
void zzfree_ast(AST *);
AST *zztmake(AST *, ...);
AST *zzdup_ast(AST *);
void zztfree(AST *);
void zzdouble_link(AST *, AST *, AST *);
AST *zzastnew(void);
#else
void zzlink();
AST *zzastnew();
void zzsubchild();
void zzsubroot();
void zzpre_ast();
void zzfree_ast();
AST *zztmake();
AST *zzdup_ast();
void zztfree();
void zzdouble_link();
#endif
#endif

View File

@@ -0,0 +1,46 @@
/* ANTLR attribute definition -- constant width text
*
* 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-1998
*/
#ifndef ZZCHARBUF_H
#define ZZCHARBUF_H
#include "pcctscfg.h"
#include "pccts_string.h"
#ifndef D_TextSize
#define D_TextSize 30
#endif
typedef struct { char text[D_TextSize]; } Attrib;
#define zzcr_attr(a,tok,t) strncpy((a)->text, t, D_TextSize-1); \
(a)->text[D_TextSize-1] = '\0';
#endif

View File

@@ -0,0 +1,58 @@
/*
* 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-1998
*/
#include "pcctscfg.h"
#ifdef __STDC__
#include "pccts_stdlib.h"
#else
#include <malloc.h>
#endif
#include "pccts_string.h"
/* 133MR1 include stdio.h for fprintf in charptr.c */
#include "pccts_stdio.h"
/* 133MR1 include charptr.h for Attrib in charptr.c */
#include "charptr.h"
#ifdef __USE_PROTOS
zzcr_attr(Attrib *a,int token,char *text)
#else
zzcr_attr(a,token,text)
Attrib *a;
int token;
char *text;
#endif
{
*a = (char *) malloc(strlen(text)+1); /* MR6 */
if ( *a == NULL ) {fprintf(stderr, "zzcr_attr: out of memory!\n"); exit(-1);}
strcpy(*a, text);
}

View File

@@ -0,0 +1,48 @@
/*
*
* 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-1998
*/
/*
* WARNING!!!!: charptr.h does NOT make copies and the
* memory is freed after the attribute scope exits.
*/
#ifndef ZZCHARPTR_H
#define ZZCHARPTR_H
typedef char *Attrib;
#define zzdef0(a) {*(a)=NULL;}
/* MR8 Jens Tingleff (jensting@imaginet.fr) */
/* Set memory pointer to null after free() */
#define zzd_attr(a) {if ( *(a)!=NULL ) {free(*(a)); *(a)=NULL; }; }
#ifdef __STDC__
extern zzcr_attr(Attrib *,int,char *);
#endif
#endif

View File

@@ -0,0 +1 @@
#include "pcctscfg.h"

View File

@@ -0,0 +1,499 @@
/* dlgauto.h automaton
*
* 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
* Will Cohen and Terence Parr
* Parr Research Corporation
* with Purdue University and AHPCRC, University of Minnesota
* 1989-1998
*/
#ifndef ZZDEFAUTO_H
#define ZZDEFAUTO_H
/* 10-Apr-97 133MR1 Uses __USE_PROTOS show should #include pcctscfg.h */
#include "pcctscfg.h"
zzchar_t *zzlextext; /* text of most recently matched token */
zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */
zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */
int zzbufsize = 0; /* number of characters in zzlextext */ /* MR7 */
int zzbegcol = 0; /* column that first character of token is in*/
int zzendcol = 0; /* column that last character of token is in */
int zzline = 1; /* line current token is on */
int zzreal_line=1; /* line of 1st portion of token that is not skipped */
int zzchar; /* character to determine next state */
int zzbufovf; /* indicates that buffer too small for text */
int zzcharfull = 0;
static zzchar_t *zznextpos;/* points to next available position in zzlextext*/
static int zzclass;
#ifdef __USE_PROTOS
void zzerrstd(const char *);
void (*zzerr)(const char *)=zzerrstd;/* pointer to error reporting function */
extern int zzerr_in(void);
static int (*zzfunc_in)(void) = zzerr_in; /* MR20 */
#else
void zzerrstd();
void (*zzerr)()=zzerrstd; /* pointer to error reporting function */
extern int zzerr_in();
static int (*zzfunc_in)() = zzerr_in; /* MR20 */
#endif
static FILE *zzstream_in=0;
static zzchar_t *zzstr_in=0;
#ifdef USER_ZZMODE_STACK
int zzauto = 0;
#else
static int zzauto = 0;
#endif
static int zzadd_erase;
static char zzebuf[70];
#ifdef ZZCOL
#define ZZINC (++zzendcol)
#else
#define ZZINC
#endif
#define ZZGETC_STREAM {zzchar = getc(zzstream_in); zzclass = ZZSHIFT(zzchar);}
#define ZZGETC_FUNC {zzchar = (*zzfunc_in)(); zzclass = ZZSHIFT(zzchar);}
#define ZZGETC_STR { \
if (*zzstr_in){ \
zzchar = *zzstr_in; \
++zzstr_in; \
}else{ \
zzchar = EOF; \
} \
zzclass = ZZSHIFT(zzchar); \
}
#define ZZNEWSTATE (newstate = dfa[state][zzclass])
#ifndef ZZCOPY
#define ZZCOPY \
/* Truncate matching buffer to size (not an error) */ \
if (zznextpos < lastpos){ \
*(zznextpos++) = zzchar; \
}else{ \
zzbufovf = 1; \
}
#endif
void
#ifdef __USE_PROTOS
zzrdstream( FILE *f )
#else
zzrdstream( f )
FILE *f;
#endif
{
/* make sure that it is really set to something, otherwise just
leave it be.
*/
if (f){
/* make sure that there is always someplace to get input
before closing zzstream_in
*/
#if 0
if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );
#endif
zzline = 1;
zzstream_in = f;
zzfunc_in = NULL;
zzstr_in = 0;
zzcharfull = 0;
}
}
void
#ifdef __USE_PROTOS
zzrdfunc( int (*f)(void) )
#else
zzrdfunc( f )
int (*f)();
#endif
{
/* make sure that it is really set to something, otherwise just
leave it be.
*/
if (f){
/* make sure that there is always someplace to get input
before closing zzstream_in
*/
#if 0
if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );
#endif
zzline = 1;
zzstream_in = NULL;
zzfunc_in = f;
zzstr_in = 0;
zzcharfull = 0;
}
}
void
#ifdef __USE_PROTOS
zzrdstr( zzchar_t *s )
#else
zzrdstr( s )
zzchar_t *s;
#endif
{
/* make sure that it is really set to something, otherwise just
leave it be.
*/
if (s){
/* make sure that there is always someplace to get input
before closing zzstream_in
*/
#if 0
if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );
#endif
zzline = 1;
zzstream_in = NULL;
zzfunc_in = 0;
zzstr_in = s;
zzcharfull = 0;
}
}
#ifdef __USE_PROTOS
void zzclose_stream(void)
#else
void zzclose_stream()
#endif
{
#if 0
fclose( zzstream_in );
zzstream_in = NULL;
zzfunc_in = NULL;
#endif
}
/* saves dlg state, but not what feeds dlg (such as file position) */
void
#ifdef __USE_PROTOS
zzsave_dlg_state(struct zzdlg_state *state)
#else
zzsave_dlg_state(state)
struct zzdlg_state *state;
#endif
{
state->stream = zzstream_in;
state->func_ptr = zzfunc_in;
state->str = zzstr_in;
state->auto_num = zzauto;
state->add_erase = zzadd_erase;
state->lookc = zzchar;
state->char_full = zzcharfull;
state->begcol = zzbegcol;
state->endcol = zzendcol;
state->line = zzline;
state->lextext = zzlextext;
state->begexpr = zzbegexpr;
state->endexpr = zzendexpr;
state->bufsize = zzbufsize;
state->bufovf = zzbufovf;
state->nextpos = zznextpos;
state->class_num = zzclass;
}
void
#ifdef __USE_PROTOS
zzrestore_dlg_state(struct zzdlg_state *state)
#else
zzrestore_dlg_state(state)
struct zzdlg_state *state;
#endif
{
zzstream_in = state->stream;
zzfunc_in = state->func_ptr;
zzstr_in = state->str;
zzauto = state->auto_num;
zzadd_erase = state->add_erase;
zzchar = state->lookc;
zzcharfull = state->char_full;
zzbegcol = state->begcol;
zzendcol = state->endcol;
zzline = state->line;
zzlextext = state->lextext;
zzbegexpr = state->begexpr;
zzendexpr = state->endexpr;
zzbufsize = state->bufsize;
zzbufovf = state->bufovf;
zznextpos = state->nextpos;
zzclass = state->class_num;
}
void
#ifdef __USE_PROTOS
zzmode( int m )
#else
zzmode( m )
int m;
#endif
{
/* points to base of dfa table */
if (m<MAX_MODE){
zzauto = m;
/* have to redo class since using different compression */
zzclass = ZZSHIFT(zzchar);
}else{
sprintf(zzebuf,"Invalid automaton mode = %d ",m);
zzerr(zzebuf);
}
}
/* erase what is currently in the buffer, and get a new reg. expr */
#ifdef __USE_PROTOS
void zzskip(void)
#else
void zzskip()
#endif
{
zzadd_erase = 1;
}
/* don't erase what is in the zzlextext buffer, add on to it */
#ifdef __USE_PROTOS
void zzmore()
#else
void zzmore()
#endif
{
zzadd_erase = 2;
}
/* substitute c for the reg. expr last matched and is in the buffer */
#ifdef __USE_PROTOS
void
zzreplchar(zzchar_t c)
#else
void
zzreplchar(c)
zzchar_t c;
#endif
{
/* can't allow overwriting null at end of string */
if (zzbegexpr < &zzlextext[zzbufsize-1]){
*zzbegexpr = c;
*(zzbegexpr+1) = '\0';
}
zzendexpr = zzbegexpr;
zznextpos = zzbegexpr + 1;
}
/* replace the string s for the reg. expr last matched and in the buffer */
void
#ifdef __USE_PROTOS
zzreplstr(register zzchar_t *s)
#else
zzreplstr(s)
register zzchar_t *s;
#endif
{
register zzchar_t *l= &zzlextext[zzbufsize -1];
zznextpos = zzbegexpr;
if (s){
while ((zznextpos <= l) && (*(zznextpos++) = *(s++))!=0){
/* empty */
}
/* correct for NULL at end of string */
zznextpos--;
}
if ((zznextpos <= l) && (*(--s) == 0)){
zzbufovf = 0;
}else{
zzbufovf = 1;
}
*(zznextpos) = '\0';
zzendexpr = zznextpos - 1;
}
#ifdef __USE_PROTOS
void zzgettok(void)
#else
void zzgettok()
#endif
{
register int state, newstate;
/* last space reserved for the null char */
register zzchar_t *lastpos;
skip:
zzreal_line = zzline;
zzbufovf = 0;
lastpos = &zzlextext[zzbufsize-1];
zznextpos = zzlextext;
zzbegcol = zzendcol+1;
more:
zzbegexpr = zznextpos;
#ifdef ZZINTERACTIVE
/* interactive version of automaton */
/* if there is something in zzchar, process it */
state = newstate = dfa_base[zzauto];
if (zzcharfull){
ZZINC;
ZZCOPY;
ZZNEWSTATE;
}
if (zzstr_in)
while (zzalternatives[newstate]){
state = newstate;
ZZGETC_STR;
ZZINC;
ZZCOPY;
ZZNEWSTATE;
}
else if (zzstream_in)
while (zzalternatives[newstate]){
state = newstate;
ZZGETC_STREAM;
ZZINC;
ZZCOPY;
ZZNEWSTATE;
}
else if (zzfunc_in)
while (zzalternatives[newstate]){
state = newstate;
ZZGETC_FUNC;
ZZINC;
ZZCOPY;
ZZNEWSTATE;
}
/* figure out if last character really part of token */
if ((state != dfa_base[zzauto]) && (newstate == DfaStates)){
zzcharfull = 1;
--zznextpos;
}else{
zzcharfull = 0;
state = newstate;
}
*(zznextpos) = '\0';
/* Able to transition out of start state to some non err state?*/
if ( state == dfa_base[zzauto] ){
/* make sure doesn't get stuck */
zzadvance();
}
#else
/* non-interactive version of automaton */
if (!zzcharfull)
zzadvance();
else
ZZINC;
state = dfa_base[zzauto];
if (zzstr_in)
while (ZZNEWSTATE != DfaStates){
state = newstate;
ZZCOPY;
ZZGETC_STR;
ZZINC;
}
else if (zzstream_in)
while (ZZNEWSTATE != DfaStates){
state = newstate;
ZZCOPY;
ZZGETC_STREAM;
ZZINC;
}
else if (zzfunc_in)
while (ZZNEWSTATE != DfaStates){
state = newstate;
ZZCOPY;
ZZGETC_FUNC;
ZZINC;
}
zzcharfull = 1;
if ( state == dfa_base[zzauto] ){
if (zznextpos < lastpos){
*(zznextpos++) = zzchar;
}else{
zzbufovf = 1;
}
*zznextpos = '\0';
/* make sure doesn't get stuck */
zzadvance();
}else{
*zznextpos = '\0';
}
#endif
#ifdef ZZCOL
zzendcol -= zzcharfull;
#endif
zzendexpr = zznextpos -1;
zzadd_erase = 0;
(*actions[accepts[state]])();
switch (zzadd_erase) {
case 1: goto skip;
case 2: goto more;
}
}
#ifdef __USE_PROTOS
void zzadvance(void)
#else
void zzadvance()
#endif
{
if (zzstream_in) { ZZGETC_STREAM; zzcharfull = 1; ZZINC;}
if (zzfunc_in) { ZZGETC_FUNC; zzcharfull = 1; ZZINC;}
if (zzstr_in) { ZZGETC_STR; zzcharfull = 1; ZZINC;}
if (!(zzstream_in || zzfunc_in || zzstr_in)){
zzerr_in();
}
}
void
#ifdef __USE_PROTOS
zzerrstd(const char *s)
#else
zzerrstd(s)
char *s;
#endif
{
zzLexErrCount++; /* MR11 */
fprintf(stderr,
"%s near line %d (text was '%s')\n",
((s == NULL) ? "Lexical error" : s),
zzline,zzlextext);
}
#ifdef __USE_PROTOS
int zzerr_in(void)
#else
int zzerr_in()
#endif
{
fprintf(stderr,"No input stream, function, or string\n");
/* return eof to get out gracefully */
return EOF;
}
#endif

View File

@@ -0,0 +1,128 @@
/* dlgdef.h
* Things in scanner produced by dlg that should be visible to the outside
* world
*
* 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-1998
*/
#ifndef ZZDLGDEF_H
#define ZZDLGDEF_H
#include "pcctscfg.h"
#ifndef zzchar_t
#ifdef ZZWCHAR_T
#define zzchar_t wchar_t
#else
#define zzchar_t char
#endif
#endif
struct zzdlg_state {
FILE *stream;
#ifdef __USE_PROTOS
int (*func_ptr)(void);
#else
int (*func_ptr)();
#endif
zzchar_t *str;
int auto_num;
int add_erase;
int lookc;
int char_full;
int begcol, endcol;
int line;
zzchar_t *lextext, *begexpr, *endexpr;
int bufsize;
int bufovf;
zzchar_t *nextpos;
int class_num;
};
extern zzchar_t *zzlextext; /* text of most recently matched token */
extern zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */
extern zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */
extern int zzbufsize; /* how long zzlextext is */
extern int zzbegcol; /* column that first character of token is in*/
extern int zzendcol; /* column that last character of token is in */
extern int zzline; /* line current token is on */
extern int zzreal_line; /* line of 1st portion of token that is not skipped */
extern int zzchar; /* character to determine next state */
extern int zzbufovf; /* indicates that buffer too small for text */
#ifdef __USE_PROTOS
extern void (*zzerr)(const char *);/* pointer to error reporting function */
#else
extern void (*zzerr)();
#endif
#ifdef USER_ZZMODE_STACK
extern int zzauto;
#endif
#ifdef __USE_PROTOS
extern void zzadvance(void);
extern void zzskip(void); /* erase zzlextext, look for antoher token */
extern void zzmore(void); /* keep zzlextext, look for another token */
extern void zzmode(int k); /* switch to automaton 'k' */
extern void zzrdstream(FILE *);/* what stream to read from */
extern void zzclose_stream(void);/* close the current input stream */
extern void zzrdfunc(int (*)(void));/* what function to get char from */
extern void zzrdstr( zzchar_t * );
extern void zzgettok(void); /* get next token */
extern void zzreplchar(zzchar_t c);/* replace last recognized reg. expr. with
a character */
extern void zzreplstr(zzchar_t *s);/* replace last recognized reg. expr. with
a string */
extern void zzsave_dlg_state(struct zzdlg_state *);
extern void zzrestore_dlg_state(struct zzdlg_state *);
extern int zzerr_in(void);
extern void zzerrstd(const char *);
extern void zzerraction(void);
#else
extern void zzadvance();
extern void zzskip(); /* erase zzlextext, look for antoher token */
extern void zzmore(); /* keep zzlextext, look for another token */
extern void zzmode(/*k*/); /* switch to automaton 'k' */
extern void zzrdstream(); /* what stream to read from */
extern void zzclose_stream();/* close the current input stream */
extern void zzrdfunc(); /* what function to get char from */
extern void zzrdstr();
extern void zzgettok(); /* get next token */
extern void zzreplchar(); /* replace last recognized reg. expr. with
a character */
extern void zzreplstr(); /* replace last recognized reg. expr. with
a string */
extern void zzsave_dlg_state();
extern void zzrestore_dlg_state();
extern int zzerr_in();
extern void zzerrstd();
extern void zzerraction();
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/* ANTLR attribute definition -- long integers
*
* 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-1998
*/
#ifndef ZZINT_H
#define ZZINT_H
typedef long Attrib;
#define zzcr_attr(a,tok,t) *(a) = atol(t);
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_ASSERT_H__
#define __PCCTS_ASSERT_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <cassert>
#else
#include <assert.h>
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_IOSTREAM_H__
#define __PCCTS_IOSTREAM_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <iostream>
#else
#include <iostream.h>
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_ISTREAM_H__
#define __PCCTS_ISTREAM_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <istream>
#else
#include <istream.h>
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_SETJMP_H__
#define __PCCTS_SETJMP_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <csetjmp>
#else
#include <setjmp.h>
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_STDARG_H__
#define __PCCTS_STDARG_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <cstdarg>
#else
#include <stdarg.h>
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_STDIO_H__
#define __PCCTS_STDIO_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <cstdio>
#else
#include <stdio.h>
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_STDLIB_H__
#define __PCCTS_STDLIB_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __PCCTS_STRING_H__
#define __PCCTS_STRING_H__
#ifdef PCCTS_USE_NAMESPACE_STD
#include <cstring>
#else
#include <string.h>
#endif
#endif

View File

@@ -0,0 +1,350 @@
#ifndef PCCTS_CONFIG_H
#define PCCTS_CONFIG_H
/*
* pcctscfg.h (formerly config.h) (for ANTLR, DLG, and SORCERER)
*
* This is a simple configuration file that doesn't have config stuff
* in it, but it's a start.
*
* 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.
*
* Used by PCCTS 1.33 (SORCERER 1.00B11 and up)
* Terence Parr
* Parr Research Corporation
* with Purdue University and AHPCRC, University of Minnesota
* 1989-1998
*/
/* This file knows about the following ``environments''
UNIX (default)
DOS (use #define PC)
MAC (use #define MPW; has a few things for THINK C, Metrowerks)
MS/C++ (MR14 Microsoft Visual C++ environment uses symbol _MSC_VER)
*/
/* should test __STDC__ for 1, but some compilers don't set value, just def */
#ifndef __USE_PROTOS
#ifdef __STDC__
#define __USE_PROTOS
#endif
#ifdef __cplusplus
#define __USE_PROTOS
#endif
#endif
#ifdef PCCTS_USE_NAMESPACE_STD
#define PCCTS_NAMESPACE_STD namespace std {}; using namespace std;
#else
#define PCCTS_NAMESPACE_STD
#endif
#include "pccts_stdio.h"
#include "pccts_stdlib.h"
/* largest file name size */
#ifdef _MAX_PATH
#define MaxFileName _MAX_PATH /* MR9 RJV: MAX_PATH defined in stdlib.h (MSVC++ 5.0) */
#else
#define MaxFileName 300
#endif
/*
* Define PC32 if in a 32-bit PC environment (e.g. extended DOS or Win32).
* The macros tested here are defined by Watcom, Microsoft, Borland,
* and djgpp, respectively, when they are used as 32-bit compilers.
* Users of these compilers *must* be sure to define PC in their
* makefiles for this to work correctly.
*/
#ifdef PC
# if (defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) || \
defined(__GNUC__) || defined(__GNUG__))
# ifndef PC32
# define PC32
# endif
# endif
#endif
/* MR1 10-Apr-97 Default for PC is short file names */
/* MR1 Default for non-PC is long file names */
/* MR1 Can override via command line option LONGFILENAMES */
#ifndef LONGFILENAMES
#ifndef PC
#define LONGFILENAMES
#endif
#endif
#ifndef LONGFILENAMES
#define ATOKEN_H "AToken.h"
#define ATOKPTR_H "ATokPtr.h"
#define ATOKPTR_C "ATokPtr.cpp"
#define ATOKENBUFFER_H "ATokBuf.h"
#define ATOKENBUFFER_C "ATokBuf.cpp"
#define ATOKENSTREAM_H "ATokStr.h"
#define APARSER_H "AParser.h"
#define APARSER_C "AParser.cpp"
#define ASTBASE_H "ASTBase.h"
#define ASTBASE_C "ASTBase.cpp"
#define PCCTSAST_C "PCCTSAST.cpp"
#define LIST_C "List.cpp"
#define DLEXERBASE_H "DLexBase.h"
#define DLEXERBASE_C "DLexBase.cpp"
#define DLEXER_C "DLexer.cpp"
#define STREESUPPORT_C "STreeSup.C"
#else
#define ATOKEN_H "AToken.h"
#define ATOKPTR_H "ATokPtr.h"
#define ATOKPTR_C "ATokPtr.cpp"
#define ATOKENBUFFER_H "ATokenBuffer.h"
#define ATOKENBUFFER_C "ATokenBuffer.cpp"
#define ATOKENSTREAM_H "ATokenStream.h"
#define APARSER_H "AParser.h"
#define APARSER_C "AParser.cpp"
#define ASTBASE_H "ASTBase.h"
#define ASTBASE_C "ASTBase.cpp"
#define PCCTSAST_C "PCCTSAST.cpp"
#define LIST_C "List.cpp"
#define DLEXERBASE_H "DLexerBase.h"
#define DLEXERBASE_C "DLexerBase.cpp"
#define DLEXER_C "DLexer.cpp"
#define STREESUPPORT_C "STreeSupport.cpp"
#endif
/* SORCERER Stuff */
/* MR8 6-Aug-97 Change from ifdef PC to ifndef LONGFILENAMES */
#ifndef LONGFILENAMES
#define STPARSER_H "STreePar.h"
#define STPARSER_C "STreePar.C"
#else
#define STPARSER_H "STreeParser.h"
#define STPARSER_C "STreeParser.cpp"
#endif
#ifdef MPW
#define CPP_FILE_SUFFIX ".cp"
#define CPP_FILE_SUFFIX_NO_DOT "cp"
#define OBJ_FILE_SUFFIX ".o"
#else
#ifdef PC
#define CPP_FILE_SUFFIX ".cpp"
#define CPP_FILE_SUFFIX_NO_DOT "cpp"
#define OBJ_FILE_SUFFIX ".obj"
#else
#ifdef __VMS
#define CPP_FILE_SUFFIX ".cpp"
#define CPP_FILE_SUFFIX_NO_DOT "cpp"
#define OBJ_FILE_SUFFIX ".obj"
#else
#define CPP_FILE_SUFFIX ".cpp"
#define CPP_FILE_SUFFIX_NO_DOT "cpp"
#define OBJ_FILE_SUFFIX ".o"
#endif
#endif
#endif
/* User may redefine how line information looks */ /* make it #line MR7 */
/* MR21 Use #ifndef */
#ifndef LineInfoFormatStr
#define LineInfoFormatStr "#line %d \"%s\"\n"
#endif
#ifdef MPW /* Macintosh Programmer's Workshop */
#define ErrHdr "File \"%s\"; Line %d #"
#else
#ifdef _MSC_VER /* MR14 Microsoft Visual C++ environment */
#define ErrHdr "%s(%d) :"
#else
#define ErrHdr "%s, line %d:" /* default */
#endif
#endif
/* must assume old K&R cpp here, can't use #if defined(..)... */
#ifdef MPW
#define TopDirectory ":"
#define DirectorySymbol ":"
#define OutputDirectoryOption "Directory where all output files should go (default=\":\")"
#else
#ifdef PC
#define TopDirectory "."
#define DirectorySymbol "\\"
#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"
#else
#ifdef __VMS
#define TopDirectory "[000000]"
#define DirectorySymbol "]"
#define OutputDirectoryOption "Directory where all output files should go (default=\"[]\")"
#else
#define TopDirectory "."
#define DirectorySymbol "/"
#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"
#endif
#endif
#endif
#ifdef MPW
/* Make sure we have prototypes for all functions under MPW */
#include "pccts_string.h"
#include "pccts_stdlib.h"
/* MR6 2-Jun-97 Fixes false dependency caused by VC++ #include scanner */
/* MR6 Reported by Brad Schick (schick@interaccess.com) */
#define MPW_CursorCtl_Header <CursorCtl.h>
#include MPW_CursorCtl_Header
#ifdef __cplusplus
extern "C" {
#endif
extern void fsetfileinfo (const char *filename, unsigned long newcreator, unsigned long newtype);
#ifdef __cplusplus
}
#endif
/* File creators for various popular development environments */
#define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */
#if 0
#define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */
#endif
#if 0
#define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */
#endif
#endif
#ifdef MPW
#define DAWDLE SpinCursor(1)
#else
#define DAWDLE
#endif
#ifdef MPW
#define SPECIAL_INITS
#define SPECIAL_FOPEN
#endif
#ifdef MPW
#ifdef __cplusplus
inline
#else
static
#endif
void special_inits()
{
InitCursorCtl((acurHandle) 0);
}
#endif
#ifdef MPW
#ifdef __cplusplus
inline
#else
static
#endif
void special_fopen_actions(char * s)
{
fsetfileinfo (s, MAC_FILE_CREATOR, 'TEXT');
}
#endif
/* Define usable bits for set.c stuff */
#define BytesPerWord sizeof(unsigned)
#define WORDSIZE (sizeof(unsigned)*8)
#define LogWordSize (WORDSIZE==16?4:5)
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#if defined(VAXC) || defined(__VMS)
#include <ssdef.h>
#define PCCTS_EXIT_SUCCESS 1
#define PCCTS_EXIT_FAILURE SS$_ABORT
#define zzDIE return SS$_ABORT;
#define zzDONE return 1;
#else /* !VAXC and !__VMS */
#define PCCTS_EXIT_SUCCESS 0
#define PCCTS_EXIT_FAILURE 1
#define zzDIE return 1;
#define zzDONE return 0;
#endif
#ifdef USER_ZZMODE_STACK
# ifndef ZZSTACK_MAX_MODE
# define ZZSTACK_MAX_MODE 32
# endif
# define ZZMAXSTK (ZZSTACK_MAX_MODE * 2)
#endif
#ifndef DllExportPCCTS
#define DllExportPCCTS
#endif
#ifdef PC
#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME
#define PCCTS_CASE_INSENSITIVE_FILE_NAME
#endif
#endif
#ifdef PC32
#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME
#define PCCTS_CASE_INSENSITIVE_FILE_NAME
#endif
#endif
#ifdef __VMS
#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME
#define PCCTS_CASE_INSENSITIVE_FILE_NAME
#endif
#endif
#ifdef __USE_PROTOS
#ifndef PCCTS_USE_STDARG
#define PCCTS_USE_STDARG
#endif
#endif
#ifdef __STDC__
#ifndef PCCTS_USE_STDARG
#define PCCTS_USE_STDARG
#endif
#endif
#ifdef __cplusplus
#ifndef PCCTS_USE_STDARG
#define PCCTS_USE_STDARG
#endif
#endif
#endif

View File

@@ -0,0 +1,118 @@
# Microsoft Developer Studio Project File - Name="pcctslib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=pcctslib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "pcctslib50.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "pcctslib50.mak" CFG="pcctslib - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "pcctslib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "pcctslib - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
!IF "$(CFG)" == "pcctslib - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"pccts_release.lib"
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Copy to ..\lib
PostBuild_Cmds=mkdir ..\lib copy pccts_release.lib ..\lib\pccts_release.lib
# End Special Build Tool
!ELSEIF "$(CFG)" == "pcctslib - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"pccts_debug.lib"
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Copy to ..\lib
PostBuild_Cmds=mkdir ..\lib copy pccts_debug.lib ..\lib\pccts_debug.lib
# End Special Build Tool
!ENDIF
# Begin Target
# Name "pcctslib - Win32 Release"
# Name "pcctslib - Win32 Debug"
# Begin Source File
SOURCE=.\AParser.cpp
# End Source File
# Begin Source File
SOURCE=.\ASTBase.cpp
# End Source File
# Begin Source File
SOURCE=.\ATokenBuffer.cpp
# End Source File
# Begin Source File
SOURCE=.\BufFileInput.cpp
# End Source File
# Begin Source File
SOURCE=.\DLexerBase.cpp
# End Source File
# Begin Source File
SOURCE=.\PCCTSAST.cpp
# End Source File
# Begin Source File
SOURCE=.\SList.cpp
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 5.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "pcctslib"=.\pcctslib50.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,124 @@
# Microsoft Developer Studio Project File - Name="pcctslib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=pcctslib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "pcctslib60.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "pcctslib60.mak" CFG="pcctslib - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "pcctslib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "pcctslib - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "pcctslib - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"pccts_release.lib"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Copy to ..\lib
PostBuild_Cmds=mkdir ..\lib copy pccts_release.lib ..\lib\pccts_release.lib
# End Special Build Tool
!ELSEIF "$(CFG)" == "pcctslib - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"pccts_debug.lib"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Copy to ..\lib
PostBuild_Cmds=mkdir ..\lib copy pccts_debug.lib ..\lib\pccts_debug.lib
# End Special Build Tool
!ENDIF
# Begin Target
# Name "pcctslib - Win32 Release"
# Name "pcctslib - Win32 Debug"
# Begin Source File
SOURCE=.\AParser.cpp
# End Source File
# Begin Source File
SOURCE=.\ASTBase.cpp
# End Source File
# Begin Source File
SOURCE=.\ATokenBuffer.cpp
# End Source File
# Begin Source File
SOURCE=.\BufFileInput.cpp
# End Source File
# Begin Source File
SOURCE=.\DLexerBase.cpp
# End Source File
# Begin Source File
SOURCE=.\PCCTSAST.cpp
# End Source File
# Begin Source File
SOURCE=.\SList.cpp
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "pcctslib"=.\pcctslib60.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,11 @@
ren aparser.c aparser.cpp
ren astbase.c astbase.cpp
ren atokenbu.c atokbuf.cpp
ren atokenbu.h atokbuf.h
ren atokenst.h atokstr.h
ren dlexerba.c dlexbase.cpp
ren dlexerba.h dlexbase.h
ren dlexer.c dlexer.cpp
ren list.c list.cpp
ren pblackbo.h pblckbox.h
ren pcctsast.c pcctsast.cpp

View File

@@ -0,0 +1,105 @@
/*
* SList.C
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* PCCTS 1.33
* Terence Parr
* Parr Research Corporation
* with Purdue University and AHPCRC, University of Minnesota
* 1992-1998
*/
#define ANTLR_SUPPORT_CODE
#include "SList.h"
/* Iterate over a list of elements; returns ptr to a new element
* in list upon every call and NULL when no more are left.
* Very useful like this:
*
* cursor = mylist;
* while ( (p=mylist->iterate(&cursor)) ) {
* // place with element p
* }
*
* The cursor must be initialized to point to the list to iterate over.
*/
void *SList::
iterate(SListNode **cursor)
{
void *e;
if ( cursor == NULL || *cursor==NULL ) return NULL;
if ( head == *cursor ) { *cursor = (*cursor)->next(); }
e = (*cursor)->elem();
(*cursor) = (*cursor)->next();
return e;
}
/* add an element to end of list. */
void SList::
add(void *e)
{
SListNode *p, *tail=NULL;
require(e!=NULL, "slist_add: attempting to add NULL list element");
p = new SListNode;
require(p!=NULL, "add: cannot alloc new list node");
p->setElem(e);
if ( head == NULL )
{
head = tail = p;
}
else /* find end of list */
{
tail->setNext(p);
tail = p;
}
}
void SList::
lfree()
{
SListNode *p,*q;
if ( head==NULL ) return; /* empty list */
for (p = head; p!=NULL; p=q)
{
q = p->next();
free(p);
}
}
PCCTS_AST *SList::
to_ast(SList list)
{
PCCTS_AST *t=NULL, *last=NULL;
SListNode *p;
for (p = head; p!=NULL; p=p->next())
{
PCCTS_AST *u = (PCCTS_AST *)p->elem();
if ( last==NULL ) last = t = u;
else { last->setRight(u); last = u; }
}
return t;
}

View File

@@ -0,0 +1,8 @@
#ifndef SASTBase_h
#define SASTBase_h
#include "PCCTSAST.h"
typedef PCCTS_AST SORASTBase;
#endif

View File

@@ -0,0 +1,26 @@
#ifndef SCommonAST_h
#define SCommonAST_h
#include <stdio.h>
#include "PCCTSAST.h"
#include "SASTBase.h"
/* If you use SORCERER alone, you can subclass this to get a nice tree def */
class SORCommonAST : public SORASTBase {
protected:
SORCommonAST *_right, *_down;
int _type;
public:
SORCommonAST() { _right = _down = NULL; }
PCCTS_AST *right() { return _right; } // define the SORCERER interface
PCCTS_AST *down() { return _down; }
int type() { return _type; }
void setRight(PCCTS_AST *t) { _right = (SORCommonAST *)t; }
void setDown(PCCTS_AST *t) { _down = (SORCommonAST *)t; }
void setType(int t) { _type = t; }
virtual PCCTS_AST *shallowCopy() {return NULL;}
};
#endif

View File

@@ -0,0 +1,110 @@
#ifndef STreeParser_h
#define STreeParser_h
/*
* STreeParser.h
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Parr Research Corporation
* with Purdue University and AHPCRC, University of Minnesota
* 1992-1994
*/
/* The programmer should derive a class from SORASTBase; SORASTBase defines
* the minimum public interface that a tree node must follow for SORCERER to
* be able to walk the trees.
*/
/* The @-vars are added by the subclass created by SORCERER; the constructor
* is used to init the @-vars.
*/
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
#include "SASTBase.h"
#define _DOWN _t=(SORASTBase *)_t->down()
#define _RIGHT _t=(SORASTBase *)_t->right()
#define _SAVE SORASTBase *_save=_t
#define _RESTORE _t = _save
#define _GUESS_BLOCK STreeParser _st; int _gv; SORASTBase *_savet=NULL;
#define _GUESS {save_state(&_st); \
_savet = _t; \
guessing = 1; \
_gv = setjmp(startofguess.state);}
#define _GUESS_FAIL longjmp(startofguess.state, 1)
#define _GUESS_DONE {restore_state(&_st); _t = _savet;}
#define _MATCH(tok) MATCH(_t,tok)
#define _MATCHRANGE(t1,t2) MATCHRANGE(_t,t1,t2)
#define _WILDCARD WILDCARD(_t)
#define ast_return(t) *_result = (SORASTBase *)t;
#define STreeTry(r,p,t) \
(p)->try_result = NULL; \
(p)->sjrv = setjmp((p)->startofguess); \
if ( !(p)->sjrv ) { \
rule(p,t,&try_result); \
(p)->try_ok = 1; \
} \
else { \
(p)->try_ok = 0; \
} \
if ( (p)->try_ok )
/* Used only during TRANSFORM mode */
#define TREE_CONSTR_PTRS SORASTBase *_r=NULL,*_s=NULL,*_e=NULL
typedef struct _Sjmp_buf {
jmp_buf state;
} Sjmp_buf;
class STreeParser {
protected:
int try_ok, sjrv; /* used by STreeTry macro */
SORASTBase *try_result; /* tree coming back from try */
int guessing;
Sjmp_buf startofguess;
// SORASTBase *t;
void _mkroot(SORASTBase **, SORASTBase **, SORASTBase **, SORASTBase *);
void _mkchild(SORASTBase **, SORASTBase **, SORASTBase **, SORASTBase *);
virtual void mismatched_range(int looking_for, int upper_token, SORASTBase *found);
virtual void missing_wildcard();
virtual void mismatched_token(int looking_for, SORASTBase *found);
virtual void no_viable_alt(char *rulename, SORASTBase *root);
virtual void MATCH(SORASTBase *_t, int tok);
virtual void MATCHRANGE(SORASTBase *_t, int tok, int tok2);
virtual void WILDCARD(SORASTBase *_t);
public:
STreeParser() { guessing = 0; }
virtual void panic(char *err);
void save_state(STreeParser *);
void restore_state(STreeParser *);
};
#endif

View File

@@ -0,0 +1,72 @@
#ifndef astlib_h
#define astlib_h
/*
* astlib.h -- C ast_* library header
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include <setjmp.h>
#include "sorcerer.h"
#include "sorlist.h"
#define MaxTreeStackDepth 400
#ifdef __USE_PROTOS
extern SORAST *ast_make(SORAST *rt, ...);
extern SORAST *ast_find_all(SORAST *t, SORAST *u, SORAST **cursor);
extern int ast_match(SORAST *t, SORAST *u);
extern void ast_insert_after(SORAST *a, SORAST *b);
extern void ast_append(SORAST *a, SORAST *b);
extern SORAST *ast_tail(SORAST *a);
extern SORAST *ast_bottom(SORAST *a);
extern SORAST *ast_cut_between(SORAST *a, SORAST *b);
extern SList *ast_to_slist(SORAST *t);
extern SORAST *slist_to_ast(SList *list);
extern void ast_free(SORAST *t);
extern int ast_scan(char *template, SORAST *tree, ...);
extern int ast_nsiblings(SORAST *t);
extern SORAST *ast_sibling_index(SORAST *t, int i);
extern int ast_match_partial(SORAST *t, SORAST *u);
#else
extern SORAST *ast_make();
extern SORAST *ast_find_all();
extern int ast_match();
extern void ast_insert_after();
extern void ast_append();
extern SORAST *ast_tail();
extern SORAST *ast_bottom();
extern SORAST *ast_cut_between();
extern SList *ast_to_slist();
extern SORAST *slist_to_ast();
extern void ast_free();
extern int ast_scan();
extern int ast_nsiblings();
extern SORAST *ast_sibling_index();
extern int ast_match_partial();
#endif
#endif

View File

@@ -0,0 +1,61 @@
#ifndef SINTSTACK_H
#define SINTSTACK_H
/*
* SIntStack.h
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include "sorcerer.h"
typedef struct _istack {
int *data;
int sp;
int size;
} SIntStack;
#ifdef __USE_PROTOS
extern SIntStack *sint_newstack(int size);
extern void sint_freestack(SIntStack *st);
extern void sint_push(SIntStack *st, int i);
extern int sint_pop(SIntStack *st);
extern int sint_stacksize(SIntStack *st);
extern void sint_stackreset(SIntStack *st);
extern int sint_stackempty(SIntStack *st);
extern int sint_top(SIntStack *st);
#else
extern SIntStack *sint_newstack();
extern void sint_freestack();
extern void sint_push();
extern int sint_pop();
extern int sint_stacksize();
extern void sint_stackreset();
extern int sint_stackempty();
extern int sint_top();
#endif
#endif

View File

@@ -0,0 +1,172 @@
#ifndef sorcerer_h
#define sorcerer_h
/*
* sorcerer.h -- header for all sorcerer files
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include "pcctscfg.h"
#ifdef __USE_PROTOS
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <setjmp.h>
/* SUPERCLASS SORAST (your tree must look at minimum like this)
typedef struct _node {
struct _node *right, *down;
int token;
-- user-defined stuff goes here
} SORAST;
*/
/* Can be used sort of like inheritance to get the desired struct def */
#define AST_REQD_FIELDS \
struct _node *right, *down; \
int token;
/* C MATCH */ /* MR21 Short circuit on null pointer */
#define _MATCH(tok) if (! _t || _t->token!=tok ) if ( _parser->guessing ) _GUESS_FAIL; else mismatched_token(_parser, tok, _t)
#define _MATCHRANGE(tok,tok2) \
if (! _t || _t->token<tok || _t->token>tok2 ) if ( _parser->guessing ) _GUESS_FAIL; else mismatched_range(_parser, tok, tok2, _t)
/* C++ MATCH */
#define _CPPMATCH(tok) if ( _t->token()!=tok ) if ( _parser->guessing ) _GUESS_FAIL; else mismatched_token(_parser, tok, _t)
#define _CPPMATCHRANGE(tok,tok2) \
if ( _t->token()<tok || _t->token()>tok2 ) if ( _parser->guessing ) _GUESS_FAIL; else mismatched_range(_parser, tok, tok2, _t)
/* Normal DOWN and RIGHT */
#define _DOWN _t=_t->down
#define _RIGHT _t=_t->right
/* C++ DOWN and RIGHT */
#define _CPPDOWN _t=(SORAST *) _t->down()
#define _CPPRIGHT _t=(SORAST *) _t->right()
#define _SAVE SORAST *_save=_t
#define _RESTORE _t = _save
#define _SETLABEL(u) u=_t
#define _WILDCARD if ( _t==NULL ) if ( _parser->guessing ) _GUESS_FAIL; else missing_wildcard(_parser)
#define _GUESS_BLOCK STreeParser _st; int _gv; SORAST *_savet=NULL;
#define _GUESS {_st = *_parser; \
_savet = _t; \
_parser->guessing = 1; \
_gv = setjmp(_parser->startofguess.state);}
#define _GUESS_FAIL longjmp(_parser->startofguess.state, 1)
#define _GUESS_DONE {*_parser = _st; _t = _savet;}
/* These are used mainly by the C output */
#ifndef ast_down
#define ast_down down
#endif
#ifndef ast_right
#define ast_right right
#endif
#define STreeTry(r,p,t) \
(p)->try_result = NULL; \
(p)->sjrv = setjmp((p)->startofguess); \
if ( !(p)->sjrv ) { \
rule(p,t,&try_result); \
(p)->try_ok = 1; \
} \
else { \
(p)->try_ok = 0; \
} \
if ( (p)->try_ok )
/* Used only during TRANSFORM mode */
#define TREE_CONSTR_PTRS SORAST *_r=NULL,*_s=NULL,*_e=NULL
typedef struct _Sjmp_buf {
jmp_buf state;
} Sjmp_buf;
#ifndef _PARSER_VARS
#define _PARSER_VARS
#endif
#ifndef _REFVARS
#define _REFVARS
#endif
typedef struct _STreeParser {
int try_ok, sjrv; /* used by STreeTry macro */
SORAST *try_result; /* tree coming back from try */
int guessing;
Sjmp_buf startofguess;
SORAST *t;
_REFVARS
_PARSER_VARS
} STreeParser;
#define STreeParserInit(_p) { (_p)->guessing = 0; _refvar_inits(_p); }
/* S a n i t y C h e c k i n g */
#ifndef require
#define require(expr, err) {if ( !(expr) ) sorcerer_panic(err);}
#endif
/* T r a n s f o r m M a c r o s */
#define ast_return(_t) *_result = _t
#ifdef __USE_PROTOS
extern void mismatched_range(STreeParser *_parser, int looking_for, int upper_token, SORAST *found);
extern void missing_wildcard(STreeParser *_parser);
extern void mismatched_token(STreeParser *_parser, int looking_for, SORAST *found);
extern void no_viable_alt(STreeParser *_parser, char *rulename, SORAST *root);
extern void sorcerer_panic(char *err);
extern void _refvar_inits(STreeParser *); /* MR15 Kevin J. Cummings */
extern void _mkroot(SORAST **, SORAST **, SORAST **, SORAST *);
extern void _mkchild(SORAST **, SORAST **, SORAST **, SORAST *);
extern SORAST *ast_alloc(void);
extern SORAST *ast_dup(SORAST *t);
extern SORAST *ast_dup_node(SORAST *t);
#else
extern void mismatched_range();
extern void missing_wildcard();
extern void mismatched_token();
extern void no_viable_alt();
extern void sorcerer_panic();
extern void _refvar_inits(); /* MR15 Kevin J. Cummings */
extern void _mkroot();
extern void _mkchild();
extern SORAST *ast_alloc();
extern SORAST *ast_dup();
extern SORAST *ast_dup_node();
#endif
#endif

View File

@@ -0,0 +1,52 @@
#ifndef SLIST_H
#define SLIST_H
/*
* SList.h
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include "sorcerer.h"
typedef struct _SList {
void *elem; /* pointer to any kind of element */
struct _SList *next;
} SList;
#define newSList (SList *) calloc(1, sizeof(SList));
#ifdef __USE_PROTOS
extern void *slist_iterate(SList *list, SList **);
extern void slist_add( SList **list, void *e );
extern void slist_free(SList *list);
#else
extern void *slist_iterate();
extern void slist_add();
extern void slist_free();
#endif
#endif

View File

@@ -0,0 +1,46 @@
#ifndef SSTACK_H
#define SSTACK_H
/*
* SStack.h
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include "sorlist.h"
typedef SList SStack;
#define newSStack (SStack *) calloc(1, sizeof(SStack));
#ifdef __USE_PROTOS
extern void sstack_push( SStack **st, void *e );
extern void *sstack_pop( SStack **st );
#else
extern void sstack_push();
extern void *sstack_pop();
#endif
#endif

View File

@@ -0,0 +1,45 @@
#ifndef CASTBase_h
#define CASTBase_h
/*
* CASTBase.h
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
/* ONLY USED TO C COMPILE LIBRARY FUNCTIONS; YOU CAN FORCE THEM TO COMPILE WITH
* YOUR SORAST DEF IF YOU WANT (THAT WAY, ORDER OF FIELD DEFINITION IS IRRELEVANT)
*/
/* Typically, this file is not used / seen by the programmer */
/* Used as "super-class" for compiling C library routines */
typedef struct _nodebase {
struct _nodebase *right, *down;
int token;
} SORAST;
#endif

View File

@@ -0,0 +1,151 @@
#include <stdio.h>
#include "STreeParser.h"
void STreeParser::
MATCH(SORASTBase *_t,int tok)
{
if ( _t->type()!=tok )
{
if ( guessing ) _GUESS_FAIL;
else mismatched_token(tok, _t);
}
}
void STreeParser::
MATCHRANGE(SORASTBase *_t,int tok,int tok2)
{
if ( _t->type()<tok || _t->type()>tok2 )
{
if ( guessing ) _GUESS_FAIL;
else mismatched_range(tok, tok2, _t);
}
}
void STreeParser::
WILDCARD(SORASTBase *_t)
{
if ( _t==NULL )
{
if ( guessing ) _GUESS_FAIL;
else missing_wildcard();
}
}
void STreeParser::
mismatched_range(int looking_for, int upper_token, SORASTBase *found)
{
if ( found!=NULL ) {
fprintf(stderr,
"parse error: expected token range %d..%d found token %d\n",
looking_for, upper_token,
found->type());
}
else {
fprintf(stderr,
"parse error: expected token range %d..%d found NULL tree\n",
looking_for, upper_token);
}
}
void STreeParser::
missing_wildcard()
{
fprintf(stderr, "parse error: expected any token/tree found found NULL tree\n");
}
void STreeParser::
mismatched_token(int looking_for, SORASTBase *found)
{
if ( found!=NULL ) {
fprintf(stderr,
"parse error: expected token %d found token %d\n",
looking_for,
found->type());
}
else {
fprintf(stderr,
"parse error: expected token %d found NULL tree\n",
looking_for);
}
}
void STreeParser::
no_viable_alt(char *rulename, SORASTBase *root)
{
if ( root==NULL )
fprintf(stderr,
"parse error: in rule %s, no viable alternative for NULL tree\n",
rulename);
else
fprintf(stderr,
"parse error: in rule %s, no viable alternative for tree\n",
rulename);
}
void STreeParser::
panic(char *err)
{
fprintf(stderr, "panic: %s\n", err);
exit(-1);
}
void STreeParser::
save_state(STreeParser *buf)
{
buf->try_ok = this->try_ok;
buf->sjrv = this->sjrv;
buf->guessing = this->guessing;
buf->startofguess = this->startofguess;
}
void STreeParser::
restore_state(STreeParser *buf)
{
this->try_ok = buf->try_ok;
this->sjrv = buf->sjrv;
this->guessing = buf->guessing;
this->startofguess = buf->startofguess;
}
void STreeParser::
_mkroot(SORASTBase **r, SORASTBase **s, SORASTBase **e, SORASTBase *t)
{
*r = t;
}
void STreeParser::
_mkchild(SORASTBase **r, SORASTBase **s, SORASTBase **e, SORASTBase *t)
{
#ifdef BEFORE_GARYS_FIX
/* if no sibling list, must attach to any existing root */
if ( *s==NULL )
{
*s = *e = t;
/* If r is NULL, then there was no root defined--must be sibling list */
if ( *r==NULL ) *r = *s;
else (*r)->setDown(t);
}
else { (*e)->setRight(t); *e = t; }
#endif
/*
should do nothing if asked to add a NULL argument. NULL's come up
when a rule wants to return "nothing".
*/
/* if no sibling list, must attach to any existing root */
if (*s == NULL)
{
*s = *e = t;
// If r is NULL then there was no root defined--must be sibling list
if (*r == NULL) *r = *s;
else (*r)->setDown(t);
}
else if (*e != NULL)
{
(*e)->setRight(t);
*e = t;
}
if (*e != NULL) {
while ((*e)->right() != NULL) *e = (SORASTBase *)(*e)->right();
}
}

View File

@@ -0,0 +1,834 @@
/*
* astlib.c
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include <stdio.h>
#include "pcctscfg.h"
#include <ctype.h>
#define SORCERER_TRANSFORM
#include "CASTBase.h"
#include "astlib.h"
#ifdef PCCTS_USE_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
/* String Scanning/Parsing Stuff */
#define StringScanMaxText 50
typedef struct stringlexer {
#ifdef __USE_PROTOS
signed int c;
#else
int c;
#endif
char *input;
char *p;
char text[StringScanMaxText];
} StringLexer;
#define LPAREN 1
#define RPAREN 2
#define PERCENT 3
#define INT 4
#define COLON 5
#define POUND 6
#define PERIOD 7
#define StringScanEOF -1
#define VALID_SCAN_TOKEN(t) (t>=LPAREN && t<=PERIOD)
static char *scan_token_tbl[] = {
"invalid", /* 0 */
"LPAREN", /* 1 */
"RPAREN", /* 2 */
"PERCENT", /* 3 */
"INT", /* 4 */
"COLON", /* 5 */
"POUND", /* 6 */
"PERIOD", /* 7 */
};
char *
#ifdef __USE_PROTOS
scan_token_str(int t)
#else
scan_token_str(t)
int t;
#endif
{
if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t];
else if ( t==StringScanEOF ) return "<end-of-string>";
else return "<invalid-token>";
}
typedef struct stringparser {
int token;
StringLexer *lexer;
int num_labels;
} StringParser;
/* This type ONLY USED by ast_scan() */
typedef struct _scanast {
struct _scanast *right, *down;
int token;
int label_num;
} ScanAST;
#ifdef __USE_PROTOS
static void stringlexer_init(StringLexer *scanner, char *input);
static void stringparser_init(StringParser *, StringLexer *);
static ScanAST *stringparser_parse_scanast(char *templ, int *n);
static ScanAST *stringparser_parse_tree(StringParser *parser);
static ScanAST *stringparser_parse_element(StringParser *parser);
static void stringscan_advance(StringLexer *scanner);
static int stringscan_gettok(StringLexer *scanner);
#else
static void stringlexer_init();
static void stringparser_init();
static ScanAST *stringparser_parse_scanast();
static ScanAST *stringparser_parse_tree();
static ScanAST *stringparser_parse_element();
static void stringscan_advance();
static int stringscan_gettok();
#endif
/* build a tree (root child1 child2 ... NULL)
* If root is NULL, simply make the children siblings and return ptr
* to 1st sibling (child1). If root is not single node, return NULL.
*
* Siblings that are actually sibling lists themselves are handled
* correctly. For example #( NULL, #( NULL, A, B, C), D) results
* in the tree ( NULL A B C D ).
*
* Requires at least two parameters with the last one being NULL. If
* both are NULL, return NULL.
*
* The ast_down and ast_right down/right pointers are used to make the tree.
*/
SORAST *
#ifdef PCCTS_USE_STDARG
ast_make(SORAST *rt, ...)
#else
ast_make(va_alist)
va_dcl
#endif
{
va_list ap;
register SORAST *child, *sibling=NULL, *tail = NULL, *w;
SORAST *root;
#ifdef PCCTS_USE_STDARG
va_start(ap, rt);
root = rt;
#else
va_start(ap);
root = va_arg(ap, SORAST *);
#endif
if ( root != NULL )
if ( root->ast_down != NULL ) return NULL;
child = va_arg(ap, SORAST *);
while ( child != NULL )
{
/* find end of child */
for (w=child; w->ast_right!=NULL; w=w->ast_right) {;}
if ( sibling == NULL ) {sibling = child; tail = w;}
else {tail->ast_right = child; tail = w;}
child = va_arg(ap, SORAST *);
}
if ( root==NULL ) root = sibling;
else root->ast_down = sibling;
va_end(ap);
return root;
}
/* The following push and pop routines are only used by ast_find_all() */
static void
#ifdef __USE_PROTOS
_push(SORAST **st, int *sp, SORAST *e)
#else
_push(st, sp, e)
SORAST **st;
int *sp;
SORAST *e;
#endif
{
(*sp)--;
require((*sp)>=0, "stack overflow");
st[(*sp)] = e;
}
static SORAST *
#ifdef __USE_PROTOS
_pop(SORAST **st, int *sp)
#else
_pop(st, sp)
SORAST **st;
int *sp;
#endif
{
SORAST *e = st[*sp];
(*sp)++;
require((*sp)<=MaxTreeStackDepth, "stack underflow");
return e;
}
/* Is 'u' a subtree of 't' beginning at the root? */
int
#ifdef __USE_PROTOS
ast_match_partial(SORAST *t, SORAST *u)
#else
ast_match_partial(t, u)
SORAST *t, *u;
#endif
{
SORAST *sib;
if ( u==NULL ) return 1;
if ( t==NULL ) if ( u!=NULL ) return 0; else return 1;
for (sib=t; sib!=NULL&&u!=NULL; sib=sib->ast_right, u=u->ast_right)
{
if ( sib->token != u->token ) return 0;
if ( sib->ast_down!=NULL )
if ( !ast_match_partial(sib->ast_down, u->ast_down) ) return 0;
}
return 1;
}
/* Find all occurrences of u in t.
* 'cursor' must be initialized to 't'. It eventually
* returns NULL when no more occurrences of 'u' are found.
*/
SORAST *
#ifdef __USE_PROTOS
ast_find_all(SORAST *t, SORAST *u, SORAST **cursor)
#else
ast_find_all(t, u, cursor)
SORAST *t, *u, **cursor;
#endif
{
SORAST *sib;
static SORAST *template_stack[MaxTreeStackDepth];
static int tsp = MaxTreeStackDepth;
if ( *cursor == NULL ) return NULL;
if ( *cursor!=t ) sib = *cursor;
else {
/* else, first time--start at top of template 't' */
tsp = MaxTreeStackDepth;
sib = t;
/* bottom of stack is always a NULL--"cookie" indicates "done" */
_push(template_stack, &tsp, NULL);
}
keep_looking:
if ( sib==NULL ) /* hit end of sibling list */
{
sib = _pop(template_stack, &tsp);
if ( sib == NULL ) { *cursor = NULL; return NULL; }
}
if ( sib->token != u->token )
{
/* look for another match */
if ( sib->ast_down!=NULL )
{
if ( sib->ast_right!=NULL ) _push(template_stack, &tsp, sib->ast_right);
sib=sib->ast_down;
goto keep_looking;
}
/* nothing below to try, try next sibling */
sib=sib->ast_right;
goto keep_looking;
}
/* found a matching root node, try to match what's below */
if ( ast_match_partial(sib, u) )
{
/* record sibling cursor so we can pick up next from there */
if ( sib->ast_down!=NULL )
{
if ( sib->ast_right!=NULL ) _push(template_stack, &tsp, sib->ast_right);
*cursor = sib->ast_down;
}
else if ( sib->ast_right!=NULL ) *cursor = sib->ast_right;
else *cursor = _pop(template_stack, &tsp);
return sib;
}
/* no match, keep searching */
if ( sib->ast_down!=NULL )
{
if ( sib->ast_right!=NULL ) _push(template_stack, &tsp, sib->ast_right);
sib=sib->ast_down;
}
else sib = sib->ast_right; /* else, try to right if zip below */
goto keep_looking;
}
/* are two trees exactly alike? */
int
#ifdef __USE_PROTOS
ast_match(SORAST *t, SORAST *u)
#else
ast_match(t, u)
SORAST *t, *u;
#endif
{
SORAST *sib;
if ( t==NULL ) if ( u!=NULL ) return 0; else return 1;
if ( u==NULL ) return 0;
for (sib=t; sib!=NULL&&u!=NULL; sib=sib->ast_right, u=u->ast_right)
{
if ( sib->token != u->token ) return 0;
if ( sib->ast_down!=NULL )
if ( !ast_match(sib->ast_down, u->ast_down) ) return 0;
}
return 1;
}
static int
#ifdef __USE_PROTOS
ast_scanmatch(ScanAST *t, SORAST *u, SORAST **labels[], int *n)
#else
ast_scanmatch(t, u, labels, n)
ScanAST *t;
SORAST *u;
SORAST **labels[];
int *n;
#endif
{
ScanAST *sib;
if ( t==NULL ) if ( u!=NULL ) return 0; else return 1;
if ( u==NULL ) return 0;
for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right, u=u->ast_right)
{
/* make sure tokens match; token of '0' means wildcard match */
if ( sib->token != u->token && sib->token!=0 ) return 0;
/* we have a matched token here; set label pointers if exists */
if ( sib->label_num>0 )
{
require(labels!=NULL, "label found in template, but no array of labels");
(*n)++;
*(labels[sib->label_num-1]) = u;
}
/* match what's below if something there and current node is not wildcard */
if ( sib->down!=NULL && sib->token!=0 )
if ( !ast_scanmatch(sib->down, u->ast_down, labels, n) ) return 0;
}
return 1;
}
void
#ifdef __USE_PROTOS
ast_insert_after(SORAST *a, SORAST *b)
#else
ast_insert_after(a, b)
SORAST *a,*b;
#endif
{
SORAST *end;
require(a!=NULL, "ast_insert_after: NULL input tree");
if ( b==NULL ) return;
/* find end of b's child list */
for (end=b; end->ast_right!=NULL; end=end->ast_right) {;}
end->ast_right = a->ast_right;
a->ast_right = b;
}
void
#ifdef __USE_PROTOS
ast_append(SORAST *a, SORAST *b)
#else
ast_append(a, b)
SORAST *a,*b;
#endif
{
SORAST *end;
require(a!=NULL&&b!=NULL, "ast_append: NULL input tree");
/* find end of child list */
for (end=a; end->ast_right!=NULL; end=end->ast_right) {;}
end->ast_right = b;
}
SORAST *
#ifdef __USE_PROTOS
ast_tail(SORAST *a)
#else
ast_tail(a)
SORAST *a;
#endif
{
SORAST *end;
require(a!=NULL, "ast_tail: NULL input tree");
/* find end of child list */
for (end=a; end->ast_right!=NULL; end=end->ast_right) {;}
return end;
}
SORAST *
#ifdef __USE_PROTOS
ast_bottom(SORAST *a)
#else
ast_bottom(a)
SORAST *a;
#endif
{
SORAST *end;
require(a!=NULL, "ast_bottom: NULL input tree");
/* find end of child list */
for (end=a; end->ast_down!=NULL; end=end->ast_down) {;}
return end;
}
SORAST *
#ifdef __USE_PROTOS
ast_cut_between(SORAST *a, SORAST *b)
#else
ast_cut_between(a, b)
SORAST *a,*b;
#endif
{
SORAST *end, *ret;
require(a!=NULL&&b!=NULL, "ast_cut_between: NULL input tree");
/* find node pointing to b */
for (end=a; end->ast_right!=NULL&&end->ast_right!=b; end=end->ast_right)
{;}
require(end->ast_right!=NULL, "ast_cut_between: a,b not connected");
end->ast_right = NULL; /* don't want it point to 'b' anymore */
ret = a->ast_right;
a->ast_right = b;
return ret;
}
SList *
#ifdef __USE_PROTOS
ast_to_slist(SORAST *t)
#else
ast_to_slist(t)
SORAST *t;
#endif
{
SList *list=NULL;
SORAST *p;
for (p=t; p!=NULL; p=p->ast_right)
{
slist_add(&list, p);
}
return list;
}
SORAST *
#ifdef __USE_PROTOS
slist_to_ast(SList *list)
#else
slist_to_ast(list)
SList *list;
#endif
{
SORAST *t=NULL, *last=NULL;
SList *p;
for (p = list->next; p!=NULL; p=p->next)
{
SORAST *u = (SORAST *)p->elem;
if ( last==NULL ) last = t = u;
else { last->ast_right = u; last = u; }
}
return t;
}
void
#ifdef __USE_PROTOS
ast_free(SORAST *t)
#else
ast_free(t)
SORAST *t;
#endif
{
if ( t == NULL ) return;
ast_free( t->ast_down );
ast_free( t->ast_right );
free( t );
}
int
#ifdef __USE_PROTOS
ast_nsiblings(SORAST *t)
#else
ast_nsiblings(t)
SORAST *t;
#endif
{
int n=0;
while ( t!=NULL )
{
n++;
t = t->ast_right;
}
return n;
}
SORAST *
#ifdef __USE_PROTOS
ast_sibling_index(SORAST *t, int i)
#else
ast_sibling_index(t,i)
SORAST *t;
int i;
#endif
{
int j=1;
require(i>0, "ast_sibling_index: i<=0");
while ( t!=NULL )
{
if ( j==i ) return t;
j++;
t = t->ast_right;
}
return NULL;
}
static void
#ifdef __USE_PROTOS
scanast_free(ScanAST *t)
#else
scanast_free(t)
ScanAST *t;
#endif
{
if ( t == NULL ) return;
scanast_free( t->down );
scanast_free( t->right );
free( t );
}
/*
* ast_scan
*
* This function is like scanf(): it attempts to match a template
* against an input tree. A variable number of tree pointers
* may be set according to the '%i' labels in the template string.
* For example:
*
* ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )",
* t, &w, &x, &y, &z);
*
* Naturally, you'd want this converted from
*
* ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )",
* t, &w, &x, &y, &z);
*
* by SORCERER.
*
* This function call must be done withing a SORCERER file because SORCERER
* must convert the token references to the associated token number.
*
* This functions parses the template and creates trees which are then
* matched against the input tree. The labels are set as they are
* encountered; hence, partial matches may leave some pointers set
* and some NULL. This routines initializes all argument pointers to NULL
* at the beginning.
*
* This function returns the number of labels matched.
*/
int
#ifdef PCCTS_USE_STDARG
ast_scan(char *templ, SORAST *tree, ...)
#else
ast_scan(va_alist)
va_dcl
#endif
{
va_list ap;
ScanAST *t;
int n, i, found=0;
SORAST ***label_ptrs=NULL;
#ifdef PCCTS_USE_STDARG
va_start(ap, tree);
#else
char *templ;
SORAST *tree;
va_start(ap);
templ = va_arg(ap, char *);
tree = va_arg(ap, SORAST *);
#endif
/* make a ScanAST tree out of the template */
t = stringparser_parse_scanast(templ, &n);
/* make an array out of the labels */
if ( n>0 )
{
label_ptrs = (SORAST ***) calloc(n, sizeof(SORAST **));
require(label_ptrs!=NULL, "ast_scan: out of memory");
for (i=1; i<=n; i++)
{
label_ptrs[i-1] = va_arg(ap, SORAST **);
*(label_ptrs[i-1]) = NULL;
}
}
/* match the input tree against the template */
ast_scanmatch(t, tree, label_ptrs, &found);
scanast_free(t);
free(label_ptrs);
return found;
}
static ScanAST *
#ifdef __USE_PROTOS
new_scanast(int tok)
#else
new_scanast(tok)
int tok;
#endif
{
ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST));
if ( p == NULL ) {fprintf(stderr, "out of mem\n"); exit(-1);}
p->token = tok;
return p;
}
static ScanAST *
#ifdef __USE_PROTOS
stringparser_parse_scanast(char *templ, int *num_labels)
#else
stringparser_parse_scanast(templ, num_labels)
char *templ;
int *num_labels;
#endif
{
StringLexer lex;
StringParser parser;
ScanAST *t;
stringlexer_init(&lex, templ);
stringparser_init(&parser, &lex);
t = stringparser_parse_tree(&parser);
*num_labels = parser.num_labels;
return t;
}
static void
#ifdef __USE_PROTOS
stringparser_match(StringParser *parser, int token)
#else
stringparser_match(parser, token)
StringParser *parser;
int token;
#endif
{
if ( parser->token != token ) sorcerer_panic("bad tree in ast_scan()");
}
/*
* Match a tree of the form:
* (root child1 child2 ... childn)
* or,
* node
*
* where the elements are integers or labeled integers.
*/
static ScanAST *
#ifdef __USE_PROTOS
stringparser_parse_tree(StringParser *parser)
#else
stringparser_parse_tree(parser)
StringParser *parser;
#endif
{
ScanAST *t=NULL, *root, *child, *last = NULL;
if ( parser->token != POUND )
{
return stringparser_parse_element(parser);
}
stringparser_match(parser,POUND);
parser->token = stringscan_gettok(parser->lexer);
stringparser_match(parser,LPAREN);
parser->token = stringscan_gettok(parser->lexer);
root = stringparser_parse_element(parser);
while ( parser->token != RPAREN )
{
child = stringparser_parse_element(parser);
if ( t==NULL ) { t = child; last = t; }
else { last->right = child; last = child; }
}
stringparser_match(parser,RPAREN);
parser->token = stringscan_gettok(parser->lexer);
root->down = t;
return root;
}
static ScanAST *
#ifdef __USE_PROTOS
stringparser_parse_element(StringParser *parser)
#else
stringparser_parse_element(parser)
StringParser *parser;
#endif
{
static char ebuf[100];
int label = 0;
if ( parser->token == POUND )
{
return stringparser_parse_tree(parser);
}
if ( parser->token == PERCENT )
{
parser->token = stringscan_gettok(parser->lexer);
stringparser_match(parser,INT);
label = atoi(parser->lexer->text);
parser->num_labels++;
if ( label==0 ) sorcerer_panic("%%0 is an invalid label");
parser->token = stringscan_gettok(parser->lexer);
stringparser_match(parser,COLON);
parser->token = stringscan_gettok(parser->lexer);
/* can label tokens and wildcards */
if ( parser->token != INT && parser->token != PERIOD )
sorcerer_panic("can only label tokens");
}
if ( parser->token == INT )
{
ScanAST *p = new_scanast(atoi(parser->lexer->text));
parser->token = stringscan_gettok(parser->lexer);
p->label_num = label;
return p;
}
if ( parser->token == PERIOD )
{
ScanAST *p = new_scanast(0); /* token of 0 is wildcard */
parser->token = stringscan_gettok(parser->lexer);
p->label_num = label;
return p;
}
sprintf(ebuf, "mismatch token in ast_scan(): %s", scan_token_str(parser->token));
sorcerer_panic(ebuf);
return NULL; /* MR20 make -Wall happy */
}
static void
#ifdef __USE_PROTOS
stringparser_init(StringParser *parser, StringLexer *input)
#else
stringparser_init(parser, input)
StringParser *parser;
StringLexer *input;
#endif
{
parser->lexer = input;
parser->token = stringscan_gettok(parser->lexer);
parser->num_labels = 0;
}
static void
#ifdef __USE_PROTOS
stringlexer_init(StringLexer *scanner, char *input)
#else
stringlexer_init(scanner, input)
StringLexer *scanner;
char *input;
#endif
{
scanner->text[0]='\0';
scanner->input = input;
scanner->p = input;
stringscan_advance(scanner);
}
static void
#ifdef __USE_PROTOS
stringscan_advance(StringLexer *scanner)
#else
stringscan_advance(scanner)
StringLexer *scanner;
#endif
{
if ( *(scanner->p) == '\0' ) scanner->c = StringScanEOF;
scanner->c = *(scanner->p)++;
}
static int
#ifdef __USE_PROTOS
stringscan_gettok(StringLexer *scanner)
#else
stringscan_gettok(scanner)
StringLexer *scanner;
#endif
{
char *index = &scanner->text[0];
static char ebuf[100];
while ( isspace(scanner->c) ) { stringscan_advance(scanner); }
if ( isdigit(scanner->c) )
{
int tok = INT;
while ( isdigit(scanner->c) ) {
*index++ = scanner->c;
stringscan_advance(scanner);
}
*index = '\0';
return tok;
}
switch ( scanner->c )
{
case '#' : stringscan_advance(scanner); return POUND;
case '(' : stringscan_advance(scanner); return LPAREN;
case ')' : stringscan_advance(scanner); return RPAREN;
case '%' : stringscan_advance(scanner); return PERCENT;
case ':' : stringscan_advance(scanner); return COLON;
case '.' : stringscan_advance(scanner); return PERIOD;
case '\0' : return StringScanEOF;
case StringScanEOF : return StringScanEOF;
default :
sprintf(ebuf, "invalid char in ast_scan: '%c'", scanner->c);
sorcerer_panic(ebuf);
return 0; /* MR20 Make -Wall happy */
}
}

View File

@@ -0,0 +1,100 @@
/*
* errsupport.c -- error support code for SORCERER output
*
* Define your own or compile and link this in.
*
* Terence Parr
* U of MN, AHPCRC
* February 1994
*/
#include "sorcerer.h"
void
#ifdef __USE_PROTOS
mismatched_range( STreeParser *_parser, int looking_for, int upper_token, SORAST *found )
#else
mismatched_range( _parser, looking_for, upper_token, found )
int looking_for;
int upper_token;
SORAST *found;
STreeParser *_parser;
#endif
{
if ( found!=NULL ) {
fprintf(stderr,
"parse error: expected token range %d..%d found token %d\n",
looking_for, upper_token,
found->token);
}
else {
fprintf(stderr,
"parse error: expected token range %d..%d found NULL tree\n",
looking_for, upper_token);
}
}
void
#ifdef __USE_PROTOS
missing_wildcard(STreeParser *_parser)
#else
missing_wildcard(_parser)
STreeParser *_parser;
#endif
{
fprintf(stderr, "parse error: expected any token/tree found found NULL tree\n");
}
void
#ifdef __USE_PROTOS
mismatched_token( STreeParser *_parser, int looking_for, SORAST *found )
#else
mismatched_token( _parser, looking_for, found )
int looking_for;
SORAST *found;
STreeParser *_parser;
#endif
{
if ( found!=NULL ) {
fprintf(stderr,
"parse error: expected token %d found token %d\n",
looking_for,
found->token);
}
else {
fprintf(stderr,
"parse error: expected token %d found NULL tree\n",
looking_for);
}
}
void
#ifdef __USE_PROTOS
no_viable_alt( STreeParser *_parser, char *rulename, SORAST *root )
#else
no_viable_alt( _parser, rulename, root )
char *rulename;
SORAST *root;
STreeParser *_parser;
#endif
{
if ( root==NULL )
fprintf(stderr,
"parse error: in rule %s, no viable alternative for NULL tree\n",
rulename);
else
fprintf(stderr,
"parse error: in rule %s, no viable alternative for tree\n",
rulename);
}
void
#ifdef __USE_PROTOS
sorcerer_panic(char *err)
#else
sorcerer_panic(err)
char *err;
#endif
{
fprintf(stderr, "panic: %s\n", err);
exit(-1);
}

View File

@@ -0,0 +1,21 @@
#
# Makefile for SORCERER libraries
#
SRC = astlib.c sstack.c sorlist.c sintstack.c
OBJ = astlib.o sstack.o sorlist.o sintstack.o
CFLAGS=-g -I../../h -I../h
CC=cc
libs : $(OBJ) $(SRC)
clean:
rm -f *.o core
scrub:
rm -f *.o core
ci:
ci -u $(SRC) *.h makefile
co:
co -l $(SRC) *.h makefile

View File

@@ -0,0 +1,130 @@
# Microsoft Developer Studio Project File - Name="lib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=lib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "lib.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "lib.mak" CFG="lib - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "lib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "lib - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""$/pccts/Sorcerer/lib", EPABAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
!IF "$(CFG)" == "lib - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "h" /I "..\h" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PC" /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "lib - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /Z7 /Od /I "h" /I "..\h" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PC" /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "lib - Win32 Release"
# Name "lib - Win32 Debug"
# Begin Group "Header files"
# PROP Default_Filter "h"
# Begin Source File
SOURCE=.\CASTBase.h
# End Source File
# End Group
# Begin Group "Source files"
# PROP Default_Filter "c,cpp"
# Begin Source File
SOURCE=.\astlib.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\errsupport.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\PCCTSAST.cpp
# End Source File
# Begin Source File
SOURCE=.\sintstack.c
# End Source File
# Begin Source File
SOURCE=.\SList.cpp
# End Source File
# Begin Source File
SOURCE=.\sorcerer.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\sorlist.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\sstack.c
# End Source File
# Begin Source File
SOURCE=.\STreeParser.cpp
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,140 @@
/*
* sint.c
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include <stdio.h>
#include <setjmp.h>
#ifdef PCCTS_USE_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "CASTBase.h"
#include "sintstack.h"
SIntStack *
#ifdef __USE_PROTOS
sint_newstack(int size)
#else
sint_newstack(size)
int size;
#endif
{
SIntStack *p = (SIntStack *) calloc(1, sizeof(SIntStack));
require(p!=NULL, "sint_newstack: out of memory");
p->data = (int *) calloc(size, sizeof(int));
require(p!=NULL, "sint_newstack: out of memory");
p->size = size;
p->sp = size;
return p;
}
void
#ifdef __USE_PROTOS
sint_freestack(SIntStack *st)
#else
sint_freestack(st)
SIntStack *st;
#endif
{
if ( st==NULL ) return;
if ( st->data==NULL ) return;
free(st->data);
free(st);
}
void
#ifdef __USE_PROTOS
sint_push(SIntStack *st,int i)
#else
sint_push(st,i)
SIntStack *st;
int i;
#endif
{
require(st->sp>0, "sint_push: stack overflow");
st->data[--(st->sp)] = i;
}
int
#ifdef __USE_PROTOS
sint_pop(SIntStack *st)
#else
sint_pop(st)
SIntStack *st;
#endif
{
require(st->sp<st->size, "sint_pop: stack underflow");
return st->data[st->sp++];
}
int
#ifdef __USE_PROTOS
sint_stacksize(SIntStack *st)
#else
sint_stacksize(st)
SIntStack *st;
#endif
{
return st->size - st->sp;
}
void
#ifdef __USE_PROTOS
sint_stackreset(SIntStack *st)
#else
sint_stackreset(st)
SIntStack *st;
#endif
{
st->sp = st->size;
}
int
#ifdef __USE_PROTOS
sint_stackempty(SIntStack *st)
#else
sint_stackempty(st)
SIntStack *st;
#endif
{
return st->sp==st->size;
}
int
#ifdef __USE_PROTOS
sint_top(SIntStack *st)
#else
sint_top(st)
SIntStack *st;
#endif
{
require(st->sp<st->size, "sint_top: stack underflow");
return st->data[st->sp];
}

View File

@@ -0,0 +1,169 @@
/*
* sorcerer.c -- support code for SORCERER output
*
* Define your own or compile and link this in.
*
* Terence Parr
* U of MN, AHPCRC
* February 1994
*/
/***********************************************************************
2-Oct-97 The routine ast_dup() appeared to have a bug in it. Instead
of providing a deep copy of its argument it made a bushy copy
of its argument - by duplicating the nodes pointed to by
its right link. This is certainly not deliberate and does
not match code in PCCTSAST.cpp (which had its own bug). This
has been changed to do a deep copy in the traditional sense.
***********************************************************************/
#ifdef OLD
/* Given a result pointer, return the same one if *t is NULL,
* else find the end of the sibling list and return the address
* the 'next[write]' field in that last node.
*/
AST **
#ifdef __USE_PROTOS
_nextresult(STreeParser *_parser, AST **t)
#else
_nextresult(_parser, t)
AST **t;
STreeParser *_parser;
#endif
{
AST *p = *t;
if ( p==NULL ) return t;
while ( p->ast_right(_parser->write) != NULL )
{
p = p->ast_right(_parser->write);
}
return &(p->ast_right(_parser->write));
}
/*
* Copy the read pointers to the write pointers for a node or entire subtree
*/
void
#ifdef __USE_PROTOS
_copy_wildcard(STreeParser *_parser, AST *t, int root)
#else
_copy_wildcard(_parser, t, root)
STreeParser *_parser;
AST *t;
int root;
#endif
{
while ( t!=NULL )
{
if ( !root ) t->ast_right(_parser->write) = t->ast_right(_parser->read);
t->ast_down(_parser->write) = t->ast_down(_parser->read);
if ( t->ast_down(_parser->read)!=NULL )
_copy_wildcard(_parser, t->ast_down(_parser->read), 0);
if ( root ) return;
else root=0;
t = t->ast_right(_parser->read);
}
}
#endif
void
#ifdef __USE_PROTOS
_mkroot(SORAST **r, SORAST **s, SORAST **e, SORAST *t)
#else
_mkroot(r,s,e,t)
SORAST **r, **s, **e, *t;
#endif
{
*r = t;
}
void
#ifdef __USE_PROTOS
_mkchild(SORAST **r, SORAST **s, SORAST **e, SORAST *t)
#else
_mkchild(r,s,e,t)
SORAST **r, **s, **e, *t;
#endif
{
/* if no sibling list, must attach to any existing root */
if ( *s==NULL )
{
*s = *e = t;
/* If r is NULL, then there was no root defined--must be sibling list */
if ( *r==NULL ) *r = *s;
else (*r)->ast_down = t;
}
else { (*e)->ast_right = t; *e = t; }
}
/* THESE FUNCS HAVE TO GO HERE BECAUSE THEY ARE SENSITIVE TO USER'S SORAST DEF */
SORAST *
#ifdef __USE_PROTOS
ast_alloc(void)
#else
ast_alloc()
#endif
{
SORAST *t = (SORAST *)calloc(1, sizeof(SORAST));
if ( t==NULL ) sorcerer_panic("out of memory");
return t;
}
SORAST *
#ifdef __USE_PROTOS
ast_dup_bushy(SORAST *t)
#else
ast_dup_bushy(t)
SORAST *t;
#endif
{
SORAST *u;
if ( t == NULL ) return NULL;
u = ast_alloc();
*u = *t; /* copy contents */
u->ast_down = ast_dup_bushy(t->ast_down); /* copy the rest of the tree */
u->ast_right = ast_dup_bushy(t->ast_right);
return u;
}
/* Assume t is a root node of a tree--duplicate that node and what's below */
SORAST *
#ifdef __USE_PROTOS
ast_dup(SORAST *t)
#else
ast_dup(t)
SORAST *t;
#endif
{
SORAST *u;
if ( t == NULL ) return NULL;
u = ast_alloc();
*u = *t; /* copy contents */
u->ast_down = ast_dup_bushy(t->ast_down); /* copy the rest of the tree */
u->ast_right = NULL;
return u;
}
/* Assume t is a root node of a tree--duplicate that node and what's below */
SORAST *
#ifdef __USE_PROTOS
ast_dup_node(SORAST *t)
#else
ast_dup_node(t)
SORAST *t;
#endif
{
SORAST *u;
if ( t == NULL ) return NULL;
u = ast_alloc();
*u = *t; /* copy contents */
u->down = NULL;
u->right = NULL;
return u;
}

View File

@@ -0,0 +1,123 @@
/*
* slist.c
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include <stdio.h>
#include <setjmp.h>
#ifdef PCCTS_USE_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "CASTBase.h"
#include "sorlist.h"
/* Iterate over a list of elements; returns ptr to a new element
* in list upon every call and NULL when no more are left.
* Very useful like this:
*
* cursor = mylist;
* while ( (p=slist_iterate(mylist,&cursor)) ) {
* / * place with element p * /
* }
*
* The cursor must be initialized to point to the list to iterate over.
*/
void *
#ifdef __USE_PROTOS
slist_iterate(SList *list, SList **cursor)
#else
slist_iterate(list, cursor)
SList *list, **cursor;
#endif
{
void *e;
if ( list==NULL || cursor == NULL || *cursor==NULL ) return NULL;
if ( list== *cursor ) { *cursor = (*cursor)->next; }
e = (*cursor)->elem;
(*cursor) = (*cursor)->next;
return e;
}
/*
* add an element to a list.
*
* Any non-empty list has a sentinel node whose 'elem' pointer is really
* a pointer to the last element. (i.e. length(list) = #elemIn(list)+1).
* Elements are appended to the list.
*/
void
#ifdef __USE_PROTOS
slist_add( SList **list, void *e )
#else
slist_add( list, e )
SList **list;
void *e;
#endif
{
SList *p, *tail;
require(e!=NULL, "slist_add: attempting to add NULL list element");
p = newSList;
require(p!=NULL, "slist_add: cannot alloc new list node");
p->elem = e;
if ( *list == NULL )
{
SList *sentinel = newSList;
require(sentinel!=NULL, "slist_add: cannot alloc sentinel node");
*list=sentinel;
sentinel->next = p;
sentinel->elem = (char *)p; /* set tail pointer */
}
else /* find end of list */
{
tail = (SList *) (*list)->elem; /* get tail pointer */
tail->next = p;
(*list)->elem = (char *) p; /* reset tail */
}
}
void
#ifdef __USE_PROTOS
slist_free(SList *list)
#else
slist_free(list)
SList *list;
#endif
{
SList *p,*q;
if ( list==NULL ) return; /* empty list */
for (p = list->next; p!=NULL; p=q)
{
q = p->next;
free(p);
}
}

View File

@@ -0,0 +1,78 @@
/*
* sstack.c
*
* SOFTWARE RIGHTS
*
* We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
* domain. An individual or company may do whatever they wish with
* source code distributed with SORCERER or the code generated by
* SORCERER, including the incorporation of SORCERER, or its output, into
* commerical software.
*
* We encourage users to develop software with SORCERER. However, we do
* ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
* output, please mention that you developed it using SORCERER. 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.
*
* SORCERER 1.00B
* Terence Parr
* AHPCRC, University of Minnesota
* 1992-1994
*/
#include "pcctscfg.h"
#include <stdio.h>
#include <setjmp.h>
#ifdef PCCTS_USE_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "CASTBase.h"
#include "sstack.h"
void
#ifdef __USE_PROTOS
sstack_push( SStack **st, void *e )
#else
sstack_push( st, e )
SStack **st;
void *e;
#endif
{
SStack *p;
require(e!=NULL, "sstack_push: attempting to add NULL list element");
p = newSStack;
require(p!=NULL, "sstack_push: cannot alloc new list node");
p->elem = e;
p->next = *st;
*st = p;
}
void *
#ifdef __USE_PROTOS
sstack_pop( SStack **st )
#else
sstack_pop( st )
SStack **st;
#endif
{
SStack *p = *st;
void *r;
*st = (*st)->next;
r = p->elem;
free(p);
return r;
}