-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathyytree.c
197 lines (180 loc) · 6.17 KB
/
yytree.c
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*-
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if !defined(lint) && defined(sccs)
static char sccsid[] = "@(#)yytree.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#include <whoami.h>
#include <0.h>
#include <tree.h>
#include <tree_ty.h>
extern int *spacep;
/*
* LIST MANIPULATION ROUTINES
*
* The grammar for Pascal is written left recursively.
* Because of this, the portions of parse trees which are to resemble
* lists are in the somewhat inconvenient position of having
* the nodes built from left to right, while we want to eventually
* have as semantic value the leftmost node.
* We could carry the leftmost node as semantic value, but this
* would be inefficient as to add a new node to the list we would
* have to chase down to the end. Other solutions involving a head
* and tail pointer waste space.
*
* The simple solution to this apparent dilemma is to carry along
* a pointer to the leftmost node in a list in the rightmost node
* which is the current semantic value of the list.
* When we have completed building the list, we can retrieve this
* left end pointer very easily; neither adding new elements to the list
* nor finding the left end is thus expensive. As the bottommost node
* has an unused next pointer in it, no space is wasted either.
*
* The nodes referred to here are of the T_LISTPP type and have
* the form:
*
* T_LISTPP some_pointer next_element
*
* Here some_pointer points to the things of interest in the list,
* and next_element to the next thing in the list except for the
* rightmost node, in which case it points to the leftmost node.
* The next_element of the rightmost node is of course zapped to the
* NIL pointer when the list is completed.
*
* Thinking of the lists as tree we heceforth refer to the leftmost
* node as the "top", and the rightmost node as the "bottom" or as
* the "virtual root".
*/
/*
* Make a new list
*/
struct tnode *
newlist(new)
register struct tnode *new;
{
if (new == TR_NIL)
return (TR_NIL);
return ((struct tnode *) tree3(T_LISTPP, (int) new,
(struct tnode *) spacep));
}
/*
* Add a new element to an existing list
*/
struct tnode *
addlist(vroot, new)
register struct tnode *vroot;
struct tnode *new;
{
register struct tnode *top;
if (new == TR_NIL)
return (vroot);
if (vroot == TR_NIL)
return (newlist(new));
top = vroot->list_node.next;
vroot->list_node.next = (struct tnode *) spacep;
return ((struct tnode *) tree3(T_LISTPP, (int) new, top));
}
/*
* Fix up the list which has virtual root vroot.
* We grab the top pointer and return it, zapping the spot
* where it was so that the tree is not circular.
*/
struct tnode *
fixlist(vroot)
register struct tnode *vroot;
{
register struct tnode *top;
if (vroot == TR_NIL)
return (TR_NIL);
top = vroot->list_node.next;
vroot->list_node.next = TR_NIL;
return (top);
}
/*
* Set up a T_VAR node for a qualified variable.
* Init is the initial entry in the qualification,
* or NIL if there is none.
*
* if we are building pTrees, there has to be an extra slot for
* a pointer to the namelist entry of a field, if this T_VAR refers
* to a field name within a WITH statement.
* this extra field is set in lvalue, and used in VarCopy.
*/
struct tnode *
setupvar(var, init)
char *var;
register struct tnode *init;
{
if (init != TR_NIL)
init = newlist(init);
# ifndef PTREE
return (tree4(T_VAR, NOCON, (struct tnode *) var, init));
# else
return tree5( T_VAR, NOCON, (struct tnode *) var, init, TR_NIL );
# endif
}
/*
* set up a T_TYREC node for a record
*
* if we are building pTrees, there has to be an extra slot for
* a pointer to the namelist entry of the record.
* this extra field is filled in in gtype, and used in RecTCopy.
*/
struct tnode *
setuptyrec( line , fldlist )
int line;
struct tnode *fldlist;
{
# ifndef PTREE
return tree3( T_TYREC , line , fldlist );
# else
return tree4( T_TYREC , line , fldlst , TR_NIL );
# endif
}
/*
* set up a T_FIELD node for a field.
*
* if we are building pTrees, there has to be an extra slot for
* a pointer to the namelist entry of the field.
* this extra field is set in lvalue, and used in SelCopy.
*/
struct tnode *
setupfield( field , other )
struct tnode *field;
struct tnode *other;
{
# ifndef PTREE
return tree3( T_FIELD , (int) field , other );
# else
return tree4( T_FIELD , (int) field , other , TR_NIL );
# endif
}