1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
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;
}
|