1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2:
3: /*
4: * $Header: tabl.c,v 2.4 85/08/22 16:08:42 timo Exp $
5: */
6:
7: /*
8: * B editor -- Grammar table.
9: */
10:
11: #include "b.h"
12: #include "node.h"
13: #include "gram.h"
14: #include "tabl.h"
15:
16:
17: /*
18: * ***** DISCLAIMER *****
19: *
20: * This file is a mess. There should really be a separate program (like Yacc)
21: * to compile a grammar into tables. But for the time being . . .
22: */
23:
24:
25: /*
26: * Values returned by function symbol(n).
27: * They are used directly as index in the grammar table.
28: * The NAMES of the #defined constants are of no importance outside this file.
29: */
30:
31: #define Put 1
32: #define Insert 2
33: #define Remove 3
34: #define Choose 4
35: #define Draw 5
36: #define Set_random 6
37: #define Delete 7
38: #define Check 8
39: #define Share 9
40:
41: #define Write 10
42: #define Read 11
43: #define Read_raw 12
44:
45: #define If 13
46: #define While 14
47: #define For 15
48:
49: #define Select 16
50:
51: #define Quit 18
52: #define Return 19
53: #define Report 20
54: #define Succeed 21
55: #define Fail 22
56:
57: #define How_to 23
58: #define Yield 24
59: #define Test 25
60: #define Suite 26
61: #define Refinement 27
62:
63: #define Compound 28
64: #define Collateral 29
65: #define Tag 30
66: #define Number 31
67: #define Selection 32
68: #define Behead 33
69: #define Curtail 34
70:
71: #define And 35
72: #define Or 36
73: #define Not 37
74: #define Some_in 38
75: #define Each_in 39
76: #define No_in 40
77: #define Some_parsing 41
78: #define Each_parsing 42
79: #define No_parsing 43
80:
81: #define 44
82: #define Keyword 45
83:
84: #define L_t_dis 46
85: #define List_body 47
86: #define Tab_body 48
87: #define Tab_entry 49
88:
89: #define E_number 50
90: #define Com_target 51
91: #define Col_target 52
92: #define Sel_expr 53
93: #define Text1 54
94: #define Text2 55
95: #define Grouped 56
96: #define Blocked 57
97: #define Operators 58
98:
99: #define Else_kw 59
100: #define Kw_plus 60
101: #define E_plus 61
102: #define Conversion 62
103: #define T1 63
104: #define T1_plus 64
105: #define T2 65
106: #define T2_plus 66
107: #define Cmt_cmd 67
108:
109: #define F_kw_plus 69
110: #define F_e_plus 70
111: #define Plus_sign 71
112: #define Minus_sign 72
113:
114: #define Long_comp 73
115: #define Short_comp 74
116: #define Cmt_comp 75
117:
118: #define Long_unit 76
119: #define Short_unit 77
120: #define Cmt_head 78
121:
122: #define Ref_join 79
123:
124: #define And_kw 80
125: #define Or_kw 81
126:
127: #define E_part 82
128:
129: #define Unit_edit 83
130: #define Target_edit 84
131: #define Imm_cmd 85
132: #define Raw 86
133: #define Raw_input 87
134: #define Edit_unit 88
135: #define Edit_target 89
136: #define Colon 90
137: #define Equals 91
138: #define Test_suite 92
139: #define Expression 93
140:
141: /*
142: * The last three, `Suggestion', `Optional' and `Hole',
143: * with values 97, 98 and 99, are defined in "gram.h".
144: */
145:
146:
147: /*
148: * Symbol values used for lexical elements.
149: * Cross-reference: "lexi.c", table `chclass'.
150: */
151:
152: #define LEXICAL 100
153:
154: #define IDENT (LEXICAL+0)
155: #define KEYWORD (LEXICAL+1)
156: #define NUMBER (LEXICAL+2)
157: #define (LEXICAL+3)
158: #define TEXT1 (LEXICAL+4)
159: #define TEXT2 (LEXICAL+5)
160: #define OPERATORS (LEXICAL+6)
161: #define RAWINPUT (LEXICAL+7)
162: #define SUGGESTION (LEXICAL+8)
163:
164:
165: /*
166: * Classes used in table initialization.
167: */
168:
169: Hidden classelem Asugg_body[] = {SUGGESTION, 0};
170: Hidden struct classinfo sugg_body[] = {Asugg_body};
171:
172: #define TARGET Tag, Com_target, Selection, Behead, Curtail
173: #define PRIMARY \
174: Sel_expr, Tag, E_number, Number, Compound, L_t_dis, Text1, Text2
175: #define EXPR Blocked, Grouped, Operators, PRIMARY
176:
177: Hidden classelem Atag_body[] = {IDENT, 0};
178: Hidden struct classinfo tag_body[] = {Atag_body};
179: Hidden classelem Anum_body[] = {NUMBER, 0};
180: Hidden struct classinfo num_body[] = {Anum_body};
181: Hidden classelem Acom_body[] = {COMMENT, 0};
182: Hidden struct classinfo com_body[] = {Acom_body};
183: Hidden classelem Akw_body[] = {KEYWORD, 0};
184: Hidden struct classinfo kw_body[] = {Akw_body};
185: Hidden classelem At1_body[] = {TEXT1, 0};
186: Hidden struct classinfo t1_body[] = {At1_body};
187: Hidden classelem At2_body[] = {TEXT2, 0};
188: Hidden struct classinfo t2_body[] = {At2_body};
189: Hidden classelem Aops_body[] = {OPERATORS, 0};
190: Hidden struct classinfo ops_body[] = {Aops_body};
191: Hidden classelem Araw_body[] = {RAWINPUT, 0};
192: Hidden struct classinfo raw_body[] = {Araw_body};
193: Hidden classelem Araw_input[] = {Optional, Raw, 0};
194: Hidden struct classinfo raw_input[] = {Araw_input};
195:
196: Hidden classelem Aid_or_kw[] = {Tag, Keyword, 0};
197: Hidden struct classinfo id_or_kw[] = {Aid_or_kw};
198: Hidden classelem Anumber[] = {Number, 0};
199: Hidden struct classinfo number[] = {Anumber};
200: Hidden classelem Asign[] = {Optional, Plus_sign, Minus_sign, 0};
201: Hidden struct classinfo sign[] = {Asign};
202:
203: Hidden classelem Ao_c_expr[] = {Optional, Collateral, EXPR, 0};
204: Hidden struct classinfo o_c_expr[] = {Ao_c_expr};
205:
206: #define Ac_expr (Ao_c_expr+1)
207: Hidden struct classinfo c_expr[] = {Ac_expr};
208: #define Aexpr (Ao_c_expr+2)
209: Hidden struct classinfo expr[] = {Aexpr};
210: #define Aprimary (Ao_c_expr+5)
211: Hidden struct classinfo primary[] = {Aprimary};
212:
213: Hidden classelem Ablock[] = {Operators, PRIMARY, 0};
214: Hidden struct classinfo block[] = {Ablock};
215: Hidden classelem Agroup[] = {Blocked, Operators, PRIMARY, 0};
216: Hidden struct classinfo group[] = {Agroup};
217:
218: #define Ar_expr Agroup
219: Hidden struct classinfo r_expr[] = {Ar_expr};
220:
221: Hidden classelem Al_t_body[] = {Optional, List_body, PRIMARY, Blocked,
222: Grouped, Operators, Tab_body, Tab_entry, 0};
223: Hidden struct classinfo l_t_body[] = {Al_t_body};
224: Hidden classelem Alist_body[] = {List_body, EXPR, 0};
225: Hidden struct classinfo list_body[] = {Alist_body};
226: Hidden classelem Atab_body[] = {Tab_body, Tab_entry, 0};
227: Hidden struct classinfo tab_body[] = {Atab_body};
228: Hidden classelem Atab_entry[] = {Tab_entry, 0};
229: Hidden struct classinfo tab_entry[] = {Atab_entry};
230:
231: Hidden classelem Ac_target[] = {Col_target, TARGET, 0};
232: Hidden struct classinfo c_target[] = {Ac_target};
233:
234: #define Atarget (Ac_target+1)
235: Hidden struct classinfo target[] = {Atarget};
236:
237: #define SOME_ETC \
238: Not, Some_in, Each_in, No_in, Some_parsing, Each_parsing, No_parsing
239:
240: Hidden classelem Ae_test[] = {Else_kw, SOME_ETC, And, Or, EXPR, 0};
241: Hidden struct classinfo e_test[] = {Ae_test};
242:
243: #define Atest (Ae_test+1)
244: Hidden struct classinfo test[] = {Atest};
245: #define At_test Aexpr
246: Hidden struct classinfo t_test[] = {At_test};
247: Hidden classelem Ar_test[] = {SOME_ETC, EXPR, 0};
248: Hidden struct classinfo r_test[] = {Ar_test};
249: Hidden classelem Aand_test[] = {SOME_ETC, And, EXPR, 0};
250: Hidden struct classinfo and_test[] = {Aand_test};
251: Hidden classelem Aor_test[] = {SOME_ETC, Or, EXPR, 0};
252: Hidden struct classinfo or_test[] = {Aor_test};
253: Hidden classelem Ac_test[] = {Collateral, SOME_ETC, And, Or, EXPR, 0};
254: Hidden struct classinfo c_test[] = {Ac_test};
255: /*
256: * This means that a compound expression may in fact
257: * contain a `collateral test', e.g. (a AND b, c AND d).
258: * Of course, this is illegal in B, but I couldn't
259: * solve the ambiguity of `(' where a test is expected
260: * otherwise (this may start a parenthesized test, or
261: * a compound expression; the latter may be followed
262: * by more expression fragments, the first may not).
263: */
264:
265: Hidden classelem [] = {Comment, 0};
266: Hidden struct classinfo [] = {Acomment};
267: Hidden classelem [] = {Optional, Comment, 0};
268: Hidden struct classinfo [] = {Ao_comment};
269:
270: #define HEAD How_to, Yield, Test
271: #define BODY HEAD, Cmt_head, Long_unit, Short_unit
272:
273: /* The order here determines which are suggested first and is subject
274: to constant change! */
275: #define SIMPLE_CMD SC1, SC2, SC3
276: #define SC1 Share, Quit, Return, Write, Read, Read_raw, Put, Delete
277: #define SC2 Report, Fail, Succeed, Insert, Remove, Check
278: #define SC3 Choose, Draw, Set_random, Suggestion, Keyword, Kw_plus
279:
280: #define CONTROL_CMD If, While, For
281: #define COMP_CMD Short_comp, Long_comp, Cmt_comp, Select
282: #define CMD If, For, COMP_CMD, SIMPLE_CMD, While
283: /* #define SHORTCMD SIMPLE_CMD, Cmt_cmd */
284: #define SHORTCMD If, For, SIMPLE_CMD, While, Short_comp, Cmt_comp, Cmt_cmd
285:
286: Hidden classelem Ac_head[] = {Cmt_head, HEAD, 0};
287: Hidden struct classinfo c_head[] = {Ac_head};
288: #define Ahead (Ac_head+1)
289: Hidden struct classinfo head[] = {Ahead};
290:
291: Hidden classelem Aunit[] = {Optional, EXPR, BODY, Ref_join, 0};
292: Hidden struct classinfo unit[] = {Aunit};
293: Hidden classelem Ao_refinements[] = {Optional, Refinement, 0};
294: Hidden struct classinfo o_refinements[] = {Ao_refinements};
295: #define Arefinements (Ao_refinements+1)
296: Hidden struct classinfo refinements[] = {Arefinements};
297: Hidden classelem Arefpred[] = {BODY, 0};
298: Hidden struct classinfo refpred[] = {Arefpred};
299:
300: Hidden classelem Af_cmd[] = {Keyword, F_kw_plus, 0};
301: Hidden struct classinfo f_cmd[] = {Af_cmd};
302: #define Af_formula Aexpr /*****/
303: Hidden struct classinfo f_formula[] = {Af_formula};
304:
305: Hidden classelem Ao_suite[] = {Optional, Suite, 0};
306: Hidden struct classinfo o_suite[] = {Ao_suite};
307: Hidden classelem At_suite[] = {Test_suite, 0};
308: Hidden struct classinfo t_suite[] = {At_suite};
309: Hidden classelem Ao_t_suite[] = {Optional, Test_suite, 0};
310: Hidden struct classinfo o_t_suite[] = {Ao_t_suite};
311:
312: Hidden classelem Acmd[] = {Comment, CMD, Cmt_cmd, 0};
313: Hidden struct classinfo cmd[] = {Acmd};
314: Hidden classelem Ashortcmd[] = {SHORTCMD, 0};
315: Hidden struct classinfo shortcmd[] = {Ashortcmd};
316: Hidden classelem Ao_cmdsuite[] = {Optional, SHORTCMD, Suite, 0};
317: Hidden struct classinfo o_cmdsuite[] = {Ao_cmdsuite};
318: Hidden classelem Asuite[] = {Suite, 0};
319: Hidden struct classinfo suite[] = {Asuite};
320: Hidden classelem Asimple_cmd[] = {SIMPLE_CMD, 0};
321: Hidden struct classinfo simple_cmd[] = {Asimple_cmd};
322:
323: Hidden classelem Ac_ifforwhile[] = {CONTROL_CMD, Cmt_comp, 0};
324: Hidden struct classinfo c_ifforwhile[] = {Ac_ifforwhile};
325: Hidden classelem Aifforwhile[] = {CONTROL_CMD, 0};
326: Hidden struct classinfo ifforwhile[] = {Aifforwhile};
327:
328: Hidden classelem Akeyword[] = {Keyword, 0};
329: Hidden struct classinfo keyword[] = {Akeyword};
330: Hidden classelem Akw_next[] = {Collateral, EXPR, Keyword, E_plus, Kw_plus, 0};
331: Hidden struct classinfo kw_next[] = {Akw_next};
332: Hidden classelem Ae_next[] = {Keyword, Kw_plus, 0};
333: Hidden struct classinfo e_next[] = {Ae_next};
334:
335: Hidden classelem Af_kw_next[] = {Tag, Keyword, F_kw_plus, F_e_plus, 0};
336: Hidden struct classinfo f_kw_next[] = {Af_kw_next};
337: Hidden classelem Af_e_next[] = {Keyword, F_kw_plus, 0};
338: Hidden struct classinfo f_e_next[] = {Af_e_next};
339: Hidden classelem Atag[] = {Tag, 0};
340: Hidden struct classinfo tag[] = {Atag};
341:
342: Hidden classelem Atext1[] = {Optional, T1, Conversion, T1_plus, 0};
343: Hidden struct classinfo text1[] = {Atext1};
344: Hidden classelem At1_conv[] = {T1, Conversion, 0};
345: Hidden struct classinfo t1_conv[] = {At1_conv};
346: Hidden classelem At1_next[] = {T1, Conversion, T1_plus, 0};
347: Hidden struct classinfo t1_next[] = {At1_next};
348:
349: Hidden classelem Atext2[] = {Optional, T2, Conversion, T2_plus, 0};
350: Hidden struct classinfo text2[] = {Atext2};
351: Hidden classelem At2_conv[] = {T2, Conversion, 0};
352: Hidden struct classinfo t2_conv[] = {At2_conv};
353: Hidden classelem At2_next[] = {T2, Conversion, T2_plus, 0};
354: Hidden struct classinfo t2_next[] = {At2_next};
355:
356: Hidden classelem Aand[] = {And_kw, 0};
357: Hidden struct classinfo and[] = {Aand};
358: Hidden classelem Aor[] = {Or_kw, 0};
359: Hidden struct classinfo or[] = {Aor};
360:
361: Hidden classelem Ae_part[] = {E_part, 0};
362: Hidden struct classinfo e_part[] = {Ae_part};
363:
364: Hidden classelem Aunit_edit[] = {Optional, BODY, Ref_join, 0};
365: Hidden struct classinfo unit_edit[] = {Aunit_edit};
366: Hidden classelem Atarget_edit[] = {Optional, EXPR, 0};
367: Hidden struct classinfo target_edit[] = {Atarget_edit};
368: Hidden classelem Aimm_cmd[] = {Optional, Comment, HEAD, CMD, Cmt_cmd, Cmt_head,
369: Edit_unit, Edit_target, 0};
370: Hidden struct classinfo imm_cmd[] = {Aimm_cmd};
371:
372: Hidden classelem Aed_unit[] = {Optional, Tag, Keyword, Colon, 0};
373: Hidden struct classinfo ed_unit[] = {Aed_unit};
374: Hidden classelem Aed_target[] = {Optional, Tag, Equals, 0};
375: Hidden struct classinfo ed_target[] = {Aed_target};
376:
377:
378: /*
379: * WARNING: The entries in this table must correspond one by one
380: * to the symbols defined earlier. This is checked dynamically
381: * by the initialization procedure (syserr "table order").
382: */
383:
384: #define XX(name) name, "name"
385:
386: Hidden struct table b_grammar[] = {
387: {XX(Rootsymbol), {0}, {unit}}, /* Start symbol of the grammar,
388: may be overridden by setroot("Blabla") call. */
389: {XX(Put), {"PUT ", " IN "}, {c_expr, c_target}},
390: {XX(Insert), {"INSERT ", " IN "}, {c_expr, target}},
391: {XX(Remove), {"REMOVE ", " FROM "}, {c_expr, target}},
392: {XX(Choose), {"CHOOSE ", " FROM "}, {c_expr, expr}},
393: {XX(Draw), {"DRAW "}, {target}},
394: {XX(Set_random), {"SET'RANDOM "}, {c_expr}},
395: {XX(Delete), {"DELETE "}, {c_target}},
396: {XX(Check), {"CHECK "}, {test}},
397: {XX(Share), {"SHARE "}, {c_target}},
398:
399: {XX(Write), {"WRITE "}, {c_expr}},
400: {XX(Read), {"READ ", " EG "}, {c_target, c_expr}},
401: {XX(Read_raw), {"READ ", " RAW"}, {target}},
402:
403: {XX(If), {"IF ", ": "}, {test}},
404: {XX(While), {"WHILE ", ": "}, {test}},
405: {XX(For), {"FOR ", " IN ", ": "}, {c_target, expr}},
406:
407: {XX(Select), {"SELECT: ", "\t", "\b"}, {o_comment, t_suite}},
408: {0}, /* Test_suite moved to 92 */
409:
410: {XX(Quit), {"QUIT"}, {0}},
411: {XX(Return), {"RETURN "}, {c_expr}},
412: {XX(Report), {"REPORT "}, {test}},
413: {XX(Succeed), {"SUCCEED"}, {0}},
414: {XX(Fail), {"FAIL"}, {0}},
415:
416: {XX(How_to), {"HOW'TO ", ": "}, {f_cmd}},
417: {XX(Yield), {"YIELD ", ": "}, {f_formula}},
418: {XX(Test), {"TEST ", ": "}, {f_formula}},
419:
420: {XX(Suite), {"\n"}, {cmd, o_suite}},
421: {XX(Refinement), {"\n", ": ", "\t", "\b"},
422: {id_or_kw, o_comment, o_cmdsuite, o_refinements}},
423:
424: {XX(Compound), {"(", ")"}, {c_test}},
425: {XX(Collateral), {0, ", "}, {expr, c_expr}},
426: {XX(Tag), {0}, {tag_body}},
427: {XX(Number), {0}, {num_body}},
428: {XX(Selection), {0, "[", "]"}, {target, c_expr}},
429: {XX(Behead), {0, "@"}, {target, r_expr}},
430: {XX(Curtail), {0, "|"}, {target, r_expr}},
431:
432: {XX(And), {0, " "}, {t_test, and}},
433: {XX(Or), {0, " "}, {t_test, or}},
434: {XX(Not), {"NOT "}, {r_test}},
435: {XX(Some_in), {"SOME ", " IN ", " HAS "}, {c_target, expr, r_test}},
436: {XX(Each_in), {"EACH ", " IN ", " HAS "}, {c_target, expr, r_test}},
437: {XX(No_in), {"NO ", " IN ", " HAS "}, {c_target, expr, r_test}},
438: {XX(Some_parsing), {"SOME ", " PARSING ", " HAS "},
439: {c_target, expr, r_test}},
440: {XX(Each_parsing), {"EACH ", " PARSING ", " HAS "},
441: {c_target, expr, r_test}},
442: {XX(No_parsing), {"NO ", " PARSING ", " HAS "}, {c_target, expr, r_test}},
443:
444: {XX(Comment), {0}, {com_body}},
445: {XX(Keyword), {0}, {kw_body}},
446:
447: {XX(L_t_dis), {"{", "}"}, {l_t_body}},
448: {XX(List_body), {0, "; "}, {expr, list_body}},
449: {XX(Tab_body), {0, "; "}, {tab_entry, tab_body}},
450: {XX(Tab_entry), {"[", "]: "}, {c_expr, expr}},
451: {XX(E_number), {0}, {number, e_part}},
452:
453: {XX(Com_target), {"(", ")"}, {c_target}},
454: {XX(Col_target), {0, ", "}, {target, c_target}},
455: {XX(Sel_expr), {0, "[", "]"}, {primary, c_expr}},
456:
457: {XX(Text1), {"'", "'"}, {text1}},
458: {XX(Text2), {"\"", "\""}, {text2}},
459: {XX(Grouped), {0, " "}, {group, expr}},
460: {XX(Blocked), {0}, {block, group}},
461: {XX(Operators), {0}, {ops_body}},
462: {XX(Else_kw), {"ELSE"}, {0}},
463: {XX(Kw_plus), {0, " "}, {keyword, kw_next}},
464: {XX(E_plus), {0, " "}, {c_expr, e_next}},
465: {XX(Conversion), {"`", "`"}, {o_c_expr}},
466: {XX(T1), {0}, {t1_body}},
467: {XX(T1_plus), {0}, {t1_conv, t1_next}},
468: {XX(T2), {0}, {t2_body}},
469: {XX(T2_plus), {0}, {t2_conv, t2_next}},
470: {XX(Cmt_cmd), {0, " "}, {simple_cmd, comment}},
471: {0},
472: {XX(F_kw_plus), {0, " "}, {keyword, f_kw_next}},
473: {XX(F_e_plus), {0, " "}, {tag, f_e_next}},
474: {XX(Plus_sign), {"+"}, {0}},
475: {XX(Minus_sign), {"-"}, {0}},
476:
477: {XX(Long_comp), {0, "\t", "\b"}, {c_ifforwhile, suite}},
478: {XX(Short_comp), {0, "\t", "\b"}, {ifforwhile, shortcmd}},
479: {XX(Cmt_comp), {0}, {ifforwhile, comment}},
480:
481: {XX(Long_unit), {0, "\t", "\b"}, {c_head, suite}},
482: {XX(Short_unit), {0, "\t", "\b"}, {head, shortcmd}},
483: {XX(Cmt_head), {0}, {head, comment}},
484:
485: {XX(Ref_join), {0}, {refpred, refinements}},
486:
487: {XX(And_kw), {"AND "}, {and_test}},
488: {XX(Or_kw), {"OR "}, {or_test}},
489:
490: {XX(E_part), {"E"}, {sign, number}},
491:
492: /* Alternate root symbols */
493:
494: {XX(Unit_edit), {0}, {unit_edit}},
495: {XX(Target_edit), {0}, {target_edit}},
496: {XX(Imm_cmd), {0}, {imm_cmd}},
497: {XX(Raw), {0}, {raw_body}},
498: {XX(Raw_input), {0}, {raw_input}},
499: {XX(Edit_unit), {":"}, {ed_unit}},
500: {XX(Edit_target), {"="}, {ed_target}},
501: {XX(Colon), {":"}, {0}},
502: {XX(Equals), {"="}, {0}},
503: {XX(Test_suite), {"\n", ": ", "\t", "\b"},
504: {e_test, o_comment, o_cmdsuite, o_t_suite}},
505: {XX(Expression), {0}, {c_expr}},
506:
507: /* Spare(s); change Optional and Hole in "gram.h" if you run out. */
508:
509: {0}, {0}, {0},
510:
511: /* Next three entries must be the last entries of the table. */
512: /* (See comments in "gram.c", initgram().) */
513:
514: {XX(Suggestion), {0}, {sugg_body}},
515: {XX(Optional), {0}, {0}},
516: {XX(Hole), {"?"}, {0}},
517: };
518:
519: Visible struct table *table= b_grammar;