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