http://gimel.esc.cam.ac.uk/james/rpld/src/rpld-1.2.tar.gz
[rpld.git] / rpld_conf.tab.c
1 #ifndef lint
2 static char yysccsid[] = "@(#)yaccpar   1.9 (Berkeley) 02/21/93";
3 #endif
4 #define YYBYACC 1
5 #define YYMAJOR 1
6 #define YYMINOR 9
7 #define yyclearin (yychar=(-1))
8 #define yyerrok (yyerrflag=0)
9 #define YYRECOVERING (yyerrflag!=0)
10 #define YYPREFIX "yy"
11 #line 65 "rpld_conf.y"
12
13 static char rcsid[]="$Id: rpld_conf.y,v 1.3 2000/07/16 13:18:10 root Exp root $";
14
15 #include "project.h"
16
17 /* state machine stuff*/
18
19 typedef enum {START, BLOCK_START, BLOCK_END, ASSERTION, ASSIGNMENT} THING ;
20 typedef enum {INIT, GLOBALBLOCK, HOSTBLOCK, FILEBLOCK} STATE ;
21
22 /*void process_thing(THING thing, char *name, int type, YYSTYPE *pvalue);*/
23
24 #line 81 "rpld_conf.y"
25 typedef union {
26                 long number;
27                 char *name;
28                 char *text;
29                 char mac_address[6];
30         } YYSTYPE;
31 #line 32 "rpld_conf.tab.c"
32 #define BLOCK_START 257
33 #define BLOCK_END 258
34 #define NAME 259
35 #define TEXT 260
36 #define NUMBER 261
37 #define MACADDR 262
38 #define YYERRCODE 256
39 short yylhs[] = {                                        -1,
40     0,    0,    1,    1,    2,    2,    3,    3,    3,    4,
41     4,    4,    4,    4,
42 };
43 short yylen[] = {                                         2,
44     2,    3,    3,    2,    2,    1,    1,    2,    3,    1,
45     3,    3,    3,    1,
46 };
47 short yydefred[] = {                                      0,
48     6,    0,    0,    0,    0,    5,    0,    1,    4,    0,
49     7,   14,    0,    0,    2,    0,    3,    0,    8,   11,
50    12,   13,    9,
51 };
52 short yydgoto[] = {                                       3,
53    12,    5,   13,   14,
54 };
55 short yysindex[] = {                                   -244,
56     0, -254, -244,  -55,  -59,    0,  -50,    0,    0,  -60,
57     0,    0, -251,  -45,    0, -250,    0,  -43,    0,    0,
58     0,    0,    0,
59 };
60 short yyrindex[] = {                                      0,
61     0,    0,    0,    0,    0,    0,    0,    0,    0,  -42,
62     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
63     0,    0,    0,
64 };
65 short yygindex[] = {                                      0,
66     2,    0,    0,    5,
67 };
68 #define YYTABLESIZE 200
69 short yytable[] = {                                      11,
70    16,    4,    6,    8,    7,    1,   17,   10,   15,   20,
71    21,   22,    1,   19,    2,   23,   10,   18,    0,    0,
72     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
73     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
74     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
75     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
76     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
77     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
78     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
79     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
80     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
81     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
82     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
83     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
84     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
85     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
86     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
87     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
88     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
89     0,    0,    0,    0,    0,    0,    6,    1,    9,   10,
90 };
91 short yycheck[] = {                                      59,
92    61,    0,  257,   59,    3,  257,  258,  259,   59,  260,
93   261,  262,  257,   59,  259,   59,   59,   13,   -1,   -1,
94    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
95    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
96    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
97    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
98    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
99    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
100    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
101    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
102    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
103    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
104    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
105    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
106    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
107    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
108    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
109    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
110    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
111    -1,   -1,   -1,   -1,   -1,   -1,  257,  257,  258,  259,
112 };
113 #define YYFINAL 3
114 #ifndef YYDEBUG
115 #define YYDEBUG 0
116 #endif
117 #define YYMAXTOKEN 262
118 #if YYDEBUG
119 char *yyname[] = {
120 "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
121 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",0,"'='",0,0,0,0,0,0,0,0,
122 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
123 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
124 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
125 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
126 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"BLOCK_START","BLOCK_END",
127 "NAME","TEXT","NUMBER","MACADDR",
128 };
129 char *yyrule[] = {
130 "$accept : block_list",
131 "block_list : block ';'",
132 "block_list : block_list block ';'",
133 "block : block_start statement_list BLOCK_END",
134 "block : block_start BLOCK_END",
135 "block_start : NAME BLOCK_START",
136 "block_start : BLOCK_START",
137 "statement_list : ';'",
138 "statement_list : statement ';'",
139 "statement_list : statement_list statement ';'",
140 "statement : NAME",
141 "statement : NAME '=' TEXT",
142 "statement : NAME '=' NUMBER",
143 "statement : NAME '=' MACADDR",
144 "statement : block",
145 };
146 #endif
147 #ifdef YYSTACKSIZE
148 #undef YYMAXDEPTH
149 #define YYMAXDEPTH YYSTACKSIZE
150 #else
151 #ifdef YYMAXDEPTH
152 #define YYSTACKSIZE YYMAXDEPTH
153 #else
154 #define YYSTACKSIZE 500
155 #define YYMAXDEPTH 500
156 #endif
157 #endif
158 int yydebug;
159 int yynerrs;
160 int yyerrflag;
161 int yychar;
162 short *yyssp;
163 YYSTYPE *yyvsp;
164 YYSTYPE yyval;
165 YYSTYPE yylval;
166 short yyss[YYSTACKSIZE];
167 YYSTYPE yyvs[YYSTACKSIZE];
168 #define yystacksize YYSTACKSIZE
169 #line 114 "rpld_conf.y"
170
171 //
172 // ERROR REPORTING
173 //
174
175 // the lineno variable from our parser
176 extern int lineno;
177
178 // the yytext variable from lex for error reporting
179 extern char* yytext;
180
181 void yyerror(char *s)
182 {
183         fprintf(stderr, "rpld: config line %d: %s near `%s'\n", lineno, s, yytext);
184 }
185
186 //
187 // CONFIGURATION PROCESSOR
188 //
189
190 // This is the bit that actually does the work
191
192 #define strsame(a, b)   (!strcmp((a), (b)))
193 /*
194 struct global_parameters
195 {
196
197 } g_params;
198 */
199
200 struct clientinfo
201 {
202         int have_mac;
203         int have_run_addr;
204         int have_files;
205         // optional
206         int have_framesize;
207         int have_blocksize;
208 };
209
210 struct clfileinfo
211 {
212         int have_path;
213         int have_load_addr;
214         // optional
215         int have_offset;
216         int have_length;
217 };
218
219 extern struct client *clients;
220
221 // hideous, we need to cope with a semicolon after this
222 //#define THROW_ERROR(a)        do { yyerror((a)); exit(1); } while(0)
223 #define THROW_ERROR(a)  do { fprintf(stderr, "rpld: config line %d: %s near `%s'\n", lineno, (a), name); exit(1); } while(0)
224
225 void process_thing(THING thing, char *name, int type, YYSTYPE *pvalue)
226 {
227         static STATE state;
228         static struct client *pc;
229         static struct clientinfo ci;
230         static struct clfile *pcf;
231         static struct clfileinfo cfi;
232
233         switch(thing)
234         {
235         // boot the state machine
236         case START:
237                 state = INIT;
238                 break;
239
240         //
241         // Blocks, which contain related options
242         //
243         
244         // start of a block
245         case BLOCK_START:
246                 // in initial state, move to GLOBALBLOCK or HOSTBLOCK
247                 if (state == INIT) {
248                         if (strsame(name, "GLOBAL")) {
249                                 state = GLOBALBLOCK;
250                                 break;
251                         } else if (strsame(name, "HOST") || strsame(name, "CLIENT")) {
252                                 // construct a new client entity
253                                 pc = (struct client*)malloc(sizeof(struct client));
254                                 bzero(pc, sizeof(struct client));
255                                 // reset info about what options have been set for this client
256                                 bzero(&ci, sizeof(ci));
257
258                                 pc->blocklen=MY_BLOCK_LEN;
259                                 pc->framelen=MY_FRAME_LEN;
260                                 
261                                 state = HOSTBLOCK;
262                                 break;
263                         } else THROW_ERROR("Unknown top-level parameter block");
264                 }
265                 // in a HOST block, this must be a FILE
266                 else if (state == HOSTBLOCK) {
267                         if (strsame(name, "FILE")) {
268                                 // construct a new file entity
269                                 pcf = (struct clfile*)malloc(sizeof(struct clfile));
270                                 bzero(pcf, sizeof(struct clfile));
271                                 pcf->length=-1;
272                                 // reset info about options set for this file
273                                 bzero(&cfi, sizeof(cfi));
274                                 
275                                 state = FILEBLOCK;
276                                 break;
277                         } else THROW_ERROR("Only a FILE parameter block can be included in a HOST block");
278                 }
279                 // fuck knows
280                 else
281                 {
282                         yyerror("Unknown parameter block");
283                         exit(1);
284                 }
285                 break;
286
287         // end of a block, we should have a bunch of info now
288         case BLOCK_END:
289                 // end GLOBAL block
290                 if (state == GLOBALBLOCK) {
291                         // no more global params, at least for the moment
292                 }
293                 // end HOST block
294                 else if (state == HOSTBLOCK) {
295                         // should have a complete host specification
296                         if (!ci.have_mac) THROW_ERROR("Must specify an ethernet (MAC) address for host");
297                         else if (!ci.have_run_addr) THROW_ERROR("Must specify an initial execute address for host");
298                         else if (!ci.have_files) THROW_ERROR("Must specify at least one file to load for host");
299
300                         // OK, should have an entire host spec, so copy it in
301                         pc->next = clients;
302                         clients = pc;
303
304                         // finished this host spec
305                         state = INIT;
306                         break;
307                 }
308                 // end FILE block
309                 else if (state == FILEBLOCK) {
310                         // should have a complete file specification
311                         if (!cfi.have_path) THROW_ERROR("Must specify a path for file");
312                         else if (!cfi.have_load_addr) THROW_ERROR("Must specify a load address for file");
313
314                         // have an entire file spec, copy it into the host spec
315                         pcf->next = pc->files;
316                         pc->files = pcf;
317
318                         ci.have_files = 1;
319
320                         // done
321                         state = HOSTBLOCK;
322                         break;
323                 }
324
325         //
326         // The various things that go inside blocks
327         //
328         
329         case ASSERTION:
330                 if (state == GLOBALBLOCK) {
331                         // no global assertions ATM
332                         THROW_ERROR("Unknown directive");
333                 } else if (state == HOSTBLOCK) {
334                         // no host assertions ATM
335                         THROW_ERROR("Unknown directive");
336                 } else if (state == FILEBLOCK) {
337                         if (strsame(name,"linux")) {
338                                 if (!cfi.have_path) THROW_ERROR("A path to a
339 valid kernel must precede linux");
340
341                                 do_linux_kernel(pc,pcf);
342                                 cfi.have_load_addr=1;
343                                 cfi.have_offset=1;
344                                 cfi.have_length=1;
345                                 ci.have_run_addr=1;
346                         } else{
347                         THROW_ERROR("Unknown directive");
348                         }
349                 } else THROW_ERROR("Unknown directive");
350                 break;
351
352         case ASSIGNMENT:
353                 if (state == GLOBALBLOCK) {
354                         // no global assignments ATM
355                         THROW_ERROR("Unknown directive");
356                 } else if (state == HOSTBLOCK) {
357                         // ethernet address
358                         if (strsame(name, "ethernet") || strsame(name, "mac")) {
359                                 if (type != MACADDR) THROW_ERROR("Directive must be followed by an ethernet address");
360                                 else if (ci.have_mac) THROW_ERROR("Repeated directive");
361
362                                 // set MAC address
363                                 bcopy(pvalue->mac_address,pc->mac,ETH_ALEN);
364                                 ci.have_mac = 1;
365                         }
366                         // execute address
367                         else if (strsame(name, "execute") || strsame(name, "run")) {
368                                 if (type != NUMBER) THROW_ERROR("Directive must be followed by a memory address");
369                                 else if (ci.have_run_addr==2) THROW_ERROR("Repeated directive");
370
371                                 // set address
372                                 pc->run_addr = pvalue->number;
373                                 ci.have_run_addr = 2;
374                         }
375                         else if (strsame(name, "blocksize")) {
376                                 if (type != NUMBER) THROW_ERROR("Directive must be followed by an integer ");
377                                 else if (ci.have_blocksize) THROW_ERROR("Repeated directive");
378
379                                 // set address
380                                 pc->blocklen = pvalue->number;
381                                 ci.have_blocksize = 1;
382                         }
383                         else if (strsame(name, "framesize")) {
384                                 if (type != NUMBER) THROW_ERROR("Directive must be followed by an integer ");
385                                 else if (ci.have_framesize) THROW_ERROR("Repeated directive");
386
387                                 // set size
388                                 pc->framelen = pvalue->number;
389                                 ci.have_framesize = 1;
390                         }
391                         else THROW_ERROR("Unknown directive");
392                 } else if (state == FILEBLOCK) {
393                         // path
394                         if (strsame(name, "path")) {
395                                 if (type != TEXT) THROW_ERROR("Directive must be followed by a filename");
396                                 else if (cfi.have_path) THROW_ERROR("Repeated directive");
397
398                                 // set filename
399                                 pcf->path = pvalue->text;
400                                 cfi.have_path = 1;
401                         }
402                         // load address
403                         else if (strsame(name, "load")) {
404                                 if (type != NUMBER) THROW_ERROR("Directive must be followed by a memory address");
405                                 else if (cfi.have_load_addr) THROW_ERROR("Repeated directive");
406
407                                 // set load address
408                                 pcf->load_addr = pvalue->number;
409                                 cfi.have_load_addr = 1;
410                         }
411                         // offset
412                         else if (strsame(name, "offset")) {
413                                 if (type != NUMBER) THROW_ERROR("Directive must be followed by a memory address");
414                                 else if (cfi.have_offset) THROW_ERROR("Repeated directive");
415
416                                 // set offset
417                                 pcf->offset = pvalue->number;
418                                 cfi.have_offset = 1;
419                         }
420                         // length
421                         else if (strsame(name, "length")) {
422                                 if (type != NUMBER) THROW_ERROR("Directive must be followed by a memory address");
423                                 else if (cfi.have_length) THROW_ERROR("Repeated directive");
424
425                                 // set length
426                                 pcf->length = pvalue->number;
427                                 cfi.have_length = 1;
428                         }
429                         else THROW_ERROR("Unknown directive");
430                 }
431                 break;
432
433                 default: THROW_ERROR("Mistake");
434         }
435         
436
437 }
438 #line 439 "rpld_conf.tab.c"
439 #define YYABORT goto yyabort
440 #define YYREJECT goto yyabort
441 #define YYACCEPT goto yyaccept
442 #define YYERROR goto yyerrlab
443 int
444 yyparse()
445 {
446     register int yym, yyn, yystate;
447 #if YYDEBUG
448     register char *yys;
449     extern char *getenv();
450
451     if (yys = getenv("YYDEBUG"))
452     {
453         yyn = *yys;
454         if (yyn >= '0' && yyn <= '9')
455             yydebug = yyn - '0';
456     }
457 #endif
458
459     yynerrs = 0;
460     yyerrflag = 0;
461     yychar = (-1);
462
463     yyssp = yyss;
464     yyvsp = yyvs;
465     *yyssp = yystate = 0;
466
467 yyloop:
468     if (yyn = yydefred[yystate]) goto yyreduce;
469     if (yychar < 0)
470     {
471         if ((yychar = yylex()) < 0) yychar = 0;
472 #if YYDEBUG
473         if (yydebug)
474         {
475             yys = 0;
476             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
477             if (!yys) yys = "illegal-symbol";
478             printf("%sdebug: state %d, reading %d (%s)\n",
479                     YYPREFIX, yystate, yychar, yys);
480         }
481 #endif
482     }
483     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
484             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
485     {
486 #if YYDEBUG
487         if (yydebug)
488             printf("%sdebug: state %d, shifting to state %d\n",
489                     YYPREFIX, yystate, yytable[yyn]);
490 #endif
491         if (yyssp >= yyss + yystacksize - 1)
492         {
493             goto yyoverflow;
494         }
495         *++yyssp = yystate = yytable[yyn];
496         *++yyvsp = yylval;
497         yychar = (-1);
498         if (yyerrflag > 0)  --yyerrflag;
499         goto yyloop;
500     }
501     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
502             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
503     {
504         yyn = yytable[yyn];
505         goto yyreduce;
506     }
507     if (yyerrflag) goto yyinrecovery;
508 #ifdef lint
509     goto yynewerror;
510 #endif
511 yynewerror:
512     yyerror("syntax error");
513 #ifdef lint
514     goto yyerrlab;
515 #endif
516 yyerrlab:
517     ++yynerrs;
518 yyinrecovery:
519     if (yyerrflag < 3)
520     {
521         yyerrflag = 3;
522         for (;;)
523         {
524             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
525                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
526             {
527 #if YYDEBUG
528                 if (yydebug)
529                     printf("%sdebug: state %d, error recovery shifting\
530  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
531 #endif
532                 if (yyssp >= yyss + yystacksize - 1)
533                 {
534                     goto yyoverflow;
535                 }
536                 *++yyssp = yystate = yytable[yyn];
537                 *++yyvsp = yylval;
538                 goto yyloop;
539             }
540             else
541             {
542 #if YYDEBUG
543                 if (yydebug)
544                     printf("%sdebug: error recovery discarding state %d\n",
545                             YYPREFIX, *yyssp);
546 #endif
547                 if (yyssp <= yyss) goto yyabort;
548                 --yyssp;
549                 --yyvsp;
550             }
551         }
552     }
553     else
554     {
555         if (yychar == 0) goto yyabort;
556 #if YYDEBUG
557         if (yydebug)
558         {
559             yys = 0;
560             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
561             if (!yys) yys = "illegal-symbol";
562             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
563                     YYPREFIX, yystate, yychar, yys);
564         }
565 #endif
566         yychar = (-1);
567         goto yyloop;
568     }
569 yyreduce:
570 #if YYDEBUG
571     if (yydebug)
572         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
573                 YYPREFIX, yystate, yyn, yyrule[yyn]);
574 #endif
575     yym = yylen[yyn];
576     yyval = yyvsp[1-yym];
577     switch (yyn)
578     {
579 case 3:
580 #line 96 "rpld_conf.y"
581 { process_thing(BLOCK_END, "", 0, NULL); }
582 break;
583 case 4:
584 #line 97 "rpld_conf.y"
585 { process_thing(BLOCK_END, "", 0, NULL); }
586 break;
587 case 5:
588 #line 99 "rpld_conf.y"
589 { process_thing(BLOCK_START, yyvsp[-1].name, 0, NULL); }
590 break;
591 case 6:
592 #line 100 "rpld_conf.y"
593 { process_thing(BLOCK_START, "", 0, NULL); }
594 break;
595 case 10:
596 #line 107 "rpld_conf.y"
597 { process_thing(ASSERTION, yyvsp[0].name, 0, NULL); }
598 break;
599 case 11:
600 #line 108 "rpld_conf.y"
601 { process_thing(ASSIGNMENT, yyvsp[-2].name, TEXT, &yyvsp[0]); }
602 break;
603 case 12:
604 #line 109 "rpld_conf.y"
605 { process_thing(ASSIGNMENT, yyvsp[-2].name, NUMBER, &yyvsp[0]); }
606 break;
607 case 13:
608 #line 110 "rpld_conf.y"
609 { process_thing(ASSIGNMENT, yyvsp[-2].name, MACADDR, &yyvsp[0]); }
610 break;
611 #line 612 "rpld_conf.tab.c"
612     }
613     yyssp -= yym;
614     yystate = *yyssp;
615     yyvsp -= yym;
616     yym = yylhs[yyn];
617     if (yystate == 0 && yym == 0)
618     {
619 #if YYDEBUG
620         if (yydebug)
621             printf("%sdebug: after reduction, shifting from state 0 to\
622  state %d\n", YYPREFIX, YYFINAL);
623 #endif
624         yystate = YYFINAL;
625         *++yyssp = YYFINAL;
626         *++yyvsp = yyval;
627         if (yychar < 0)
628         {
629             if ((yychar = yylex()) < 0) yychar = 0;
630 #if YYDEBUG
631             if (yydebug)
632             {
633                 yys = 0;
634                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
635                 if (!yys) yys = "illegal-symbol";
636                 printf("%sdebug: state %d, reading %d (%s)\n",
637                         YYPREFIX, YYFINAL, yychar, yys);
638             }
639 #endif
640         }
641         if (yychar == 0) goto yyaccept;
642         goto yyloop;
643     }
644     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
645             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
646         yystate = yytable[yyn];
647     else
648         yystate = yydgoto[yym];
649 #if YYDEBUG
650     if (yydebug)
651         printf("%sdebug: after reduction, shifting from state %d \
652 to state %d\n", YYPREFIX, *yyssp, yystate);
653 #endif
654     if (yyssp >= yyss + yystacksize - 1)
655     {
656         goto yyoverflow;
657     }
658     *++yyssp = yystate;
659     *++yyvsp = yyval;
660     goto yyloop;
661 yyoverflow:
662     yyerror("yacc stack overflow");
663 yyabort:
664     return (1);
665 yyaccept:
666     return (0);
667 }