1/*
2 * numbers.lex : An example of the definitions and techniques
3 *               for scanning numbers
4 */
5
6%{
7#include <stdio.h>
8
9#define UNSIGNED_LONG_SYM   1
10#define SIGNED_LONG_SYM     2
11#define UNSIGNED_SYM        3
12#define SIGNED_SYM          4
13#define LONG_DOUBLE_SYM     5
14#define FLOAT_SYM           6
15
16union _yylval {
17  long double    ylong_double;
18  float          yfloat;
19  unsigned long  yunsigned_long;
20  unsigned       yunsigned;
21  long           ysigned_long;
22  int            ysigned;
23} yylval;
24
25%}
26
27digit             [0-9]
28hex_digit         [0-9a-fA-F]
29oct_digit         [0-7]
30
31exponent          [eE][+-]?{digit}+
32i                 {digit}+
33float_constant    ({i}\.{i}?|{i}?\.{i}){exponent}?
34hex_constant      0[xX]{hex_digit}+
35oct_constant      0{oct_digit}*
36int_constant      {digit}+
37long_ext          [lL]
38unsigned_ext      [uU]
39float_ext         [fF]
40ulong_ext         {long_ext}{unsigned_ext}|{unsigned_ext}{long_ext}
41
42%%
43
44{hex_constant}{ulong_ext} {  /* we need to skip the "0x" part */
45                             sscanf(&yytext[2],"%lx",&yylval.yunsigned_long);
46                             return(UNSIGNED_LONG_SYM);
47                          }
48{hex_constant}{long_ext}  {
49                             sscanf(&yytext[2],"%lx",&yylval.ysigned_long);
50                             return(SIGNED_LONG_SYM);
51                          }
52{hex_constant}{unsigned_ext}  {
53                             sscanf(&yytext[2],"%x",&yylval.yunsigned);
54                             return(UNSIGNED_SYM);
55                          }
56{hex_constant}            { /* use %lx to protect against overflow */
57                             sscanf(&yytext[2],"%lx",&yylval.ysigned_long);
58                             return(SIGNED_LONG_SYM);
59                          }
60{oct_constant}{ulong_ext} {
61                             sscanf(yytext,"%lo",&yylval.yunsigned_long);
62                             return(UNSIGNED_LONG_SYM);
63                          }
64{oct_constant}{long_ext}  {
65                             sscanf(yytext,"%lo",&yylval.ysigned_long);
66                             return(SIGNED_LONG_SYM);
67                          }
68{oct_constant}{unsigned_ext}  {
69                             sscanf(yytext,"%o",&yylval.yunsigned);
70                             return(UNSIGNED_SYM);
71                          }
72{oct_constant}            { /* use %lo to protect against overflow */
73                             sscanf(yytext,"%lo",&yylval.ysigned_long);
74                             return(SIGNED_LONG_SYM);
75                          }
76{int_constant}{ulong_ext} {
77                             sscanf(yytext,"%ld",&yylval.yunsigned_long);
78                             return(UNSIGNED_LONG_SYM);
79                          }
80{int_constant}{long_ext}  {
81                             sscanf(yytext,"%ld",&yylval.ysigned_long);
82                             return(SIGNED_LONG_SYM);
83                          }
84{int_constant}{unsigned_ext}  {
85                             sscanf(yytext,"%d",&yylval.yunsigned);
86                             return(UNSIGNED_SYM);
87                          }
88{int_constant}            { /* use %ld to protect against overflow */
89                             sscanf(yytext,"%ld",&yylval.ysigned_long);
90                             return(SIGNED_LONG_SYM);
91                          }
92{float_constant}{long_ext}  {
93                             sscanf(yytext,"%lf",&yylval.ylong_double);
94                             return(LONG_DOUBLE_SYM);
95                          }
96{float_constant}{float_ext}  {
97                             sscanf(yytext,"%f",&yylval.yfloat);
98                             return(FLOAT_SYM);
99                          }
100{float_constant}          { /* use %lf to protect against overflow */
101                             sscanf(yytext,"%lf",&yylval.ylong_double);
102                             return(LONG_DOUBLE_SYM);
103                          }
104%%
105
106int main(void)
107{
108  int code;
109
110  while((code = yylex())){
111    printf("yytext          : %s\n",yytext);
112    switch(code){
113    case UNSIGNED_LONG_SYM:
114       printf("Type of number  : UNSIGNED LONG\n");
115       printf("Value of number : %lu\n",yylval.yunsigned_long);
116       break;
117    case SIGNED_LONG_SYM:
118       printf("Type of number  : SIGNED LONG\n");
119       printf("Value of number : %ld\n",yylval.ysigned_long);
120       break;
121    case UNSIGNED_SYM:
122       printf("Type of number  : UNSIGNED\n");
123       printf("Value of number : %u\n",yylval.yunsigned);
124       break;
125    case SIGNED_SYM:
126       printf("Type of number  : SIGNED\n");
127       printf("Value of number : %d\n",yylval.ysigned);
128       break;
129    case LONG_DOUBLE_SYM:
130       printf("Type of number  : LONG DOUBLE\n");
131       printf("Value of number : %lf\n",yylval.ylong_double);
132       break;
133    case FLOAT_SYM:
134       printf("Type of number  : FLOAT\n");
135       printf("Value of number : %f\n",yylval.yfloat);
136       break;
137    default:
138       printf("Type of number  : UNDEFINED\n");
139       printf("Value of number : UNDEFINED\n");
140       break;
141    }
142  }
143  return(0);
144}
145
146