~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/genksyms/lex.l

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-or-later */
  2 /*
  3  * Lexical analysis for genksyms.
  4  * Copyright 1996, 1997 Linux International.
  5  *
  6  * New implementation contributed by Richard Henderson <rth@tamu.edu>
  7  * Based on original work by Bjorn Ekwall <bj0rn@blox.se>
  8  *
  9  * Taken from Linux modutils 2.4.22.
 10  */
 11 
 12 %{
 13 
 14 #include <limits.h>
 15 #include <stdlib.h>
 16 #include <string.h>
 17 #include <ctype.h>
 18 
 19 #include "genksyms.h"
 20 #include "parse.tab.h"
 21 
 22 /* We've got a two-level lexer here.  We let flex do basic tokenization
 23    and then we categorize those basic tokens in the second stage.  */
 24 #define YY_DECL         static int yylex1(void)
 25 
 26 %}
 27 
 28 IDENT                   [A-Za-z_\$][A-Za-z0-9_\$]*
 29 
 30 O_INT                   0[0-7]*
 31 D_INT                   [1-9][0-9]*
 32 X_INT                   0[Xx][0-9A-Fa-f]+
 33 I_SUF                   [Uu]|[Ll]|[Uu][Ll]|[Ll][Uu]
 34 INT                     ({O_INT}|{D_INT}|{X_INT}){I_SUF}?
 35 
 36 FRAC                    ([0-9]*\.[0-9]+)|([0-9]+\.)
 37 EXP                     [Ee][+-]?[0-9]+
 38 F_SUF                   [FfLl]
 39 REAL                    ({FRAC}{EXP}?{F_SUF}?)|([0-9]+{EXP}{F_SUF}?)
 40 
 41 STRING                  L?\"([^\\\"]*\\.)*[^\\\"]*\"
 42 CHAR                    L?\'([^\\\']*\\.)*[^\\\']*\'
 43 
 44 MC_TOKEN                ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
 45 
 46 /* We don't do multiple input files.  */
 47 %option noyywrap
 48 
 49 %option noinput
 50 
 51 %%
 52 
 53 
 54  /* Keep track of our location in the original source files.  */
 55 ^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n     return FILENAME;
 56 ^#.*\n                                  cur_line++;
 57 \n                                      cur_line++;
 58 
 59  /* Ignore all other whitespace.  */
 60 [ \t\f\v\r]+                            ;
 61 
 62 
 63 {STRING}                                return STRING;
 64 {CHAR}                                  return CHAR;
 65 {IDENT}                                 return IDENT;
 66 
 67  /* The Pedant requires that the other C multi-character tokens be
 68     recognized as tokens.  We don't actually use them since we don't
 69     parse expressions, but we do want whitespace to be arranged
 70     around them properly.  */
 71 {MC_TOKEN}                              return OTHER;
 72 {INT}                                   return INT;
 73 {REAL}                                  return REAL;
 74 
 75 "..."                                   return DOTS;
 76 
 77  /* All other tokens are single characters.  */
 78 .                                       return yytext[0];
 79 
 80 
 81 %%
 82 
 83 /* Bring in the keyword recognizer.  */
 84 
 85 #include "keywords.c"
 86 
 87 
 88 /* Macros to append to our phrase collection list.  */
 89 
 90 /*
 91  * We mark any token, that that equals to a known enumerator, as
 92  * SYM_ENUM_CONST. The parser will change this for struct and union tags later,
 93  * the only problem is struct and union members:
 94  *    enum e { a, b }; struct s { int a, b; }
 95  * but in this case, the only effect will be, that the ABI checksums become
 96  * more volatile, which is acceptable. Also, such collisions are quite rare,
 97  * so far it was only observed in include/linux/telephony.h.
 98  */
 99 #define _APP(T,L)       do {                                               \
100                           cur_node = next_node;                            \
101                           next_node = xmalloc(sizeof(*next_node));         \
102                           next_node->next = cur_node;                      \
103                           cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
104                           cur_node->tag =                                  \
105                             find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
106                             SYM_ENUM_CONST : SYM_NORMAL ;                  \
107                           cur_node->in_source_file = in_source_file;       \
108                         } while (0)
109 
110 #define APP             _APP(yytext, yyleng)
111 
112 
113 /* The second stage lexer.  Here we incorporate knowledge of the state
114    of the parser to tailor the tokens that are returned.  */
115 
116 int
117 yylex(void)
118 {
119   static enum {
120     ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_TYPEOF, ST_TYPEOF_1,
121     ST_BRACKET, ST_BRACE, ST_EXPRESSION, ST_STATIC_ASSERT,
122   } lexstate = ST_NOTSTARTED;
123 
124   static int suppress_type_lookup, dont_want_brace_phrase;
125   static struct string_list *next_node;
126   static char *source_file;
127 
128   int token, count = 0;
129   struct string_list *cur_node;
130 
131   if (lexstate == ST_NOTSTARTED)
132     {
133       next_node = xmalloc(sizeof(*next_node));
134       next_node->next = NULL;
135       lexstate = ST_NORMAL;
136     }
137 
138 repeat:
139   token = yylex1();
140 
141   if (token == 0)
142     return 0;
143   else if (token == FILENAME)
144     {
145       char *file, *e;
146 
147       /* Save the filename and line number for later error messages.  */
148 
149       if (cur_filename)
150         free(cur_filename);
151 
152       file = strchr(yytext, '\"')+1;
153       e = strchr(file, '\"');
154       *e = '\0';
155       cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
156       cur_line = atoi(yytext+2);
157 
158       if (!source_file) {
159         source_file = xstrdup(cur_filename);
160         in_source_file = 1;
161       } else {
162         in_source_file = (strcmp(cur_filename, source_file) == 0);
163       }
164 
165       goto repeat;
166     }
167 
168   switch (lexstate)
169     {
170     case ST_NORMAL:
171       switch (token)
172         {
173         case IDENT:
174           APP;
175           {
176             int r = is_reserved_word(yytext, yyleng);
177             if (r >= 0)
178               {
179                 switch (token = r)
180                   {
181                   case ATTRIBUTE_KEYW:
182                     lexstate = ST_ATTRIBUTE;
183                     count = 0;
184                     goto repeat;
185                   case ASM_KEYW:
186                     lexstate = ST_ASM;
187                     count = 0;
188                     goto repeat;
189                   case TYPEOF_KEYW:
190                     lexstate = ST_TYPEOF;
191                     count = 0;
192                     goto repeat;
193 
194                   case STRUCT_KEYW:
195                   case UNION_KEYW:
196                   case ENUM_KEYW:
197                     dont_want_brace_phrase = 3;
198                     suppress_type_lookup = 2;
199                     goto fini;
200 
201                   case EXPORT_SYMBOL_KEYW:
202                       goto fini;
203 
204                   case STATIC_ASSERT_KEYW:
205                     lexstate = ST_STATIC_ASSERT;
206                     count = 0;
207                     goto repeat;
208                   }
209               }
210             if (!suppress_type_lookup)
211               {
212                 if (find_symbol(yytext, SYM_TYPEDEF, 1))
213                   token = TYPE;
214               }
215           }
216           break;
217 
218         case '[':
219           APP;
220           lexstate = ST_BRACKET;
221           count = 1;
222           goto repeat;
223 
224         case '{':
225           APP;
226           if (dont_want_brace_phrase)
227             break;
228           lexstate = ST_BRACE;
229           count = 1;
230           goto repeat;
231 
232         case '=': case ':':
233           APP;
234           lexstate = ST_EXPRESSION;
235           break;
236 
237         default:
238           APP;
239           break;
240         }
241       break;
242 
243     case ST_ATTRIBUTE:
244       APP;
245       switch (token)
246         {
247         case '(':
248           ++count;
249           goto repeat;
250         case ')':
251           if (--count == 0)
252             {
253               lexstate = ST_NORMAL;
254               token = ATTRIBUTE_PHRASE;
255               break;
256             }
257           goto repeat;
258         default:
259           goto repeat;
260         }
261       break;
262 
263     case ST_ASM:
264       APP;
265       switch (token)
266         {
267         case '(':
268           ++count;
269           goto repeat;
270         case ')':
271           if (--count == 0)
272             {
273               lexstate = ST_NORMAL;
274               token = ASM_PHRASE;
275               break;
276             }
277           goto repeat;
278         default:
279           goto repeat;
280         }
281       break;
282 
283     case ST_TYPEOF_1:
284       if (token == IDENT)
285         {
286           if (is_reserved_word(yytext, yyleng) >= 0
287               || find_symbol(yytext, SYM_TYPEDEF, 1))
288             {
289               yyless(0);
290               unput('(');
291               lexstate = ST_NORMAL;
292               token = TYPEOF_KEYW;
293               break;
294             }
295           _APP("(", 1);
296         }
297         lexstate = ST_TYPEOF;
298         /* FALLTHRU */
299 
300     case ST_TYPEOF:
301       switch (token)
302         {
303         case '(':
304           if ( ++count == 1 )
305             lexstate = ST_TYPEOF_1;
306           else
307             APP;
308           goto repeat;
309         case ')':
310           APP;
311           if (--count == 0)
312             {
313               lexstate = ST_NORMAL;
314               token = TYPEOF_PHRASE;
315               break;
316             }
317           goto repeat;
318         default:
319           APP;
320           goto repeat;
321         }
322       break;
323 
324     case ST_BRACKET:
325       APP;
326       switch (token)
327         {
328         case '[':
329           ++count;
330           goto repeat;
331         case ']':
332           if (--count == 0)
333             {
334               lexstate = ST_NORMAL;
335               token = BRACKET_PHRASE;
336               break;
337             }
338           goto repeat;
339         default:
340           goto repeat;
341         }
342       break;
343 
344     case ST_BRACE:
345       APP;
346       switch (token)
347         {
348         case '{':
349           ++count;
350           goto repeat;
351         case '}':
352           if (--count == 0)
353             {
354               lexstate = ST_NORMAL;
355               token = BRACE_PHRASE;
356               break;
357             }
358           goto repeat;
359         default:
360           goto repeat;
361         }
362       break;
363 
364     case ST_EXPRESSION:
365       switch (token)
366         {
367         case '(': case '[': case '{':
368           ++count;
369           APP;
370           goto repeat;
371         case '}':
372           /* is this the last line of an enum declaration? */
373           if (count == 0)
374             {
375               /* Put back the token we just read so's we can find it again
376                  after registering the expression.  */
377               unput(token);
378 
379               lexstate = ST_NORMAL;
380               token = EXPRESSION_PHRASE;
381               break;
382             }
383           /* FALLTHRU */
384         case ')': case ']':
385           --count;
386           APP;
387           goto repeat;
388         case ',': case ';':
389           if (count == 0)
390             {
391               /* Put back the token we just read so's we can find it again
392                  after registering the expression.  */
393               unput(token);
394 
395               lexstate = ST_NORMAL;
396               token = EXPRESSION_PHRASE;
397               break;
398             }
399           APP;
400           goto repeat;
401         default:
402           APP;
403           goto repeat;
404         }
405       break;
406 
407     case ST_STATIC_ASSERT:
408       APP;
409       switch (token)
410         {
411         case '(':
412           ++count;
413           goto repeat;
414         case ')':
415           if (--count == 0)
416             {
417               lexstate = ST_NORMAL;
418               token = STATIC_ASSERT_PHRASE;
419               break;
420             }
421           goto repeat;
422         default:
423           goto repeat;
424         }
425       break;
426 
427     default:
428       exit(1);
429     }
430 fini:
431 
432   if (suppress_type_lookup > 0)
433     --suppress_type_lookup;
434   if (dont_want_brace_phrase > 0)
435     --dont_want_brace_phrase;
436 
437   yylval = &next_node->next;
438 
439   return token;
440 }

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php