/* scanner for arithmetic expressions */
/* the generated file MUST have the macro YY_FATAL_ERROR edited  */
/* in order to point ot an externaly defined function that sends */
/* the error messages through a message box (and not via printf) */
%{
#include <string.h>
#include <math.h>

struct nodet{
             char item;
             unsigned char val;
             unsigned char left;
             unsigned char right;
            } ;

struct treet{
             struct nodet node[256];
             char id[64][10];
             float constant[32];
             int nnode,
                 nnum,
                 nid,
                 nsub,
                 npro,
                 nmodf,
                 nconst,
                 revers;
             char descr[64];
            } ;

extern	char			errstr[80];				/* string to hold lex and parser errors	*/
extern	unsigned char	lex;					/* index for parser						*/
extern  struct treet tr;
extern  int errfl;

int lexyy_fatal( char *m );
#define YY_FATAL_ERROR(msg) \
	do \
		{ \
		(void) lexyy_fatal( msg ); \
		return YY_NULL; \
		} \
	while ( 0 )

int k;
float faux;
%}

DIGIT	  [0-9]
ID	  [a-zA-Z][a-zA-Z0-9]*
INTEGER {DIGIT}+
DECIMAL ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
FLOAT ({DECIMAL}|{INTEGER})("e"|"E")("+"|"-")?{DIGIT}+

%%
({INTEGER}|{DECIMAL}|{FLOAT}) {
         faux = (float) atof( yytext );
		 tr.node[tr.nnode].item = 'N';
         for( k=0; k<tr.nnum; k++ )
          if( faux == tr.constant[k] ) break;
		 tr.node[tr.nnode].val = (unsigned char) k;
		 if( k==tr.nnum )
		 {
		  tr.constant[tr.nnum] = faux;
		  ++tr.nnum;
		 }
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	     }


log	    {
         tr.node[tr.nnode].item = 'F';
		 tr.node[tr.nnode].val = 'L';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

ln	    {
         tr.node[tr.nnode].item = 'F';
		 tr.node[tr.nnode].val = 'l';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

exp	    {
         tr.node[tr.nnode].item = 'F';
		 tr.node[tr.nnode].val = 'e';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

sin	    {
         tr.node[tr.nnode].item = 'F';
		 tr.node[tr.nnode].val = 'S';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

cos	    {
         tr.node[tr.nnode].item = 'F';
		 tr.node[tr.nnode].val = 'C';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
	     ++tr.nnode;
		 return 1;
	    }

{ID}	{
		 tr.node[tr.nnode].item = 'I';
         for( k=0; k<tr.nid; k++ )
          if( strncmp( &tr.id[k][0], yytext, 8 ) == 0 ) break;
		 tr.node[tr.nnode].val = (unsigned char) k;
		 if( k==tr.nid )
		 {
		  strncpy( &tr.id[tr.nid][0], yytext, 8 );
		  tr.id[tr.nid][8] = '\0';
		  tr.id[tr.nid][9] = '\0';
		  ++tr.nid;
		 }
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
		}

"+"	    {
         tr.node[tr.nnode].item = 'O';
		 tr.node[tr.nnode].val = '+';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

"-"	    {
         tr.node[tr.nnode].item = 'O';
		 tr.node[tr.nnode].val = '-';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

"*"	    {
         tr.node[tr.nnode].item = 'O';
		 tr.node[tr.nnode].val = '*';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

"/"	    {
         tr.node[tr.nnode].item = 'O';
		 tr.node[tr.nnode].val = '/';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

"^"	    {
         tr.node[tr.nnode].item = 'O';
		 tr.node[tr.nnode].val = '^';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

"("	    {
         tr.node[tr.nnode].item = 'O';
		 tr.node[tr.nnode].val = '(';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }

")"	    {
         tr.node[tr.nnode].item = 'O';
		 tr.node[tr.nnode].val = ')';
		 if( tr.nnode==253 )
		 {
		  if( !errfl )
           sprintf( errstr, "ERROR - expression too long." );
          errfl++;
          yyterminate();
         }
		 ++tr.nnode;
		 return 1;
	    }


[ \t\n]+	   /* eat up whitespace	*/

.	    {
         if( !errfl )
          sprintf( errstr, "ERROR - character not allowed: %s", yytext );
         errfl++;
         yyterminate();
        }
%%
void yyreset( void )
{
 YY_NEW_FILE;
}