1 /*
2 * Copyright 1991-1998 by Open Software Foundation, Inc.
3 * All Rights Reserved
4 *
5 * Permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby granted,
7 * provided that the above copyright notice appears in all copies and
8 * that both the copyright notice and this permission notice appear in
9 * supporting documentation.
10 *
11 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
14 *
15 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
16 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
18 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21 /*
22 * cmk1.1
23 */
24 /*
25 * Mach Operating System
26 * Copyright (c) 1991,1990 Carnegie Mellon University
27 * All Rights Reserved.
28 *
29 * Permission to use, copy, modify and distribute this software and its
30 * documentation is hereby granted, provided that both the copyright
31 * notice and this permission notice appear in all copies of the
32 * software, derivative works or modified versions, and any portions
33 * thereof, and that both notices appear in supporting documentation.
34 *
35 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
36 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
37 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
38 *
39 * Carnegie Mellon requests users of this software to return to
40 *
41 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
42 * School of Computer Science
43 * Carnegie Mellon University
44 * Pittsburgh PA 15213-3890
45 *
46 * any improvements or extensions that they make and grant Carnegie the
47 * rights to redistribute these changes.
48 */
49 /*
50 * 91/08/28 11:17:06 jsb
51 * Added ServerDemux.
52 * [91/08/13 rpd]
53 *
54 * Removed Camelot, TrapRoutine support.
55 * Removed obsolete translation and destructor specs.
56 * Replaced MsgKind with MsgSeqno.
57 * [91/08/12 rpd]
58 *
59 * 91/07/31 18:10:00 dbg
60 * Allow 'dealloc[]' to mean user-specified deallocate flag.
61 *
62 * Added c_string.
63 * [91/04/03 dbg]
64 *
65 * 91/02/05 17:55:12 mrt
66 * Changed to new Mach copyright
67 * [91/02/01 17:54:54 mrt]
68 *
69 * 90/06/02 15:05:11 rpd
70 * Created for new IPC.
71 * [90/03/26 21:12:20 rpd]
72 *
73 * 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
74 * Extensive revamping. Added polymorphic arguments.
75 * Allow multiple variable-sized inline arguments in messages.
76 *
77 * 17-Feb-87 Mary Thompson (mrt) at Carnegie Mellon
78 * Simplied syntax for translation and destructor functions.
79 * Also allowed any combination of these functions.
80 *
81 * 16-Nov-87 David Golub (dbg) at Carnegie-Mellon University
82 * Added maximum-size notation for arrays. Added destructor
83 * for server-side.
84 *
85 * 27-May-87 Richard Draves (rpd) at Carnegie-Mellon University
86 * Created.
87 */
88
89 %token sySkip
90 %token syRoutine
91 %token sySimpleRoutine
92
93 %token sySubsystem
94 %token syKernelUser
95 %token syKernelServer
96
97 %token syMsgOption
98 %token syMsgSeqno
99 %token syWaitTime
100 %token sySendTime
101 %token syNoWaitTime
102 %token syNoSendTime
103 %token syErrorProc
104 %token syServerPrefix
105 %token syUserPrefix
106 %token syServerDemux
107 %token syRCSId
108
109 %token syImport
110 %token syUImport
111 %token sySImport
112 %token syIImport
113 %token syDImport
114
115 %token syIn
116 %token syOut
117 %token syInOut
118 %token syUserImpl
119 %token syServerImpl
120 %token syRequestPort
121 %token syReplyPort
122 %token sySReplyPort
123 %token syUReplyPort
124
125 %token syType
126 %token syArray
127 %token syStruct
128 %token syOf
129
130 %token syInTran
131 %token syOutTran
132 %token syDestructor
133 %token syCType
134 %token syCUserType
135 %token syUserTypeLimit
136 %token syOnStackLimit
137 %token syCServerType
138 %token syPointerTo
139 %token syPointerToIfNot
140 %token syValueOf
141
142 %token syCString
143 %token sySecToken
144 %token syUserSecToken
145 %token syServerSecToken
146 %token syAuditToken
147 %token syUserAuditToken
148 %token syServerAuditToken
149 %token syServerContextToken
150
151 %token syColon
152 %token sySemi
153 %token syComma
154 %token syPlus
155 %token syMinus
156 %token syStar
157 %token syDiv
158 %token syLParen
159 %token syRParen
160 %token syEqual
161 %token syCaret
162 %token syTilde
163 %token syLAngle
164 %token syRAngle
165 %token syLBrack
166 %token syRBrack
167 %token syBar
168
169 %token syError /* lex error */
170
171 %token <number> syNumber
172 %token <symtype> sySymbolicType
173 %token <identifier> syIdentifier
174 %token <string> syString syQString
175 %token <string> syFileName
176 %token <flag> syIPCFlag
177
178 %left syPlus syMinus
179 %left syStar syDiv
180
181
182 %type <statement_kind> ImportIndicant
183 %type <number> VarArrayHead ArrayHead StructHead IntExp
184 %type <type> NamedTypeSpec TransTypeSpec NativeTypeSpec TypeSpec
185 %type <type> CStringSpec
186 %type <type> BasicTypeSpec PrevTypeSpec ArgumentType
187 %type <identifier> TypePhrase
188 %type <symtype> PrimIPCType IPCType
189 %type <routine> RoutineDecl Routine SimpleRoutine
190 %type <direction> Direction TrImplKeyword
191 %type <argument> Argument Trailer Arguments ArgumentList
192 %type <flag> IPCFlags
193
194 %{
195
196 #include <stdio.h>
197 #include "lexxer.h"
198 #include "strdefs.h"
199 #include "type.h"
200 #include "routine.h"
201 #include "statement.h"
202 #include "global.h"
203 #include "error.h"
204
205 static const char *import_name(statement_kind_t);
206 int yylex(void);
207 extern int yydebug;
208 extern int yynerrs;
209 extern int yyerrflag;
210 extern int yychar;
211 union migyys;
212 extern union migyys yyval;
213 extern union migyys yylval;
214 %}
215
216 %union migyys
217 {
218 u_int number;
219 identifier_t identifier;
220 string_t string;
221 statement_kind_t statement_kind;
222 ipc_type_t *type;
223 struct
224 {
225 u_int innumber; /* msgt_name value, when sending */
226 string_t instr;
227 u_int outnumber; /* msgt_name value, when receiving */
228 string_t outstr;
229 u_int size; /* 0 means there is no default size */
230 } symtype;
231 routine_t *routine;
232 arg_kind_t direction;
233 argument_t *argument;
234 ipc_flags_t flag;
235 }
236
237 %%
238
239 Statements : /* empty */
240 | Statements Statement
241 ;
242
243 Statement : Subsystem sySemi
244 | WaitTime sySemi
245 | SendTime sySemi
246 | MsgOption sySemi
247 | UserTypeLimit sySemi
248 | OnStackLimit sySemi
249 | Error sySemi
250 | ServerPrefix sySemi
251 | UserPrefix sySemi
252 | ServerDemux sySemi
253 | TypeDecl sySemi
254 | RoutineDecl sySemi
255 {
256 register statement_t *st = stAlloc();
257
258 st->stKind = skRoutine;
259 st->stRoutine = $1;
260 rtCheckRoutine($1);
261 if (BeVerbose)
262 rtPrintRoutine($1);
263 }
264 | sySkip sySemi
265 { rtSkip(); }
266 | Import sySemi
267 | RCSDecl sySemi
268 | sySemi
269 | error sySemi
270 { yyerrok; }
271 ;
272
273 Subsystem : SubsystemStart SubsystemMods
274 SubsystemName SubsystemBase
275 {
276 if (BeVerbose)
277 {
278 printf("Subsystem %s: base = %u%s%s\n\n",
279 SubsystemName, SubsystemBase,
280 IsKernelUser ? ", KernelUser" : "",
281 IsKernelServer ? ", KernelServer" : "");
282 }
283 }
284 ;
285
286 SubsystemStart : sySubsystem
287 {
288 if (SubsystemName != strNULL)
289 {
290 warn("previous Subsystem decl (of %s) will be ignored", SubsystemName);
291 IsKernelUser = FALSE;
292 IsKernelServer = FALSE;
293 strfree(__DECONST(char *, SubsystemName));
294 }
295 }
296 ;
297
298 SubsystemMods : /* empty */
299 | SubsystemMods SubsystemMod
300 ;
301
302 SubsystemMod : syKernelUser
303 {
304 if (IsKernelUser)
305 warn("duplicate KernelUser keyword");
306 if (!UseMsgRPC)
307 {
308 warn("with KernelUser the -R option is meaningless");
309 UseMsgRPC = TRUE;
310 }
311 IsKernelUser = TRUE;
312 }
313 | syKernelServer
314 {
315 if (IsKernelServer)
316 warn("duplicate KernelServer keyword");
317 IsKernelServer = TRUE;
318 }
319 ;
320
321 SubsystemName : syIdentifier { SubsystemName = $1; }
322 ;
323
324 SubsystemBase : syNumber { SubsystemBase = $1; }
325 ;
326
327 MsgOption : LookString syMsgOption syString
328 {
329 if (streql($3, "MACH_MSG_OPTION_NONE"))
330 {
331 MsgOption = strNULL;
332 if (BeVerbose)
333 printf("MsgOption: canceled\n\n");
334 }
335 else
336 {
337 MsgOption = $3;
338 if (BeVerbose)
339 printf("MsgOption %s\n\n",$3);
340 }
341 }
342 ;
343
344 UserTypeLimit : syUserTypeLimit syNumber
345 {UserTypeLimit = $2; }
346 ;
347 OnStackLimit : syOnStackLimit syNumber
348 {MaxMessSizeOnStack = $2; }
349 ;
350
351 WaitTime : LookString syWaitTime syString
352 {
353 WaitTime = $3;
354 if (BeVerbose)
355 printf("WaitTime %s\n\n", WaitTime);
356 }
357 | syNoWaitTime
358 {
359 WaitTime = strNULL;
360 if (BeVerbose)
361 printf("NoWaitTime\n\n");
362 }
363 ;
364
365 SendTime : LookString sySendTime syString
366 {
367 SendTime = $3;
368 if (BeVerbose)
369 printf("SendTime %s\n\n", SendTime);
370 }
371 | syNoSendTime
372 {
373 SendTime = strNULL;
374 if (BeVerbose)
375 printf("NoSendTime\n\n");
376 }
377 ;
378
379 Error : syErrorProc syIdentifier
380 {
381 ErrorProc = $2;
382 if (BeVerbose)
383 printf("ErrorProc %s\n\n", ErrorProc);
384 }
385 ;
386
387 ServerPrefix : syServerPrefix syIdentifier
388 {
389 ServerPrefix = $2;
390 if (BeVerbose)
391 printf("ServerPrefix %s\n\n", ServerPrefix);
392 }
393 ;
394
395 UserPrefix : syUserPrefix syIdentifier
396 {
397 UserPrefix = $2;
398 if (BeVerbose)
399 printf("UserPrefix %s\n\n", UserPrefix);
400 }
401 ;
402
403 ServerDemux : syServerDemux syIdentifier
404 {
405 ServerDemux = $2;
406 if (BeVerbose)
407 printf("ServerDemux %s\n\n", ServerDemux);
408 }
409 ;
410
411 Import : LookFileName ImportIndicant syFileName
412 {
413 register statement_t *st = stAlloc();
414 st->stKind = $2;
415 st->stFileName = $3;
416
417 if (BeVerbose)
418 printf("%s %s\n\n", import_name($2), $3);
419 }
420 ;
421
422 ImportIndicant : syImport { $$ = skImport; }
423 | syUImport { $$ = skUImport; }
424 | sySImport { $$ = skSImport; }
425 | syIImport { $$ = skIImport; }
426 | syDImport { $$ = skDImport; }
427 ;
428
429 RCSDecl : LookQString syRCSId syQString
430 {
431 if (RCSId != strNULL)
432 warn("previous RCS decl will be ignored");
433 if (BeVerbose)
434 printf("RCSId %s\n\n", $3);
435 RCSId = $3;
436 }
437 ;
438
439 TypeDecl : syType NamedTypeSpec
440 {
441 register identifier_t name = $2->itName;
442
443 if (itLookUp(name) != itNULL)
444 warn("overriding previous definition of %s", name);
445 itInsert(name, $2);
446 }
447 ;
448
449 NamedTypeSpec : syIdentifier syEqual TransTypeSpec
450 { itTypeDecl($1, $$ = $3); }
451 ;
452
453 TransTypeSpec : TypeSpec
454 { $$ = itResetType($1); }
455 | TransTypeSpec syInTran syColon syIdentifier
456 syIdentifier syLParen syIdentifier syRParen
457 {
458 $$ = $1;
459
460 if (($$->itTransType != strNULL) && !streql($$->itTransType, $4))
461 warn("conflicting translation types (%s, %s)",
462 $$->itTransType, $4);
463 $$->itTransType = $4;
464
465 if (($$->itInTrans != strNULL) && !streql($$->itInTrans, $5))
466 warn("conflicting in-translation functions (%s, %s)",
467 $$->itInTrans, $5);
468 $$->itInTrans = $5;
469
470 if (($$->itServerType != strNULL) && !streql($$->itServerType, $7))
471 warn("conflicting server types (%s, %s)",
472 $$->itServerType, $7);
473 $$->itServerType = $7;
474 }
475 | TransTypeSpec syOutTran syColon syIdentifier
476 syIdentifier syLParen syIdentifier syRParen
477 {
478 $$ = $1;
479
480 if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
481 warn("conflicting server types (%s, %s)",
482 $$->itServerType, $4);
483 $$->itServerType = $4;
484
485 if (($$->itOutTrans != strNULL) && !streql($$->itOutTrans, $5))
486 warn("conflicting out-translation functions (%s, %s)",
487 $$->itOutTrans, $5);
488 $$->itOutTrans = $5;
489
490 if (($$->itTransType != strNULL) && !streql($$->itTransType, $7))
491 warn("conflicting translation types (%s, %s)",
492 $$->itTransType, $7);
493 $$->itTransType = $7;
494 }
495 | TransTypeSpec syDestructor syColon syIdentifier
496 syLParen syIdentifier syRParen
497 {
498 $$ = $1;
499
500 if (($$->itDestructor != strNULL) && !streql($$->itDestructor, $4))
501 warn("conflicting destructor functions (%s, %s)",
502 $$->itDestructor, $4);
503 $$->itDestructor = $4;
504
505 if (($$->itTransType != strNULL) && !streql($$->itTransType, $6))
506 warn("conflicting translation types (%s, %s)",
507 $$->itTransType, $6);
508 $$->itTransType = $6;
509 }
510 | TransTypeSpec syCType syColon syIdentifier
511 {
512 $$ = $1;
513
514 if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
515 warn("conflicting user types (%s, %s)",
516 $$->itUserType, $4);
517 $$->itUserType = $4;
518
519 if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
520 warn("conflicting server types (%s, %s)",
521 $$->itServerType, $4);
522 $$->itServerType = $4;
523 }
524 | TransTypeSpec syCUserType syColon syIdentifier
525 {
526 $$ = $1;
527
528 if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
529 warn("conflicting user types (%s, %s)",
530 $$->itUserType, $4);
531 $$->itUserType = $4;
532 }
533 | TransTypeSpec syCServerType
534 syColon syIdentifier
535 {
536 $$ = $1;
537
538 if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
539 warn("conflicting server types (%s, %s)",
540 $$->itServerType, $4);
541 $$->itServerType = $4;
542 }
543 ;
544
545 TypeSpec : BasicTypeSpec
546 { $$ = $1; }
547 | PrevTypeSpec
548 { $$ = $1; }
549 | VarArrayHead TypeSpec
550 { $$ = itVarArrayDecl($1, $2); }
551 | ArrayHead TypeSpec
552 { $$ = itArrayDecl($1, $2); }
553 | syCaret TypeSpec
554 { $$ = itPtrDecl($2); }
555 | StructHead TypeSpec
556 { $$ = itStructDecl($1, $2); }
557 | CStringSpec
558 { $$ = $1; }
559 | NativeTypeSpec
560 { $$ = $1; }
561 ;
562
563 NativeTypeSpec : syPointerTo syLParen TypePhrase syRParen
564 { $$ = itNativeType($3, TRUE, 0); }
565 | syPointerToIfNot syLParen TypePhrase syComma
566 TypePhrase syRParen
567 { $$ = itNativeType($3, TRUE, $5); }
568 | syValueOf syLParen TypePhrase syRParen
569 { $$ = itNativeType($3, FALSE, 0); }
570 ;
571
572 BasicTypeSpec : IPCType
573 {
574 $$ = itShortDecl($1.innumber, $1.instr,
575 $1.outnumber, $1.outstr,
576 $1.size);
577 }
578 | syLParen IPCType syComma IntExp
579 IPCFlags syRParen
580 {
581 error("Long form type declarations aren't allowed anylonger\n");
582 }
583 ;
584
585 PrimIPCType : syNumber
586 {
587 $$.innumber = $$.outnumber = $1;
588 $$.instr = $$.outstr = strNULL;
589 $$.size = 0;
590 }
591 | sySymbolicType
592 { $$ = $1; }
593 ;
594
595 IPCType : PrimIPCType
596 { $$ = $1; }
597 | PrimIPCType syBar PrimIPCType
598 {
599 if ($1.size != $3.size)
600 {
601 if ($1.size == 0)
602 $$.size = $3.size;
603 else if ($3.size == 0)
604 $$.size = $1.size;
605 else
606 {
607 error("sizes in IPCTypes (%d, %d) aren't equal",
608 $1.size, $3.size);
609 $$.size = 0;
610 }
611 }
612 else
613 $$.size = $1.size;
614 $$.innumber = $1.innumber;
615 $$.instr = $1.instr;
616 $$.outnumber = $3.outnumber;
617 $$.outstr = $3.outstr;
618 }
619 ;
620
621 PrevTypeSpec : syIdentifier
622 { $$ = itPrevDecl($1); }
623 ;
624
625 VarArrayHead : syArray syLBrack syRBrack syOf
626 { $$ = 0; }
627 | syArray syLBrack syStar syRBrack syOf
628 { $$ = 0; }
629 | syArray syLBrack syStar syColon IntExp
630 syRBrack syOf
631 { $$ = $5; }
632 ;
633
634 ArrayHead : syArray syLBrack IntExp syRBrack syOf
635 { $$ = $3; }
636 ;
637
638 StructHead : syStruct syLBrack IntExp syRBrack syOf
639 { $$ = $3; }
640 ;
641
642 CStringSpec : syCString syLBrack IntExp syRBrack
643 { $$ = itCStringDecl($3, FALSE); }
644 | syCString syLBrack syStar syColon
645 IntExp syRBrack
646 { $$ = itCStringDecl($5, TRUE); }
647 ;
648
649 TypePhrase : syIdentifier
650 { $$ = $1; }
651 | TypePhrase syIdentifier
652 { $$ = strphrase($1, $2); strfree($2); }
653 ;
654
655 IntExp : IntExp syPlus IntExp
656 { $$ = $1 + $3; }
657 | IntExp syMinus IntExp
658 { $$ = $1 - $3; }
659 | IntExp syStar IntExp
660 { $$ = $1 * $3; }
661 | IntExp syDiv IntExp
662 { $$ = $1 / $3; }
663 | syNumber
664 { $$ = $1; }
665 | syLParen IntExp syRParen
666 { $$ = $2; }
667 ;
668
669
670 RoutineDecl : Routine { $$ = $1; }
671 | SimpleRoutine { $$ = $1; }
672 ;
673
674 Routine : syRoutine syIdentifier Arguments
675 { $$ = rtMakeRoutine($2, $3); }
676 ;
677
678 SimpleRoutine : sySimpleRoutine syIdentifier Arguments
679 { $$ = rtMakeSimpleRoutine($2, $3); }
680 ;
681
682 Arguments : syLParen syRParen
683 { $$ = argNULL; }
684 | syLParen ArgumentList syRParen
685 { $$ = $2; }
686
687 ;
688
689 ArgumentList : Argument
690 { $$ = $1; }
691 | Trailer
692 { $$ = $1; }
693 | Argument sySemi ArgumentList
694 {
695 $$ = $1;
696 $$->argNext = $3;
697 }
698 | Trailer sySemi ArgumentList
699 {
700 $$ = $1;
701 $$->argNext = $3;
702 }
703 ;
704
705 Argument : Direction syIdentifier ArgumentType IPCFlags
706 {
707 $$ = argAlloc();
708 $$->argKind = $1;
709 $$->argName = $2;
710 $$->argType = $3;
711 $$->argFlags = $4;
712 if ($3 && $3->itNative) {
713 if ($1 != akIn && $1 != akOut && $1 != akInOut)
714 error("Illegal direction specified");
715
716 if (!($3->itNativePointer) && $1 != akIn)
717 error("ValueOf only valid for in");
718
719 if (($3->itBadValue) != NULL && $1 != akIn)
720 error("PointerToIfNot only valid for in");
721 }
722 }
723 ;
724
725 Trailer : TrImplKeyword syIdentifier ArgumentType
726 {
727 $$ = argAlloc();
728 $$->argKind = $1;
729 $$->argName = $2;
730 $$->argType = $3;
731 }
732 ;
733
734
735 Direction : /* empty */ { $$ = akNone; }
736 | syIn { $$ = akIn; }
737 | syOut { $$ = akOut; }
738 | syInOut { $$ = akInOut; }
739 | syRequestPort { $$ = akRequestPort; }
740 | syReplyPort { $$ = akReplyPort; }
741 | sySReplyPort { $$ = akSReplyPort; }
742 | syUReplyPort { $$ = akUReplyPort; }
743 | syWaitTime { $$ = akWaitTime; }
744 | sySendTime { $$ = akSendTime; }
745 | syMsgOption { $$ = akMsgOption; }
746 | sySecToken { $$ = akSecToken; }
747 | syServerSecToken { $$ = akServerSecToken; }
748 | syUserSecToken { $$ = akUserSecToken; }
749 | syAuditToken { $$ = akAuditToken; }
750 | syServerAuditToken { $$ = akServerAuditToken; }
751 | syUserAuditToken { $$ = akUserAuditToken; }
752 | syServerContextToken { $$ = akServerContextToken; }
753 | syMsgSeqno { $$ = akMsgSeqno; }
754 ;
755
756 TrImplKeyword : syServerImpl { $$ = akServerImpl; }
757 | syUserImpl { $$ = akUserImpl; }
758 ;
759
760
761 ArgumentType : syColon syIdentifier
762 {
763 $$ = itLookUp($2);
764 if ($$ == itNULL)
765 error("type '%s' not defined", $2);
766 }
767 | syColon NamedTypeSpec
768 { $$ = $2; }
769 | syColon NativeTypeSpec
770 { $$ = $2; }
771 ;
772
773 IPCFlags : /* empty */
774 { $$ = flNone; }
775 | IPCFlags syComma syIPCFlag
776 {
777 if ($1 & $3)
778 warn("redundant IPC flag ignored");
779 else
780 $$ = $1 | $3;
781 }
782 | IPCFlags syComma syIPCFlag syLBrack syRBrack
783 {
784 if ($3 != flDealloc)
785 warn("only Dealloc is variable");
786 else
787 $$ = $1 | flMaybeDealloc;
788 }
789
790 LookString : /* empty */
791 { LookString(); }
792 ;
793
794 LookFileName : /* empty */
795 { LookFileName(); }
796 ;
797
798 LookQString : /* empty */
799 { LookQString(); }
800 ;
801
802 %%
803
804 void yyerror(const char *s);
805
806 void
yyerror(const char * s)807 yyerror(const char *s)
808 {
809 error(s);
810 }
811
812 static const char *
import_name(statement_kind_t sk)813 import_name(statement_kind_t sk)
814 {
815 switch (sk)
816 {
817 case skImport:
818 return "Import";
819 case skSImport:
820 return "SImport";
821 case skUImport:
822 return "UImport";
823 case skIImport:
824 return "IImport";
825 case skDImport:
826 return "DImport";
827 default:
828 fatal("import_name(%d): not import statement", (int) sk);
829 /*NOTREACHED*/
830 return strNULL;
831 }
832 }
833