%{
/* This file is used to generate the lexical analysis for etags. 
*/

int	level = 0;
extern  char lastcaller[];
long     yycharno = 0;
int	complex_define = 0;	/*That is, define's with more than one line*/

/* Make sure that input macros keep track of character position. */
/* Also, use the current input file inf instead of yyin (standard input) */

#undef input
# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(inf))==10?(yylineno++,yytchar):yytchar)==EOF?0:(yycharno++,yytchar))
#undef unput
# define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;yycharno--;}

/* yytext is too short for long comments such as those generated by RCS */
#undef YYLMAX
#define YYLMAX 4096
#define YYEOF 0

typedef struct {
	char	*name;
	int	line;
	long	charpos;
	} save_ident;

int sp = 0;
#define StackSize 100
save_ident *Stack[StackSize];

push(stack_value)
  save_ident *	stack_value;
{
  if (sp < StackSize)
    Stack[sp++] = stack_value;
  else
    printf ("Stack overflow\n");
}

save_ident * pop ()
{
  if (sp > 0)
    return (Stack[--sp]);
  else
    printf ("Stack underflow\n");
}
save_ident * funcid;
extern FILE *inf;
extern char * savestr();
extern int xmalloc();

%}

%p 3072

 /* regular expressions */


delim	[ \t\n]
ws	{delim}+
letter	[A-Za-z_]
digit	[0-9]
funcid	~?{letter}({letter}|{digit})*
funcid2 {funcid}\:\:{funcid}
EXP	([eE][+-]?[0-9]+)
FS	[flFL]
IS	([uU][lL]?|[lL][uU]?)

number1 ([0-9]+"."[0-9]*{EXP}?{FS}?)
number2 ("."[0-9]+{EXP}?{FS}?)
number3 ([0-9]+({EXP})?({FS})?)		
number4 ([1-9][0-9]*{IS}?)		
number5 (0[0-7]*{IS}?)			
number6 (0[xX][0-9a-fA-F]+{IS}?)

macdef	(\#define[^\n]*\/\*)|(\#define[^\n]*\n)|(\#{ws}define[^\n]*\n)
string	\"([^\"\n]|\"\"|\\\")*\" 
charac	('[^'\n]')|('''')
a	[^\*]*(\*)+
a_comment	(\/\/[^\n]*\n)

%START NORM COMMENT ACOMMENT DEFINE DEFCOM 
%%

	{BEGIN NORM; fflush(stdout); yylval=0;}

<NORM>{ws}			{/* no action, no return */}
<NORM>asm			{return (TOTHER);}
<NORM>auto			{return (TAUTO);}
<NORM>break			{return (TOTHER);}
<NORM>case			{return (TOTHER);}
<NORM>char			{return (TCHAR);}
<NORM>class			{return (TCLASS);}
<NORM>const			{return (TOTHER);}
<NORM>continue		{return (TOTHER);}
<NORM>default			{return (TOTHER);}
<NORM>delete			{return (TOTHER);}
<NORM>do			{return (TOTHER);}
<NORM>double			{return (TOTHER);}
<NORM>else			{return (TOTHER);}
<NORM>enum			{return (TENUM);}
<NORM>extern			{return (TEXTERN);}
<NORM>float 			{return (TFLOAT);}
<NORM>for			{return (TOTHER);}
<NORM>friend			{return (TFRIEND);}
<NORM>goto			{return (TOTHER);}
<NORM>if			{return (TOTHER);}
<NORM>inline			{return (TOTHER);}
<NORM>int			{return (TINT);}
<NORM>long			{return (TLONG);}
<NORM>new			{return (TOTHER);}
<NORM>operator		{return (TOTHER);}
<NORM>overload		{return (TOTHER);}
<NORM>public			{return (TPUBLIC);}
<NORM>register		{return (TREG);}
<NORM>reg			{return (TREG);}
<NORM>return			{return (TOTHER);}
<NORM>short			{return (TSHORT);}
<NORM>sizeof			{return (TOTHER);}
<NORM>static			{return (TSTATIC);}
<NORM>struct			{return (TSTRUCT);}
<NORM>switch			{return (TOTHER);}
<NORM>this			{return (TOTHER);}
<NORM>typedef			{return (TTYPEDEF);}
<NORM>union			{return (TUNION);}
<NORM>unsigned		{return (TUNSIGNED);}
<NORM>virtual			{return (TVIRTUAL);}
<NORM>void			{return (TVOID);}
<NORM>while			{return (TOTHER);}
<NORM>#undef			{BEGIN DEFINE;}
<NORM>#define			{BEGIN DEFINE;}
<NORM>#ifndef			{BEGIN DEFINE;}
<NORM>#ifdef			{BEGIN DEFINE;}
<NORM>#include		{return (TOTHER);}
<NORM>#if			{BEGIN DEFINE;}
<NORM>#endif			{BEGIN DEFINE;}
<NORM>#elif			{BEGIN DEFINE;}
<NORM>#line			{return (TOTHER);}
<NORM>"("			{return (TLPAREN);}
<NORM>")"			{return (TRPAREN);}
<NORM>"{"			{level++; return (TLBRACE);}
<NORM>"}"		{level--; 
			 if (level == 0) strcpy (lastcaller, "");
			 return (TRBRACE);}
<NORM>"["			{return (TLBRACK);}
<NORM>"]"			{return (TRBRACK);}
<NORM>":"			{return (TCOLON);}
<NORM>"::"			{return (TDBLCOLON);}
<NORM>"*"			{return (TSTAR);}
<NORM>","			{return (TCOMMA);}
<NORM>";"			{return (TSEMI);}
<NORM>"="			{return (TEQUAL);}
<NORM>{funcid2}		{do_funcid(); return (TIDENT);}			 
<NORM>{funcid}		{do_funcid(); return (TIDENT);}			 
<NORM>{number1}		{return (TNUM);}
<NORM>{number2}		{return (TNUM);}
<NORM>{number3}		{return (TNUM);}
<NORM>{number4}		{return (TNUM);}
<NORM>{number5}		{return (TNUM);}
<NORM>{number6}		{return (TNUM);}
<NORM>{string}		{return (TOTHER);}
<NORM>{charac}		{return (TOTHER);}
<NORM>.			{return (TOTHER);}
<NORM>"/*"              {BEGIN COMMENT;}
<NORM>"//"              {BEGIN ACOMMENT;}

<ACOMMENT>.              {}
<ACOMMENT>\n             {BEGIN NORM;}

<COMMENT>.              {}
<COMMENT>\n             {}
<COMMENT>"*/"           {BEGIN NORM;}

<DEFINE>\\		{complex_define = 1;}
<DEFINE>.		{}
<DEFINE>\n		{if ( !complex_define ) BEGIN NORM;
			 else complex_define = 0;}

<DEFINE>"/*"		{BEGIN DEFCOM;}
<DEFCOM>.		{}
<DEFCOM>\n		{}
<DEFCOM>"*/"		{BEGIN DEFINE;}

%%

do_funcid ()
{
  funcid = (save_ident *) xmalloc (sizeof(save_ident));
  funcid->name = savestr (yytext);
  funcid->charpos = yycharno - yyleng + 1;
  funcid->line = yylineno;
  push (funcid);
}
