| /* |
| * numbers.lex : An example of the definitions and techniques |
| * for scanning numbers |
| */ |
| |
| %{ |
| #include <stdio.h> |
| |
| #define UNSIGNED_LONG_SYM 1 |
| #define SIGNED_LONG_SYM 2 |
| #define UNSIGNED_SYM 3 |
| #define SIGNED_SYM 4 |
| #define LONG_DOUBLE_SYM 5 |
| #define FLOAT_SYM 6 |
| |
| union _yylval { |
| long double ylong_double; |
| float yfloat; |
| unsigned long yunsigned_long; |
| unsigned yunsigned; |
| long ysigned_long; |
| int ysigned; |
| } yylval; |
| |
| %} |
| |
| digit [0-9] |
| hex_digit [0-9a-fA-F] |
| oct_digit [0-7] |
| |
| exponent [eE][+-]?{digit}+ |
| i {digit}+ |
| float_constant ({i}\.{i}?|{i}?\.{i}){exponent}? |
| hex_constant 0[xX]{hex_digit}+ |
| oct_constant 0{oct_digit}* |
| int_constant {digit}+ |
| long_ext [lL] |
| unsigned_ext [uU] |
| float_ext [fF] |
| ulong_ext {long_ext}{unsigned_ext}|{unsigned_ext}{long_ext} |
| |
| %% |
| |
| {hex_constant}{ulong_ext} { /* we need to skip the "0x" part */ |
| sscanf(&yytext[2],"%lx",&yylval.yunsigned_long); |
| return(UNSIGNED_LONG_SYM); |
| } |
| {hex_constant}{long_ext} { |
| sscanf(&yytext[2],"%lx",&yylval.ysigned_long); |
| return(SIGNED_LONG_SYM); |
| } |
| {hex_constant}{unsigned_ext} { |
| sscanf(&yytext[2],"%x",&yylval.yunsigned); |
| return(UNSIGNED_SYM); |
| } |
| {hex_constant} { /* use %lx to protect against overflow */ |
| sscanf(&yytext[2],"%lx",&yylval.ysigned_long); |
| return(SIGNED_LONG_SYM); |
| } |
| {oct_constant}{ulong_ext} { |
| sscanf(yytext,"%lo",&yylval.yunsigned_long); |
| return(UNSIGNED_LONG_SYM); |
| } |
| {oct_constant}{long_ext} { |
| sscanf(yytext,"%lo",&yylval.ysigned_long); |
| return(SIGNED_LONG_SYM); |
| } |
| {oct_constant}{unsigned_ext} { |
| sscanf(yytext,"%o",&yylval.yunsigned); |
| return(UNSIGNED_SYM); |
| } |
| {oct_constant} { /* use %lo to protect against overflow */ |
| sscanf(yytext,"%lo",&yylval.ysigned_long); |
| return(SIGNED_LONG_SYM); |
| } |
| {int_constant}{ulong_ext} { |
| sscanf(yytext,"%ld",&yylval.yunsigned_long); |
| return(UNSIGNED_LONG_SYM); |
| } |
| {int_constant}{long_ext} { |
| sscanf(yytext,"%ld",&yylval.ysigned_long); |
| return(SIGNED_LONG_SYM); |
| } |
| {int_constant}{unsigned_ext} { |
| sscanf(yytext,"%d",&yylval.yunsigned); |
| return(UNSIGNED_SYM); |
| } |
| {int_constant} { /* use %ld to protect against overflow */ |
| sscanf(yytext,"%ld",&yylval.ysigned_long); |
| return(SIGNED_LONG_SYM); |
| } |
| {float_constant}{long_ext} { |
| sscanf(yytext,"%lf",&yylval.ylong_double); |
| return(LONG_DOUBLE_SYM); |
| } |
| {float_constant}{float_ext} { |
| sscanf(yytext,"%f",&yylval.yfloat); |
| return(FLOAT_SYM); |
| } |
| {float_constant} { /* use %lf to protect against overflow */ |
| sscanf(yytext,"%lf",&yylval.ylong_double); |
| return(LONG_DOUBLE_SYM); |
| } |
| %% |
| |
| int main(void) |
| { |
| int code; |
| |
| while((code = yylex())){ |
| printf("yytext : %s\n",yytext); |
| switch(code){ |
| case UNSIGNED_LONG_SYM: |
| printf("Type of number : UNSIGNED LONG\n"); |
| printf("Value of number : %lu\n",yylval.yunsigned_long); |
| break; |
| case SIGNED_LONG_SYM: |
| printf("Type of number : SIGNED LONG\n"); |
| printf("Value of number : %ld\n",yylval.ysigned_long); |
| break; |
| case UNSIGNED_SYM: |
| printf("Type of number : UNSIGNED\n"); |
| printf("Value of number : %u\n",yylval.yunsigned); |
| break; |
| case SIGNED_SYM: |
| printf("Type of number : SIGNED\n"); |
| printf("Value of number : %d\n",yylval.ysigned); |
| break; |
| case LONG_DOUBLE_SYM: |
| printf("Type of number : LONG DOUBLE\n"); |
| printf("Value of number : %lf\n",yylval.ylong_double); |
| break; |
| case FLOAT_SYM: |
| printf("Type of number : FLOAT\n"); |
| printf("Value of number : %f\n",yylval.yfloat); |
| break; |
| default: |
| printf("Type of number : UNDEFINED\n"); |
| printf("Value of number : UNDEFINED\n"); |
| break; |
| } |
| } |
| return(0); |
| } |
| |