/*----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//----------------------------------------------------------------------------
//
// Description:    
//        Lexer for rsvc logic expression
//
// Author:  jie chen
//
//
//
//---------------------------------------------------------------------------*/

%{
#include <string.h>
#include <stdlib.h>
#include <rsvcLogic.h>

#if defined (__VMS)
/* Assume we are using BISON as our yacc compiler if this is a VMS platform.*/
#define _BISON_YACC
#endif

#ifdef _BISON_YACC
/* When using gnu bison, bison produces ns_tab.c, not y.tab.h.
   (also, can't have two periods in a filename under VMS). */
#include "rsvc_logic_tab.c"
#else
#include "y.tab.h" 
#endif

static char *_logic_input_text = 0;

void 
set_input_text (char* text)
{
   _logic_input_text = text;
}

#ifdef FLEX_SCANNER 
/* Flex defines yywrap() as a macro by default. 
   We define it below (in rsvc_logic) as a function, so we must undefine it 
   here first. */
#ifdef yywrap
#undef yywrap
#endif

/* The flex manual states that the flex implementation does not permit 
   input() to be redefined. This is because input() in FLEX is a function, 
   not a macro.
   
   The flex manual also states that the proper thing to do in flex is 
   redefine the macro YY_INPUT, which is what we do below.

   unput() is also a function in flex, but since we are now using
   YYINPUT(), hopefully unput() will work correctly. */

#ifdef YY_INPUT
#undef  YY_INPUT
#endif
#define YY_INPUT(buf,result,max_size) {                                               \
   int text_left = strlen(_logic_input_text) ;      /* get length of input. */        \
   (result) = ((max_size)<text_left)?(max_size):text_left;                            \
          /* bytes to copy is max_size, unless this is more than text_left */         \
   memcpy ((char *)buf,_logic_input_text,(result)); /* copy from input to buf. */     \
   _logic_input_text += result ;                    /* remove copied text from input*/\
}  
#else

#undef input
#undef unput
#define input() (*_logic_input_text++)
#define unput(c) (*--_logic_input_text = c)

#endif /* FLEX_SCANNER (defined)/(not defined) */

%}

tagname [a-zA-Z][a-zA-Z0-9"-""_"]*
cstring \'[^'\n]*['\n]
intnum  -?[0-9]+
fnum    -?[0-9]*\.[0-9]+

%s COMMENT
%%

"=="               {return EQUAL; }
"<"                {return LESS; }
">"                {return GREATER; }
"!="               {return NOTEQUAL; }
"<="               {return LESSOREQUAL;}
">="               {return GREATEROREQUAL;}
"("                {return LEFTP;}
")"                {return RIGHTP;}
"||"               {return OR;}
"&&"               {return AND;}
"!"                {return NOT;}
"like"             {return LIKE;}
{intnum}           {yylval.data = new_logic_data ();
                    logic_data_assign_int (yylval.data, atoi (yytext));
                    return IVALUE;
                   }
{fnum}             {yylval.data = new_logic_data ();
                    logic_data_assign_dbl (yylval.data, atof (yytext));
                    return DVALUE;
                   }
{tagname}          {yylval.data = new_logic_data ();
                    logic_data_assign_str (yylval.data, yytext);
                    return TAGNAME; }
{cstring}          {yylval.data = new_logic_data ();
                    logic_data_assign_str (yylval.data, yytext + 1);
                    if (yylval.data->u.string[yyleng - 2] != '\'') {
                        printf ("Unterminated char string %s\n", yytext);
                        return CERROR;
                    }
                    else
                        yylval.data->u.string[yyleng - 2] = '\0';
                        return CSTRING;
                   }

[ \t] ;
.                  {fprintf(stdout,"unrecognized char %02x\n",yytext[0]);}
%%

#ifdef __cplusplus
void yyerror()
#elif defined(_BISON_YACC)
/* BISON produces calls to a yyerror function that takes a single char *.
   Since yyerror is not previously declared, the compiler assumes that
   yyerror must be of type "int yyerror( char * c )" */
int yyerror( char * c )
#else
yyerror()
#endif
{
   fprintf(stderr, "syntax error for logical expression\n");
}

#if defined(__cplusplus) 
int yywrap(void)
#else
yywrap()
#endif
{
   return EOF;
}
    
