Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.astro.louisville.edu/software/sbig/archive/xmccd-4.1/xmccd-4.1e/libcfitsio/libcfitsio-3.310/eval.l
Дата изменения: Fri Aug 28 21:51:18 2009
Дата индексирования: Sun Apr 10 06:15:34 2016
Кодировка:

Поисковые слова: viking 2
%{
/************************************************************************/
/* */
/* CFITSIO Lexical Parser */
/* */
/* This file is one of 3 files containing code which parses an */
/* arithmetic expression and evaluates it in the context of an input */
/* FITS file table extension. The CFITSIO lexical parser is divided */
/* into the following 3 parts/files: the CFITSIO "front-end", */
/* eval_f.c, contains the interface between the user/CFITSIO and the */
/* real core of the parser; the FLEX interpreter, eval_l.c, takes the */
/* input string and parses it into tokens and identifies the FITS */
/* information required to evaluate the expression (ie, keywords and */
/* columns); and, the BISON grammar and evaluation routines, eval_y.c, */
/* receives the FLEX output and determines and performs the actual */
/* operations. The files eval_l.c and eval_y.c are produced from */
/* running flex and bison on the files eval.l and eval.y, respectively. */
/* (flex and bison are available from any GNU archive: see www.gnu.org) */
/* */
/* The grammar rules, rather than evaluating the expression in situ, */
/* builds a tree, or Nodal, structure mapping out the order of */
/* operations and expression dependencies. This "compilation" process */
/* allows for much faster processing of multiple rows. This technique */
/* was developed by Uwe Lammers of the XMM Science Analysis System, */
/* although the CFITSIO implementation is entirely code original. */
/* */
/* */
/* Modification History: */
/* */
/* Kent Blackburn c1992 Original parser code developed for the */
/* FTOOLS software package, in particular, */
/* the fselect task. */
/* Kent Blackburn c1995 BIT column support added */
/* Peter D Wilson Feb 1998 Vector column support added */
/* Peter D Wilson May 1998 Ported to CFITSIO library. User */
/* interface routines written, in essence */
/* making fselect, fcalc, and maketime */
/* capabilities available to all tools */
/* via single function calls. */
/* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */
/* create a run-time evaluation tree, */
/* inspired by the work of Uwe Lammers, */
/* resulting in a speed increase of */
/* 10-100 times. */
/* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */
/* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */
/* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */
/* allowing a purely vector-based usage */
/* */
/************************************************************************/

#include
#include
#include
#ifdef sparc
#include
#else
#include
#endif
#include "eval_defs.h"

ParseData gParse; /* Global structure holding all parser information */

/***** Internal functions *****/

int yyGetVariable( char *varName, YYSTYPE *varVal );

static int find_variable( char *varName );
static int expr_read( char *buf, int nbytes );

/***** Definitions *****/

#define YY_NO_UNPUT /* Don't include YYUNPUT function */
#define YY_NEVER_INTERACTIVE 1

#define MAXCHR 256
#define MAXBIT 128

#define OCT_0 "000"
#define OCT_1 "001"
#define OCT_2 "010"
#define OCT_3 "011"
#define OCT_4 "100"
#define OCT_5 "101"
#define OCT_6 "110"
#define OCT_7 "111"
#define OCT_X "xxx"

#define HEX_0 "0000"
#define HEX_1 "0001"
#define HEX_2 "0010"
#define HEX_3 "0011"
#define HEX_4 "0100"
#define HEX_5 "0101"
#define HEX_6 "0110"
#define HEX_7 "0111"
#define HEX_8 "1000"
#define HEX_9 "1001"
#define HEX_A "1010"
#define HEX_B "1011"
#define HEX_C "1100"
#define HEX_D "1101"
#define HEX_E "1110"
#define HEX_F "1111"
#define HEX_X "xxxx"

/*
MJT - 13 June 1996
read from buffer instead of stdin
(as per old ftools.skel)
*/
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
if ( (result = expr_read( (char *) buf, max_size )) < 0 ) \
YY_FATAL_ERROR( "read() in flex scanner failed" );

%}
bit ([bB][01xX]+)
oct ([oO][01234567xX]+)
hex ([hH][0123456789aAbBcCdDeEfFxX]+)
integer [0-9]+
boolean (t|f|T|F)
real ([0-9]*"."[0-9]+)|([0-9]*"."*[0-9]+[eEdD][+-]?[0-9]+)|([0-9]*".")
constant ("#"[a-zA-Z0-9_]+)|("#""$"[^\n]*"$")
string ([\"][^\"\n]*[\"])|([\'][^\'\n]*[\'])
variable ([a-zA-Z_][a-zA-Z0-9_]*)|("$"[^$\n]*"$")
function [a-zA-Z][a-zA-Z0-9]+"("
intcast ("(int)"|"(INT)")
fltcast ("(float)"|"(FLOAT)"|"(double)"|"(DOUBLE)")
power ("^"|"**")
not ("!"|".not."|".NOT."|"not."|"NOT.")
or ("||"|".or."|".OR."|"or."|"OR.")
and ("&&"|".and."|".AND."|"and."|"AND.")
equal ("=="|".eq."|".EQ."|"eq."|"EQ.")
not_equal ("!="|".ne."|".NE."|"ne."|"NE.")
greater (">"|".gt."|".GT."|"gt."|"GT.")
lesser ("<"|".lt."|".LT."|"lt."|"LT.")
greater_eq (">="|"=>"|".ge."|".GE."|"ge."|"GE.")
lesser_eq ("<="|"=<"|".le."|".LE."|"le."|"LE.")
nl \n

%%

[ \t]+ ;
{bit} {
int len;
len = strlen(yytext);
while (yytext[len] == ' ')
len--;
len = len - 1;
strncpy(yylval.str,&yytext[1],len);
yylval.str[len] = '\0';
return( BITSTR );
}
{oct} {
int len;
char tmpstring[256];
char bitstring[256];
len = strlen(yytext);
if (len >= 256) {
char errMsg[100];
gParse.status = PARSE_SYNTAX_ERR;
strcpy (errMsg,"Bit string exceeds maximum length: '");
strncat(errMsg, &(yytext[0]), 20);
strcat (errMsg,"...'");
ffpmsg (errMsg);
len = 0;
} else {
while (yytext[len] == ' ')
len--;
len = len - 1;
strncpy(tmpstring,&yytext[1],len);
}
tmpstring[len] = '\0';
bitstring[0] = '\0';
len = 0;
while ( tmpstring[len] != '\0')
{
switch ( tmpstring[len] )
{
case '0':
strcat(bitstring,OCT_0);
break;
case '1':
strcat(bitstring,OCT_1);
break;
case '2':
strcat(bitstring,OCT_2);
break;
case '3':
strcat(bitstring,OCT_3);
break;
case '4':
strcat(bitstring,OCT_4);
break;
case '5':
strcat(bitstring,OCT_5);
break;
case '6':
strcat(bitstring,OCT_6);
break;
case '7':
strcat(bitstring,OCT_7);
break;
case 'x':
case 'X':
strcat(bitstring,OCT_X);
break;
}
len++;
}
strcpy( yylval.str, bitstring );
return( BITSTR );
}
{hex} {
int len;
char tmpstring[256];
char bitstring[256];
len = strlen(yytext);
if (len >= 256) {
char errMsg[100];
gParse.status = PARSE_SYNTAX_ERR;
strcpy (errMsg,"Hex string exceeds maximum length: '");
strncat(errMsg, &(yytext[0]), 20);
strcat (errMsg,"...'");
ffpmsg (errMsg);
len = 0;
} else {
while (yytext[len] == ' ')
len--;
len = len - 1;
strncpy(tmpstring,&yytext[1],len);
}
tmpstring[len] = '\0';
bitstring[0] = '\0';
len = 0;
while ( tmpstring[len] != '\0')
{
switch ( tmpstring[len] )
{
case '0':
strcat(bitstring,HEX_0);
break;
case '1':
strcat(bitstring,HEX_1);
break;
case '2':
strcat(bitstring,HEX_2);
break;
case '3':
strcat(bitstring,HEX_3);
break;
case '4':
strcat(bitstring,HEX_4);
break;
case '5':
strcat(bitstring,HEX_5);
break;
case '6':
strcat(bitstring,HEX_6);
break;
case '7':
strcat(bitstring,HEX_7);
break;
case '8':
strcat(bitstring,HEX_8);
break;
case '9':
strcat(bitstring,HEX_9);
break;
case 'a':
case 'A':
strcat(bitstring,HEX_A);
break;
case 'b':
case 'B':
strcat(bitstring,HEX_B);
break;
case 'c':
case 'C':
strcat(bitstring,HEX_C);
break;
case 'd':
case 'D':
strcat(bitstring,HEX_D);
break;
case 'e':
case 'E':
strcat(bitstring,HEX_E);
break;
case 'f':
case 'F':
strcat(bitstring,HEX_F);
break;
case 'x':
case 'X':
strcat(bitstring,HEX_X);
break;
}
len++;
}

strcpy( yylval.str, bitstring );
return( BITSTR );
}
{integer} {
yylval.lng = atol(yytext);
return( LONG );
}
{boolean} {
if ((yytext[0] == 't') || (yytext[0] == 'T'))
yylval.log = 1;
else
yylval.log = 0;
return( BOOLEAN );
}
{real} {
yylval.dbl = atof(yytext);
return( DOUBLE );
}
{constant} {
if( !strcasecmp(yytext,"#PI") ) {
yylval.dbl = (double)(4) * atan((double)(1));
return( DOUBLE );
} else if( !strcasecmp(yytext,"#E") ) {
yylval.dbl = exp((double)(1));
return( DOUBLE );
} else if( !strcasecmp(yytext,"#DEG") ) {
yylval.dbl = ((double)4)*atan((double)1)/((double)180);
return( DOUBLE );
} else if( !strcasecmp(yytext,"#ROW") ) {
return( ROWREF );
} else if( !strcasecmp(yytext,"#NULL") ) {
return( NULLREF );
} else if( !strcasecmp(yytext,"#SNULL") ) {
return( SNULLREF );
} else {
int len;
if (yytext[1] == '$') {
len = strlen(yytext) - 3;
yylval.str[0] = '#';
strncpy(yylval.str+1,&yytext[2],len);
yylval.str[len+1] = '\0';
yytext = yylval.str;
}
return( (*gParse.getData)(yytext, &yylval) );
}
}
{string} {
int len;
len = strlen(yytext) - 2;
if (len >= MAX_STRLEN) {
char errMsg[100];
gParse.status = PARSE_SYNTAX_ERR;
strcpy (errMsg,"String exceeds maximum length: '");
strncat(errMsg, &(yytext[1]), 20);
strcat (errMsg,"...'");
ffpmsg (errMsg);
len = 0;
} else {
strncpy(yylval.str,&yytext[1],len);
}
yylval.str[len] = '\0';
return( STRING );
}
{variable} {
int len,type;

if (yytext[0] == '$') {
len = strlen(yytext) - 2;
strncpy(yylval.str,&yytext[1],len);
yylval.str[len] = '\0';
yytext = yylval.str;
}
type = yyGetVariable(yytext, &yylval);
return( type );
}
{function} {
char *fname;
int len=0;
fname = &yylval.str[0];
while( (fname[len]=toupper(yytext[len])) ) len++;

if( FSTRCMP(fname,"BOX(")==0
|| FSTRCMP(fname,"CIRCLE(")==0
|| FSTRCMP(fname,"ELLIPSE(")==0
|| FSTRCMP(fname,"NEAR(")==0
|| FSTRCMP(fname,"ISNULL(")==0
)
/* Return type is always boolean */
return( BFUNCTION );

else if( FSTRCMP(fname,"GTIFILTER(")==0 )
return( GTIFILTER );

else if( FSTRCMP(fname,"REGFILTER(")==0 )
return( REGFILTER );

else if( FSTRCMP(fname,"STRSTR(")==0 )
return( IFUNCTION ); /* Returns integer */

else
return( FUNCTION );
}
{intcast} { return( INTCAST ); }
{fltcast} { return( FLTCAST ); }
{power} { return( POWER ); }
{not} { return( NOT ); }
{or} { return( OR ); }
{and} { return( AND ); }
{equal} { return( EQ ); }
{not_equal} { return( NE ); }
{greater} { return( GT ); }
{lesser} { return( LT ); }
{greater_eq} { return( GTE ); }
{lesser_eq} { return( LTE ); }
{nl} { return( '\n' ); }
. { return( yytext[0] ); }
%%

int yywrap()
{
/* MJT -- 13 June 1996
Supplied for compatibility with
pre-2.5.1 versions of flex which
do not recognize %option noyywrap
*/
return(1);
}

/*
expr_read is lifted from old ftools.skel.
Now we can use any version of flex with
no .skel file necessary! MJT - 13 June 1996

keep a memory of how many bytes have been
read previously, so that an unlimited-sized
buffer can be supported. PDW - 28 Feb 1998
*/

static int expr_read(char *buf, int nbytes)
{
int n;

n = 0;
if( !gParse.is_eobuf ) {
do {
buf[n++] = gParse.expr[gParse.index++];
} while ((n if( gParse.expr[gParse.index] == '\0' ) gParse.is_eobuf = 1;
}
buf[n] = '\0';
return(n);
}

int yyGetVariable( char *varName, YYSTYPE *thelval )
{
int varNum, type;
char errMsg[MAXVARNAME+25];

varNum = find_variable( varName );
if( varNum<0 ) {
if( gParse.getData ) {
type = (*gParse.getData)( varName, thelval );
} else {
type = pERROR;
gParse.status = PARSE_SYNTAX_ERR;
strcpy (errMsg,"Unable to find data: ");
strncat(errMsg, varName, MAXVARNAME);
ffpmsg (errMsg);
}
} else {
/* Convert variable type into expression type */
switch( gParse.varData[ varNum ].type ) {
case LONG:
case DOUBLE: type = COLUMN; break;
case BOOLEAN: type = BCOLUMN; break;
case STRING: type = SCOLUMN; break;
case BITSTR: type = BITCOL; break;
default:
type = pERROR;
gParse.status = PARSE_SYNTAX_ERR;
strcpy (errMsg,"Bad datatype for data: ");
strncat(errMsg, varName, MAXVARNAME);
ffpmsg (errMsg);
break;
}
thelval->lng = varNum;
}
return( type );
}

static int find_variable(char *varName)
{
int i;

if( gParse.nCols )
for( i=0; i if( ! strncasecmp(gParse.varData[i].name,varName,MAXVARNAME) ) {
return( i );
}
}
return( -1 );
}

#if defined(vms) || defined(__vms) || defined(WIN32) || defined(__WIN32__) || defined(macintosh)

/* ================================================================== */
/* A hack for nonunix machines, which lack strcasecmp and strncasecmp */
/* ================================================================== */

int strcasecmp(const char *s1, const char *s2)
{
char c1, c2;

for (;;) {
c1 = toupper( *s1 );
c2 = toupper( *s2 );

if (c1 < c2) return(-1);
if (c1 > c2) return(1);
if (c1 == 0) return(0);
s1++;
s2++;
}
}

int strncasecmp(const char *s1, const char *s2, size_t n)
{
char c1, c2;

for (; n-- ;) {
c1 = toupper( *s1 );
c2 = toupper( *s2 );

if (c1 < c2) return(-1);
if (c1 > c2) return(1);
if (c1 == 0) return(0);
s1++;
s2++;
}
return(0);
}

#endif