|
|
1.1 root 1:
2: /* A Bison parser, made from cexp.y */
3:
4: #define INT 258
5: #define CHAR 259
6: #define NAME 260
7: #define ERROR 261
8: #define OR 262
9: #define AND 263
10: #define EQUAL 264
11: #define NOTEQUAL 265
12: #define LEQ 266
13: #define GEQ 267
14: #define LSH 268
15: #define RSH 269
16: #define UNARY 270
17:
18: #line 109 "cexp.y"
19:
20: #include <setjmp.h>
21: /* #define YYDEBUG 1 */
22:
23: static int yylex ();
24: static yyerror ();
25: int expression_value;
26:
27: static jmp_buf parse_return_error;
28:
29: /* some external tables of character types */
30: extern unsigned char is_idstart[], is_idchar[];
31:
32:
33: #line 124 "cexp.y"
34: typedef union {
35: long lval;
36: int voidval;
37: char *sval;
38: } YYSTYPE;
39:
40: #ifndef YYLTYPE
41: typedef
42: struct yyltype
43: {
44: int timestamp;
45: int first_line;
46: int first_column;
47: int last_line;
48: int last_column;
49: char *text;
50: }
51: yyltype;
52:
53: #define YYLTYPE yyltype
54: #endif
55:
56: #define YYACCEPT return(0)
57: #define YYABORT return(1)
58: #define YYERROR return(1)
59: #include <stdio.h>
60:
61:
62:
63: #define YYFINAL 59
64: #define YYFLAG -32768
65: #define YYNTBASE 33
66:
67: #define YYTRANSLATE(x) (yytranslate[x])
68:
69: static char yytranslate[] = { 0,
70: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
71: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
72: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
73: 2, 2, 29, 2, 2, 2, 27, 14, 2, 31,
74: 32, 25, 23, 9, 24, 2, 26, 2, 2, 2,
75: 2, 2, 2, 2, 2, 2, 2, 8, 2, 17,
76: 2, 18, 7, 2, 2, 2, 2, 2, 2, 2,
77: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
78: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
79: 2, 2, 2, 13, 2, 2, 2, 2, 2, 2,
80: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
81: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
82: 2, 2, 2, 12, 2, 30, 2, 2, 2, 2,
83: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
84: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
85: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
86: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
87: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
88: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
89: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
90: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
91: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
92: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
93: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
94: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
95: 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
96: 6, 10, 11, 15, 16, 19, 20, 21, 22, 28
97: };
98:
99: static short yyrline[] = { 0,
100: 153, 158, 159, 164, 166, 168, 170, 175, 177, 179,
101: 181, 183, 185, 187, 189, 191, 193, 195, 197, 199,
102: 201, 203, 205, 207, 209, 211, 213, 215, 217
103: };
104:
105: static char * yytname[] = { 0,
106: "error","$illegal.","INT","CHAR","NAME","ERROR","'?'","':'","','","OR",
107: "AND","'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'","'>'","LEQ","GEQ",
108: "LSH","RSH","'+'","'-'","'*'","'/'","'%'","UNARY","'!'","'~'",
109: "'('","')'","start"
110: };
111:
112: static short yyr1[] = { 0,
113: 33, 34, 34, 35, 35, 35, 35, 35, 35, 35,
114: 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
115: 35, 35, 35, 35, 35, 35, 35, 35, 35
116: };
117:
118: static short yyr2[] = { 0,
119: 1, 1, 3, 2, 2, 2, 3, 3, 3, 3,
120: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
121: 3, 3, 3, 3, 3, 5, 1, 1, 1
122: };
123:
124: static short yydefact[] = { 0,
125: 27, 28, 29, 0, 0, 0, 0, 1, 2, 4,
126: 5, 6, 0, 0, 0, 0, 0, 0, 0, 0,
127: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
128: 0, 0, 0, 7, 3, 0, 25, 24, 23, 22,
129: 21, 15, 16, 19, 20, 17, 18, 13, 14, 11,
130: 12, 8, 9, 10, 0, 26, 0, 0, 0
131: };
132:
133: static short yydefgoto[] = { 57,
134: 8, 9
135: };
136:
137: static short yypact[] = { 28,
138: -32768,-32768,-32768, 28, 28, 28, 28, -3, 74,-32768,
139: -32768,-32768, -2, 28, 28, 28, 28, 28, 28, 28,
140: 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
141: 28, 28, 28,-32768, 74, 53, 23, 90, 105, 119,
142: 132, 143, 143, 150, 150, 150, 150, 155, 155, -22,
143: -22,-32768,-32768,-32768, 28, 74, 8, 9,-32768
144: };
145:
146: static short yypgoto[] = {-32768,
147: 46, -4
148: };
149:
150:
151: #define YYLAST 182
152:
153:
154: static short yytable[] = { 10,
155: 11, 12, 31, 32, 33, 14, 14, 58, 59, 35,
156: 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
157: 46, 47, 48, 49, 50, 51, 52, 53, 54, 34,
158: 1, 2, 3, 17, 18, 19, 20, 21, 22, 23,
159: 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
160: 56, 4, 13, 0, 0, 0, 5, 6, 7, 15,
161: 55, 0, 16, 17, 18, 19, 20, 21, 22, 23,
162: 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
163: 15, 0, 0, 16, 17, 18, 19, 20, 21, 22,
164: 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
165: 33, 18, 19, 20, 21, 22, 23, 24, 25, 26,
166: 27, 28, 29, 30, 31, 32, 33, 19, 20, 21,
167: 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
168: 32, 33, 20, 21, 22, 23, 24, 25, 26, 27,
169: 28, 29, 30, 31, 32, 33, 21, 22, 23, 24,
170: 25, 26, 27, 28, 29, 30, 31, 32, 33, 23,
171: 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
172: 27, 28, 29, 30, 31, 32, 33, 29, 30, 31,
173: 32, 33
174: };
175:
176: static short yycheck[] = { 4,
177: 5, 6, 25, 26, 27, 9, 9, 0, 0, 14,
178: 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
179: 25, 26, 27, 28, 29, 30, 31, 32, 33, 32,
180: 3, 4, 5, 11, 12, 13, 14, 15, 16, 17,
181: 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
182: 55, 24, 7, -1, -1, -1, 29, 30, 31, 7,
183: 8, -1, 10, 11, 12, 13, 14, 15, 16, 17,
184: 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
185: 7, -1, -1, 10, 11, 12, 13, 14, 15, 16,
186: 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
187: 27, 12, 13, 14, 15, 16, 17, 18, 19, 20,
188: 21, 22, 23, 24, 25, 26, 27, 13, 14, 15,
189: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
190: 26, 27, 14, 15, 16, 17, 18, 19, 20, 21,
191: 22, 23, 24, 25, 26, 27, 15, 16, 17, 18,
192: 19, 20, 21, 22, 23, 24, 25, 26, 27, 17,
193: 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
194: 21, 22, 23, 24, 25, 26, 27, 23, 24, 25,
195: 26, 27
196: };
197: #define YYPURE 1
198:
199: #line 2 "bison.simple"
200:
201: /* Skeleton output parser for bison,
202: copyright (C) 1984 Bob Corbett and Richard Stallman
203:
204: Permission is granted to anyone to make or distribute verbatim copies of this program
205: provided that the copyright notice and this permission notice are preserved;
206: and provided that the recipient is not asked to waive or limit his right to
207: redistribute copies as permitted by this permission notice;
208: and provided that anyone possessing an executable copy
209: is granted access to copy the source code, in machine-readable form,
210: in some reasonable manner.
211:
212: Permission is granted to distribute derived works or enhanced versions of
213: this program under the above conditions with the additional condition
214: that the entire derivative or enhanced work
215: must be covered by a permission notice identical to this one.
216:
217: Anything distributed as part of a package containing portions derived
218: from this program, which cannot in current practice perform its function usefully
219: in the absense of what was derived directly from this program,
220: is to be considered as forming, together with the latter,
221: a single work derived from this program,
222: which must be entirely covered by a permission notice identical to this one
223: in order for distribution of the package to be permitted.
224:
225: In other words, you are welcome to use, share and improve this program.
226: You are forbidden to forbid anyone else to use, share and improve
227: what you give them. Help stamp out software-hoarding! */
228:
229: /* This is the parser code that is written into each bison parser
230: when the %semantic_parser declaration is not specified in the grammar.
231: It was written by Richard Stallman by simplifying the hairy parser
232: used when %semantic_parser is specified. */
233:
234: /* Note: there must be only one dollar sign in this file.
235: It is replaced by the list of actions, each action
236: as one case of the switch. */
237:
238: #define yyerrok (yyerrstatus = 0)
239: #define yyclearin (yychar = YYEMPTY)
240: #define YYEMPTY -2
241: #define YYEOF 0
242: #define YYFAIL goto yyerrlab;
243:
244: #define YYTERROR 1
245:
246: #ifndef YYIMPURE
247: #define YYLEX yylex()
248: #endif
249:
250: #ifndef YYPURE
251: #define YYLEX yylex(&yylval, &yylloc)
252: #endif
253:
254: /* If nonreentrant, generate the variables here */
255:
256: #ifndef YYIMPURE
257:
258: int yychar; /* the lookahead symbol */
259: YYSTYPE yylval; /* the semantic value of the */
260: /* lookahead symbol */
261:
262: YYLTYPE yylloc; /* location data for the lookahead */
263: /* symbol */
264:
265: int yydebug = 0; /* nonzero means print parse trace */
266:
267: #endif /* YYIMPURE */
268:
269:
270: /* YYMAXDEPTH indicates the initial size of the parser's stacks */
271:
272: #ifndef YYMAXDEPTH
273: #define YYMAXDEPTH 200
274: #endif
275:
276: /* YYMAXLIMIT is the maximum size the stacks can grow to
277: (effective only if the built-in stack extension method is used). */
278:
279: #ifndef YYMAXLIMIT
280: #define YYMAXLIMIT 10000
281: #endif
282:
283:
284: #line 87 "bison.simple"
285: int
286: yyparse()
287: {
288: register int yystate;
289: register int yyn;
290: register short *yyssp;
291: register YYSTYPE *yyvsp;
292: YYLTYPE *yylsp;
293: int yyerrstatus; /* number of tokens to shift before error messages enabled */
294: int yychar1; /* lookahead token as an internal (translated) token number */
295:
296: short yyssa[YYMAXDEPTH]; /* the state stack */
297: YYSTYPE yyvsa[YYMAXDEPTH]; /* the semantic value stack */
298: YYLTYPE yylsa[YYMAXDEPTH]; /* the location stack */
299:
300: short *yyss = yyssa; /* refer to the stacks thru separate pointers */
301: YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
302: YYLTYPE *yyls = yylsa;
303:
304: int yymaxdepth = YYMAXDEPTH;
305:
306: #ifndef YYPURE
307:
308: int yychar;
309: YYSTYPE yylval;
310: YYLTYPE yylloc;
311:
312: extern int yydebug;
313:
314: #endif
315:
316:
317: YYSTYPE yyval; /* the variable used to return */
318: /* semantic values from the action */
319: /* routines */
320:
321: int yylen;
322:
323: if (yydebug)
324: fprintf(stderr, "Starting parse\n");
325:
326: yystate = 0;
327: yyerrstatus = 0;
328: yychar = YYEMPTY; /* Cause a token to be read. */
329:
330: /* Initialize stack pointers.
331: Waste one element of value and location stack
332: so that they stay on the same level as the state stack. */
333:
334: yyssp = yyss - 1;
335: yyvsp = yyvs;
336: yylsp = yyls;
337:
338: /* Push a new state, which is found in yystate . */
339: /* In all cases, when you get here, the value and location stacks
340: have just been pushed. so pushing a state here evens the stacks. */
341: yynewstate:
342:
343: *++yyssp = yystate;
344:
345: if (yyssp >= yyss + yymaxdepth - 1)
346: {
347: /* Give user a chance to reallocate the stack */
348: /* Use copies of these so that the &'s don't force the real ones into memory. */
349: YYSTYPE *yyvs1 = yyvs;
350: YYLTYPE *yyls1 = yyls;
351: short *yyss1 = yyss;
352:
353: /* Get the current used size of the three stacks, in elements. */
354: int size = yyssp - yyss + 1;
355:
356: #ifdef yyoverflow
357: /* Each stack pointer address is followed by the size of
358: the data in use in that stack, in bytes. */
359: yyoverflow("parser stack overflow",
360: &yyss1, size * sizeof (*yyssp),
361: &yyvs1, size * sizeof (*yyvsp),
362: &yyls1, size * sizeof (*yylsp),
363: &yymaxdepth);
364:
365: yyss = yyss1; yyvs = yyvs1; yyls = yyls1;
366: #else /* no yyoverflow */
367: /* Extend the stack our own way. */
368: if (yymaxdepth >= YYMAXLIMIT)
369: yyerror("parser stack overflow");
370: yymaxdepth *= 2;
371: if (yymaxdepth > YYMAXLIMIT)
372: yymaxdepth = YYMAXLIMIT;
373: yyss = (short *) alloca (yymaxdepth * sizeof (*yyssp));
374: bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
375: yyls = (YYLTYPE *) alloca (yymaxdepth * sizeof (*yylsp));
376: bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
377: yyvs = (YYSTYPE *) alloca (yymaxdepth * sizeof (*yyvsp));
378: bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
379: #endif /* no yyoverflow */
380:
381: yyssp = yyss + size - 1;
382: yylsp = yyls + size - 1;
383: yyvsp = yyvs + size - 1;
384:
385: if (yydebug)
386: fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);
387:
388: if (yyssp >= yyss + yymaxdepth - 1)
389: YYERROR;
390: }
391:
392: if (yydebug)
393: fprintf(stderr, "Entering state %d\n", yystate);
394:
395: /* Do appropriate processing given the current state. */
396: /* Read a lookahead token if we need one and don't already have one. */
397: yyresume:
398:
399: /* First try to decide what to do without reference to lookahead token. */
400:
401: yyn = yypact[yystate];
402: if (yyn == YYFLAG)
403: goto yydefault;
404:
405: /* Not known => get a lookahead token if don't already have one. */
406:
407: /* yychar is either YYEMPTY or YYEOF
408: or a valid token in external form. */
409:
410: if (yychar == YYEMPTY)
411: {
412: yychar = YYLEX;
413: }
414:
415: /* Convert token to internal form (in yychar1) for indexing tables with */
416:
417: if (yychar <= 0) /* This means end of input. */
418: {
419: yychar1 = 0;
420: yychar = YYEOF; /* Don't call YYLEX any more */
421:
422: if (yydebug)
423: fprintf(stderr, "Now at end of input.\n");
424: }
425: else
426: {
427: yychar1 = YYTRANSLATE(yychar);
428:
429: if (yydebug)
430: fprintf(stderr, "Parsing next token; it is %d (%s)\n", yychar, yytname[yychar1]);
431: }
432:
433: yyn += yychar1;
434: if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
435: goto yydefault;
436:
437: yyn = yytable[yyn];
438:
439: /* yyn is what to do for this token type in this state.
440: Negative => reduce, -yyn is rule number.
441: Positive => shift, yyn is new state.
442: New state is final state => don't bother to shift,
443: just return success.
444: 0, or most negative number => error. */
445:
446: if (yyn < 0)
447: {
448: if (yyn == YYFLAG)
449: goto yyerrlab;
450: yyn = -yyn;
451: goto yyreduce;
452: }
453: else if (yyn == 0)
454: goto yyerrlab;
455:
456: if (yyn == YYFINAL)
457: YYACCEPT;
458:
459: /* Shift the lookahead token. */
460:
461: if (yydebug)
462: fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
463:
464: /* Discard the token being shifted unless it is eof. */
465: if (yychar != YYEOF)
466: yychar = YYEMPTY;
467:
468: *++yyvsp = yylval;
469: *++yylsp = yylloc;
470:
471: /* count tokens shifted since error; after three, turn off error status. */
472: if (yyerrstatus) yyerrstatus--;
473:
474: yystate = yyn;
475: goto yynewstate;
476:
477: /* Do the default action for the current state. */
478: yydefault:
479:
480: yyn = yydefact[yystate];
481: if (yyn == 0)
482: goto yyerrlab;
483:
484: /* Do a reduction. yyn is the number of a rule to reduce with. */
485: yyreduce:
486: yylen = yyr2[yyn];
487: yyval = yyvsp[1-yylen]; /* implement default value of the action */
488:
489: if (yydebug)
490: {
491: if (yylen == 1)
492: fprintf (stderr, "Reducing 1 value via line %d, ",
493: yyrline[yyn]);
494: else
495: fprintf (stderr, "Reducing %d values via line %d, ",
496: yylen, yyrline[yyn]);
497: }
498:
499:
500: switch (yyn) {
501:
502: case 1:
503: #line 154 "cexp.y"
504: { expression_value = yyvsp[0].lval; ;
505: break;}
506: case 3:
507: #line 160 "cexp.y"
508: { yyval.lval = yyvsp[0].lval; ;
509: break;}
510: case 4:
511: #line 165 "cexp.y"
512: { yyval.lval = - yyvsp[0].lval; ;
513: break;}
514: case 5:
515: #line 167 "cexp.y"
516: { yyval.lval = ! yyvsp[0].lval; ;
517: break;}
518: case 6:
519: #line 169 "cexp.y"
520: { yyval.lval = ~ yyvsp[0].lval; ;
521: break;}
522: case 7:
523: #line 171 "cexp.y"
524: { yyval.lval = yyvsp[-1].lval; ;
525: break;}
526: case 8:
527: #line 176 "cexp.y"
528: { yyval.lval = yyvsp[-2].lval * yyvsp[0].lval; ;
529: break;}
530: case 9:
531: #line 178 "cexp.y"
532: { yyval.lval = yyvsp[-2].lval / yyvsp[0].lval; ;
533: break;}
534: case 10:
535: #line 180 "cexp.y"
536: { yyval.lval = yyvsp[-2].lval % yyvsp[0].lval; ;
537: break;}
538: case 11:
539: #line 182 "cexp.y"
540: { yyval.lval = yyvsp[-2].lval + yyvsp[0].lval; ;
541: break;}
542: case 12:
543: #line 184 "cexp.y"
544: { yyval.lval = yyvsp[-2].lval - yyvsp[0].lval; ;
545: break;}
546: case 13:
547: #line 186 "cexp.y"
548: { yyval.lval = yyvsp[-2].lval << yyvsp[0].lval; ;
549: break;}
550: case 14:
551: #line 188 "cexp.y"
552: { yyval.lval = yyvsp[-2].lval >> yyvsp[0].lval; ;
553: break;}
554: case 15:
555: #line 190 "cexp.y"
556: { yyval.lval = (yyvsp[-2].lval == yyvsp[0].lval); ;
557: break;}
558: case 16:
559: #line 192 "cexp.y"
560: { yyval.lval = (yyvsp[-2].lval != yyvsp[0].lval); ;
561: break;}
562: case 17:
563: #line 194 "cexp.y"
564: { yyval.lval = (yyvsp[-2].lval <= yyvsp[0].lval); ;
565: break;}
566: case 18:
567: #line 196 "cexp.y"
568: { yyval.lval = (yyvsp[-2].lval >= yyvsp[0].lval); ;
569: break;}
570: case 19:
571: #line 198 "cexp.y"
572: { yyval.lval = (yyvsp[-2].lval < yyvsp[0].lval); ;
573: break;}
574: case 20:
575: #line 200 "cexp.y"
576: { yyval.lval = (yyvsp[-2].lval > yyvsp[0].lval); ;
577: break;}
578: case 21:
579: #line 202 "cexp.y"
580: { yyval.lval = (yyvsp[-2].lval & yyvsp[0].lval); ;
581: break;}
582: case 22:
583: #line 204 "cexp.y"
584: { yyval.lval = (yyvsp[-2].lval ^ yyvsp[0].lval); ;
585: break;}
586: case 23:
587: #line 206 "cexp.y"
588: { yyval.lval = (yyvsp[-2].lval | yyvsp[0].lval); ;
589: break;}
590: case 24:
591: #line 208 "cexp.y"
592: { yyval.lval = (yyvsp[-2].lval && yyvsp[0].lval); ;
593: break;}
594: case 25:
595: #line 210 "cexp.y"
596: { yyval.lval = (yyvsp[-2].lval || yyvsp[0].lval); ;
597: break;}
598: case 26:
599: #line 212 "cexp.y"
600: { yyval.lval = yyvsp[-4].lval ? yyvsp[-2].lval : yyvsp[0].lval; ;
601: break;}
602: case 27:
603: #line 214 "cexp.y"
604: { yyval.lval = yylval.lval; ;
605: break;}
606: case 28:
607: #line 216 "cexp.y"
608: { yyval.lval = yylval.lval; ;
609: break;}
610: case 29:
611: #line 218 "cexp.y"
612: { yyval.lval = 0; ;
613: break;}
614: }
615: /* the action file gets copied in in place of this dollarsign */
616: #line 303 "bison.simple"
617:
618: yyvsp -= yylen;
619: yylsp -= yylen;
620: yyssp -= yylen;
621:
622: if (yydebug)
623: {
624: short *ssp1 = yyss - 1;
625: fprintf (stderr, "state stack now", yyssp-yyss);
626: while (ssp1 != yyssp)
627: fprintf (stderr, " %d", *++ssp1);
628: fprintf (stderr, "\n");
629: }
630:
631: *++yyvsp = yyval;
632:
633: yylsp++;
634: if (yylen == 0)
635: {
636: yylsp->first_line = yylloc.first_line;
637: yylsp->first_column = yylloc.first_column;
638: yylsp->last_line = (yylsp-1)->last_line;
639: yylsp->last_column = (yylsp-1)->last_column;
640: yylsp->text = 0;
641: }
642: else
643: {
644: yylsp->last_line = (yylsp+yylen-1)->last_line;
645: yylsp->last_column = (yylsp+yylen-1)->last_column;
646: }
647:
648: /* Now "shift" the result of the reduction.
649: Determine what state that goes to,
650: based on the state we popped back to
651: and the rule number reduced by. */
652:
653: yyn = yyr1[yyn];
654:
655: yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
656: if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
657: yystate = yytable[yystate];
658: else
659: yystate = yydefgoto[yyn - YYNTBASE];
660:
661: goto yynewstate;
662:
663: yyerrlab: /* here on detecting error */
664:
665: if (! yyerrstatus)
666: /* If not already recovering from an error, report this error. */
667: {
668: yyerror("parse error");
669: }
670:
671: if (yyerrstatus == 3)
672: {
673: /* if just tried and failed to reuse lookahead token after an error, discard it. */
674:
675: /* return failure if at end of input */
676: if (yychar == YYEOF)
677: YYERROR;
678:
679: if (yydebug)
680: fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
681:
682: yychar = YYEMPTY;
683: }
684:
685: /* Else will try to reuse lookahead token
686: after shifting the error token. */
687:
688: yyerrstatus = 3; /* Each real token shifted decrements this */
689:
690: goto yyerrhandle;
691:
692: yyerrdefault: /* current state does not do anything special for the error token. */
693:
694: #if 0
695: /* This is wrong; only states that explicitly want error tokens
696: should shift them. */
697: yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
698: if (yyn) goto yydefault;
699: #endif
700:
701: yyerrpop: /* pop the current state because it cannot handle the error token */
702:
703: if (yyssp == yyss) YYERROR;
704: yyvsp--;
705: yylsp--;
706: yystate = *--yyssp;
707:
708: if (yydebug)
709: {
710: short *ssp1 = yyss - 1;
711: fprintf (stderr, "Error: state stack now", yyssp-yyss);
712: while (ssp1 != yyssp)
713: fprintf (stderr, " %d", *++ssp1);
714: fprintf (stderr, "\n");
715: }
716:
717: yyerrhandle:
718:
719: yyn = yypact[yystate];
720: if (yyn == YYFLAG)
721: goto yyerrdefault;
722:
723: yyn += YYTERROR;
724: if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
725: goto yyerrdefault;
726:
727: yyn = yytable[yyn];
728: if (yyn < 0)
729: {
730: if (yyn == YYFLAG)
731: goto yyerrpop;
732: yyn = -yyn;
733: goto yyreduce;
734: }
735: else if (yyn == 0)
736: goto yyerrpop;
737:
738: if (yyn == YYFINAL)
739: YYACCEPT;
740:
741: if (yydebug)
742: fprintf(stderr, "Shifting error token, ");
743:
744: *++yyvsp = yylval;
745: *++yylsp = yylloc;
746:
747: yystate = yyn;
748: goto yynewstate;
749: }
750: #line 220 "cexp.y"
751:
752:
753: /* During parsing of a C expression, the pointer to the next character
754: is in this variable. */
755:
756: static char *lexptr;
757:
758: /* Take care of parsing a number (anything that starts with a digit).
759: Set yylval and return the token type; update lexptr.
760: LEN is the number of characters in it. */
761:
762: /* maybe needs to actually deal with floating point numbers */
763:
764: static int
765: parse_number (olen)
766: int olen;
767: {
768: register char *p = lexptr;
769: register long n = 0;
770: register int c;
771: register int base = 10;
772: register len = olen;
773: char *err_copy;
774:
775: extern double atof ();
776:
777: for (c = 0; c < len; c++)
778: if (p[c] == '.') {
779: /* It's a float since it contains a point. */
780: yyerror ("floating point numbers not allowed in #if expressions");
781: return ERROR;
782:
783: /* ****************
784: yylval.dval = atof (p);
785: lexptr += len;
786: return FLOAT;
787: **************** */
788: }
789:
790: if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
791: p += 2;
792: base = 16;
793: len -= 2;
794: }
795: else if (*p == '0')
796: base = 8;
797:
798: while (len-- > 0) {
799: c = *p++;
800: n *= base;
801: if (c >= '0' && c <= '9')
802: n += c - '0';
803: else {
804: if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
805: if (base == 16 && c >= 'a' && c <= 'f')
806: n += c - 'a' + 10;
807: else if (len == 0 && c == 'l')
808: ;
809: else {
810: yyerror ("Invalid number in #if expression");
811: return ERROR;
812: }
813: }
814: }
815:
816: lexptr = p;
817: yylval.lval = n;
818: return INT;
819: }
820:
821: struct token {
822: char *operator;
823: int token;
824: };
825:
826: #define NULL 0
827:
828: static struct token tokentab2[] = {
829: {"&&", AND},
830: {"||", OR},
831: {"<<", LSH},
832: {">>", RSH},
833: {"==", EQUAL},
834: {"!=", NOTEQUAL},
835: {"<=", LEQ},
836: {">=", GEQ},
837: {NULL, ERROR}
838: };
839:
840: /* Read one token, getting characters through lexptr. */
841:
842: static int
843: yylex ()
844: {
845: register int c;
846: register int namelen;
847: register char *tokstart;
848: register struct token *toktab;
849:
850: retry:
851:
852: tokstart = lexptr;
853: c = *tokstart;
854: /* See if it is a special token of length 2. */
855: for (toktab = tokentab2; toktab->operator != NULL; toktab++)
856: if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
857: lexptr += 2;
858: return toktab->token;
859: }
860:
861: switch (c) {
862: case 0:
863: return 0;
864:
865: case ' ':
866: case '\t':
867: case '\n':
868: lexptr++;
869: goto retry;
870:
871: case '\'':
872: lexptr++;
873: c = *lexptr++;
874: if (c == '\\')
875: c = parse_escape (&lexptr);
876: yylval.lval = c;
877: c = *lexptr++;
878: if (c != '\'') {
879: yyerror ("Invalid character constant in #if");
880: return ERROR;
881: }
882:
883: return CHAR;
884:
885: /* some of these chars are invalid in constant expressions;
886: maybe do something about them later */
887: case '/':
888: case '+':
889: case '-':
890: case '*':
891: case '%':
892: case '|':
893: case '&':
894: case '^':
895: case '~':
896: case '!':
897: case '@':
898: case '<':
899: case '>':
900: case '(':
901: case ')':
902: case '[':
903: case ']':
904: case '.':
905: case '?':
906: case ':':
907: case '=':
908: case '{':
909: case '}':
910: case ',':
911: lexptr++;
912: return c;
913:
914: case '"':
915: yyerror ("double quoted strings not allowed in #if expressions");
916: return ERROR;
917: }
918: if (c >= '0' && c <= '9') {
919: /* It's a number */
920: for (namelen = 0;
921: c = tokstart[namelen], is_idchar[c] || c == '.';
922: namelen++)
923: ;
924: return parse_number (namelen);
925: }
926:
927: if (!is_idstart[c]) {
928: yyerror ("Invalid token in expression");
929: return ERROR;
930: }
931:
932: /* It is a name. See how long it is. */
933:
934: for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
935: ;
936:
937: lexptr += namelen;
938: return NAME;
939: }
940:
941:
942: /* Parse a C escape sequence. STRING_PTR points to a variable
943: containing a pointer to the string to parse. That pointer
944: is updated past the characters we use. The value of the
945: escape sequence is returned.
946:
947: A negative value means the sequence \ newline was seen,
948: which is supposed to be equivalent to nothing at all.
949:
950: If \ is followed by a null character, we return a negative
951: value and leave the string pointer pointing at the null character.
952:
953: If \ is followed by 000, we return 0 and leave the string pointer
954: after the zeros. A value of 0 does not mean end of string. */
955:
956: static int
957: parse_escape (string_ptr)
958: char **string_ptr;
959: {
960: register int c = *(*string_ptr)++;
961: switch (c)
962: {
963: case 'a':
964: return '\a';
965: case 'b':
966: return '\b';
967: case 'e':
968: return 033;
969: case 'f':
970: return '\f';
971: case 'n':
972: return '\n';
973: case 'r':
974: return '\r';
975: case 't':
976: return '\t';
977: case 'v':
978: return '\v';
979: case '\n':
980: return -2;
981: case 0:
982: (*string_ptr)--;
983: return 0;
984: case '^':
985: c = *(*string_ptr)++;
986: if (c == '\\')
987: c = parse_escape (string_ptr);
988: if (c == '?')
989: return 0177;
990: return (c & 0200) | (c & 037);
991:
992: case '0':
993: case '1':
994: case '2':
995: case '3':
996: case '4':
997: case '5':
998: case '6':
999: case '7':
1000: {
1001: register int i = c - '0';
1002: register int count = 0;
1003: while (++count < 3)
1004: {
1005: if ((c = *(*string_ptr)++) >= '0' && c <= '7')
1006: {
1007: i *= 8;
1008: i += c - '0';
1009: }
1010: else
1011: {
1012: (*string_ptr)--;
1013: break;
1014: }
1015: }
1016: return i;
1017: }
1018: default:
1019: return c;
1020: }
1021: }
1022:
1023: static
1024: yyerror (s)
1025: char *s;
1026: {
1027: error (s);
1028: longjmp (parse_return_error, 1);
1029: }
1030:
1031: /* This page contains the entry point to this file. */
1032:
1033: /* Parse STRING as an expression, and complain if this fails
1034: to use up all of the contents of STRING. */
1035: /* We do not support C comments. They should be removed before
1036: this function is called. */
1037:
1038: int
1039: parse_c_expression (string)
1040: char *string;
1041: {
1042: lexptr = string;
1043:
1044: if (lexptr == 0 || *lexptr == 0) {
1045: error ("empty #if expression");
1046: return 0; /* don't include the #if group */
1047: }
1048:
1049: /* if there is some sort of scanning error, just return 0 and assume
1050: the parsing routine has printed an error message somewhere.
1051: there is surely a better thing to do than this. */
1052: if (setjmp(parse_return_error))
1053: return 0;
1054:
1055: if (yyparse ())
1056: return 0; /* actually this is never reached
1057: the way things stand. */
1058: if (*lexptr)
1059: error ("Junk after end of expression.");
1060:
1061: return expression_value; /* set by yyparse() */
1062: }
1063:
1064: #ifdef TEST_EXP_READER
1065: /* main program, for testing purposes. */
1066: main()
1067: {
1068: int n;
1069: char buf[1024];
1070: extern int yydebug;
1071: /*
1072: yydebug = 1;
1073: */
1074: initialize_random_junk ();
1075:
1076: for (;;) {
1077: printf("enter expression: ");
1078: n = 0;
1079: while ((buf[n] = getchar()) != '\n')
1080: n++;
1081: buf[n] = '\0';
1082: printf("parser returned %d\n", parse_c_expression(buf));
1083: }
1084: }
1085:
1086: /* table to tell if char can be part of a C identifier. */
1087: char is_idchar[256];
1088: /* table to tell if char can be first char of a c identifier. */
1089: char is_idstart[256];
1090: /* table to tell if c is horizontal space. isspace() thinks that
1091: newline is space; this is not a good idea for this program. */
1092: char is_hor_space[256];
1093:
1094: /*
1095: * initialize random junk in the hash table and maybe other places
1096: */
1097: initialize_random_junk()
1098: {
1099: register int i;
1100:
1101: /*
1102: * Set up is_idchar and is_idstart tables. These should be
1103: * faster than saying (is_alpha(c) || c == '_'), etc.
1104: * Must do set up these things before calling any routines tthat
1105: * refer to them.
1106: */
1107: for (i = 'a'; i <= 'z'; i++) {
1108: ++is_idchar[i - 'a' + 'A'];
1109: ++is_idchar[i];
1110: ++is_idstart[i - 'a' + 'A'];
1111: ++is_idstart[i];
1112: }
1113: for (i = '0'; i <= '9'; i++)
1114: ++is_idchar[i];
1115: ++is_idchar['_'];
1116: ++is_idstart['_'];
1117: #ifdef DOLLARS_IN_IDENTIFIERS
1118: ++is_idchar['$'];
1119: ++is_idstart['$'];
1120: #endif
1121:
1122: /* horizontal space table */
1123: ++is_hor_space[' '];
1124: ++is_hor_space['\t'];
1125: }
1126:
1127: error (msg)
1128: {
1129: printf("error: %s\n", msg);
1130: }
1131: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.