1 /*
2  * string2.lex: An example of using scanning strings
3  *              by using start states.
4  */
5 
6 %{
7 #include <ctype.h>
8 #include <malloc.h>
9 
10 #define isodigit(x) ((x) >= '0' && (x) <= '7')
11 #define hextoint(x) (isdigit((x)) ? (x) - '0' : ((x) - 'A') + 10)
12 
13 char *buffer      = NULL;
14 int  buffer_size  = 0;
15 
16 void yyerror(char *message)
17 {
18   printf("\nError: %s\n",message);
19 }
20 
21 %}
22 
23 %x STRING
24 
25 hex (x|X)[0-9a-fA-F]{1,2}
26 oct [0-7]{1,3}
27 
28 %%
29 
30 \"                 {
31                      buffer      = malloc(1);
32                      buffer_size = 1; strcpy(buffer,"");
33                      BEGIN(STRING);
34                    }
35 <STRING>\n         {
36                       yyerror("Unterminated string");
37                       free(buffer);
38                       BEGIN(INITIAL);
39                    }
40 <STRING><<EOF>>    {
41                       yyerror("EOF in string");
42                       free(buffer);
43                       BEGIN(INITIAL);
44                    }
45 <STRING>[^\\\n"]   {
46                      buffer = realloc(buffer,buffer_size+yyleng+1);
47                      buffer_size += yyleng;
48                      strcat(buffer,yytext);
49                    }
50 <STRING>\\\n       /* ignore this */
51 <STRING>\\{hex}    {
52                      int temp =0,loop = 0;
53                      for(loop=yyleng-2; loop>0; loop--){
54                        temp  <<= 4;
55                        temp  += hextoint(toupper(yytext[yyleng-loop]));
56                      }
57                      buffer = realloc(buffer,buffer_size+1);
58                      buffer[buffer_size-1] = temp;
59                      buffer[buffer_size]   = '\0';
60                      buffer_size += 1;
61                    }
62 <STRING>\\{oct}    {
63                      int temp =0,loop = 0;
64                      for(loop=yyleng-1; loop>0; loop--){
65                        temp  <<= 3;
66                        temp  += (yytext[yyleng-loop] - '0');
67                      }
68                      buffer = realloc(buffer,buffer_size+1);
69                      buffer[buffer_size-1] = temp;
70                      buffer[buffer_size]   = '\0';
71                      buffer_size += 1;
72                    }
73 <STRING>\\[^\n]    {
74                      buffer = realloc(buffer,buffer_size+1);
75                      switch(yytext[yyleng-1]){
76                      case 'b' : buffer[buffer_size-1] = '\b';  break;
77                      case 't' : buffer[buffer_size-1] = '\t';  break;
78                      case 'n' : buffer[buffer_size-1] = '\n';  break;
79                      case 'v' : buffer[buffer_size-1] = '\v';  break;
80                      case 'f' : buffer[buffer_size-1] = '\f';  break;
81                      case 'r' : buffer[buffer_size-1] = '\r';  break;
82                      default  : buffer[buffer_size-1] = yytext[yyleng-1];
83                      }
84                      buffer[buffer_size] = '\0';
85                      buffer_size += 1;
86                    }
87 <STRING>\"         {
88                      printf("string = \"%s\"",buffer);
89                      free(buffer);
90                      BEGIN(INITIAL);
91                    }
92 %%
93 
94 
95