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