"Fossies" - the Fresh Open Source Software Archive

Member "cfitsio-4.0.0/eval.l" (20 May 2021, 16293 Bytes) of package /linux/misc/cfitsio-4.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "eval.l" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.49_vs_4.0.0.

    1 %{
    2 /************************************************************************/
    3 /*                                                                      */
    4 /*                       CFITSIO Lexical Parser                         */
    5 /*                                                                      */
    6 /* This file is one of 3 files containing code which parses an          */
    7 /* arithmetic expression and evaluates it in the context of an input    */
    8 /* FITS file table extension.  The CFITSIO lexical parser is divided    */
    9 /* into the following 3 parts/files: the CFITSIO "front-end",           */
   10 /* eval_f.c, contains the interface between the user/CFITSIO and the    */
   11 /* real core of the parser; the FLEX interpreter, eval_l.c, takes the   */
   12 /* input string and parses it into tokens and identifies the FITS       */
   13 /* information required to evaluate the expression (ie, keywords and    */
   14 /* columns); and, the BISON grammar and evaluation routines, eval_y.c,  */
   15 /* receives the FLEX output and determines and performs the actual      */
   16 /* operations.  The files eval_l.c and eval_y.c are produced from       */
   17 /* running flex and bison on the files eval.l and eval.y, respectively. */
   18 /* (flex and bison are available from any GNU archive: see www.gnu.org) */
   19 /*                                                                      */
   20 /* The grammar rules, rather than evaluating the expression in situ,    */
   21 /* builds a tree, or Nodal, structure mapping out the order of          */
   22 /* operations and expression dependencies.  This "compilation" process  */
   23 /* allows for much faster processing of multiple rows.  This technique  */
   24 /* was developed by Uwe Lammers of the XMM Science Analysis System,     */
   25 /* although the CFITSIO implementation is entirely code original.       */
   26 /*                                                                      */
   27 /*                                                                      */
   28 /* Modification History:                                                */
   29 /*                                                                      */
   30 /*   Kent Blackburn      c1992  Original parser code developed for the  */
   31 /*                              FTOOLS software package, in particular, */
   32 /*                              the fselect task.                       */
   33 /*   Kent Blackburn      c1995  BIT column support added                */
   34 /*   Peter D Wilson   Feb 1998  Vector column support added             */
   35 /*   Peter D Wilson   May 1998  Ported to CFITSIO library.  User        */
   36 /*                              interface routines written, in essence  */
   37 /*                              making fselect, fcalc, and maketime     */
   38 /*                              capabilities available to all tools     */
   39 /*                              via single function calls.              */
   40 /*   Peter D Wilson   Jun 1998  Major rewrite of parser core, so as to  */
   41 /*                              create a run-time evaluation tree,      */
   42 /*                              inspired by the work of Uwe Lammers,    */
   43 /*                              resulting in a speed increase of        */
   44 /*                              10-100 times.                           */
   45 /*   Peter D Wilson   Jul 1998  gtifilter(a,b,c,d) function added       */
   46 /*   Peter D Wilson   Aug 1998  regfilter(a,b,c,d) function added       */
   47 /*   Peter D Wilson   Jul 1999  Make parser fitsfile-independent,       */
   48 /*                              allowing a purely vector-based usage    */
   49 /*                                                                      */
   50 /************************************************************************/
   51 
   52 #include <math.h>
   53 #include <string.h>
   54 #include <ctype.h>
   55 #ifdef sparc
   56 #include <malloc.h>
   57 #else
   58 #include <stdlib.h>
   59 #endif
   60 #include "eval_defs.h"
   61 
   62 ParseData gParse;     /* Global structure holding all parser information     */
   63 
   64 /*****  Internal functions  *****/
   65 
   66        int yyGetVariable( char *varName, YYSTYPE *varVal );
   67 
   68 static int find_variable( char *varName );
   69 static int expr_read( char *buf, int nbytes );
   70 
   71 /*****  Definitions  *****/
   72 
   73 #define YY_NO_UNPUT   /*  Don't include YYUNPUT function  */
   74 #define YY_NEVER_INTERACTIVE 1
   75 
   76 #define MAXCHR 256
   77 #define MAXBIT 128
   78 
   79 #define OCT_0 "000"
   80 #define OCT_1 "001"
   81 #define OCT_2 "010"
   82 #define OCT_3 "011"
   83 #define OCT_4 "100"
   84 #define OCT_5 "101"
   85 #define OCT_6 "110"
   86 #define OCT_7 "111"
   87 #define OCT_X "xxx"
   88 
   89 #define HEX_0 "0000"
   90 #define HEX_1 "0001"
   91 #define HEX_2 "0010"
   92 #define HEX_3 "0011"
   93 #define HEX_4 "0100"
   94 #define HEX_5 "0101"
   95 #define HEX_6 "0110"
   96 #define HEX_7 "0111"
   97 #define HEX_8 "1000"
   98 #define HEX_9 "1001"
   99 #define HEX_A "1010"
  100 #define HEX_B "1011"
  101 #define HEX_C "1100"
  102 #define HEX_D "1101"
  103 #define HEX_E "1110"
  104 #define HEX_F "1111"
  105 #define HEX_X "xxxx"
  106 
  107 /* 
  108    MJT - 13 June 1996
  109    read from buffer instead of stdin
  110    (as per old ftools.skel)
  111 */
  112 #undef YY_INPUT
  113 #define YY_INPUT(buf,result,max_size) \
  114         if ( (result = expr_read( (char *) buf, max_size )) < 0 ) \
  115             YY_FATAL_ERROR( "read() in flex scanner failed" );
  116 
  117 %}
  118 bit     ([bB][01xX]+)
  119 oct     ([oO][01234567xX]+)
  120 hex     ([hH][0123456789aAbBcCdDeEfFxX]+)
  121 bitconst        (0b[01]+)
  122 hexconst        (0x[0123456789aAbBcCdDeEfF]+)
  123 octconst        (0o]+)
  124 integer     [0-9]+
  125 boolean         (t|f|T|F)
  126 real        ([0-9]*"."[0-9]+)|([0-9]*"."*[0-9]+[eEdD][+-]?[0-9]+)|([0-9]*".")
  127 constant        ("#"[a-zA-Z0-9_]+)|("#""$"[^\n]*"$")
  128 string      ([\"][^\"\n]*[\"])|([\'][^\'\n]*[\'])
  129 variable    ([a-zA-Z_][a-zA-Z0-9_]*)|("$"[^$\n]*"$")
  130 function    [a-zA-Z][a-zA-Z0-9]+"("
  131 intcast     ("(int)"|"(INT)")
  132 fltcast     ("(float)"|"(FLOAT)"|"(double)"|"(DOUBLE)")
  133 power       ("^"|"**")
  134 not             ("!"|".not."|".NOT."|"not."|"NOT.")
  135 or              ("||"|".or."|".OR."|"or."|"OR.")
  136 and             ("&&"|".and."|".AND."|"and."|"AND.")
  137 equal       ("=="|".eq."|".EQ."|"eq."|"EQ.")
  138 not_equal   ("!="|".ne."|".NE."|"ne."|"NE.")
  139 greater         (">"|".gt."|".GT."|"gt."|"GT.")
  140 lesser          ("<"|".lt."|".LT."|"lt."|"LT.")
  141 greater_eq  (">="|"=>"|".ge."|".GE."|"ge."|"GE.")
  142 lesser_eq   ("<="|"=<"|".le."|".LE."|"le."|"LE.")
  143 xor             ("^^"|".xor."|".XOR.")
  144 nl      \n
  145 
  146 %%
  147 
  148 [ \t]+     ;
  149 {bit}       {
  150                   int len;
  151                   len = strlen(yytext);
  152           while (yytext[len] == ' ')
  153             len--;
  154                   len = len - 1;
  155           strncpy(yylval.str,&yytext[1],len);
  156           yylval.str[len] = '\0';
  157           return( BITSTR );
  158         }
  159 {oct}       {
  160                   int len;
  161                   char tmpstring[256];
  162                   char bitstring[256];
  163                   len = strlen(yytext);
  164           if (len >= 256) {
  165             char errMsg[100];
  166             gParse.status = PARSE_SYNTAX_ERR;
  167             strcpy (errMsg,"Bit string exceeds maximum length: '");
  168             strncat(errMsg, &(yytext[0]), 20);
  169             strcat (errMsg,"...'");
  170             ffpmsg (errMsg);
  171             len = 0;
  172           } else {
  173             while (yytext[len] == ' ')
  174               len--;
  175             len = len - 1;
  176             strncpy(tmpstring,&yytext[1],len);
  177           }
  178                   tmpstring[len] = '\0';
  179                   bitstring[0] = '\0';
  180           len = 0;
  181                   while ( tmpstring[len] != '\0')
  182                        {
  183             switch ( tmpstring[len] )
  184                   {
  185                    case '0':
  186                     strcat(bitstring,OCT_0);
  187                     break;
  188                    case '1':
  189                     strcat(bitstring,OCT_1);
  190                     break;
  191                    case '2':
  192                     strcat(bitstring,OCT_2);
  193                     break;
  194                    case '3':
  195                     strcat(bitstring,OCT_3);
  196                     break;
  197                    case '4':
  198                     strcat(bitstring,OCT_4);
  199                     break;
  200                    case '5':
  201                     strcat(bitstring,OCT_5);
  202                     break;
  203                    case '6':
  204                     strcat(bitstring,OCT_6);
  205                     break;
  206                    case '7':
  207                     strcat(bitstring,OCT_7);
  208                     break;
  209                    case 'x':
  210                    case 'X':
  211                     strcat(bitstring,OCT_X);
  212                     break;
  213                   }
  214             len++;
  215                        }
  216                   strcpy( yylval.str, bitstring );
  217           return( BITSTR );
  218         }
  219 {hex}       {
  220                   int len;
  221                   char tmpstring[256];
  222                   char bitstring[256];
  223                   len = strlen(yytext);
  224           if (len >= 256) {
  225             char errMsg[100];
  226             gParse.status = PARSE_SYNTAX_ERR;
  227             strcpy (errMsg,"Hex string exceeds maximum length: '");
  228             strncat(errMsg, &(yytext[0]), 20);
  229             strcat (errMsg,"...'");
  230             ffpmsg (errMsg);
  231             len = 0;
  232           } else {
  233             while (yytext[len] == ' ')
  234               len--;
  235             len = len - 1;
  236             strncpy(tmpstring,&yytext[1],len);
  237           }
  238                   tmpstring[len] = '\0';
  239                   bitstring[0] = '\0';
  240           len = 0;
  241                   while ( tmpstring[len] != '\0')
  242                        {
  243             switch ( tmpstring[len] )
  244                   {
  245                    case '0':
  246                     strcat(bitstring,HEX_0);
  247                     break;
  248                    case '1':
  249                     strcat(bitstring,HEX_1);
  250                     break;
  251                    case '2':
  252                     strcat(bitstring,HEX_2);
  253                     break;
  254                    case '3':
  255                     strcat(bitstring,HEX_3);
  256                     break;
  257                    case '4':
  258                     strcat(bitstring,HEX_4);
  259                     break;
  260                    case '5':
  261                     strcat(bitstring,HEX_5);
  262                     break;
  263                    case '6':
  264                     strcat(bitstring,HEX_6);
  265                     break;
  266                    case '7':
  267                     strcat(bitstring,HEX_7);
  268                     break;
  269                    case '8':
  270                     strcat(bitstring,HEX_8);
  271                     break;
  272                    case '9':
  273                     strcat(bitstring,HEX_9);
  274                     break;
  275                    case 'a':
  276                    case 'A':
  277                     strcat(bitstring,HEX_A);
  278                     break;
  279                    case 'b':
  280                    case 'B':
  281                     strcat(bitstring,HEX_B);
  282                     break;
  283                    case 'c':
  284                    case 'C':
  285                     strcat(bitstring,HEX_C);
  286                     break;
  287                    case 'd':
  288                    case 'D':
  289                     strcat(bitstring,HEX_D);
  290                     break;
  291                    case 'e':
  292                    case 'E':
  293                     strcat(bitstring,HEX_E);
  294                     break;
  295                    case 'f':
  296                    case 'F':
  297                     strcat(bitstring,HEX_F);
  298                     break;
  299                    case 'x':
  300                    case 'X':
  301                     strcat(bitstring,HEX_X);
  302                     break;
  303                   }
  304             len++;
  305                        }
  306 
  307                   strcpy( yylval.str, bitstring );
  308           return( BITSTR );
  309         }
  310 {bitconst}      {
  311           long int constval = 0;
  312           char *p;
  313           for (p = &(yytext[2]); *p; p++) {
  314             constval = (constval << 1) | (*p == '1');
  315           }
  316           yylval.lng = constval;
  317           return( LONG );
  318         }
  319 {octconst}      {
  320           long int constval = 0;
  321           char *p;
  322           for (p = &(yytext[2]); *p; p++) {
  323             constval = (constval << 3) | (*p - '0');
  324           }
  325           yylval.lng = constval;
  326           return( LONG );
  327         }
  328 {hexconst}      {
  329           long int constval = 0;
  330           char *p;
  331           for (p = &(yytext[2]); *p; p++) {
  332                     int v = (isdigit(*p) ? (*p - '0') : (*p - 'a' + 10));
  333                     constval = (constval << 4) | v;
  334           }
  335           yylval.lng = constval;
  336           return( LONG );
  337         }
  338 
  339                   
  340 {integer}   {
  341                   yylval.lng = atol(yytext);
  342           return( LONG );
  343         }
  344 {boolean}   {
  345                   if ((yytext[0] == 't') || (yytext[0] == 'T'))
  346             yylval.log = 1;
  347           else
  348             yylval.log = 0;
  349           return( BOOLEAN );
  350         }
  351 {real}      {
  352                   yylval.dbl = atof(yytext);
  353           return( DOUBLE );
  354         }
  355 {constant}  {
  356                   if(        !fits_strcasecmp(yytext,"#PI") ) {
  357              yylval.dbl = (double)(4) * atan((double)(1));
  358              return( DOUBLE );
  359           } else if( !fits_strcasecmp(yytext,"#E") ) {
  360              yylval.dbl = exp((double)(1));
  361              return( DOUBLE );
  362           } else if( !fits_strcasecmp(yytext,"#DEG") ) {
  363              yylval.dbl = ((double)4)*atan((double)1)/((double)180);
  364              return( DOUBLE );
  365           } else if( !fits_strcasecmp(yytext,"#ROW") ) {
  366              return( ROWREF );
  367           } else if( !fits_strcasecmp(yytext,"#NULL") ) {
  368              return( NULLREF );
  369           } else if( !fits_strcasecmp(yytext,"#SNULL") ) {
  370              return( SNULLREF );
  371           } else {
  372                      int len; 
  373                      if (yytext[1] == '$') {
  374                         len = strlen(yytext) - 3;
  375                         yylval.str[0]     = '#';
  376                         strncpy(yylval.str+1,&yytext[2],len);
  377                         yylval.str[len+1] = '\0';
  378                         yytext = yylval.str;
  379              }
  380                      return( (*gParse.getData)(yytext, &yylval) );
  381                   }
  382                 }
  383 {string}    {
  384                   int len;
  385                   len = strlen(yytext) - 2;
  386           if (len >= MAX_STRLEN) {
  387             char errMsg[100];
  388             gParse.status = PARSE_SYNTAX_ERR;
  389             strcpy (errMsg,"String exceeds maximum length: '");
  390             strncat(errMsg, &(yytext[1]), 20);
  391             strcat (errMsg,"...'");
  392             ffpmsg (errMsg);
  393             len = 0;
  394           } else {
  395             strncpy(yylval.str,&yytext[1],len);
  396           }
  397           yylval.str[len] = '\0';
  398           return( STRING );
  399         }
  400 {variable}  {
  401          int    len,type;
  402 
  403                  if (yytext[0] == '$') {
  404             len = strlen(yytext) - 2;
  405             strncpy(yylval.str,&yytext[1],len);
  406             yylval.str[len] = '\0';
  407             yytext = yylval.str;
  408          } 
  409          type = yyGetVariable(yytext, &yylval);
  410          return( type );
  411         }
  412 {function}  {
  413                   char *fname;
  414           int len=0;
  415                   fname = &yylval.str[0];
  416           while( (fname[len]=toupper(yytext[len])) ) len++;
  417 
  418                   if(      FSTRCMP(fname,"BOX(")==0 
  419                         || FSTRCMP(fname,"CIRCLE(")==0 
  420                         || FSTRCMP(fname,"ELLIPSE(")==0 
  421                         || FSTRCMP(fname,"NEAR(")==0 
  422                         || FSTRCMP(fname,"ISNULL(")==0 
  423                          )
  424                      /* Return type is always boolean  */
  425              return( BFUNCTION );
  426 
  427                   else if( FSTRCMP(fname,"GTIFILTER(")==0 )
  428                      return( GTIFILTER );
  429 
  430                   else if( FSTRCMP(fname,"GTIOVERLAP(")==0 )
  431                      return( GTIOVERLAP );
  432 
  433                   else if( FSTRCMP(fname,"REGFILTER(")==0 )
  434                      return( REGFILTER );
  435 
  436                   else if( FSTRCMP(fname,"STRSTR(")==0 )
  437                      return( IFUNCTION );  /* Returns integer */
  438 
  439                   else 
  440              return( FUNCTION  );
  441         }
  442 {intcast}   { return( INTCAST ); }
  443 {fltcast}   { return( FLTCAST ); }
  444 {power}     { return( POWER   ); }
  445 {not}       { return( NOT     ); }
  446 {or}        { return( OR      ); }
  447 {and}       { return( AND     ); }
  448 {equal}     { return( EQ      ); }
  449 {not_equal} { return( NE      ); }
  450 {greater}   { return( GT      ); }
  451 {lesser}    { return( LT      ); }
  452 {greater_eq}    { return( GTE     ); }
  453 {lesser_eq} { return( LTE     ); }
  454 {xor}           { return( XOR     ); }
  455 {nl}        { return( '\n'    ); }
  456 .       { return( yytext[0] ); }
  457 %%
  458 
  459 int yywrap()
  460 {
  461   /* MJT -- 13 June 1996
  462      Supplied for compatibility with
  463      pre-2.5.1 versions of flex which
  464      do not recognize %option noyywrap 
  465   */
  466   return(1);
  467 }
  468 
  469 /* 
  470    expr_read is lifted from old ftools.skel. 
  471    Now we can use any version of flex with
  472    no .skel file necessary! MJT - 13 June 1996
  473 
  474    keep a memory of how many bytes have been
  475    read previously, so that an unlimited-sized
  476    buffer can be supported. PDW - 28 Feb 1998
  477 */
  478 
  479 static int expr_read(char *buf, int nbytes)
  480 {
  481  int n;
  482  
  483  n = 0;
  484  if( !gParse.is_eobuf ) {
  485      do {
  486         buf[n++] = gParse.expr[gParse.index++];
  487        } while ((n<nbytes)&&(gParse.expr[gParse.index] != '\0'));
  488      if( gParse.expr[gParse.index] == '\0' ) gParse.is_eobuf = 1;
  489  }
  490  buf[n] = '\0';
  491  return(n);
  492 }
  493 
  494 int yyGetVariable( char *varName, YYSTYPE *thelval )
  495 {
  496    int varNum, type;
  497    char errMsg[MAXVARNAME+25];
  498 
  499    varNum = find_variable( varName );
  500    if( varNum<0 ) {
  501       if( gParse.getData ) {
  502      type = (*gParse.getData)( varName, thelval );
  503       } else {
  504      type = pERROR;
  505      gParse.status = PARSE_SYNTAX_ERR;
  506      strcpy (errMsg,"Unable to find data: ");
  507      strncat(errMsg, varName, MAXVARNAME);
  508      ffpmsg (errMsg);
  509       }
  510    } else {
  511       /*  Convert variable type into expression type  */
  512       switch( gParse.varData[ varNum ].type ) {
  513       case LONG:
  514       case DOUBLE:   type =  COLUMN;  break;
  515       case BOOLEAN:  type = BCOLUMN;  break;
  516       case STRING:   type = SCOLUMN;  break;
  517       case BITSTR:   type =  BITCOL;  break;
  518       default:
  519      type = pERROR;
  520      gParse.status = PARSE_SYNTAX_ERR;
  521      strcpy (errMsg,"Bad datatype for data: ");
  522      strncat(errMsg, varName, MAXVARNAME);
  523      ffpmsg (errMsg);
  524      break;
  525       }
  526       thelval->lng = varNum;
  527    }
  528    return( type );
  529 }
  530 
  531 static int find_variable(char *varName)
  532 {
  533    int i;
  534  
  535    if( gParse.nCols )
  536       for( i=0; i<gParse.nCols; i++ ) {
  537          if( ! fits_strncasecmp(gParse.varData[i].name,varName,MAXVARNAME) ) {
  538             return( i );
  539          }
  540       }
  541    return( -1 );
  542 }