Mercurial > ~dholland > hg > ag > index.cgi
comparison anagram/agcore/rpz.cpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children | 607e3be6bad8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 /* | |
2 * AnaGram, A System for Syntax Directed Programming | |
3 * Copyright 1993-2002 Parsifal Software. All Rights Reserved. | |
4 * See the file COPYING for license and usage terms. | |
5 * | |
6 * rpz.cpp | |
7 */ | |
8 | |
9 #include "arrays.h" | |
10 #include "assert.h" | |
11 #include "bpe3.h" | |
12 #include "config.h" | |
13 #include "csexp.h" | |
14 #include "dict.h" | |
15 #include "error.h" | |
16 #include "keyword.h" | |
17 #include "myalloc.h" | |
18 #include "pgg24-defs.h" | |
19 #include "pgg24.h" | |
20 #include "q1glbl.h" | |
21 #include "rpk.h" | |
22 #include "rpz.h" | |
23 #include "rproc.h" | |
24 #include "rule.h" | |
25 #include "symbol.h" | |
26 #include "stacks.h" | |
27 #include "token.h" | |
28 #include "tree.h" | |
29 #include "tsd.h" | |
30 #include "ut.h" | |
31 | |
32 //#define INCLUDE_LOGGING | |
33 #include "log.h" | |
34 | |
35 | |
36 #define PCB pgcb | |
37 | |
38 | |
39 void definition_1(CharSetExpression *x) { | |
40 LOGSECTION("definition_1"); | |
41 int k; | |
42 Symbol id = Symbol::create(); | |
43 LOGV(id); | |
44 if (x->recursive(id)) { | |
45 LOGS("Recursive definition"); | |
46 warning_here("Recursive definition of character set %s", | |
47 id->string.pointer()); | |
48 delete x; | |
49 return; | |
50 } | |
51 if (id->parse_tree.isNotNull()) { | |
52 warning_here("Redefinition of %s", id->string.pointer()); | |
53 delete x; | |
54 return; | |
55 } | |
56 if ((k = id->token_number) != 0) { | |
57 if (Token(k)->non_terminal_flag) { | |
58 warning_here("Redefinition of token T%03d: %s", k, id->string.pointer()); | |
59 delete x; | |
60 return; | |
61 } | |
62 } | |
63 LOGS("Ready to identify parse tree"); | |
64 ParseTree tree(x); | |
65 LOGV((int) tree) LCV((int) tree->expression); | |
66 id->parse_tree = tree; | |
67 tree->token_name = id; | |
68 } | |
69 | |
70 | |
71 void definition_3(int cn) { | |
72 LOGSECTION("definition_3"); | |
73 definition_1(new IndividualCode(cn)); | |
74 } | |
75 | |
76 void definition_2(int tn) { | |
77 LOGSECTION("definition_2"); | |
78 LOGV(tn); | |
79 int t; | |
80 token_number_map *mtn; | |
81 unsigned name; | |
82 | |
83 Symbol id = Symbol::create(); | |
84 LOGV(id); | |
85 if (id->parse_tree.isNotNull()) { | |
86 warning_here("Redefinition of %s", id->string.pointer()); | |
87 return; | |
88 } | |
89 if ((t = id->token_number) != 0) { | |
90 mtn = &map_token_number[t]; | |
91 if (mtn->non_terminal_flag || mtn->key) { | |
92 warning_here("Redefinition of token T%03d: %s",t, id->string.pointer()); | |
93 return; | |
94 } | |
95 shell_production(t,tn); | |
96 return; | |
97 } | |
98 name = map_token_number[tn].token_name; | |
99 if (name == (unsigned) id) { | |
100 return; | |
101 } | |
102 if (name) { | |
103 LOGS("call shell_production") LV(t) LCV(tn); | |
104 shell_production(t,tn); | |
105 return; | |
106 } | |
107 map_token_number[tn].token_name = id; | |
108 id->token_number = tn; | |
109 LOGV(tn) LCV(id); | |
110 } | |
111 | |
112 int form_spec_2(int fn, int pn) { | |
113 LOGSECTION("form_spec_2"); | |
114 LOGV(fn) LCV(pn); | |
115 Procedure reductionProc(pn); | |
116 Rule rule(fn); | |
117 | |
118 rule->proc_name = pn; | |
119 LOGV(rule) LCV(rule->proc_name); | |
120 reductionProc->form_number = rule; | |
121 return fn; | |
122 } | |
123 | |
124 int head_list_2(int flag) { | |
125 LOGSECTION("head_list_2"); | |
126 unsigned tn; | |
127 token_name(); | |
128 tn = fis(); | |
129 LOGV(tn) LCV(ntkns); | |
130 assert(tn <= ntkns); | |
131 if (flag) { | |
132 if (grammar_token) { | |
133 log_error("Redefinition of grammar token"); | |
134 } | |
135 grammar_token = tn; | |
136 } | |
137 return tn; | |
138 } | |
139 | |
140 int mid_line(int pn) { | |
141 LOGSECTION("mid_line"); | |
142 Rule rule = form1(); | |
143 Procedure proc(pn); | |
144 LOGV(rule); | |
145 LOGV(ruleElementStack.size()); | |
146 int bias = ruleElementStack.top().size(); | |
147 LOGV(bias); | |
148 rule->immediate_proc = 1; | |
149 rule->proc_name = pn; | |
150 proc->form_number = rule; | |
151 LOGV(rule) LCV(rule->proc_name); | |
152 rule->hostElementList = AgArray<RuleElement>(ruleElementStack.top()); | |
153 rule->op_bias = bias; | |
154 return rule; | |
155 } | |
156 | |
157 int proc_spec_4(int flag) { | |
158 LOGSECTION("proc_spec_4"); | |
159 | |
160 CSegment cSegment = cSegmentStack.pop(); | |
161 Procedure proc(cSegment); | |
162 LOGV(proc); | |
163 proc->value_flag = flag; | |
164 proc->line = PRULE_CONTEXT(PCB)->y; | |
165 proc->col = PRULE_CONTEXT(PCB)->x; | |
166 return proc; | |
167 } | |
168 | |
169 static int proc_spec_6(int, int fn) { | |
170 LOGSECTION("proc_spec_6"); | |
171 | |
172 CSegment segment; | |
173 segment.end = segment.begin; | |
174 Procedure proc(segment); | |
175 proc->value_flag = 1; | |
176 proc->form_number = fn; | |
177 return proc; | |
178 } | |
179 | |
180 | |
181 int semantic_productions = 0; | |
182 | |
183 | |
184 void production(int type) { | |
185 LOGSECTION("production"); | |
186 unsigned *fl, *tl, nf, nt,i,j, zl; | |
187 | |
188 zl = 0; | |
189 fl = (unsigned *) build_list(); | |
190 nf = fis(); | |
191 tl = (unsigned *) build_list(); | |
192 ok_ptr(tl); | |
193 LOGV((int) tl); | |
194 nt = fis(); | |
195 LOGV(nt) LCV(nf); | |
196 if (nt > 1) { | |
197 semantic_productions = 1; | |
198 } | |
199 for (j = 0; j < nf; j++) { | |
200 ok_ptr(tl); | |
201 LOGV(fl[j]); | |
202 Rule rule(fl[j]); | |
203 //int pn = rule->proc_name; | |
204 //const unsigned *rp = rule->tokens(); | |
205 int rl = rule->length(), i = rl; | |
206 | |
207 ok_ptr(tl); | |
208 LOGV(fl[j]); | |
209 iws(); | |
210 int tokenIndex = 0; | |
211 //while (i--) aws(*rp++); | |
212 while (i--) { | |
213 aws(rule.token(tokenIndex++)); | |
214 } | |
215 i = nt; | |
216 rl++; | |
217 while (i--) { | |
218 aws(tl[i]); | |
219 if (list_in_dict(list_base, rl, prod_dict)) { | |
220 log_error("Duplicate production"); | |
221 } | |
222 fws(); | |
223 } | |
224 rws(); | |
225 //check_size(map_proc_name,pn, pn + pn/2); | |
226 rule->prim_tkn = tl[0]; | |
227 rule->fast_loop = nt == 1 && | |
228 rule->length() == 2 && | |
229 tl[0] == (unsigned) rule.token(0); | |
230 //tl[0] == lstptr(*mfn,tokens)[0]; | |
231 if (rule->length() == 0) zl = 1; | |
232 if (rule-> length() == 1) { | |
233 int i = nt; | |
234 unsigned t = rule.token(0); | |
235 while (i--) { | |
236 if (t != tl[i]) { | |
237 continue; | |
238 } | |
239 warning_here("Suspicious production for %s", | |
240 Token(t)->token_name->string.pointer()); | |
241 } | |
242 } | |
243 if (nt > 1) { | |
244 rule->not_unique_reduction = 1; | |
245 if (rule->proc_name == 0) { | |
246 rule->proc_name = proc_spec_6(rule->line, fl[j]); | |
247 } | |
248 } | |
249 } | |
250 for (i = 0; i < nt; i++) { | |
251 token_number_map *tp = &map_token_number[tl[i]]; | |
252 int vt = tp->value_type; | |
253 ok_ptr(tl); | |
254 LOGV((int) tl); | |
255 LOGV(tl[i]) LCV(vt); | |
256 if (nf) { | |
257 tp->non_terminal_flag = 1; | |
258 } | |
259 tp->zero_length_flag = zl; | |
260 tp->sem_det_flag = nt > 1; | |
261 if (type && vt && vt != type) { | |
262 ssprintf("Type Redefinition of T%03d: ", tl[i]); | |
263 atkn(tl[i]); | |
264 log_error(); | |
265 } | |
266 if (type) { | |
267 tp->value_type = type; | |
268 } | |
269 ok_ptr(tl); | |
270 LOGV(type); | |
271 for (j = 0; j < nf; j++) { | |
272 at(bnf_table, tl[i], fl[j]); | |
273 } | |
274 } | |
275 LOGS("Ready to free tl"); | |
276 ok_ptr(tl); | |
277 LOGV((int) tl); | |
278 DEALLOCATE(tl); | |
279 LOGS("Ready to free fl"); | |
280 if (fl != NULL) { | |
281 DEALLOCATE(fl); | |
282 } | |
283 LOGS("Production analysis complete"); | |
284 } | |
285 | |
286 CharSetExpression *ss2(void) { | |
287 LOGSECTION("ss2"); | |
288 Symbol name = Symbol::create(); | |
289 | |
290 LOGV(name->token_number) LCV(name->string); | |
291 if (name->string == "error") { | |
292 Token token = name->token_number; | |
293 LOGV(token); | |
294 if (error_token || token.isNotNull() || name->parse_tree.isNotNull()) { | |
295 return new NamedCharSet(name); | |
296 } | |
297 token = Token::create(); | |
298 token->token_name = name; | |
299 name->token_number = token; | |
300 token->value_type = default_input_type; | |
301 error_token = token; | |
302 LOGV(error_token); | |
303 checkParams(); | |
304 } | |
305 return new NamedCharSet(name); | |
306 } | |
307 | |
308 void token_name(void) { | |
309 LOGSECTION("token_name"); | |
310 | |
311 unsigned symbolCount = Symbol::count(); | |
312 Symbol n = Symbol::create(); | |
313 int flag = Symbol::count() > symbolCount; //true if new symbol | |
314 | |
315 LOGV(n) LCV(ntkns); | |
316 Token tn = n->token_number; | |
317 LOGV(tn) LCV(ntkns); | |
318 if (tn.isNotNull()) { | |
319 sis(tn); | |
320 return; | |
321 } | |
322 tn = n->token_number = Token::create(); | |
323 tn->token_name = n; | |
324 tn->value_type = 0; | |
325 if (!flag && n->parse_tree.isNotNull()) { | |
326 n->parse_tree = ParseTree(); | |
327 warning_here("Redefinition of %s", n->string.pointer()); | |
328 } | |
329 sis(tn); /* push token on stack */ | |
330 return; | |
331 } | |
332 | |
333 //int idsx(string_dict *); | |
334 | |
335 /* -> keyword string =vp_s(); */ | |
336 | |
337 int vp_s(void) { | |
338 LOGSECTION("vp_s"); | |
339 int n; | |
340 int i; | |
341 | |
342 n = tis(); | |
343 if (n > max_key_length) max_key_length = n; | |
344 tss(); | |
345 LOGV(string_base); | |
346 if (!case_sensitive) { | |
347 for (i = n; i--; ) { | |
348 string_base[i] = agToUpper(string_base[i]); | |
349 } | |
350 } | |
351 if (n == 0) { | |
352 log_error("Empty keyword string"); | |
353 } | |
354 Keyword keyword(string_base); | |
355 LOGV(keyword->string); | |
356 rcs(); | |
357 LOGV((int) keyword->token_number); | |
358 if (keyword->token_number.isNull()) { | |
359 Token token = keyword->token_number = Token::create(); | |
360 LOGV((int) token); | |
361 token->key = keyword; | |
362 token->value_type = void_token_type; | |
363 token->operatorCandidate = 1; | |
364 } | |
365 return keyword->token_number; | |
366 /* | |
367 if (!idsx(key_dict)) { | |
368 key = fis(); | |
369 assert(key == (int) keyword); | |
370 LOGV(key) LCV(keyword); | |
371 check_size(map_key_word, key, key + key/2); | |
372 LOGV(key) LCV(map_key_word[key].token_number) LCV(ntkns); | |
373 return map_key_word[key].token_number; | |
374 } | |
375 if (n > max_key_length) { | |
376 max_key_length = n; | |
377 } | |
378 key = fis(); | |
379 LOGV(key) LCV(keyword); | |
380 assert(key == (int) keyword); | |
381 check_size(map_key_word, key,key + key/2 ); | |
382 map_key_word[key].token_number = Token::create(); | |
383 map_token_number[ntkns].key = key; | |
384 LOGV(key) LCV(map_key_word[key].token_number) LCV(ntkns); | |
385 return ntkns; | |
386 */ | |
387 } | |
388 | |
389 /* -> left bracket, proper vp rule specs, right bracket =vp_3(); */ | |
390 | |
391 int vp_3(void) { | |
392 LOGSECTION("vp_3"); | |
393 int tn; | |
394 int flag,vptn; | |
395 | |
396 aws(3); | |
397 flag = idl(vp_prod_dict); | |
398 vptn = fis(); | |
399 check_size(map_vp_prod_number,vptn,vptn + vptn/2); | |
400 if (flag == 0) { | |
401 tn = map_vp_prod_number[vptn].token_number; | |
402 LOGV(tn) LCV(ntkns); | |
403 return tn; | |
404 } | |
405 sws(form1()); | |
406 fdl(vp_prod_dict,vptn); | |
407 fws(); | |
408 vp_forms(); | |
409 concat_list(); | |
410 map_vp_prod_number[vptn].token_number = Token::create(); | |
411 gen_vp_prods(ntkns,1,vptn); | |
412 LOGV(ntkns); | |
413 return ntkns; | |
414 } | |
415 | |
416 /* | |
417 -> keyword string, '?', blank?... =vp_5(vp_s()); | |
418 -> union:n, '?', blank?... =vp_5(form_element_1(n)); | |
419 */ | |
420 | |
421 int vp_5(int tn) { | |
422 LOGSECTION("vp_5"); | |
423 int flag, vptn; | |
424 | |
425 sws(tn); aws(5); | |
426 flag = idl(vp_prod_dict); | |
427 vptn = fis(); | |
428 check_size(map_vp_prod_number,vptn,vptn + vptn/2); | |
429 if (flag == 0) { | |
430 tn = map_vp_prod_number[vptn].token_number; | |
431 return tn; | |
432 } | |
433 map_vp_prod_number[vptn].token_number = Token::create(); | |
434 sws(form1()); | |
435 aws(makeRule(tn)); | |
436 gen_vp_prods(ntkns,0,vptn); | |
437 return ntkns; | |
438 } | |
439 | |
440 int vp_8a(int fn) { | |
441 LOGSECTION("vp_8a"); | |
442 token_number_map *tp; | |
443 | |
444 Token::create(); | |
445 tp = &map_token_number[ntkns]; | |
446 tp->non_terminal_flag = 1; | |
447 map_form_number[fn].prim_tkn = ntkns; | |
448 tp->zero_length_flag = 1; | |
449 tp->fine_structure = 1; | |
450 tp->immediate_action = 1; | |
451 at(bnf_table, ntkns, fn); | |
452 LOGV(ntkns) LCV(tp->immediate_action); | |
453 return ntkns; | |
454 } | |
455 | |
456 //static void build_choice(int tn) { | |
457 static void build_choice(Token token) { | |
458 LOGSECTION("build_choice"); | |
459 int *fl, nf, j; | |
460 int i, zl; | |
461 //token_number_map *tp; | |
462 | |
463 | |
464 zl = 0; | |
465 vp_forms(); | |
466 fl = list_base; | |
467 nf = rws(); | |
468 //tp = &map_token_number[tn]; | |
469 //if (nf) tp->non_terminal_flag = 1; | |
470 if (nf) { | |
471 token->non_terminal_flag = 1; | |
472 } | |
473 for (i = 0; i < nf; i++) { | |
474 Rule rule(fl[i]); | |
475 //rule->prim_tkn = tn; | |
476 rule->prim_tkn = token; | |
477 if (rule->length() == 0) { | |
478 zl = 1; | |
479 } | |
480 } | |
481 //tp->zero_length_flag = zl; | |
482 token->zero_length_flag = zl; | |
483 for (j = 0; j < nf; j++) { | |
484 //at(bnf_table,tn,fl[j]); | |
485 at(bnf_table,(int) token,fl[j]); | |
486 } | |
487 } | |
488 | |
489 //static void alter_prod(int tb, int nt, int tn, int vf) { | |
490 static void alter_prod(Token tb, int nt, Token token, VpRule vpRule) { | |
491 LOGSECTION("alter_prod"); | |
492 | |
493 LOGV(vpRule) LCV(token) LCV(tb) LCV(nt) LCV(Token::count()); | |
494 | |
495 int i,j; | |
496 iws(); | |
497 for (i = tb, j = nt; j--; i++) { | |
498 //if (i == tn) { | |
499 if (i == (int) token) { | |
500 //aws(vf); | |
501 aws(vpRule); | |
502 continue; | |
503 } | |
504 AgStack<RuleElement> elementStack; | |
505 elementStack.push(RuleElement(i,0)); | |
506 //VpRule vpRule(vf); | |
507 for (unsigned k = 0; k < vpRule->elementList.size(); k++) { | |
508 elementStack.push(vpRule->elementList[k]); | |
509 } | |
510 VpRule newRule(elementStack, vpRule->procedureName); | |
511 aws(newRule); | |
512 } | |
513 build_choice(token); | |
514 } | |
515 | |
516 static void alternate(void) { | |
517 LOGSECTION("alternate"); | |
518 //int tb = ntkns+1; | |
519 Token tb = Token::create(); | |
520 int *vfl = build_list(); | |
521 int nt = fis(); | |
522 //int tn = tb, k; | |
523 Token tn; | |
524 int k; | |
525 | |
526 for (k = 1; k < nt; k++) tn = Token::create(); | |
527 iws(); | |
528 for (k = 0; k < nt; k++) { | |
529 tn = tb + k; | |
530 alter_prod(tb,nt,tn,vfl[k]); | |
531 ruleElementStack.push(AgStack<RuleElement>()).top() | |
532 .push(RuleElement(tn,0)); | |
533 aws(vp_form3(0)); | |
534 } | |
535 DEALLOCATE(vfl); | |
536 } | |
537 | |
538 int vp_9(void){ | |
539 LOGSECTION("vp_9"); | |
540 alternate(); | |
541 return vp_1(); | |
542 } | |
543 | |
544 int vp_10(void){ | |
545 LOGSECTION("vp_10"); | |
546 alternate(); | |
547 return vp_3(); | |
548 } | |
549 |