Mercurial > ~dholland > hg > ag > index.cgi
comparison anagram/guisupport/ws.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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 /* | |
2 * AnaGram, A System for Syntax Directed Programming | |
3 * Copyright 1993-1999 Parsifal Software. All Rights Reserved. | |
4 * See the file COPYING for license and usage terms. | |
5 * | |
6 * ws.cpp - Miscellaneous Windows | |
7 */ | |
8 | |
9 #include "agstack.h" | |
10 #include "arrays.h" | |
11 #include "charsdc.h" | |
12 #include "data.h" | |
13 #include "dict.h" | |
14 #include "dc.h" | |
15 #include "items.h" | |
16 #include "q1glbl.h" | |
17 #include "q1a.h" | |
18 #include "rule.h" | |
19 #include "stexpdc.h" | |
20 #include "stacks.h" | |
21 #include "token.h" | |
22 #include "tracedc.h" | |
23 #include "ut.h" | |
24 #include "wm1.h" | |
25 #include "ws.h" | |
26 | |
27 //#define INCLUDE_LOGGING | |
28 #include "log.h" | |
29 | |
30 | |
31 #define PUREMARK '%' | |
32 | |
33 | |
34 int productions_window_ok(int tn) { | |
35 Token token = tn; | |
36 return token.isNotNull() && token->non_terminal_flag; | |
37 } | |
38 | |
39 dc_ref productions_window(int tn) { | |
40 Token token = tn; | |
41 dc_ref new_window; | |
42 | |
43 if (token.isNull() || !token->non_terminal_flag) { | |
44 return dc_ref(); | |
45 } | |
46 AgString foot = AgString::format("T%03d: ", tn).concat(token_string(token)); | |
47 return dc_ref(new productions_window_dc(token, foot)); | |
48 } | |
49 | |
50 void productions_window_dc::getLine(unsigned ln) const { | |
51 Token token = token_number; | |
52 Rule rule = token.rule(ln); | |
53 ics(); | |
54 append_item(rule, -1); | |
55 } | |
56 | |
57 void productions_window_dc::synchCursor(unsigned ln) const { | |
58 Token token = token_number; | |
59 Rule rule = token.rule(ln); | |
60 if (rule.isNotNull()) { | |
61 set_rule_line(rule); | |
62 } | |
63 } | |
64 | |
65 productions_window_dc::productions_window_dc(unsigned tn, const AgString foot) | |
66 : dc("Productions", foot) | |
67 { | |
68 Token token = token_number = tn; | |
69 des->d_size.y = token->ruleList.size(); | |
70 } | |
71 | |
72 | |
73 int token_usage_window_ok(unsigned tn) { | |
74 dc_ref new_window; | |
75 | |
76 if (tn == 0) { | |
77 return 0; | |
78 } | |
79 Token token = tn; | |
80 | |
81 //for (fn = 0; ++fn <= nforms; ) { | |
82 for (Each<Rule> rule; rule.loopNotFinished(); rule.getNext()) { | |
83 //Rule rule(fn); | |
84 int length = rule->length(); | |
85 int fx; | |
86 | |
87 if (length == 0) { | |
88 continue; | |
89 } | |
90 for (fx = 0; fx < length;) { | |
91 if (rule.token(fx++) != token) { | |
92 continue; | |
93 } | |
94 return 1; | |
95 } | |
96 } | |
97 return 0; | |
98 } | |
99 | |
100 dc_ref token_usage_window(unsigned tn) { | |
101 dc_ref new_window; | |
102 | |
103 if (tn == 0) { | |
104 return NULL; | |
105 } | |
106 | |
107 Token token = tn; | |
108 AgString foot = AgString::format("T%03d: ", tn).concat(token_string(tn)); | |
109 AgStack<int> stack; | |
110 for (Each<Rule> rule; rule.loopNotFinished(); rule.getNext()) { | |
111 int length = rule->length(); | |
112 int fx; | |
113 | |
114 if (length == 0) { | |
115 continue; | |
116 } | |
117 for (fx = 0; fx < length;) { | |
118 if (rule.token(fx++) != token) { | |
119 continue; | |
120 } | |
121 stack.push(rule).push(fx); | |
122 } | |
123 } | |
124 AgArray<int> list = stack; | |
125 if (list.size()) { | |
126 return new usage_dc(list, foot); | |
127 } | |
128 return NULL; | |
129 } | |
130 | |
131 dc_ref rule_list_dc::expansion_rules(unsigned ln) { | |
132 ln *= 2; | |
133 Rule rn = rule_list[ln]; | |
134 int rx = rule_list[ln+1]; | |
135 | |
136 if (rx >= rn->length()) { | |
137 return NULL; | |
138 } | |
139 return expand_specific_item(this, rn, rx); | |
140 } | |
141 | |
142 int rule_list_dc::expansion_rules_ok(unsigned ln) { | |
143 LOGSECTION("rule_list_dc::expansion_rules_ok"); | |
144 LOGV(ln); | |
145 return build_item_list_ok(token(ln)); | |
146 } | |
147 | |
148 void rule_list_dc::getLine(unsigned ln) const { | |
149 ln *= 2; | |
150 ics(); | |
151 append_item(rule_list[ln], rule_list[ln+1]); | |
152 } | |
153 | |
154 int rule_list_dc::productions_ok(unsigned ln) { | |
155 return productions_window_ok(token(ln)); | |
156 } | |
157 | |
158 dc_ref rule_list_dc::productions(unsigned ln) { | |
159 return productions_window(token(ln)); | |
160 } | |
161 | |
162 dc_ref rule_list_dc::rule_context(unsigned ln) { | |
163 ln *= 2; | |
164 return rule_context_window(rule_list[ln]); | |
165 } | |
166 | |
167 rule_list_dc::rule_list_dc(const AgArray<int> list, | |
168 const AgString head, const AgString foot) | |
169 : dc(head, foot), rule_list(list) | |
170 { | |
171 des->d_size.y = list.size()/2; | |
172 } | |
173 | |
174 int rule_list_dc::set_elements_ok(unsigned ln) { | |
175 return token_set_window_ok(token(ln)); | |
176 } | |
177 | |
178 dc_ref rule_list_dc::set_elements(unsigned ln) { | |
179 return token_set_window(token(ln)); | |
180 } | |
181 | |
182 void rule_list_dc::synchCursor(unsigned ln) const { | |
183 LOGSECTION("rule_list_dc::synchCursor"); | |
184 unsigned rn = rule_list[2*ln]; | |
185 LOGV(ln) LCV(rn); | |
186 set_rule_line(rn); | |
187 } | |
188 | |
189 unsigned rule_list_dc::token(unsigned ln) { | |
190 LOGSECTION("rule_list_dc::token"); | |
191 LOGV(ln); | |
192 ln *= 2; | |
193 Rule rule = rule_list[ln]; | |
194 unsigned rx = rule_list[ln+1]; | |
195 unsigned length = rule->length(); | |
196 LOGV(rule); | |
197 LOGV(rx); | |
198 LOGV(length); | |
199 if (rx >= length) { | |
200 return 0; | |
201 } | |
202 return rule.token(rx); | |
203 } | |
204 | |
205 int rule_list_dc::usage_ok(unsigned ln) { | |
206 return token_usage_window_ok(token(ln)); | |
207 } | |
208 | |
209 dc_ref rule_list_dc::usage(unsigned ln) { | |
210 return token_usage_window(token(ln)); | |
211 } | |
212 | |
213 dc_ref rule_context_window(int f) { | |
214 dc_ref new_window; | |
215 int *rl, nr; | |
216 | |
217 if (f == 0) { | |
218 return NULL; | |
219 } | |
220 | |
221 AgString foot = AgString::format("R%03d", f); | |
222 AgStack<int> stack; | |
223 rl = ibnfs + ibnfb[f]; | |
224 nr = ibnfn[f]; | |
225 while (nr--) { | |
226 Token token = *rl++; | |
227 //for (fn = 0; ++fn <= nforms;) { | |
228 for (Each<Rule> rule; rule.loopNotFinished(); rule.getNext()) { | |
229 int length = rule->length(); | |
230 int fx; | |
231 | |
232 if (length == 0) { | |
233 continue; | |
234 } | |
235 for (fx = 0; fx < length;) { | |
236 if (rule.token(fx++) != token) { | |
237 continue; | |
238 } | |
239 stack.push(rule).push(fx); | |
240 } | |
241 } | |
242 } | |
243 | |
244 AgArray<int> list = stack; | |
245 if (list.size()) { | |
246 return new rule_context_dc(list, foot); | |
247 } | |
248 return dc_ref(); | |
249 } | |
250 | |
251 tsd *build_states_table(unsigned *list, int n) { | |
252 tsd *table = init_tsd(3); | |
253 | |
254 while (n--) { | |
255 int ps = *list++; | |
256 int *is = dict_str(isht_dict, ps); | |
257 int nis = (*is++ - 1)/2; | |
258 while (nis--) { | |
259 int fn = *is++, fx = *is++; | |
260 at(table, ps, fn, fx); | |
261 } | |
262 } | |
263 return table; | |
264 } | |
265 | |
266 int previous_states_window_ok(int sn) { | |
267 return sn != 0; | |
268 } | |
269 | |
270 dc_ref previous_states_window(int sn) { | |
271 unsigned *list = lstptr(map_state_number[sn], previous_states); | |
272 int n = map_state_number[sn].n_previous_states; | |
273 dc_ref window; | |
274 tsd *table; | |
275 if (sn == 0) { | |
276 return dc_ref(); | |
277 } | |
278 AgString foot = AgString::format("S%03d", sn); | |
279 table = build_states_table(list, n); | |
280 return dc_ref(new state_list_dc("Previous States", table, foot)); | |
281 } | |
282 | |
283 static int state_list_tabs[] = {7,0}; | |
284 void state_list_dc::getLine(unsigned ln) const { | |
285 int sn, fn, fx, psn = -1; | |
286 | |
287 if (ln) { | |
288 xtx(state_list, ln-1, &psn, &fn, &fx); | |
289 } | |
290 xtx(state_list, ln, &sn, &fn, &fx); | |
291 if (sn != psn) { | |
292 ssprintf("S%03d:\t", sn); | |
293 } | |
294 else { | |
295 scs('\t'); | |
296 } | |
297 append_item(fn, fx); | |
298 } | |
299 | |
300 | |
301 | |
302 int state_list_dc::expansion_rules_ok(unsigned ln){ | |
303 int sn, fn, fx; | |
304 | |
305 LOGSECTION("expansion_rules_ok"); | |
306 xtx(state_list, ln, &sn, &fn, &fx); | |
307 LOGV(ln); | |
308 LOGV(sn); | |
309 LOGV(fn); | |
310 LOGV(fx); | |
311 | |
312 Rule rule = fn; | |
313 if (fx >= rule->length()) { | |
314 return 0; | |
315 } | |
316 Token tn = rule.token(fx); | |
317 LOGV(tn); | |
318 return tn->non_terminal_flag; | |
319 } | |
320 | |
321 dc_ref state_list_dc::expansion_rules(unsigned ln){ | |
322 int sn, fn, fx; | |
323 | |
324 xtx(state_list, ln, &sn, &fn, &fx); | |
325 if (fx >= Rule(fn)->length()) { | |
326 return NULL; | |
327 } | |
328 return expand_specific_item(this, fn, fx); | |
329 } | |
330 | |
331 void state_list_dc::synchCursor(unsigned ln) const { | |
332 unsigned rn = rule(ln); | |
333 if (rn) { | |
334 set_rule_line(rn); | |
335 } | |
336 } | |
337 | |
338 int state_list_dc::reduction_states_ok(unsigned ln) { | |
339 int sn, fn, fx; | |
340 | |
341 xtx(state_list, ln, &sn, &fn, &fx); | |
342 return reduction_states_window_ok(fn, fx); | |
343 } | |
344 | |
345 dc_ref state_list_dc::reduction_states(unsigned ln) { | |
346 int sn, fn, fx; | |
347 | |
348 xtx(state_list, ln, &sn, &fn, &fx); | |
349 return reduction_states_window(sn, fn, fx); | |
350 } | |
351 | |
352 unsigned state_list_dc::rule(unsigned ln) const { | |
353 int sn, fn, fx; | |
354 | |
355 xtx(state_list, ln, &sn, &fn, &fx); | |
356 return fn; | |
357 } | |
358 | |
359 dc_ref state_list_dc::rule_context(unsigned ln){ | |
360 return rule_context_window(rule(ln)); | |
361 } | |
362 | |
363 int state_list_dc::set_elements_ok(unsigned ln) { | |
364 return token_set_window_ok(token(ln)); | |
365 } | |
366 | |
367 dc_ref state_list_dc::set_elements(unsigned ln) { | |
368 return token_set_window(token(ln)); | |
369 } | |
370 | |
371 unsigned state_list_dc::state(unsigned ln) const { | |
372 int sn, fn, fx; | |
373 | |
374 xtx(state_list, ln, &sn, &fn, &fx); | |
375 return sn; | |
376 } | |
377 | |
378 dc_ref state_list_dc::state_expansion(unsigned ln) { | |
379 return state_expansion_window(state(ln)); | |
380 } | |
381 | |
382 state_list_dc::state_list_dc(const AgString head, tsd* states, const AgString foot) | |
383 : dc(head, foot), state_list(states) | |
384 { | |
385 tab_stops = state_list_tabs; | |
386 columnHeadTitle = "State\tCharacteristic Rules"; | |
387 des->d_size.y = state_list->nt; | |
388 } | |
389 | |
390 unsigned state_list_dc::token(unsigned ln) const { | |
391 int sn, fn, fx; | |
392 int length; | |
393 | |
394 xtx(state_list, ln, &sn, &fn, &fx); | |
395 Rule rule = fn; | |
396 length = rule->length(); | |
397 if (fx >= length) { | |
398 return 0; | |
399 } | |
400 return rule.token(fx); | |
401 } | |
402 | |
403 int state_list_dc::usage_ok(unsigned ln) { | |
404 return token_usage_window_ok(token(ln)); | |
405 } | |
406 | |
407 dc_ref state_list_dc::usage(unsigned ln) { | |
408 return token_usage_window(token(ln)); | |
409 } | |
410 | |
411 | |
412 dc_ref conflict_state_window(unsigned sn) { | |
413 dc_ref window; | |
414 tsd *table; | |
415 | |
416 AgString foot = AgString::format("S%03d", sn); | |
417 table = build_states_table(&sn, 1); | |
418 return dc_ref(new state_list_dc("State Definition", table, foot)); | |
419 } | |
420 | |
421 int keywords_window_ok(int sn) { | |
422 int kl = map_state_number[sn].key_list; | |
423 return kl != 0; | |
424 } | |
425 | |
426 dc_ref keywords_window(int sn) { | |
427 int kl = map_state_number[sn].key_list; | |
428 unsigned *list; | |
429 dc_ref window; | |
430 | |
431 if (kl == 0) return dc_ref(); | |
432 list = (unsigned *) dict_str(key_list_dict,kl); | |
433 | |
434 AgString foot = AgString::format("S%03d", sn); | |
435 return dc_ref(new keywords_dc(list + 1, *list -1, foot)); | |
436 } | |
437 | |
438 static int keywords_tabs[] = {7,0}; | |
439 | |
440 void keywords_dc::getLine(unsigned ln) const { | |
441 Token tn = keyword_list[ln]; | |
442 int key = tn->key; | |
443 | |
444 ssprintf("T%03d:\t", (int) tn); | |
445 append_key(key); | |
446 if (tn->pure) { | |
447 acs(PUREMARK); | |
448 } | |
449 } | |
450 | |
451 keywords_dc::keywords_dc(unsigned *kwl, unsigned nkw, const AgString foot) | |
452 : dc("Keywords", foot) | |
453 { | |
454 keyword_list = kwl; | |
455 des->d_size.y = nkw; | |
456 | |
457 tab_stops = keywords_tabs; | |
458 columnHeadTitle = "Token\tKeyword"; | |
459 } | |
460 | |
461 int keywords_dc::usage_ok(unsigned ln) { | |
462 return token_usage_window_ok(keyword_list[ln]); | |
463 } | |
464 | |
465 dc_ref keywords_dc::usage(unsigned ln) { | |
466 return token_usage_window(keyword_list[ln]); | |
467 } | |
468 | |
469 int reduction_states_window_ok(int fn, int fx) { | |
470 LOGSECTION("reduction_states_window_ok"); | |
471 LOGV(fn) LCV(fx); | |
472 return fn && fx == Rule(fn)->length(); | |
473 } | |
474 | |
475 dc_ref reduction_states_window(int sn, int fn, int fx) { | |
476 int cfn; | |
477 unsigned *list; | |
478 dc_ref new_window; | |
479 tsd *table; | |
480 | |
481 if (fx < Rule(fn)->length()) { | |
482 return NULL; | |
483 } | |
484 cfn = get_reduction_states(sn, fn, fx); | |
485 if (map_completed_form[cfn].n_reduction_states == 0) { | |
486 return dc_ref(); | |
487 } | |
488 | |
489 AgString foot = AgString::format("S%03d:R%03d", sn, fn); | |
490 list = lstptr(map_completed_form[cfn], reduction_states); | |
491 table = build_states_table(list, map_completed_form[cfn].n_reduction_states); | |
492 new_window = new state_list_dc("Reduction States", table, foot); | |
493 return new_window; | |
494 } | |
495 | |
496 static tsd *make_trace(void) { | |
497 int s1, s2; | |
498 int k; | |
499 tsd *aux = init_tsd(2); | |
500 | |
501 s1 = fws(); | |
502 k = tis(); | |
503 while (k--) { | |
504 s2 = fws(); | |
505 at(aux, s1, map_state_number[s2].char_token); | |
506 s1 = s2; | |
507 } | |
508 at(aux, s1, 0); | |
509 rws(); | |
510 return aux; | |
511 } | |
512 | |
513 tsd *make_stored_trace(int *trace, int depth, int tn) { | |
514 int s1, s2; | |
515 int k; | |
516 tsd *aux = init_tsd(2); | |
517 | |
518 k = depth - 1; | |
519 s1 = trace[k]; | |
520 while (k--) { | |
521 s2 = trace[k]; | |
522 at(aux, s1, map_state_number[s2].char_token); | |
523 s1 = s2; | |
524 } | |
525 at(aux, s1, tn); | |
526 return aux; | |
527 } | |
528 | |
529 dc_ref aux_trace_window(unsigned sn) { | |
530 tsd *aux; | |
531 dc_ref window; | |
532 | |
533 sws(sn); | |
534 while (sn) { | |
535 state_number_map *sp = &map_state_number[sn]; | |
536 unsigned *list = lstptr(*sp, previous_states); | |
537 int n = sp->n_previous_states; | |
538 while (n--) { | |
539 if (xws(sn = *list++) == 0) { | |
540 break; | |
541 } | |
542 } | |
543 } | |
544 aux = make_trace(); | |
545 window = dc_ref(new trace_window_dc("Auxiliary Trace", aux)); | |
546 delete_tsd(aux); | |
547 return window; | |
548 } | |
549 | |
550 | |
551 /* | |
552 int token_set_window_ok(int tn) { | |
553 int cs; | |
554 int pt; | |
555 int name; | |
556 | |
557 if (tn == 0) return 0; | |
558 cs = map_token_number[tn].token_set_id; | |
559 if (cs) return 1; | |
560 pt = map_token_number[tn].parse_tree; | |
561 if (pt) { | |
562 cs = map_parse_tree[pt].char_set; | |
563 if (cs) return 1; | |
564 } | |
565 name = map_token_number[tn].token_name; | |
566 if (name) { | |
567 pt = map_token_name[name].parse_tree; | |
568 if (pt) { | |
569 cs = map_parse_tree[pt].char_set; | |
570 if (cs) return 1; | |
571 } | |
572 } | |
573 return map_token_number[tn].part_number != 0; | |
574 } | |
575 */ | |
576 | |
577 int token_set_window_ok(int tn) { | |
578 Token token = tn; | |
579 if (token.isNull()) { | |
580 return 0; | |
581 } | |
582 int cs = token->token_set_id; | |
583 if (cs) { | |
584 return 1; | |
585 } | |
586 ParseTree tree = token->parse_tree; | |
587 if (tree.isNotNull()) { | |
588 cs = tree->char_set; | |
589 if (cs) { | |
590 return 1; | |
591 } | |
592 } | |
593 Symbol name = token->token_name; | |
594 if (name.isNotNull()) { | |
595 tree = name->parse_tree; | |
596 if (tree.isNotNull()) { | |
597 cs = tree->char_set; | |
598 if (cs) { | |
599 return 1; | |
600 } | |
601 } | |
602 } | |
603 return token->part_number != 0; | |
604 } | |
605 | |
606 /* | |
607 dc_ref token_set_window(int tn) { | |
608 int cs; | |
609 int pt; | |
610 int name; | |
611 int pn; | |
612 | |
613 if (tn == 0) { | |
614 return NULL; | |
615 } | |
616 cs = map_token_number[tn].token_set_id; | |
617 if (cs) { | |
618 return char_set_window(cs); | |
619 } | |
620 pt = map_token_number[tn].parse_tree; | |
621 if (pt) { | |
622 cs = map_parse_tree[pt].char_set; | |
623 if (cs) { | |
624 return char_set_window(cs); | |
625 } | |
626 } | |
627 name = map_token_number[tn].token_name; | |
628 if (name) { | |
629 pt = map_token_name[name].parse_tree; | |
630 if (pt) { | |
631 cs = map_parse_tree[pt].char_set; | |
632 if (cs) { | |
633 return char_set_window(cs); | |
634 } | |
635 } | |
636 } | |
637 pn = map_token_number[tn].part_number; | |
638 if (pn == 0) { | |
639 return NULL; | |
640 } | |
641 return part_set_window(pn); | |
642 } | |
643 */ | |
644 | |
645 dc_ref token_set_window(int tn) { | |
646 Token token = tn; | |
647 if (token.isNull()) { | |
648 return NULL; | |
649 } | |
650 int cs = token->token_set_id; | |
651 if (cs) { | |
652 return char_set_window(cs); | |
653 } | |
654 ParseTree tree = token->parse_tree; | |
655 if (tree.isNotNull()) { | |
656 cs = tree->char_set; | |
657 if (cs) { | |
658 return char_set_window(cs); | |
659 } | |
660 } | |
661 Symbol name = token->token_name; | |
662 if (name.isNotNull()) { | |
663 tree = name->parse_tree; | |
664 if (tree.isNotNull()) { | |
665 cs = tree->char_set; | |
666 if (cs) { | |
667 return char_set_window(cs); | |
668 } | |
669 } | |
670 } | |
671 int pn = token->part_number; | |
672 if (pn == 0) { | |
673 return NULL; | |
674 } | |
675 return part_set_window(pn); | |
676 } | |
677 | |
678 | |
679 int char_set_window_ok(int cs) { | |
680 return cs != 0; | |
681 } | |
682 | |
683 dc_ref char_set_window(int cs) { | |
684 unsigned *list = (unsigned *) dict_str(char_set_dict,cs); | |
685 dc_ref window; | |
686 | |
687 if (cs == 0) { | |
688 return dc_ref(); | |
689 } | |
690 AgString foot = AgString::format("C%03d", cs); | |
691 | |
692 return dc_ref(new set_elements_dc(list + 1, *list - 1, foot.pointer())); | |
693 } | |
694 | |
695 /* End WS.C */ |