|
|
1.1 root 1:
2: /* A Bison parser, made from cexp.y */
3:
4: #define YYBISON 1 /* Identify Bison output. */
5:
6: #define INT 258
7: #define CHAR 259
8: #define NAME 260
9: #define ERROR 261
10: #define OR 262
11: #define AND 263
12: #define EQUAL 264
13: #define NOTEQUAL 265
14: #define LEQ 266
15: #define GEQ 267
16: #define LSH 268
17: #define RSH 269
18: #define UNARY 270
19:
20: #line 26 "cexp.y"
21:
22: #include "config.h"
23: #include <setjmp.h>
24: /* #define YYDEBUG 1 */
25:
26: #ifdef MULTIBYTE_CHARS
27: #include <stdlib.h>
28: #include <locale.h>
29: #endif
30:
31: typedef unsigned char U_CHAR;
32:
33: /* This is used for communicating lists of keywords with cccp.c. */
34: struct arglist {
35: struct arglist *next;
36: U_CHAR *name;
37: int length;
38: int argno;
39: };
40:
41: int yylex ();
42: void yyerror ();
43: int expression_value;
44:
45: static jmp_buf parse_return_error;
46:
47: /* Nonzero means count most punctuation as part of a name. */
48: static int keyword_parsing = 0;
49:
50: /* some external tables of character types */
51: extern unsigned char is_idstart[], is_idchar[], is_hor_space[];
52:
53: /* Flag for -pedantic. */
54: extern int pedantic;
55:
56: /* Flag for -traditional. */
57: extern int traditional;
58:
59: #ifndef CHAR_TYPE_SIZE
60: #define CHAR_TYPE_SIZE BITS_PER_UNIT
61: #endif
62:
63: #ifndef INT_TYPE_SIZE
64: #define INT_TYPE_SIZE BITS_PER_WORD
65: #endif
66:
67: #ifndef LONG_TYPE_SIZE
68: #define LONG_TYPE_SIZE BITS_PER_WORD
69: #endif
70:
71: #ifndef WCHAR_TYPE_SIZE
72: #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
73: #endif
74:
75: #line 81 "cexp.y"
76: typedef union {
77: struct constant {long value; int unsignedp;} integer;
78: struct name {U_CHAR *address; int length;} name;
79: struct arglist *keywords;
80: int voidval;
81: char *sval;
82: } YYSTYPE;
83:
84: #ifndef YYLTYPE
85: typedef
86: struct yyltype
87: {
88: int timestamp;
89: int first_line;
90: int first_column;
91: int last_line;
92: int last_column;
93: char *text;
94: }
95: yyltype;
96:
97: #define YYLTYPE yyltype
98: #endif
99:
100: #include <stdio.h>
101:
102: #ifndef __STDC__
103: #define const
104: #endif
105:
106:
107:
108: #define YYFINAL 73
109: #define YYFLAG -32768
110: #define YYNTBASE 34
111:
112: #define YYTRANSLATE(x) ((unsigned)(x) <= 270 ? yytranslate[x] : 39)
113:
114: static const char yytranslate[] = { 0,
115: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
116: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
117: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
118: 2, 2, 29, 2, 31, 2, 27, 14, 2, 32,
119: 33, 25, 23, 9, 24, 2, 26, 2, 2, 2,
120: 2, 2, 2, 2, 2, 2, 2, 8, 2, 17,
121: 2, 18, 7, 2, 2, 2, 2, 2, 2, 2,
122: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
123: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
124: 2, 2, 2, 13, 2, 2, 2, 2, 2, 2,
125: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
126: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
127: 2, 2, 2, 12, 2, 30, 2, 2, 2, 2,
128: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
129: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
130: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
131: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
132: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
133: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
134: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
135: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
136: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
137: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
138: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
139: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
140: 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
141: 6, 10, 11, 15, 16, 19, 20, 21, 22, 28
142: };
143:
144: static const short yyprhs[] = { 0,
145: 0, 2, 4, 8, 11, 14, 17, 20, 23, 24,
146: 31, 35, 39, 43, 47, 51, 55, 59, 63, 67,
147: 71, 75, 79, 83, 87, 91, 95, 99, 103, 107,
148: 113, 115, 117, 119, 120, 125
149: };
150:
151: static const short yyrhs[] = { 35,
152: 0, 36, 0, 35, 9, 36, 0, 24, 36, 0,
153: 29, 36, 0, 23, 36, 0, 30, 36, 0, 31,
154: 5, 0, 0, 31, 5, 37, 32, 38, 33, 0,
155: 32, 35, 33, 0, 36, 25, 36, 0, 36, 26,
156: 36, 0, 36, 27, 36, 0, 36, 23, 36, 0,
157: 36, 24, 36, 0, 36, 21, 36, 0, 36, 22,
158: 36, 0, 36, 15, 36, 0, 36, 16, 36, 0,
159: 36, 19, 36, 0, 36, 20, 36, 0, 36, 17,
160: 36, 0, 36, 18, 36, 0, 36, 14, 36, 0,
161: 36, 13, 36, 0, 36, 12, 36, 0, 36, 11,
162: 36, 0, 36, 10, 36, 0, 36, 7, 36, 8,
163: 36, 0, 3, 0, 4, 0, 5, 0, 0, 32,
164: 38, 33, 38, 0, 5, 38, 0
165: };
166:
167: #if YYDEBUG != 0
168: static const short yyrline[] = { 0,
169: 113, 118, 119, 126, 129, 132, 134, 137, 141, 143,
170: 148, 153, 159, 170, 181, 184, 187, 193, 199, 202,
171: 205, 211, 217, 223, 229, 232, 235, 238, 241, 244,
172: 247, 249, 251, 256, 258, 271
173: };
174:
175: static const char * const yytname[] = { "$","error","$illegal.","INT","CHAR",
176: "NAME","ERROR","'?'","':'","','","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL",
177: "'<'","'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'","UNARY","'!'",
178: "'~'","'#'","'('","')'","start","exp1","exp","@1","keywords",""
179: };
180: #endif
181:
182: static const short yyr1[] = { 0,
183: 34, 35, 35, 36, 36, 36, 36, 36, 37, 36,
184: 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
185: 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
186: 36, 36, 36, 38, 38, 38
187: };
188:
189: static const short yyr2[] = { 0,
190: 1, 1, 3, 2, 2, 2, 2, 2, 0, 6,
191: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
192: 3, 3, 3, 3, 3, 3, 3, 3, 3, 5,
193: 1, 1, 1, 0, 4, 2
194: };
195:
196: static const short yydefact[] = { 0,
197: 31, 32, 33, 0, 0, 0, 0, 0, 0, 1,
198: 2, 6, 4, 5, 7, 8, 0, 0, 0, 0,
199: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200: 0, 0, 0, 0, 0, 0, 0, 0, 11, 3,
201: 0, 29, 28, 27, 26, 25, 19, 20, 23, 24,
202: 21, 22, 17, 18, 15, 16, 12, 13, 14, 34,
203: 0, 34, 34, 0, 30, 36, 0, 10, 34, 35,
204: 0, 0, 0
205: };
206:
207: static const short yydefgoto[] = { 71,
208: 10, 11, 38, 64
209: };
210:
211: static const short yypact[] = { 31,
212: -32768,-32768,-32768, 31, 31, 31, 31, 4, 31, 3,
213: 80,-32768,-32768,-32768,-32768, 6, 32, 31, 31, 31,
214: 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
215: 31, 31, 31, 31, 31, 31, 31, 7,-32768, 80,
216: 59, 97, 113, 128, 142, 155, 25, 25, 162, 162,
217: 162, 162, 167, 167, -19, -19,-32768,-32768,-32768, 5,
218: 31, 5, 5, -20, 80,-32768, 20,-32768, 5,-32768,
219: 40, 56,-32768
220: };
221:
222: static const short yypgoto[] = {-32768,
223: 49, -4,-32768, -58
224: };
225:
226:
227: #define YYLAST 194
228:
229:
230: static const short yytable[] = { 12,
231: 13, 14, 15, 66, 67, 35, 36, 37, 16, 62,
232: 70, 18, 68, 40, 41, 42, 43, 44, 45, 46,
233: 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
234: 57, 58, 59, 1, 2, 3, 63, -9, 60, 72,
235: 18, 27, 28, 29, 30, 31, 32, 33, 34, 35,
236: 36, 37, 69, 4, 5, 73, 65, 17, 0, 6,
237: 7, 8, 9, 0, 39, 19, 61, 0, 20, 21,
238: 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
239: 32, 33, 34, 35, 36, 37, 19, 0, 0, 20,
240: 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
241: 31, 32, 33, 34, 35, 36, 37, 21, 22, 23,
242: 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
243: 34, 35, 36, 37, 22, 23, 24, 25, 26, 27,
244: 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
245: 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
246: 33, 34, 35, 36, 37, 24, 25, 26, 27, 28,
247: 29, 30, 31, 32, 33, 34, 35, 36, 37, 25,
248: 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
249: 36, 37, 31, 32, 33, 34, 35, 36, 37, 33,
250: 34, 35, 36, 37
251: };
252:
253: static const short yycheck[] = { 4,
254: 5, 6, 7, 62, 63, 25, 26, 27, 5, 5,
255: 69, 9, 33, 18, 19, 20, 21, 22, 23, 24,
256: 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
257: 35, 36, 37, 3, 4, 5, 32, 32, 32, 0,
258: 9, 17, 18, 19, 20, 21, 22, 23, 24, 25,
259: 26, 27, 33, 23, 24, 0, 61, 9, -1, 29,
260: 30, 31, 32, -1, 33, 7, 8, -1, 10, 11,
261: 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
262: 22, 23, 24, 25, 26, 27, 7, -1, -1, 10,
263: 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
264: 21, 22, 23, 24, 25, 26, 27, 11, 12, 13,
265: 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
266: 24, 25, 26, 27, 12, 13, 14, 15, 16, 17,
267: 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
268: 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
269: 23, 24, 25, 26, 27, 14, 15, 16, 17, 18,
270: 19, 20, 21, 22, 23, 24, 25, 26, 27, 15,
271: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
272: 26, 27, 21, 22, 23, 24, 25, 26, 27, 23,
273: 24, 25, 26, 27
274: };
275: /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
276: #line 3 "bison.simple"
277:
278: /* Skeleton output parser for bison,
279: Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
280:
281: This program is free software; you can redistribute it and/or modify
282: it under the terms of the GNU General Public License as published by
283: the Free Software Foundation; either version 1, or (at your option)
284: any later version.
285:
286: This program is distributed in the hope that it will be useful,
287: but WITHOUT ANY WARRANTY; without even the implied warranty of
288: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
289: GNU General Public License for more details.
290:
291: You should have received a copy of the GNU General Public License
292: along with this program; if not, write to the Free Software
293: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
294:
295:
296: #ifndef alloca
297: #ifdef __GNUC__
298: #define alloca __builtin_alloca
299: #else /* not GNU C. */
300: #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
301: #include <alloca.h>
302: #else /* not sparc */
303: #if defined (MSDOS) && !defined (__TURBOC__)
304: #include <malloc.h>
305: #else /* not MSDOS, or __TURBOC__ */
306: #if defined(_AIX)
307: #include <malloc.h>
308: #pragma alloca
309: #endif /* not _AIX */
310: #endif /* not MSDOS, or __TURBOC__ */
311: #endif /* not sparc. */
312: #endif /* not GNU C. */
313: #endif /* alloca not defined. */
314:
315: /* This is the parser code that is written into each bison parser
316: when the %semantic_parser declaration is not specified in the grammar.
317: It was written by Richard Stallman by simplifying the hairy parser
318: used when %semantic_parser is specified. */
319:
320: /* Note: there must be only one dollar sign in this file.
321: It is replaced by the list of actions, each action
322: as one case of the switch. */
323:
324: #define yyerrok (yyerrstatus = 0)
325: #define yyclearin (yychar = YYEMPTY)
326: #define YYEMPTY -2
327: #define YYEOF 0
328: #define YYACCEPT return(0)
329: #define YYABORT return(1)
330: #define YYERROR goto yyerrlab1
331: /* Like YYERROR except do call yyerror.
332: This remains here temporarily to ease the
333: transition to the new meaning of YYERROR, for GCC.
334: Once GCC version 2 has supplanted version 1, this can go. */
335: #define YYFAIL goto yyerrlab
336: #define YYRECOVERING() (!!yyerrstatus)
337: #define YYBACKUP(token, value) \
338: do \
339: if (yychar == YYEMPTY && yylen == 1) \
340: { yychar = (token), yylval = (value); \
341: yychar1 = YYTRANSLATE (yychar); \
342: YYPOPSTACK; \
343: goto yybackup; \
344: } \
345: else \
346: { yyerror ("syntax error: cannot back up"); YYERROR; } \
347: while (0)
348:
349: #define YYTERROR 1
350: #define YYERRCODE 256
351:
352: #ifndef YYPURE
353: #define YYLEX yylex()
354: #endif
355:
356: #ifdef YYPURE
357: #ifdef YYLSP_NEEDED
358: #define YYLEX yylex(&yylval, &yylloc)
359: #else
360: #define YYLEX yylex(&yylval)
361: #endif
362: #endif
363:
364: /* If nonreentrant, generate the variables here */
365:
366: #ifndef YYPURE
367:
368: int yychar; /* the lookahead symbol */
369: YYSTYPE yylval; /* the semantic value of the */
370: /* lookahead symbol */
371:
372: #ifdef YYLSP_NEEDED
373: YYLTYPE yylloc; /* location data for the lookahead */
374: /* symbol */
375: #endif
376:
377: int yynerrs; /* number of parse errors so far */
378: #endif /* not YYPURE */
379:
380: #if YYDEBUG != 0
381: int yydebug; /* nonzero means print parse trace */
382: /* Since this is uninitialized, it does not stop multiple parsers
383: from coexisting. */
384: #endif
385:
386: /* YYINITDEPTH indicates the initial size of the parser's stacks */
387:
388: #ifndef YYINITDEPTH
389: #define YYINITDEPTH 200
390: #endif
391:
392: /* YYMAXDEPTH is the maximum size the stacks can grow to
393: (effective only if the built-in stack extension method is used). */
394:
395: #if YYMAXDEPTH == 0
396: #undef YYMAXDEPTH
397: #endif
398:
399: #ifndef YYMAXDEPTH
400: #define YYMAXDEPTH 10000
401: #endif
402:
403: #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
404: #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
405: #else /* not GNU C or C++ */
406: #ifndef __cplusplus
407:
408: /* This is the most reliable way to avoid incompatibilities
409: in available built-in functions on various systems. */
410: static void
411: __yy_bcopy (from, to, count)
412: char *from;
413: char *to;
414: int count;
415: {
416: register char *f = from;
417: register char *t = to;
418: register int i = count;
419:
420: while (i-- > 0)
421: *t++ = *f++;
422: }
423:
424: #else /* __cplusplus */
425:
426: /* This is the most reliable way to avoid incompatibilities
427: in available built-in functions on various systems. */
428: static void
429: __yy_bcopy (char *from, char *to, int count)
430: {
431: register char *f = from;
432: register char *t = to;
433: register int i = count;
434:
435: while (i-- > 0)
436: *t++ = *f++;
437: }
438:
439: #endif
440: #endif
441:
442: #line 169 "bison.simple"
443: int
444: yyparse()
445: {
446: register int yystate;
447: register int yyn;
448: register short *yyssp;
449: register YYSTYPE *yyvsp;
450: int yyerrstatus; /* number of tokens to shift before error messages enabled */
451: int yychar1; /* lookahead token as an internal (translated) token number */
452:
453: short yyssa[YYINITDEPTH]; /* the state stack */
454: YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
455:
456: short *yyss = yyssa; /* refer to the stacks thru separate pointers */
457: YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
458:
459: #ifdef YYLSP_NEEDED
460: YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
461: YYLTYPE *yyls = yylsa;
462: YYLTYPE *yylsp;
463:
1.1.1.2 ! root 464: #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
1.1 root 465: #else
1.1.1.2 ! root 466: #define YYPOPSTACK (yyvsp--, yyssp--)
1.1 root 467: #endif
468:
469: int yystacksize = YYINITDEPTH;
470:
471: #ifdef YYPURE
472: int yychar;
473: YYSTYPE yylval;
474: int yynerrs;
475: #ifdef YYLSP_NEEDED
476: YYLTYPE yylloc;
477: #endif
478: #endif
479:
480: YYSTYPE yyval; /* the variable used to return */
481: /* semantic values from the action */
482: /* routines */
483:
484: int yylen;
485:
486: #if YYDEBUG != 0
487: if (yydebug)
488: fprintf(stderr, "Starting parse\n");
489: #endif
490:
491: yystate = 0;
492: yyerrstatus = 0;
493: yynerrs = 0;
494: yychar = YYEMPTY; /* Cause a token to be read. */
495:
496: /* Initialize stack pointers.
497: Waste one element of value and location stack
498: so that they stay on the same level as the state stack. */
499:
500: yyssp = yyss - 1;
501: yyvsp = yyvs;
502: #ifdef YYLSP_NEEDED
503: yylsp = yyls;
504: #endif
505:
506: /* Push a new state, which is found in yystate . */
507: /* In all cases, when you get here, the value and location stacks
508: have just been pushed. so pushing a state here evens the stacks. */
509: yynewstate:
510:
511: *++yyssp = yystate;
512:
513: if (yyssp >= yyss + yystacksize - 1)
514: {
515: /* Give user a chance to reallocate the stack */
516: /* Use copies of these so that the &'s don't force the real ones into memory. */
517: YYSTYPE *yyvs1 = yyvs;
518: short *yyss1 = yyss;
519: #ifdef YYLSP_NEEDED
520: YYLTYPE *yyls1 = yyls;
521: #endif
522:
523: /* Get the current used size of the three stacks, in elements. */
524: int size = yyssp - yyss + 1;
525:
526: #ifdef yyoverflow
527: /* Each stack pointer address is followed by the size of
528: the data in use in that stack, in bytes. */
529: yyoverflow("parser stack overflow",
530: &yyss1, size * sizeof (*yyssp),
531: &yyvs1, size * sizeof (*yyvsp),
532: #ifdef YYLSP_NEEDED
533: &yyls1, size * sizeof (*yylsp),
534: #endif
535: &yystacksize);
536:
537: yyss = yyss1; yyvs = yyvs1;
538: #ifdef YYLSP_NEEDED
539: yyls = yyls1;
540: #endif
541: #else /* no yyoverflow */
542: /* Extend the stack our own way. */
543: if (yystacksize >= YYMAXDEPTH)
544: {
545: yyerror("parser stack overflow");
546: return 2;
547: }
548: yystacksize *= 2;
549: if (yystacksize > YYMAXDEPTH)
550: yystacksize = YYMAXDEPTH;
551: yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
552: __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
553: yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
554: __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
555: #ifdef YYLSP_NEEDED
556: yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
557: __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
558: #endif
559: #endif /* no yyoverflow */
560:
561: yyssp = yyss + size - 1;
562: yyvsp = yyvs + size - 1;
563: #ifdef YYLSP_NEEDED
564: yylsp = yyls + size - 1;
565: #endif
566:
567: #if YYDEBUG != 0
568: if (yydebug)
569: fprintf(stderr, "Stack size increased to %d\n", yystacksize);
570: #endif
571:
572: if (yyssp >= yyss + yystacksize - 1)
573: YYABORT;
574: }
575:
576: #if YYDEBUG != 0
577: if (yydebug)
578: fprintf(stderr, "Entering state %d\n", yystate);
579: #endif
580:
581: yybackup:
582:
583: /* Do appropriate processing given the current state. */
584: /* Read a lookahead token if we need one and don't already have one. */
585: /* yyresume: */
586:
587: /* First try to decide what to do without reference to lookahead token. */
588:
589: yyn = yypact[yystate];
590: if (yyn == YYFLAG)
591: goto yydefault;
592:
593: /* Not known => get a lookahead token if don't already have one. */
594:
595: /* yychar is either YYEMPTY or YYEOF
596: or a valid token in external form. */
597:
598: if (yychar == YYEMPTY)
599: {
600: #if YYDEBUG != 0
601: if (yydebug)
602: fprintf(stderr, "Reading a token: ");
603: #endif
604: yychar = YYLEX;
605: }
606:
607: /* Convert token to internal form (in yychar1) for indexing tables with */
608:
609: if (yychar <= 0) /* This means end of input. */
610: {
611: yychar1 = 0;
612: yychar = YYEOF; /* Don't call YYLEX any more */
613:
614: #if YYDEBUG != 0
615: if (yydebug)
616: fprintf(stderr, "Now at end of input.\n");
617: #endif
618: }
619: else
620: {
621: yychar1 = YYTRANSLATE(yychar);
622:
623: #if YYDEBUG != 0
624: if (yydebug)
625: {
626: fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
627: /* Give the individual parser a way to print the precise meaning
628: of a token, for further debugging info. */
629: #ifdef YYPRINT
630: YYPRINT (stderr, yychar, yylval);
631: #endif
632: fprintf (stderr, ")\n");
633: }
634: #endif
635: }
636:
637: yyn += yychar1;
638: if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
639: goto yydefault;
640:
641: yyn = yytable[yyn];
642:
643: /* yyn is what to do for this token type in this state.
644: Negative => reduce, -yyn is rule number.
645: Positive => shift, yyn is new state.
646: New state is final state => don't bother to shift,
647: just return success.
648: 0, or most negative number => error. */
649:
650: if (yyn < 0)
651: {
652: if (yyn == YYFLAG)
653: goto yyerrlab;
654: yyn = -yyn;
655: goto yyreduce;
656: }
657: else if (yyn == 0)
658: goto yyerrlab;
659:
660: if (yyn == YYFINAL)
661: YYACCEPT;
662:
663: /* Shift the lookahead token. */
664:
665: #if YYDEBUG != 0
666: if (yydebug)
667: fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
668: #endif
669:
670: /* Discard the token being shifted unless it is eof. */
671: if (yychar != YYEOF)
672: yychar = YYEMPTY;
673:
674: *++yyvsp = yylval;
675: #ifdef YYLSP_NEEDED
676: *++yylsp = yylloc;
677: #endif
678:
679: /* count tokens shifted since error; after three, turn off error status. */
680: if (yyerrstatus) yyerrstatus--;
681:
682: yystate = yyn;
683: goto yynewstate;
684:
685: /* Do the default action for the current state. */
686: yydefault:
687:
688: yyn = yydefact[yystate];
689: if (yyn == 0)
690: goto yyerrlab;
691:
692: /* Do a reduction. yyn is the number of a rule to reduce with. */
693: yyreduce:
694: yylen = yyr2[yyn];
695: yyval = yyvsp[1-yylen]; /* implement default value of the action */
696:
697: #if YYDEBUG != 0
698: if (yydebug)
699: {
700: int i;
701:
702: fprintf (stderr, "Reducing via rule %d (line %d), ",
703: yyn, yyrline[yyn]);
704:
705: /* Print the symboles being reduced, and their result. */
706: for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
707: fprintf (stderr, "%s ", yytname[yyrhs[i]]);
708: fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
709: }
710: #endif
711:
712:
713: switch (yyn) {
714:
715: case 1:
716: #line 114 "cexp.y"
717: { expression_value = yyvsp[0].integer.value; ;
718: break;}
719: case 3:
720: #line 120 "cexp.y"
721: { if (pedantic)
722: pedwarn ("comma operator in operand of `#if'");
723: yyval.integer = yyvsp[0].integer; ;
724: break;}
725: case 4:
726: #line 127 "cexp.y"
727: { yyval.integer.value = - yyvsp[0].integer.value;
728: yyval.integer.unsignedp = yyvsp[0].integer.unsignedp; ;
729: break;}
730: case 5:
731: #line 130 "cexp.y"
732: { yyval.integer.value = ! yyvsp[0].integer.value;
733: yyval.integer.unsignedp = 0; ;
734: break;}
735: case 6:
736: #line 133 "cexp.y"
737: { yyval.integer = yyvsp[0].integer; ;
738: break;}
739: case 7:
740: #line 135 "cexp.y"
741: { yyval.integer.value = ~ yyvsp[0].integer.value;
742: yyval.integer.unsignedp = yyvsp[0].integer.unsignedp; ;
743: break;}
744: case 8:
745: #line 138 "cexp.y"
746: { yyval.integer.value = check_assertion (yyvsp[0].name.address, yyvsp[0].name.length,
747: 0, 0);
748: yyval.integer.unsignedp = 0; ;
749: break;}
750: case 9:
751: #line 142 "cexp.y"
752: { keyword_parsing = 1; ;
753: break;}
754: case 10:
755: #line 144 "cexp.y"
756: { yyval.integer.value = check_assertion (yyvsp[-4].name.address, yyvsp[-4].name.length,
757: 1, yyvsp[-1].keywords);
758: keyword_parsing = 0;
759: yyval.integer.unsignedp = 0; ;
760: break;}
761: case 11:
762: #line 149 "cexp.y"
763: { yyval.integer = yyvsp[-1].integer; ;
764: break;}
765: case 12:
766: #line 154 "cexp.y"
767: { yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp;
768: if (yyval.integer.unsignedp)
769: yyval.integer.value = (unsigned) yyvsp[-2].integer.value * yyvsp[0].integer.value;
770: else
771: yyval.integer.value = yyvsp[-2].integer.value * yyvsp[0].integer.value; ;
772: break;}
773: case 13:
774: #line 160 "cexp.y"
775: { if (yyvsp[0].integer.value == 0)
776: {
777: error ("division by zero in #if");
778: yyvsp[0].integer.value = 1;
779: }
780: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp;
781: if (yyval.integer.unsignedp)
782: yyval.integer.value = (unsigned) yyvsp[-2].integer.value / yyvsp[0].integer.value;
783: else
784: yyval.integer.value = yyvsp[-2].integer.value / yyvsp[0].integer.value; ;
785: break;}
786: case 14:
787: #line 171 "cexp.y"
788: { if (yyvsp[0].integer.value == 0)
789: {
790: error ("division by zero in #if");
791: yyvsp[0].integer.value = 1;
792: }
793: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp;
794: if (yyval.integer.unsignedp)
795: yyval.integer.value = (unsigned) yyvsp[-2].integer.value % yyvsp[0].integer.value;
796: else
797: yyval.integer.value = yyvsp[-2].integer.value % yyvsp[0].integer.value; ;
798: break;}
799: case 15:
800: #line 182 "cexp.y"
801: { yyval.integer.value = yyvsp[-2].integer.value + yyvsp[0].integer.value;
802: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp; ;
803: break;}
804: case 16:
805: #line 185 "cexp.y"
806: { yyval.integer.value = yyvsp[-2].integer.value - yyvsp[0].integer.value;
807: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp; ;
808: break;}
809: case 17:
810: #line 188 "cexp.y"
811: { yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp;
812: if (yyval.integer.unsignedp)
813: yyval.integer.value = (unsigned) yyvsp[-2].integer.value << yyvsp[0].integer.value;
814: else
815: yyval.integer.value = yyvsp[-2].integer.value << yyvsp[0].integer.value; ;
816: break;}
817: case 18:
818: #line 194 "cexp.y"
819: { yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp;
820: if (yyval.integer.unsignedp)
821: yyval.integer.value = (unsigned) yyvsp[-2].integer.value >> yyvsp[0].integer.value;
822: else
823: yyval.integer.value = yyvsp[-2].integer.value >> yyvsp[0].integer.value; ;
824: break;}
825: case 19:
826: #line 200 "cexp.y"
827: { yyval.integer.value = (yyvsp[-2].integer.value == yyvsp[0].integer.value);
828: yyval.integer.unsignedp = 0; ;
829: break;}
830: case 20:
831: #line 203 "cexp.y"
832: { yyval.integer.value = (yyvsp[-2].integer.value != yyvsp[0].integer.value);
833: yyval.integer.unsignedp = 0; ;
834: break;}
835: case 21:
836: #line 206 "cexp.y"
837: { yyval.integer.unsignedp = 0;
838: if (yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp)
839: yyval.integer.value = (unsigned) yyvsp[-2].integer.value <= yyvsp[0].integer.value;
840: else
841: yyval.integer.value = yyvsp[-2].integer.value <= yyvsp[0].integer.value; ;
842: break;}
843: case 22:
844: #line 212 "cexp.y"
845: { yyval.integer.unsignedp = 0;
846: if (yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp)
847: yyval.integer.value = (unsigned) yyvsp[-2].integer.value >= yyvsp[0].integer.value;
848: else
849: yyval.integer.value = yyvsp[-2].integer.value >= yyvsp[0].integer.value; ;
850: break;}
851: case 23:
852: #line 218 "cexp.y"
853: { yyval.integer.unsignedp = 0;
854: if (yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp)
855: yyval.integer.value = (unsigned) yyvsp[-2].integer.value < yyvsp[0].integer.value;
856: else
857: yyval.integer.value = yyvsp[-2].integer.value < yyvsp[0].integer.value; ;
858: break;}
859: case 24:
860: #line 224 "cexp.y"
861: { yyval.integer.unsignedp = 0;
862: if (yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp)
863: yyval.integer.value = (unsigned) yyvsp[-2].integer.value > yyvsp[0].integer.value;
864: else
865: yyval.integer.value = yyvsp[-2].integer.value > yyvsp[0].integer.value; ;
866: break;}
867: case 25:
868: #line 230 "cexp.y"
869: { yyval.integer.value = yyvsp[-2].integer.value & yyvsp[0].integer.value;
870: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp; ;
871: break;}
872: case 26:
873: #line 233 "cexp.y"
874: { yyval.integer.value = yyvsp[-2].integer.value ^ yyvsp[0].integer.value;
875: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp; ;
876: break;}
877: case 27:
878: #line 236 "cexp.y"
879: { yyval.integer.value = yyvsp[-2].integer.value | yyvsp[0].integer.value;
880: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp; ;
881: break;}
882: case 28:
883: #line 239 "cexp.y"
884: { yyval.integer.value = (yyvsp[-2].integer.value && yyvsp[0].integer.value);
885: yyval.integer.unsignedp = 0; ;
886: break;}
887: case 29:
888: #line 242 "cexp.y"
889: { yyval.integer.value = (yyvsp[-2].integer.value || yyvsp[0].integer.value);
890: yyval.integer.unsignedp = 0; ;
891: break;}
892: case 30:
893: #line 245 "cexp.y"
894: { yyval.integer.value = yyvsp[-4].integer.value ? yyvsp[-2].integer.value : yyvsp[0].integer.value;
895: yyval.integer.unsignedp = yyvsp[-2].integer.unsignedp || yyvsp[0].integer.unsignedp; ;
896: break;}
897: case 31:
898: #line 248 "cexp.y"
899: { yyval.integer = yylval.integer; ;
900: break;}
901: case 32:
902: #line 250 "cexp.y"
903: { yyval.integer = yylval.integer; ;
904: break;}
905: case 33:
906: #line 252 "cexp.y"
907: { yyval.integer.value = 0;
908: yyval.integer.unsignedp = 0; ;
909: break;}
910: case 34:
911: #line 257 "cexp.y"
912: { yyval.keywords = 0; ;
913: break;}
914: case 35:
915: #line 259 "cexp.y"
916: { struct arglist *temp;
917: yyval.keywords = (struct arglist *) xmalloc (sizeof (struct arglist));
918: yyval.keywords->next = yyvsp[-2].keywords;
919: yyval.keywords->name = (U_CHAR *) "(";
920: yyval.keywords->length = 1;
921: temp = yyval.keywords;
922: while (temp != 0 && temp->next != 0)
923: temp = temp->next;
924: temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
925: temp->next->next = yyvsp[0].keywords;
926: temp->next->name = (U_CHAR *) ")";
927: temp->next->length = 1; ;
928: break;}
929: case 36:
930: #line 272 "cexp.y"
931: { yyval.keywords = (struct arglist *) xmalloc (sizeof (struct arglist));
932: yyval.keywords->name = yyvsp[-1].name.address;
933: yyval.keywords->length = yyvsp[-1].name.length;
934: yyval.keywords->next = yyvsp[0].keywords; ;
935: break;}
936: }
937: /* the action file gets copied in in place of this dollarsign */
938: #line 440 "bison.simple"
939:
940: yyvsp -= yylen;
941: yyssp -= yylen;
942: #ifdef YYLSP_NEEDED
943: yylsp -= yylen;
944: #endif
945:
946: #if YYDEBUG != 0
947: if (yydebug)
948: {
949: short *ssp1 = yyss - 1;
950: fprintf (stderr, "state stack now");
951: while (ssp1 != yyssp)
952: fprintf (stderr, " %d", *++ssp1);
953: fprintf (stderr, "\n");
954: }
955: #endif
956:
957: *++yyvsp = yyval;
958:
959: #ifdef YYLSP_NEEDED
960: yylsp++;
961: if (yylen == 0)
962: {
963: yylsp->first_line = yylloc.first_line;
964: yylsp->first_column = yylloc.first_column;
965: yylsp->last_line = (yylsp-1)->last_line;
966: yylsp->last_column = (yylsp-1)->last_column;
967: yylsp->text = 0;
968: }
969: else
970: {
971: yylsp->last_line = (yylsp+yylen-1)->last_line;
972: yylsp->last_column = (yylsp+yylen-1)->last_column;
973: }
974: #endif
975:
976: /* Now "shift" the result of the reduction.
977: Determine what state that goes to,
978: based on the state we popped back to
979: and the rule number reduced by. */
980:
981: yyn = yyr1[yyn];
982:
983: yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
984: if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
985: yystate = yytable[yystate];
986: else
987: yystate = yydefgoto[yyn - YYNTBASE];
988:
989: goto yynewstate;
990:
991: yyerrlab: /* here on detecting error */
992:
993: if (! yyerrstatus)
994: /* If not already recovering from an error, report this error. */
995: {
996: ++yynerrs;
997:
998: #ifdef YYERROR_VERBOSE
999: yyn = yypact[yystate];
1000:
1001: if (yyn > YYFLAG && yyn < YYLAST)
1002: {
1003: int size = 0;
1004: char *msg;
1005: int x, count;
1006:
1007: count = 0;
1008: for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
1009: if (yycheck[x + yyn] == x)
1010: size += strlen(yytname[x]) + 15, count++;
1011: msg = (char *) malloc(size + 15);
1012: if (msg != 0)
1013: {
1014: strcpy(msg, "parse error");
1015:
1016: if (count < 5)
1017: {
1018: count = 0;
1019: for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
1020: if (yycheck[x + yyn] == x)
1021: {
1022: strcat(msg, count == 0 ? ", expecting `" : " or `");
1023: strcat(msg, yytname[x]);
1024: strcat(msg, "'");
1025: count++;
1026: }
1027: }
1028: yyerror(msg);
1029: free(msg);
1030: }
1031: else
1032: yyerror ("parse error; also virtual memory exceeded");
1033: }
1034: else
1035: #endif /* YYERROR_VERBOSE */
1036: yyerror("parse error");
1037: }
1038:
1039: yyerrlab1: /* here on error raised explicitly by an action */
1040:
1041: if (yyerrstatus == 3)
1042: {
1043: /* if just tried and failed to reuse lookahead token after an error, discard it. */
1044:
1045: /* return failure if at end of input */
1046: if (yychar == YYEOF)
1047: YYABORT;
1048:
1049: #if YYDEBUG != 0
1050: if (yydebug)
1051: fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1052: #endif
1053:
1054: yychar = YYEMPTY;
1055: }
1056:
1057: /* Else will try to reuse lookahead token
1058: after shifting the error token. */
1059:
1060: yyerrstatus = 3; /* Each real token shifted decrements this */
1061:
1062: goto yyerrhandle;
1063:
1064: yyerrdefault: /* current state does not do anything special for the error token. */
1065:
1066: #if 0
1067: /* This is wrong; only states that explicitly want error tokens
1068: should shift them. */
1069: yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1070: if (yyn) goto yydefault;
1071: #endif
1072:
1073: yyerrpop: /* pop the current state because it cannot handle the error token */
1074:
1075: if (yyssp == yyss) YYABORT;
1076: yyvsp--;
1077: yystate = *--yyssp;
1078: #ifdef YYLSP_NEEDED
1079: yylsp--;
1080: #endif
1081:
1082: #if YYDEBUG != 0
1083: if (yydebug)
1084: {
1085: short *ssp1 = yyss - 1;
1086: fprintf (stderr, "Error: state stack now");
1087: while (ssp1 != yyssp)
1088: fprintf (stderr, " %d", *++ssp1);
1089: fprintf (stderr, "\n");
1090: }
1091: #endif
1092:
1093: yyerrhandle:
1094:
1095: yyn = yypact[yystate];
1096: if (yyn == YYFLAG)
1097: goto yyerrdefault;
1098:
1099: yyn += YYTERROR;
1100: if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1101: goto yyerrdefault;
1102:
1103: yyn = yytable[yyn];
1104: if (yyn < 0)
1105: {
1106: if (yyn == YYFLAG)
1107: goto yyerrpop;
1108: yyn = -yyn;
1109: goto yyreduce;
1110: }
1111: else if (yyn == 0)
1112: goto yyerrpop;
1113:
1114: if (yyn == YYFINAL)
1115: YYACCEPT;
1116:
1117: #if YYDEBUG != 0
1118: if (yydebug)
1119: fprintf(stderr, "Shifting error token, ");
1120: #endif
1121:
1122: *++yyvsp = yylval;
1123: #ifdef YYLSP_NEEDED
1124: *++yylsp = yylloc;
1125: #endif
1126:
1127: yystate = yyn;
1128: goto yynewstate;
1129: }
1130: #line 277 "cexp.y"
1131:
1132:
1133: /* During parsing of a C expression, the pointer to the next character
1134: is in this variable. */
1135:
1136: static char *lexptr;
1137:
1138: /* Take care of parsing a number (anything that starts with a digit).
1139: Set yylval and return the token type; update lexptr.
1140: LEN is the number of characters in it. */
1141:
1142: /* maybe needs to actually deal with floating point numbers */
1143:
1144: int
1145: parse_number (olen)
1146: int olen;
1147: {
1148: register char *p = lexptr;
1149: register long n = 0;
1150: register int c;
1151: register int base = 10;
1152: register int len = olen;
1153:
1154: for (c = 0; c < len; c++)
1155: if (p[c] == '.') {
1156: /* It's a float since it contains a point. */
1157: yyerror ("floating point numbers not allowed in #if expressions");
1158: return ERROR;
1159: }
1160:
1161: yylval.integer.unsignedp = 0;
1162:
1163: if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
1164: p += 2;
1165: base = 16;
1166: len -= 2;
1167: }
1168: else if (*p == '0')
1169: base = 8;
1170:
1171: while (len > 0) {
1172: c = *p++;
1173: len--;
1174: if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
1175:
1176: if (c >= '0' && c <= '9') {
1177: n *= base;
1178: n += c - '0';
1179: } else if (base == 16 && c >= 'a' && c <= 'f') {
1180: n *= base;
1181: n += c - 'a' + 10;
1182: } else {
1183: /* `l' means long, and `u' means unsigned. */
1184: while (1) {
1185: if (c == 'l' || c == 'L')
1186: ;
1187: else if (c == 'u' || c == 'U')
1188: yylval.integer.unsignedp = 1;
1189: else
1190: break;
1191:
1192: if (len == 0)
1193: break;
1194: c = *p++;
1195: len--;
1196: }
1197: /* Don't look for any more digits after the suffixes. */
1198: break;
1199: }
1200: }
1201:
1202: if (len != 0) {
1203: yyerror ("Invalid number in #if expression");
1204: return ERROR;
1205: }
1206:
1207: /* If too big to be signed, consider it unsigned. */
1208: if (n < 0)
1209: yylval.integer.unsignedp = 1;
1210:
1211: lexptr = p;
1212: yylval.integer.value = n;
1213: return INT;
1214: }
1215:
1216: struct token {
1217: char *operator;
1218: int token;
1219: };
1220:
1221: #ifndef NULL
1222: #define NULL 0
1223: #endif
1224:
1225: static struct token tokentab2[] = {
1226: {"&&", AND},
1227: {"||", OR},
1228: {"<<", LSH},
1229: {">>", RSH},
1230: {"==", EQUAL},
1231: {"!=", NOTEQUAL},
1232: {"<=", LEQ},
1233: {">=", GEQ},
1234: {"++", ERROR},
1235: {"--", ERROR},
1236: {NULL, ERROR}
1237: };
1238:
1239: /* Read one token, getting characters through lexptr. */
1240:
1241: int
1242: yylex ()
1243: {
1244: register int c;
1245: register int namelen;
1246: register char *tokstart;
1247: register struct token *toktab;
1248: int wide_flag;
1249:
1250: retry:
1251:
1252: tokstart = lexptr;
1253: c = *tokstart;
1254: /* See if it is a special token of length 2. */
1255: if (! keyword_parsing)
1256: for (toktab = tokentab2; toktab->operator != NULL; toktab++)
1257: if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
1258: lexptr += 2;
1259: if (toktab->token == ERROR)
1260: {
1261: char *buf = (char *) alloca (40);
1262: sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
1263: yyerror (buf);
1264: }
1265: return toktab->token;
1266: }
1267:
1268: switch (c) {
1269: case 0:
1270: return 0;
1271:
1272: case ' ':
1273: case '\t':
1274: case '\r':
1275: case '\n':
1276: lexptr++;
1277: goto retry;
1278:
1279: case 'L':
1280: /* Capital L may start a wide-string or wide-character constant. */
1281: if (lexptr[1] == '\'')
1282: {
1283: lexptr++;
1284: wide_flag = 1;
1285: goto char_constant;
1286: }
1287: if (lexptr[1] == '"')
1288: {
1289: lexptr++;
1290: wide_flag = 1;
1291: goto string_constant;
1292: }
1293: break;
1294:
1295: case '\'':
1296: wide_flag = 0;
1297: char_constant:
1298: lexptr++;
1299: if (keyword_parsing) {
1300: char *start_ptr = lexptr - 1;
1301: while (1) {
1302: c = *lexptr++;
1303: if (c == '\\')
1304: c = parse_escape (&lexptr);
1305: else if (c == '\'')
1306: break;
1307: }
1308: yylval.name.address = (U_CHAR *) tokstart;
1309: yylval.name.length = lexptr - start_ptr;
1310: return NAME;
1311: }
1312:
1313: /* This code for reading a character constant
1314: handles multicharacter constants and wide characters.
1315: It is mostly copied from c-lex.c. */
1316: {
1317: register int result = 0;
1318: register num_chars = 0;
1319: unsigned width = CHAR_TYPE_SIZE;
1320: int max_chars;
1321: char *token_buffer;
1322:
1323: if (wide_flag)
1324: {
1325: width = WCHAR_TYPE_SIZE;
1326: #ifdef MULTIBYTE_CHARS
1327: max_chars = MB_CUR_MAX;
1328: #else
1329: max_chars = 1;
1330: #endif
1331: }
1332: else
1333: max_chars = LONG_TYPE_SIZE / width;
1334:
1335: token_buffer = (char *) alloca (max_chars + 1);
1336:
1337: while (1)
1338: {
1339: c = *lexptr++;
1340:
1341: if (c == '\'' || c == EOF)
1342: break;
1343:
1344: if (c == '\\')
1345: {
1346: c = parse_escape (&lexptr);
1347: if (width < HOST_BITS_PER_INT
1348: && (unsigned) c >= (1 << width))
1349: pedwarn ("escape sequence out of range for character");
1350: }
1351:
1352: num_chars++;
1353:
1354: /* Merge character into result; ignore excess chars. */
1355: if (num_chars < max_chars + 1)
1356: {
1357: if (width < HOST_BITS_PER_INT)
1358: result = (result << width) | (c & ((1 << width) - 1));
1359: else
1360: result = c;
1361: token_buffer[num_chars - 1] = c;
1362: }
1363: }
1364:
1365: token_buffer[num_chars] = 0;
1366:
1367: if (c != '\'')
1368: error ("malformatted character constant");
1369: else if (num_chars == 0)
1370: error ("empty character constant");
1371: else if (num_chars > max_chars)
1372: {
1373: num_chars = max_chars;
1374: error ("character constant too long");
1375: }
1376: else if (num_chars != 1 && ! traditional)
1377: warning ("multi-character character constant");
1378:
1379: /* If char type is signed, sign-extend the constant. */
1380: if (! wide_flag)
1381: {
1382: int num_bits = num_chars * width;
1383:
1384: if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)
1385: || ((result >> (num_bits - 1)) & 1) == 0)
1386: yylval.integer.value
1387: = result & ((unsigned) ~0 >> (HOST_BITS_PER_INT - num_bits));
1388: else
1389: yylval.integer.value
1390: = result | ~((unsigned) ~0 >> (HOST_BITS_PER_INT - num_bits));
1391: }
1392: else
1393: {
1394: #ifdef MULTIBYTE_CHARS
1395: /* Set the initial shift state and convert the next sequence. */
1396: result = 0;
1397: /* In all locales L'\0' is zero and mbtowc will return zero,
1398: so don't use it. */
1399: if (num_chars > 1
1400: || (num_chars == 1 && token_buffer[0] != '\0'))
1401: {
1402: wchar_t wc;
1403: (void) mbtowc (NULL, NULL, 0);
1404: if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
1405: result = wc;
1406: else
1407: warning ("Ignoring invalid multibyte character");
1408: }
1409: #endif
1410: yylval.integer.value = result;
1411: }
1412: }
1413:
1414: /* This is always a signed type. */
1415: yylval.integer.unsignedp = 0;
1416:
1417: return CHAR;
1418:
1419: /* some of these chars are invalid in constant expressions;
1420: maybe do something about them later */
1421: case '/':
1422: case '+':
1423: case '-':
1424: case '*':
1425: case '%':
1426: case '|':
1427: case '&':
1428: case '^':
1429: case '~':
1430: case '!':
1431: case '@':
1432: case '<':
1433: case '>':
1434: case '[':
1435: case ']':
1436: case '.':
1437: case '?':
1438: case ':':
1439: case '=':
1440: case '{':
1441: case '}':
1442: case ',':
1443: case '#':
1444: if (keyword_parsing)
1445: break;
1446: case '(':
1447: case ')':
1448: lexptr++;
1449: return c;
1450:
1451: case '"':
1452: string_constant:
1453: if (keyword_parsing) {
1454: char *start_ptr = lexptr;
1455: lexptr++;
1456: while (1) {
1457: c = *lexptr++;
1458: if (c == '\\')
1459: c = parse_escape (&lexptr);
1460: else if (c == '"')
1461: break;
1462: }
1463: yylval.name.address = (U_CHAR *) tokstart;
1464: yylval.name.length = lexptr - start_ptr;
1465: return NAME;
1466: }
1467: yyerror ("string constants not allowed in #if expressions");
1468: return ERROR;
1469: }
1470:
1471: if (c >= '0' && c <= '9' && !keyword_parsing) {
1472: /* It's a number */
1473: for (namelen = 0;
1474: c = tokstart[namelen], is_idchar[c] || c == '.';
1475: namelen++)
1476: ;
1477: return parse_number (namelen);
1478: }
1479:
1480: /* It is a name. See how long it is. */
1481:
1482: if (keyword_parsing) {
1483: for (namelen = 0;; namelen++) {
1484: if (is_hor_space[tokstart[namelen]])
1485: break;
1486: if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
1487: break;
1488: if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
1489: break;
1490: }
1491: } else {
1492: if (!is_idstart[c]) {
1493: yyerror ("Invalid token in expression");
1494: return ERROR;
1495: }
1496:
1497: for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
1498: ;
1499: }
1500:
1501: lexptr += namelen;
1502: yylval.name.address = (U_CHAR *) tokstart;
1503: yylval.name.length = namelen;
1504: return NAME;
1505: }
1506:
1507:
1508: /* Parse a C escape sequence. STRING_PTR points to a variable
1509: containing a pointer to the string to parse. That pointer
1510: is updated past the characters we use. The value of the
1511: escape sequence is returned.
1512:
1513: A negative value means the sequence \ newline was seen,
1514: which is supposed to be equivalent to nothing at all.
1515:
1516: If \ is followed by a null character, we return a negative
1517: value and leave the string pointer pointing at the null character.
1518:
1519: If \ is followed by 000, we return 0 and leave the string pointer
1520: after the zeros. A value of 0 does not mean end of string. */
1521:
1522: int
1523: parse_escape (string_ptr)
1524: char **string_ptr;
1525: {
1526: register int c = *(*string_ptr)++;
1527: switch (c)
1528: {
1529: case 'a':
1530: return TARGET_BELL;
1531: case 'b':
1532: return TARGET_BS;
1533: case 'e':
1534: return 033;
1535: case 'f':
1536: return TARGET_FF;
1537: case 'n':
1538: return TARGET_NEWLINE;
1539: case 'r':
1540: return TARGET_CR;
1541: case 't':
1542: return TARGET_TAB;
1543: case 'v':
1544: return TARGET_VT;
1545: case '\n':
1546: return -2;
1547: case 0:
1548: (*string_ptr)--;
1549: return 0;
1550: case '^':
1551: c = *(*string_ptr)++;
1552: if (c == '\\')
1553: c = parse_escape (string_ptr);
1554: if (c == '?')
1555: return 0177;
1556: return (c & 0200) | (c & 037);
1557:
1558: case '0':
1559: case '1':
1560: case '2':
1561: case '3':
1562: case '4':
1563: case '5':
1564: case '6':
1565: case '7':
1566: {
1567: register int i = c - '0';
1568: register int count = 0;
1569: while (++count < 3)
1570: {
1571: c = *(*string_ptr)++;
1572: if (c >= '0' && c <= '7')
1573: i = (i << 3) + c - '0';
1574: else
1575: {
1576: (*string_ptr)--;
1577: break;
1578: }
1579: }
1580: if ((i & ~((1 << CHAR_TYPE_SIZE) - 1)) != 0)
1581: {
1582: i &= (1 << CHAR_TYPE_SIZE) - 1;
1583: warning ("octal character constant does not fit in a byte");
1584: }
1585: return i;
1586: }
1587: case 'x':
1588: {
1589: register int i = 0;
1590: for (;;)
1591: {
1592: c = *(*string_ptr)++;
1593: if (c >= '0' && c <= '9')
1594: i = (i << 4) + c - '0';
1595: else if (c >= 'a' && c <= 'f')
1596: i = (i << 4) + c - 'a' + 10;
1597: else if (c >= 'A' && c <= 'F')
1598: i = (i << 4) + c - 'A' + 10;
1599: else
1600: {
1601: (*string_ptr)--;
1602: break;
1603: }
1604: }
1605: if ((i & ~((1 << BITS_PER_UNIT) - 1)) != 0)
1606: {
1607: i &= (1 << BITS_PER_UNIT) - 1;
1608: warning ("hex character constant does not fit in a byte");
1609: }
1610: return i;
1611: }
1612: default:
1613: return c;
1614: }
1615: }
1616:
1617: void
1618: yyerror (s)
1619: char *s;
1620: {
1621: error (s);
1622: longjmp (parse_return_error, 1);
1623: }
1624:
1625: /* This page contains the entry point to this file. */
1626:
1627: /* Parse STRING as an expression, and complain if this fails
1628: to use up all of the contents of STRING. */
1629: /* We do not support C comments. They should be removed before
1630: this function is called. */
1631:
1632: int
1633: parse_c_expression (string)
1634: char *string;
1635: {
1636: lexptr = string;
1637:
1638: if (lexptr == 0 || *lexptr == 0) {
1639: error ("empty #if expression");
1640: return 0; /* don't include the #if group */
1641: }
1642:
1643: /* if there is some sort of scanning error, just return 0 and assume
1644: the parsing routine has printed an error message somewhere.
1645: there is surely a better thing to do than this. */
1646: if (setjmp (parse_return_error))
1647: return 0;
1648:
1649: if (yyparse ())
1650: return 0; /* actually this is never reached
1651: the way things stand. */
1652: if (*lexptr)
1653: error ("Junk after end of expression.");
1654:
1655: return expression_value; /* set by yyparse () */
1656: }
1657:
1658: #ifdef TEST_EXP_READER
1659: extern int yydebug;
1660:
1661: /* Main program for testing purposes. */
1662: int
1663: main ()
1664: {
1665: int n, c;
1666: char buf[1024];
1667:
1668: /*
1669: yydebug = 1;
1670: */
1671: initialize_random_junk ();
1672:
1673: for (;;) {
1674: printf ("enter expression: ");
1675: n = 0;
1676: while ((buf[n] = getchar ()) != '\n' && buf[n] != EOF)
1677: n++;
1678: if (buf[n] == EOF)
1679: break;
1680: buf[n] = '\0';
1681: printf ("parser returned %d\n", parse_c_expression (buf));
1682: }
1683:
1684: return 0;
1685: }
1686:
1687: /* table to tell if char can be part of a C identifier. */
1688: unsigned char is_idchar[256];
1689: /* table to tell if char can be first char of a c identifier. */
1690: unsigned char is_idstart[256];
1691: /* table to tell if c is horizontal space. isspace () thinks that
1692: newline is space; this is not a good idea for this program. */
1693: char is_hor_space[256];
1694:
1695: /*
1696: * initialize random junk in the hash table and maybe other places
1697: */
1698: initialize_random_junk ()
1699: {
1700: register int i;
1701:
1702: /*
1703: * Set up is_idchar and is_idstart tables. These should be
1704: * faster than saying (is_alpha (c) || c == '_'), etc.
1705: * Must do set up these things before calling any routines tthat
1706: * refer to them.
1707: */
1708: for (i = 'a'; i <= 'z'; i++) {
1709: ++is_idchar[i - 'a' + 'A'];
1710: ++is_idchar[i];
1711: ++is_idstart[i - 'a' + 'A'];
1712: ++is_idstart[i];
1713: }
1714: for (i = '0'; i <= '9'; i++)
1715: ++is_idchar[i];
1716: ++is_idchar['_'];
1717: ++is_idstart['_'];
1718: #if DOLLARS_IN_IDENTIFIERS
1719: ++is_idchar['$'];
1720: ++is_idstart['$'];
1721: #endif
1722:
1723: /* horizontal space table */
1724: ++is_hor_space[' '];
1725: ++is_hor_space['\t'];
1726: }
1727:
1728: error (msg)
1729: {
1730: printf ("error: %s\n", msg);
1731: }
1732:
1733: warning (msg)
1734: {
1735: printf ("warning: %s\n", msg);
1736: }
1737:
1738: struct hashnode *
1739: lookup (name, len, hash)
1740: char *name;
1741: int len;
1742: int hash;
1743: {
1744: return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1745: }
1746: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.