Linux Audio

Check our new training course

Open-source upstreaming

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