|
|
1.1 root 1: %{
2: #ifndef lint
3: static char RCSid[] = "$Header: courier.y,v 2.2 86/06/06 07:28:39 jqj Exp $";
4: #endif
5:
6: /* $Log: courier.y,v $
7: * Revision 2.2 86/06/06 07:28:39 jqj
8: * many mods for better symbol table management: added CurrentModule,
9: * made check_dependency, make_symbol, check_def set/use/use a symbol
10: * table instead of a module name string, etc. Result is that we can
11: * now handle DEPENDS UPON 2 versions of same program.
12: *
13: * Revision 2.1 86/05/16 05:46:50 jqj
14: * make enumeration tags local to modules rather than global, to allow
15: * DEPENDS UPON two versions of the same program. For same reason, use
16: * gensymed symbol names that include version number.
17: *
18: * Revision 2.0 85/11/21 07:21:35 jqj
19: * 4.3BSD standard release
20: *
21: * Revision 1.1 85/11/20 12:58:22 jqj
22: * Initial revision
23: *
24: * Revision 1.6 85/05/23 06:19:42 jqj
25: * Public Beta-test version, released 24 May 1985
26: *
27: * Revision 1.5 85/05/06 08:13:14 jqj
28: * Almost Beta-test version.
29: *
30: * Revision 1.4 85/03/26 06:09:49 jqj
31: * Revised public alpha-test version, released 26 March 1985
32: *
33: * Revision 1.3 85/03/11 16:39:15 jqj
34: * Public alpha-test version, released 11 March 1985
35: *
36: * Revision 1.2 85/02/21 11:05:07 jqj
37: * alpha test version
38: *
39: * Revision 1.1 85/02/15 13:53:01 jqj
40: * Initial revision
41: *
42: */
43:
44: #include "compiler.h"
45:
46: static char *currentdecl;
47: static char streamdecl;
48: %}
49:
50: %token
51: identifier number string
52:
53: %token
54: ARRAY _BEGIN BOOLEAN CARDINAL
55: CHOICE DEPENDS END ERROR
56: INTEGER LONG OF PROCEDURE
57: PROGRAM RECORD REPORTS RETURNS
58: SEQUENCE STRING TYPE UNSPECIFIED
59: UPON VERSION TRUE FALSE
60: _CHOOSES
61:
62: %union {
63: struct type *type;
64: struct constant *constant;
65: list list;
66: char *stringvalue;
67: }
68:
69: %type <type>
70: ConstructedType
71: DesignatorType
72: PredefinedType
73: ReferencedType
74: Type
75:
76: %type <constant>
77: ReferencedConstant
78: Constant
79: PredefinedConstant
80: ConstructedConstant
81:
82: %type <list>
83: ArgumentList Candidate CandidateList
84: Correspondence CorrespondenceList Designator
85: DesignatorList ErrorList Field
86: FieldList NameList ResultList
87: Component ReferencedProgramList ElementList
88: ComponentList TypedCandidate TypedCandidateList
89: TypedDesignator TypedDesignatorList CNameList
90:
91: %type <stringvalue>
92: NumericValue MaximumNumber
93: ReferencedProgram ProgramHeader
94: identifier number string
95:
96: %start Program
97: %%
98:
99: Program :
100: ProgramHeader ProgramBody
101: {
102: wrapup_program($1);
103: }
104: ;
105:
106: ProgramHeader :
107: identifier ':' PROGRAM number VERSION number '='
108: {
109: program_header($1,$4,$6);
110: $$ = $1;
111: }
112: ;
113:
114: ProgramBody :
115: _BEGIN DependencyList DeclarationList END '.'
116: ;
117:
118: DependencyList :
119: /* empty */
120: {
121: program_body();
122: }
123: | DEPENDS UPON ReferencedProgramList ';'
124: {
125: program_body();
126: }
127: ;
128:
129: ReferencedProgramList :
130: ReferencedProgram
131: {
132: }
133: | ReferencedProgramList ',' ReferencedProgram
134: {
135: }
136: ;
137:
138: ReferencedProgram :
139: identifier '(' number ')' VERSION number
140: {
141: /* as a side effect, the program is entered into the */
142: /* list of dependencies */
143: ref_program($1,$3,$6);
144: $$ = $1;
145: }
146: ;
147:
148: DeclarationList :
149: /* empty */
150: | DeclarationList Declaration
151: ;
152:
153: Declaration :
154: Target TypeDeclaration
155: | Target ConstantDeclaration
156: | error ';'
157: {
158: fprintf(stderr,"\t\t\tDeclaration skipped\n");
159: }
160: ;
161:
162: Target :
163: identifier ':'
164: {
165: struct object *symbol;
166:
167: currentdecl = $1;
168: streamdecl = 0; /* not parsing a StreamOf yet */
169: if (symbol = check_def(currentdecl, CurrentModule)) {
170: error(ERROR,
171: "Attempt to redefine ``%s''",
172: name_of(symbol));
173: YYERROR;
174: }
175: }
176: ;
177:
178: TypeDeclaration :
179: TYPE '=' Type ';'
180: {
181: struct object *symbol;
182:
183: symbol = make_symbol(currentdecl, CurrentModule);
184: define_type(symbol, $3);
185: }
186: ;
187:
188: ConstantDeclaration :
189: Type '=' Constant ';'
190: {
191: struct object *symbol;
192:
193: symbol = make_symbol(currentdecl, CurrentModule);
194: if (type_check($1, $3)) {
195: define_constant(symbol, $1, $3);
196: } else
197: error(ERROR,
198: "Type clash in declaration of ``%s''",
199: name_of(symbol));
200: }
201: ;
202:
203: Type :
204: PredefinedType
205: {
206: $$ = $1;
207: }
208: | ConstructedType
209: {
210: $$ = $1;
211: }
212: | ReferencedType
213: {
214: $$ = $1;
215: }
216: ;
217:
218: Constant :
219: PredefinedConstant
220: {
221: $$ = $1;
222: }
223: |
224: ConstructedConstant
225: {
226: $$ = $1;
227: }
228: |
229: ReferencedConstant
230: {
231: $$ = $1;
232: }
233: ;
234:
235:
236: PredefinedType :
237: BOOLEAN
238: {
239: $$ = Boolean_type;
240: }
241: | CARDINAL
242: {
243: $$ = Cardinal_type;
244: }
245: | LONG CARDINAL
246: {
247: $$ = LongCardinal_type;
248: }
249: | INTEGER
250: {
251: $$ = Integer_type;
252: }
253: | LONG INTEGER
254: {
255: $$ = LongInteger_type;
256: }
257: | STRING
258: {
259: $$ = String_type;
260: }
261: | UNSPECIFIED
262: {
263: $$ = Unspecified_type;
264: }
265: | LONG UNSPECIFIED
266: {
267: $$ = LongUnspecified_type;
268: }
269: ;
270:
271: PredefinedConstant :
272: TRUE
273: {
274: $$ = Boolean_constant("1");
275: }
276: |
277: FALSE
278: {
279: $$ = Boolean_constant("0");
280: }
281: |
282: number
283: {
284: $$ = Numeric_constant($1);
285: }
286: |
287: string
288: {
289: $$ = String_constant($1);
290: }
291: ;
292:
293: ConstructedConstant :
294: /* simple ReferencedConstant */
295: identifier
296: {
297: struct object *sym;
298:
299: if ((sym = check_def($1,ONIL)) ||
300: (sym = check_def($1,CurrentModule))) {
301: if (class_of(sym) == O_ENUMTAG)
302: $$ = enumeration_constant(sym->o_enum->en_name);
303: else if (class_of(sym) == O_CONSTANT)
304: $$ = sym->o_constant;
305: else {
306: error(ERROR,
307: "``%s'' is not of appropriate type",
308: name_of(sym));
309: YYERROR;
310: }
311: } else {
312: error(ERROR,"``%s'' is not defined",
313: $1);
314: YYERROR;
315: }
316: }
317: |
318: /* SequenceConstant */
319: /* ArrayConstant */
320: '[' ElementList ']'
321: {
322: $$ = array_constant($2);
323: }
324: |
325: /* RecordConstant */
326: '[' ComponentList ']'
327: {
328: $$ = record_constant($2);
329: }
330: |
331: /* RecordConstant */
332: /* SequenceConstant */
333: /* ArrayConstant */
334: '[' ']'
335: {
336: $$ = record_constant(NIL);
337: }
338: |
339: /* ChoiceConstant */
340: identifier Constant
341: {
342: struct object* symbol;
343:
344: if (((symbol = check_def($1,CurrentModule)) ||
345: (symbol = check_def($1,ONIL)))) {
346: if (class_of(symbol) == O_CONSTANT &&
347: symbol->o_constant->cn_constr == C_ENUMERATION) {
348: $$ = choice_constant(
349: cons((list) symbol->o_constant->cn_value,
350: (list) $2) );
351: }
352: else if (class_of(symbol) == O_ENUMTAG) {
353: $$ = choice_constant(
354: cons((list) symbol->o_enum->en_name,
355: (list) $2) );
356: }
357: else {
358: error(ERROR, "Expected enumeration constant but got ``%s''\n",
359: name_of(symbol));
360: YYERROR;
361: }
362: }
363: else {
364: error(ERROR, "Designator ``%s'' undefined\n",
365: $1);
366: YYERROR;
367: }
368: }
369: ;
370:
371:
372: ElementList :
373: Constant
374: {
375: $$ = cons((list) $1, NIL);
376:
377: }
378: |
379: Constant ',' ElementList
380: {
381: $$ = cons((list)$1, $3);
382: }
383: ;
384:
385: ComponentList :
386: Component
387: {
388: $$ = $1;
389: }
390: |
391: Component ',' ComponentList
392: {
393: /* flatten */
394: cdr($1) = $3;
395: $$ = $1;
396: }
397: ;
398:
399: Component :
400: CNameList ':' Constant
401: {
402: list p;
403:
404: /* flatten this for simplicity of representation */
405: for (p = $1; p != NIL; p = cdr(p))
406: car(p) = cons(car(p),(list)$3);
407: $$ = $1;
408: }
409: ;
410:
411: CNameList :
412: identifier
413: {
414: /* note that CNameList now is a list of strings */
415: $$ = cons((list) $1, NIL);
416: }
417: | identifier ',' CNameList
418: {
419: /* note that NameList now is a list of strings */
420: $$ = cons(cons((list)$1, NIL), $3);
421: }
422: ;
423:
424: ConstructedType :
425: '{' CorrespondenceList '}'
426: {
427: $$ = enumeration_type($2);
428: }
429: | ARRAY NumericValue OF Type
430: {
431: $$ = array_type($2, $4);
432: }
433: | SEQUENCE MaximumNumber OF Type
434: {
435: $$ = sequence_type($2, $4);
436: }
437: | RECORD ArgumentList
438: {
439: $$ = record_type($2);
440: }
441: | CHOICE DesignatorType OF '{' TypedCandidateList '}'
442: {
443: $$ = choice_type($2, $5);
444: }
445: | CHOICE OF '{' CandidateList '}'
446: {
447: if (streamdecl > 0) {
448: $$ = choice_type(StreamEnum_type, $4);
449: }
450: /* as side effect build an anonymous enumerated type */
451: else
452: $$ = choice_type((struct type *) NIL, $4);
453: }
454: | PROCEDURE ArgumentList ResultList ErrorList
455: {
456: $$ = procedure_type($2, $3, $4);
457: }
458: | ERROR ArgumentList
459: {
460: $$ = error_type( $2);
461: }
462: ;
463:
464: ReferencedType :
465: identifier
466: {
467: struct object *symbol;
468:
469: if (symbol = check_def($1,CurrentModule)) {
470: if (class_of(symbol) == O_TYPE)
471: $$ = symbol->o_type;
472: else {
473: error(ERROR,"``%s'' is not a type",
474: name_of(symbol));
475: YYERROR;
476: }
477: }
478: else if (streq($1,currentdecl)) {
479: if (strncmp(currentdecl,"StreamOf",8) == 0) {
480: streamdecl++;
481: error(WARNING,
482: "Stream definition of ``%s'';\n\
483: \t\t\trecursion treated as Nil record",
484: $1);
485: $$ = record_type(NIL);
486: } else {
487: /* fake it */
488: $$ = enumeration_type(NIL);
489: $$->type_name = make_full_name(
490: CurrentProgram, CurrentVersion,
491: currentdecl);
492: }
493: }
494: else {
495: error(ERROR,"``%s'' is unrecognized", $1);
496: YYERROR;
497: }
498: }
499: | identifier '.' identifier
500: {
501: struct object *symbol, *module;
502:
503: if ((module=check_dependency($1)) &&
504: (symbol = check_def($3,module))) {
505: if (class_of(symbol) == O_TYPE)
506: $$ = symbol->o_type;
507: else {
508: error(ERROR,"``%s'' is not a type",
509: name_of(symbol));
510: YYERROR;
511: }
512: }
513: else {
514: error(ERROR,"``%s.%s'' is unrecognized",$1,$3);
515: YYERROR;
516: }
517: }
518: ;
519:
520: CorrespondenceList :
521: Correspondence
522: {
523: $$ = cons($1, NIL);
524: }
525: | CorrespondenceList ',' Correspondence
526: {
527: $$ = nconc($1, cons($3, NIL));
528: }
529: ;
530:
531: Correspondence :
532: identifier '(' NumericValue ')'
533: {
534: struct object *symbol;
535: char *newid;
536:
537: if (!(symbol = check_def($1,ONIL)) &&
538: !(symbol = check_def($1,CurrentModule))) {
539: symbol = make_symbol($1,CurrentModule);
540: define_enumeration_symbol(symbol,$3);
541: }
542: else if (class_of(symbol) != O_ENUMTAG) {
543: error(ERROR,"``%s'' already defined",
544: name_of(symbol));
545: YYERROR;
546: }
547: else if ((streq($1,"nextSegment") &&
548: stringtocard($3) == 0) ||
549: (streq($1,"lastSegment") &&
550: stringtocard($3) == 1)) {
551: /* do nothing */
552: streamdecl++;
553: }
554: else /*
555: * if (symbol->o_enum->en_value!=stringtocard($3))
556: */ {
557: newid = gensym($1);
558: error(WARNING,
559: "Enumerator ``%s'' already declared;\n\
560: \t\t\tusing name ``%s'' instead",
561: $1,newid);
562: symbol = make_symbol(newid,CurrentModule);
563: define_enumeration_symbol(symbol,$3);
564: }
565: $$ = cons((list) symbol, (list) $3);
566: }
567: ;
568:
569: MaximumNumber :
570: NumericValue
571: {
572: $$ = $1;
573: }
574: | /* empty */
575: {
576: $$ = "65535"; /* maximum Cardinal */
577: }
578: ;
579:
580: NumericValue :
581: number
582: {
583: $$ = $1;
584: }
585: | ReferencedConstant
586: {
587: if (($1)->cn_constr != C_NUMERIC) {
588: error(ERROR,"Expected numeric constant");
589: YYERROR;
590: }
591: $$ = ($1)->cn_value;
592: }
593: ;
594:
595: DesignatorType :
596: ReferencedType
597: {
598: $$ = $1;
599: }
600: ;
601:
602: TypedCandidateList :
603: TypedCandidate
604: {
605: $$ = cons($1, NIL);
606: }
607: | TypedCandidateList ',' TypedCandidate
608: {
609: $$ = nconc($1, cons($3, NIL));
610: }
611: ;
612:
613: TypedCandidate :
614: TypedDesignatorList _CHOOSES Type
615: {
616: $$ = cons($1, (list) $3);
617: }
618: ;
619:
620: TypedDesignatorList :
621: TypedDesignator
622: {
623: $$ = cons($1, NIL);
624: }
625: | TypedDesignatorList ',' TypedDesignator
626: {
627: $$ = nconc($1, cons($3, NIL));
628: }
629: ;
630:
631: TypedDesignator :
632: identifier
633: {
634: struct object *symbol;
635:
636: if ((symbol = check_def($1,CurrentModule)) &&
637: symbol->o_constant->cn_constr == C_ENUMERATION) {
638: $1 = symbol->o_constant->cn_value;
639: }
640: else if (((symbol = check_def($1,ONIL)) ||
641: (symbol = check_def($1,CurrentModule))) &&
642: class_of(symbol) == O_ENUMTAG)
643: $$ = cons((list) symbol, NIL);
644: else {
645: error(ERROR,"Designator ``%s'' is not of appropriate type",
646: $1);
647: YYERROR;
648: }
649: }
650: ;
651:
652: CandidateList :
653: Candidate
654: {
655: $$ = cons($1, NIL);
656: }
657: | CandidateList ',' Candidate
658: {
659: $$ = nconc($1, cons($3, NIL));
660: }
661: ;
662:
663: Candidate :
664: DesignatorList _CHOOSES Type
665: {
666: $$ = cons($1, (list) $3);
667: }
668: ;
669:
670: DesignatorList :
671: Designator
672: {
673: $$ = cons($1, NIL);
674: }
675: | DesignatorList ',' Designator
676: {
677: $$ = nconc($1, cons($3, NIL));
678: }
679: ;
680:
681: Designator :
682: Correspondence
683: {
684: $$ = $1;
685: }
686: ;
687:
688: ResultList :
689: /* empty */
690: {
691: $$ = NIL;
692: }
693: | RETURNS '[' FieldList ']'
694: {
695: $$ = $3;
696: }
697: ;
698:
699: ArgumentList :
700: /* empty */
701: {
702: $$ = NIL;
703: }
704: | '[' ']'
705: {
706: $$ = NIL;
707: }
708: | '[' FieldList ']'
709: {
710: $$ = $2;
711: }
712: ;
713:
714: ErrorList :
715: /* empty */
716: {
717: $$ = NIL;
718: }
719: | REPORTS '[' NameList ']'
720: {
721: $$ = $3;
722: }
723: ;
724:
725: FieldList :
726: Field
727: {
728: $$ = $1;
729: }
730: | FieldList ',' Field
731: {
732: $$ = nconc($1, $3);
733: }
734: ;
735:
736: Field :
737: NameList ':' Type
738: {
739: /* flatten representation for simplicity */
740: /* note that this could be even simpler, but I */
741: /* don't have the patience to change code everywhere */
742: list p;
743:
744: for (p = $1; p != NIL; p = cdr(p))
745: car(p) = cons(cons(car(p),NIL),(list)$3);
746: $$ = $1;
747: }
748: ;
749:
750: ReferencedConstant :
751: /* see ConstructedConstant for simple referenced constants */
752: identifier '.' identifier
753: {
754: struct object *symbol, *module;
755:
756: if ((module=check_dependency($1)) &&
757: (symbol=check_def($3,module))) {
758: if (class_of(symbol) != O_CONSTANT) {
759: error(ERROR,"Constant expected, but got ``%s''",
760: name_of(symbol));
761: YYERROR;
762: }
763: $$ = symbol->o_constant;
764: } else {
765: error(ERROR,"Unrecognized symbol ``%s.%s''",
766: $1,$3);
767: }
768: }
769: ;
770:
771: NameList :
772: identifier
773: {
774: /* note that NameList now is a list of strings */
775: $$ = cons((list) $1, NIL);
776: }
777: | NameList ',' identifier
778: {
779: /* note that NameList now is a list of strings */
780: $$ = nconc($1, cons((list) $3, NIL));
781: }
782: ;
783:
784:
785: %%
786:
787: YYSTYPE yyv[];
788: int yynerrs;
789: extern int yylineno;
790:
791: struct parser_state {
792: YYSTYPE yyv[YYMAXDEPTH];
793: YYSTYPE yylval;
794: YYSTYPE yyval;
795: int yychar;
796: int yynerrs;
797: short yyerrflag;
798: int yylineno;
799: int recursive_flag;
800: char *CurrentProgram;
801: int CurrentVersion;
802: int CurrentNumber;
803: struct object *CurrentModule;
804: char yysbuf[200]; /*YYLMAX*/
805: char *yysptr;
806: };
807: extern char yysbuf[], *yysptr;
808:
809: int *
810: save_parser_state()
811: {
812: struct parser_state *p;
813:
814: p = New(struct parser_state);
815: bcopy(yyv, p->yyv, YYMAXDEPTH*sizeof(YYSTYPE));
816: p->yylval = yylval;
817: p->yyval = yyval;
818: p->yychar = yychar;
819: p->yynerrs = yynerrs;
820: p->yyerrflag = yyerrflag;
821: p->yylineno = yylineno;
822: p->recursive_flag = recursive_flag;
823: p->CurrentProgram = CurrentProgram;
824: p->CurrentVersion = CurrentVersion;
825: p->CurrentNumber = CurrentNumber;
826: p->CurrentModule = CurrentModule;
827: p->yysptr = yysptr;
828: bcopy(yysbuf, p->yysbuf, 200);
829: yysptr = yysbuf;
830: recursive_flag = 1;
831: return ((int*) p);
832: }
833:
834: restore_parser_state(p)
835: struct parser_state *p;
836: {
837: yysptr = p->yysptr;
838: bcopy(p->yysbuf, yysbuf, 200);
839: CurrentProgram = p->CurrentProgram;
840: CurrentVersion = p->CurrentVersion;
841: CurrentNumber = p->CurrentNumber;
842: CurrentModule = p->CurrentModule;
843: recursive_flag = p->recursive_flag;
844: yylineno = p->yylineno;
845: yyerrflag = p->yyerrflag;
846: yynerrs = p->yynerrs;
847: yychar = p->yychar;
848: yyval = p->yyval;
849: yylval = p->yylval;
850: bcopy(p->yyv, yyv, YYMAXDEPTH*sizeof(YYSTYPE));
851: free((char *) p);
852: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.