]>
Commit | Line | Data |
---|---|---|
3eb9473e | 1 | /*\r |
2 | * sorcerer.c -- support code for SORCERER output\r | |
3 | *\r | |
4 | * Define your own or compile and link this in.\r | |
5 | *\r | |
6 | * Terence Parr\r | |
7 | * U of MN, AHPCRC\r | |
8 | * February 1994\r | |
9 | */\r | |
10 | \r | |
11 | /***********************************************************************\r | |
12 | 2-Oct-97 The routine ast_dup() appeared to have a bug in it. Instead\r | |
13 | of providing a deep copy of its argument it made a bushy copy\r | |
14 | of its argument - by duplicating the nodes pointed to by\r | |
15 | its right link. This is certainly not deliberate and does\r | |
16 | not match code in PCCTSAST.cpp (which had its own bug). This\r | |
17 | has been changed to do a deep copy in the traditional sense.\r | |
18 | ***********************************************************************/\r | |
19 | \r | |
20 | #ifdef OLD\r | |
21 | /* Given a result pointer, return the same one if *t is NULL,\r | |
22 | * else find the end of the sibling list and return the address\r | |
23 | * the 'next[write]' field in that last node.\r | |
24 | */\r | |
25 | AST **\r | |
26 | #ifdef __USE_PROTOS\r | |
27 | _nextresult(STreeParser *_parser, AST **t)\r | |
28 | #else\r | |
29 | _nextresult(_parser, t)\r | |
30 | AST **t;\r | |
31 | STreeParser *_parser;\r | |
32 | #endif\r | |
33 | {\r | |
34 | AST *p = *t;\r | |
35 | \r | |
36 | if ( p==NULL ) return t;\r | |
37 | while ( p->ast_right(_parser->write) != NULL )\r | |
38 | {\r | |
39 | p = p->ast_right(_parser->write);\r | |
40 | }\r | |
41 | return &(p->ast_right(_parser->write));\r | |
42 | }\r | |
43 | \r | |
44 | /*\r | |
45 | * Copy the read pointers to the write pointers for a node or entire subtree\r | |
46 | */\r | |
47 | void\r | |
48 | #ifdef __USE_PROTOS\r | |
49 | _copy_wildcard(STreeParser *_parser, AST *t, int root)\r | |
50 | #else\r | |
51 | _copy_wildcard(_parser, t, root)\r | |
52 | STreeParser *_parser;\r | |
53 | AST *t;\r | |
54 | int root;\r | |
55 | #endif\r | |
56 | {\r | |
57 | while ( t!=NULL )\r | |
58 | {\r | |
59 | if ( !root ) t->ast_right(_parser->write) = t->ast_right(_parser->read);\r | |
60 | t->ast_down(_parser->write) = t->ast_down(_parser->read);\r | |
61 | if ( t->ast_down(_parser->read)!=NULL )\r | |
62 | _copy_wildcard(_parser, t->ast_down(_parser->read), 0);\r | |
63 | if ( root ) return;\r | |
64 | else root=0;\r | |
65 | t = t->ast_right(_parser->read);\r | |
66 | }\r | |
67 | }\r | |
68 | #endif\r | |
69 | \r | |
70 | void\r | |
71 | #ifdef __USE_PROTOS\r | |
72 | _mkroot(SORAST **r, SORAST **s, SORAST **e, SORAST *t)\r | |
73 | #else\r | |
74 | _mkroot(r,s,e,t)\r | |
75 | SORAST **r, **s, **e, *t;\r | |
76 | #endif\r | |
77 | {\r | |
78 | *r = t;\r | |
79 | }\r | |
80 | \r | |
81 | void\r | |
82 | #ifdef __USE_PROTOS\r | |
83 | _mkchild(SORAST **r, SORAST **s, SORAST **e, SORAST *t)\r | |
84 | #else\r | |
85 | _mkchild(r,s,e,t)\r | |
86 | SORAST **r, **s, **e, *t;\r | |
87 | #endif\r | |
88 | {\r | |
89 | /* if no sibling list, must attach to any existing root */\r | |
90 | if ( *s==NULL )\r | |
91 | {\r | |
92 | *s = *e = t;\r | |
93 | /* If r is NULL, then there was no root defined--must be sibling list */\r | |
94 | if ( *r==NULL ) *r = *s;\r | |
95 | else (*r)->ast_down = t;\r | |
96 | }\r | |
97 | else { (*e)->ast_right = t; *e = t; }\r | |
98 | }\r | |
99 | \r | |
100 | /* THESE FUNCS HAVE TO GO HERE BECAUSE THEY ARE SENSITIVE TO USER'S SORAST DEF */\r | |
101 | SORAST *\r | |
102 | #ifdef __USE_PROTOS\r | |
103 | ast_alloc(void)\r | |
104 | #else\r | |
105 | ast_alloc()\r | |
106 | #endif\r | |
107 | {\r | |
108 | SORAST *t = (SORAST *)calloc(1, sizeof(SORAST));\r | |
109 | if ( t==NULL ) sorcerer_panic("out of memory");\r | |
110 | return t;\r | |
111 | }\r | |
112 | \r | |
113 | SORAST *\r | |
114 | #ifdef __USE_PROTOS\r | |
115 | ast_dup_bushy(SORAST *t)\r | |
116 | #else\r | |
117 | ast_dup_bushy(t)\r | |
118 | SORAST *t;\r | |
119 | #endif\r | |
120 | {\r | |
121 | SORAST *u;\r | |
122 | \r | |
123 | if ( t == NULL ) return NULL;\r | |
124 | u = ast_alloc();\r | |
125 | *u = *t; /* copy contents */\r | |
126 | u->ast_down = ast_dup_bushy(t->ast_down); /* copy the rest of the tree */\r | |
127 | u->ast_right = ast_dup_bushy(t->ast_right);\r | |
128 | return u;\r | |
129 | }\r | |
130 | \r | |
131 | \r | |
132 | /* Assume t is a root node of a tree--duplicate that node and what's below */\r | |
133 | \r | |
134 | SORAST *\r | |
135 | #ifdef __USE_PROTOS\r | |
136 | ast_dup(SORAST *t)\r | |
137 | #else\r | |
138 | ast_dup(t)\r | |
139 | SORAST *t;\r | |
140 | #endif\r | |
141 | {\r | |
142 | SORAST *u;\r | |
143 | \r | |
144 | if ( t == NULL ) return NULL;\r | |
145 | u = ast_alloc();\r | |
146 | *u = *t; /* copy contents */\r | |
147 | u->ast_down = ast_dup_bushy(t->ast_down); /* copy the rest of the tree */\r | |
148 | u->ast_right = NULL;\r | |
149 | return u;\r | |
150 | }\r | |
151 | \r | |
152 | /* Assume t is a root node of a tree--duplicate that node and what's below */\r | |
153 | SORAST *\r | |
154 | #ifdef __USE_PROTOS\r | |
155 | ast_dup_node(SORAST *t)\r | |
156 | #else\r | |
157 | ast_dup_node(t)\r | |
158 | SORAST *t;\r | |
159 | #endif\r | |
160 | {\r | |
161 | SORAST *u;\r | |
162 | \r | |
163 | if ( t == NULL ) return NULL;\r | |
164 | u = ast_alloc();\r | |
165 | *u = *t; /* copy contents */\r | |
166 | u->down = NULL;\r | |
167 | u->right = NULL;\r | |
168 | return u;\r | |
169 | }\r |