%{
#define LT 1
#define LE 2
#define EQ 3
#define NE 4
#define GT 5
#define GE 6
#define IF 7
#define THEN 8
#define ELSE 9
#define ID 10
#define NUMBER 11
#define RELOP 12
#define LPAREN 13
#define RPAREN 14
  
#define SYMTABSIZE 211    
  
  
typedef struct { 
{char* idstring;
int other_attributes;} symtab_entry;
symtab_entry symtab[SYMTABSIZE];
    
int yylval;
    
%}
  
ws [ \t\n]+
letter [A-Za-z]
digit  [0-9]
id {letter}({letter}|{digit})*
number {digit}+(\.{digit}+)?(E[+\-]?{digit}+)?
				 
%%

{ws}     {/*no action, no return*/}
if       {return(IF);}
then     {return(THEN);}
else     {return(ELSE);}
{id}     {yylval=install_id(); return(ID);}
{number} {yylval=atof(yytext); return(ID);}
"<"      {yylval=LT; return(RELOP);}
"<="     {yylval=LE; return(RELOP);}
"="      {yylval=EQ; return(RELOP);}
"<>"     {yylval=NE; return(RELOP);}
">"      {yylval=GT; return(RELOP);}
">="     {yylval=GE; return(RELOP);}
"("      {return(LPAREN);}
")"      {return(RPAREN);}

%%


int hash(s)
     /* given a string s returns the hash value */
     char* s;
{
  char* p;
  unsigned h = 0, g;
  for (p = s; *p != '\0'; p++) {
    h = (h << 4) + (*p);
    if (g = h&0xf0000000) {
      h = h ^ (g >> 24);
      h = h ^ g;
    }
  }
  return h % SYMTABSIZE;
}


int install_id () {
  /* installs the identifier string in yytext in the symbol 
     table symtab */
  int  symtab_index; 
  symtab_index = hash(yytext);
  strcpy(symtab[symtab_index].idstring, yytext);
  symtab[symtab_index].other_attributes = yyleng;
  return(symtab_index);
}
    
