Blame ce_expr.lex

Packit a4aae4
Packit a4aae4
/*
Packit a4aae4
 -*- mode: c++; c-basic-offset:4 -*-
Packit a4aae4
Packit a4aae4
 This file is part of libdap, A C++ implementation of the OPeNDAP Data
Packit a4aae4
 Access Protocol.
Packit a4aae4
Packit a4aae4
 Copyright (c) 2002,2003 OPeNDAP, Inc.
Packit a4aae4
 Author: James Gallagher <jgallagher@opendap.org>
Packit a4aae4
Packit a4aae4
 This library is free software; you can redistribute it and/or
Packit a4aae4
 modify it under the terms of the GNU Lesser General Public
Packit a4aae4
 License as published by the Free Software Foundation; either
Packit a4aae4
 version 2.1 of the License, or (at your option) any later version.
Packit a4aae4
 
Packit a4aae4
 This library is distributed in the hope that it will be useful,
Packit a4aae4
 but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a4aae4
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a4aae4
 Lesser General Public License for more details.
Packit a4aae4
 
Packit a4aae4
 You should have received a copy of the GNU Lesser General Public
Packit a4aae4
 License along with this library; if not, write to the Free Software
Packit a4aae4
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit a4aae4
Packit a4aae4
 You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
Packit a4aae4
Packit a4aae4
 (c) COPYRIGHT URI/MIT 1994-1999
Packit a4aae4
*/ 
Packit a4aae4
Packit a4aae4
/*
Packit a4aae4
  Scanner for constraint expressions. The scanner returns tokens for each of
Packit a4aae4
  the relational and selection operators. It requires GNU flex version 2.5.2
Packit a4aae4
  or newer.
Packit a4aae4
Packit a4aae4
  The scanner is not reentrant, but can share a name space with other
Packit a4aae4
  scanners. 
Packit a4aae4
Packit a4aae4
   Note:
Packit a4aae4
   1) The `defines' file expr.tab.h is built using `bison -d'.
Packit a4aae4
   2) Define YY_DECL such that the scanner is called `exprlex'.
Packit a4aae4
   3) When bison builds the expr.tab.h file, it uses `expr' instead of `yy'
Packit a4aae4
   for variable name prefixes (e.g., yylval --> exprlval).
Packit a4aae4
Packit a4aae4
  jhrg 9/5/95
Packit a4aae4
*/
Packit a4aae4
Packit a4aae4
%{
Packit a4aae4
Packit a4aae4
#include "config.h"
Packit a4aae4
Packit a4aae4
#include <cstdio>
Packit a4aae4
#include <string>
Packit a4aae4
#include <cstring>
Packit a4aae4
Packit a4aae4
#ifndef YY_PROTO
Packit a4aae4
#define YY_PROTO(proto) proto
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
#define YY_DECL int ce_exprlex YY_PROTO(( void ))
Packit a4aae4
#define YY_FATAL_ERROR(msg) {\
Packit a4aae4
    throw(libdap::Error(malformed_expr, std::string("Error scanning constraint expression text: ") + std::string(msg))); \
Packit a4aae4
    yy_fatal_error(msg); /* see das.lex */ \
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
#include "Error.h"
Packit a4aae4
#include "parser.h"
Packit a4aae4
#include "expr.h"
Packit a4aae4
#include "RValue.h"
Packit a4aae4
#include "ce_expr.tab.hh"
Packit a4aae4
#include "escaping.h"
Packit a4aae4
Packit a4aae4
using namespace libdap ;
Packit a4aae4
Packit a4aae4
static void store_id();
Packit a4aae4
static void store_str();
Packit a4aae4
static void store_op(int op);
Packit a4aae4
Packit a4aae4
%}
Packit a4aae4
Packit a4aae4
%option noyywrap
Packit a4aae4
%option nounput
Packit a4aae4
%option noinput
Packit a4aae4
%option 8bit
Packit a4aae4
%option prefix="ce_expr"
Packit a4aae4
%option outfile="lex.ce_expr.cc"
Packit a4aae4
Packit a4aae4
%x quote
Packit a4aae4
    
Packit a4aae4
/* In the DAS and DDS parsers I removed the INT and FLOAT lexemes. However,
Packit a4aae4
   not having them here complicates parsing since you must check to see if a
Packit a4aae4
   word is a number (like 2.3) or a variable called `2.3.' I'm assuming that
Packit a4aae4
   people will always put some characters in variable names (e.g., they'll
Packit a4aae4
   use `2300.7%20MHz' and not just `2300.7'). If that turns out to be a bad
Packit a4aae4
   assumption, the we'll have to put more code in the parser to figure out
Packit a4aae4
   what exactly each word is; is it a constant or a variable name. Time will
Packit a4aae4
   tell. 10/31/2001 jhrg */
Packit a4aae4
Packit a4aae4
NAN		[Nn][Aa][Nn]
Packit a4aae4
INF		[Ii][Nn][Ff]
Packit a4aae4
/* See das.lex for comments about the characters allowed in a WORD.
Packit a4aae4
   10/31/2001 jhrg 
Packit a4aae4
Packit a4aae4
   I've added '*' to the set of characters in a WORD for both the DDS and DAS
Packit a4aae4
   scanners, but not here because it'll conflict with the url dereference
Packit a4aae4
   operator. 6/10/2002 jhrg
Packit a4aae4
*/
Packit a4aae4
Packit a4aae4
SCAN_WORD       [-+a-zA-Z0-9_/%.\\][-+a-zA-Z0-9_/%.\\#]*
Packit a4aae4
Packit a4aae4
SCAN_EQUAL	    =
Packit a4aae4
SCAN_NOT_EQUAL	!=
Packit a4aae4
SCAN_GREATER	>
Packit a4aae4
SCAN_GREATER_EQL >=
Packit a4aae4
SCAN_LESS	    <
Packit a4aae4
SCAN_LESS_EQL	<=
Packit a4aae4
SCAN_REGEXP	    =~
Packit a4aae4
Packit a4aae4
SCAN_HASH_BYTE    $Byte
Packit a4aae4
SCAN_HASH_INT16   $Int16
Packit a4aae4
SCAN_HASH_UINT16  $UInt16
Packit a4aae4
SCAN_HASH_INT32   $Int32
Packit a4aae4
SCAN_HASH_UINT32  $UInt32
Packit a4aae4
SCAN_HASH_FLOAT32 $Float32
Packit a4aae4
SCAN_HASH_FLOAT64 $Float64
Packit a4aae4
Packit a4aae4
SCAN_STAR       \*
Packit a4aae4
Packit a4aae4
NEVER		[^\-+a-zA-Z0-9_/%.\\:,(){}[\]&<>=~]
Packit a4aae4
Packit a4aae4
%%
Packit a4aae4
Packit a4aae4
"["    	return (int)*yytext;
Packit a4aae4
"]"    	return (int)*yytext;
Packit a4aae4
":"    	return (int)*yytext;
Packit a4aae4
","		return (int)*yytext;
Packit a4aae4
"&"		return (int)*yytext;
Packit a4aae4
"("		return (int)*yytext;
Packit a4aae4
")"		return (int)*yytext;
Packit a4aae4
"{"		return (int)*yytext;
Packit a4aae4
"}"		return (int)*yytext;
Packit a4aae4
Packit a4aae4
{SCAN_WORD}	        store_id(); return SCAN_WORD;
Packit a4aae4
Packit a4aae4
{SCAN_EQUAL}	    store_op(SCAN_EQUAL); return SCAN_EQUAL;
Packit a4aae4
{SCAN_NOT_EQUAL}    store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
Packit a4aae4
{SCAN_GREATER}	    store_op(SCAN_GREATER); return SCAN_GREATER;
Packit a4aae4
{SCAN_GREATER_EQL}  store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
Packit a4aae4
{SCAN_LESS}	        store_op(SCAN_LESS); return SCAN_LESS;
Packit a4aae4
{SCAN_LESS_EQL}	    store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
Packit a4aae4
{SCAN_REGEXP}	    store_op(SCAN_REGEXP); return SCAN_REGEXP;
Packit a4aae4
Packit a4aae4
{SCAN_STAR}         store_op(SCAN_STAR); return SCAN_STAR;
Packit a4aae4
Packit a4aae4
{SCAN_HASH_BYTE}      return SCAN_HASH_BYTE;
Packit a4aae4
{SCAN_HASH_INT16}     return SCAN_HASH_INT16;
Packit a4aae4
{SCAN_HASH_UINT16}    return SCAN_HASH_UINT16;
Packit a4aae4
{SCAN_HASH_INT32}     return SCAN_HASH_INT32;
Packit a4aae4
{SCAN_HASH_UINT32}    return SCAN_HASH_UINT32;
Packit a4aae4
{SCAN_HASH_FLOAT32}   return SCAN_HASH_FLOAT32;
Packit a4aae4
{SCAN_HASH_FLOAT64}   return SCAN_HASH_FLOAT64;
Packit a4aae4
Packit a4aae4
[ \t\r\n]+
Packit a4aae4
<INITIAL><<EOF>> yy_init = 1; yyterminate();
Packit a4aae4
Packit a4aae4
\"		BEGIN(quote); yymore();
Packit a4aae4
Packit a4aae4
<quote>[^"\\]*  yymore(); /*"*/
Packit a4aae4
Packit a4aae4
<quote>\\.	yymore();
Packit a4aae4
Packit a4aae4
<quote>\"	{ 
Packit a4aae4
    		  BEGIN(INITIAL); 
Packit a4aae4
              store_str();
Packit a4aae4
              return SCAN_STR;
Packit a4aae4
            }
Packit a4aae4
Packit a4aae4
<quote><<EOF>>	{
Packit a4aae4
                  BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
Packit a4aae4
                  char msg[256];
Packit a4aae4
                  sprintf(msg, "Unterminated quote\n");
Packit a4aae4
                  YY_FATAL_ERROR(msg);
Packit a4aae4
                }
Packit a4aae4
Packit a4aae4
{NEVER}         {
Packit a4aae4
                  if (yytext) {	/* suppress msgs about `' chars */
Packit a4aae4
                    fprintf(stderr, "Character `%c' is not", *yytext);
Packit a4aae4
                    fprintf(stderr, " allowed and has been ignored\n");
Packit a4aae4
                  }
Packit a4aae4
		        }
Packit a4aae4
%%
Packit a4aae4
Packit a4aae4
// Three glue routines for string scanning. These are not declared in the
Packit a4aae4
// header expr.tab.h nor is YY_BUFFER_STATE. Including these here allows them
Packit a4aae4
// to see the type definitions in lex.expr.c (where YY_BUFFER_STATE is
Packit a4aae4
// defined) and allows callers to declare them (since callers outside of this
Packit a4aae4
// file cannot declare the YY_BUFFER_STATE variable). Note that I changed the
Packit a4aae4
// name of the expr_scan_string function to expr_string because C++ cannot
Packit a4aae4
// distinguish by return type. 1/12/99 jhrg
Packit a4aae4
Packit a4aae4
void *
Packit a4aae4
ce_expr_string(const char *str)
Packit a4aae4
{
Packit a4aae4
    return (void *)ce_expr_scan_string(str);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
void
Packit a4aae4
ce_expr_switch_to_buffer(void *buf)
Packit a4aae4
{
Packit a4aae4
    ce_expr_switch_to_buffer((YY_BUFFER_STATE)buf);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
void
Packit a4aae4
ce_expr_delete_buffer(void *buf)
Packit a4aae4
{
Packit a4aae4
    ce_expr_delete_buffer((YY_BUFFER_STATE)buf);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
static void
Packit a4aae4
store_id()
Packit a4aae4
{
Packit a4aae4
    strncpy(ce_exprlval.id, yytext, ID_MAX-1);
Packit a4aae4
    ce_exprlval.id[ID_MAX-1] = '\0';
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
static void
Packit a4aae4
store_str()
Packit a4aae4
{
Packit a4aae4
    // transform %20 to a space. 7/11/2001 jhrg
Packit a4aae4
    string *s = new string(yytext); // move all calls of www2id into the parser. jhrg 7/5/13 www2id(string(yytext)));
Packit a4aae4
Packit a4aae4
    if (*s->begin() == '\"' && *(s->end()-1) == '\"') {
Packit a4aae4
	s->erase(s->begin());
Packit a4aae4
	s->erase(s->end()-1);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    ce_exprlval.val.type = dods_str_c;
Packit a4aae4
    ce_exprlval.val.v.s = s;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
static void
Packit a4aae4
store_op(int op)
Packit a4aae4
{
Packit a4aae4
    ce_exprlval.op = op;
Packit a4aae4
}
Packit a4aae4