|
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) 2014 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 |
%skeleton "lalr1.cc" /* -*- C++ -*- */
|
|
Packit |
a4aae4 |
%require "2.5"
|
|
Packit |
a4aae4 |
%defines
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// The d4_function_parser.tab.cc and .hh files define and declare this class
|
|
Packit |
a4aae4 |
%define parser_class_name {D4FunctionParser}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// D4FunctionParser is in this namespace
|
|
Packit |
a4aae4 |
%define api.namespace {libdap}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%define parse.trace
|
|
Packit |
a4aae4 |
%define parse.error verbose
|
|
Packit |
a4aae4 |
%define parse.assert
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Could not get this to work with a C++ scanner built by flex. 8/10/13 jhrg
|
|
Packit |
a4aae4 |
// %define api.token.constructor
|
|
Packit |
a4aae4 |
%define api.value.type variant
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Because the code uses the C++ mode of flex, we don't use this. 8/8/13 jhrg
|
|
Packit |
a4aae4 |
// %define api.prefix { d4_function_ }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%code requires {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "D4FunctionEvaluator.h"
|
|
Packit |
a4aae4 |
#include "D4RValue.h"
|
|
Packit |
a4aae4 |
#include "dods-datatypes.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
class D4FunctionScanner;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Pass both the scanner and parser objects to both the automatically generated
|
|
Packit |
a4aae4 |
// parser and scanner.
|
|
Packit |
a4aae4 |
%lex-param { D4FunctionScanner &scanner }
|
|
Packit |
a4aae4 |
%parse-param { D4FunctionScanner &scanner }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%lex-param { D4FunctionEvaluator &evaluator }
|
|
Packit |
a4aae4 |
%parse-param { D4FunctionEvaluator &evaluator }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%locations
|
|
Packit |
a4aae4 |
%initial-action
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// Initialize the initial location. This is printed when the parser builds
|
|
Packit |
a4aae4 |
// its own error messages - when the parse fails as opposed to when the
|
|
Packit |
a4aae4 |
// function(s) name(s) a missing variable, ...
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@$.initialize (evaluator.expression());
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%code {
|
|
Packit |
a4aae4 |
#include "BaseType.h"
|
|
Packit |
a4aae4 |
#include "DMR.h"
|
|
Packit |
a4aae4 |
#include "D4RValue.h"
|
|
Packit |
a4aae4 |
#include "ServerFunctionsList.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "parser-util.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/* include for all driver functions */
|
|
Packit |
a4aae4 |
#include "D4FunctionEvaluator.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace libdap ;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/* this is silly, but I can't figure out a way around it */
|
|
Packit |
a4aae4 |
static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
|
|
Packit |
a4aae4 |
libdap::location *loc,
|
|
Packit |
a4aae4 |
libdap::D4FunctionScanner &scanner,
|
|
Packit |
a4aae4 |
libdap::D4FunctionEvaluator &evaluator);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%type <D4RValueList*> functions "functions"
|
|
Packit |
a4aae4 |
%type <D4RValueList*> args "arguments"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%type <D4RValue*> arg "argument"
|
|
Packit |
a4aae4 |
%type <D4RValue*> function "function"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%type <D4Function> fname "function name"
|
|
Packit |
a4aae4 |
%type <D4RValue*> variable_or_constant "variable or constant"
|
|
Packit |
a4aae4 |
%type <D4RValue*> array_constant "array constant"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%type <std::vector<dods_byte>*> fast_byte_arg_list "fast byte arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_int8>*> fast_int8_arg_list "fast int8 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_uint16>*> fast_uint16_arg_list "fast uint16 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_int16>*> fast_int16_arg_list "fast int16 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_uint32>*> fast_uint32_arg_list "fast uint32 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_int32>*> fast_int32_arg_list "fast int32 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_uint64>*> fast_uint64_arg_list "fast uint64 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_int64>*> fast_int64_arg_list "fast int64 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_float32>*> fast_float32_arg_list "fast float32 arg list"
|
|
Packit |
a4aae4 |
%type <std::vector<dods_float64>*> fast_float64_arg_list "fast float64 arg list"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%type <std::string> id path group name
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// The strings used in the token definitions are used for error messages
|
|
Packit |
a4aae4 |
%token <std::string> WORD "word"
|
|
Packit |
a4aae4 |
%token <std::string> STRING "string"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%token
|
|
Packit |
a4aae4 |
END 0 "end of file"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
SEMICOLON ";"
|
|
Packit |
a4aae4 |
COLON ":"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
LPAREN "("
|
|
Packit |
a4aae4 |
RPAREN ")"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
COMMA ","
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
GROUP_SEP "/"
|
|
Packit |
a4aae4 |
PATH_SEP "."
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
DOLLAR_BYTE "$Byte"
|
|
Packit |
a4aae4 |
DOLLAR_UINT8 "$UInt8"
|
|
Packit |
a4aae4 |
DOLLAR_INT8 "$Int8"
|
|
Packit |
a4aae4 |
DOLLAR_UINT16 "$UInt16"
|
|
Packit |
a4aae4 |
DOLLAR_INT16 "$Int16"
|
|
Packit |
a4aae4 |
DOLLAR_UINT32 "$UInt32"
|
|
Packit |
a4aae4 |
DOLLAR_INT32 "$Int32"
|
|
Packit |
a4aae4 |
DOLLAR_UINT64 "$UInt64"
|
|
Packit |
a4aae4 |
DOLLAR_INT64 "$Int64"
|
|
Packit |
a4aae4 |
DOLLAR_FLOAT32 "$Float32"
|
|
Packit |
a4aae4 |
DOLLAR_FLOAT64 "$Float64"
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%%
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%start program;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
program : functions
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
evaluator.set_result($1);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
functions : function
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValueList($1);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| functions ";" function
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->add_rvalue($3);
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
function : fname "(" args ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue($1, $3); // Build a D4RValue from a D4Function pointer and a D4RValueList
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fname: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
D4Function f;
|
|
Packit |
a4aae4 |
if (!evaluator.sf_list()->find_function($1, &f)) {
|
|
Packit |
a4aae4 |
// ...cloud use @1.{first,last}_column in these error messages.
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "'" + $1 + "' is not a registered DAP4 server function.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
$$ = f;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
args: arg
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValueList($1); // build a D4RValueList from the D4RValue
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| args "," arg
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->add_rvalue($3);
|
|
Packit |
a4aae4 |
$$ = $1; // Append the D4RValue ($3) to the D4RValueList ($1), then return
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
arg: function
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| variable_or_constant
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| array_constant
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
variable_or_constant : id
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
D4RValue *rvalue = evaluator.build_rvalue($1);
|
|
Packit |
a4aae4 |
if (!rvalue) {
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "'" + $1 + "' is not a variable, number or string.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
$$ = rvalue;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
array_constant :
|
|
Packit |
a4aae4 |
DOLLAR_BYTE "(" arg_length_hint ":" fast_byte_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_UINT8 "(" arg_length_hint ":" fast_byte_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_INT8 "(" arg_length_hint ":" fast_int8_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_UINT16 "(" arg_length_hint ":" fast_uint16_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_INT16 "(" arg_length_hint ":" fast_int16_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_UINT32 "(" arg_length_hint ":" fast_uint32_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_INT32 "(" arg_length_hint ":" fast_int32_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_UINT64 "(" arg_length_hint ":" fast_uint64_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_INT64 "(" arg_length_hint ":" fast_int64_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_FLOAT32 "(" arg_length_hint ":" fast_float32_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
|
Packit |
a4aae4 |
DOLLAR_FLOAT64 "(" arg_length_hint ":" fast_float64_arg_list ")"
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = new D4RValue(*($5));
|
|
Packit |
a4aae4 |
delete $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/* Here the arg length hint is stored in the eval class so it can be used by the
|
|
Packit |
a4aae4 |
method that allocates the vector. The value is passed to vector::reserve().
|
|
Packit |
a4aae4 |
This rule is run for it's side-effect only. This is also used to track the
|
|
Packit |
a4aae4 |
current arg number so that the hint can be used. */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
arg_length_hint : WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
evaluator.set_arg_length_hint(get_uint64($1.c_str()));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_byte_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_byte(strtol($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_byte_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtol($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_int8_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_int8(strtol($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_int8_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtol($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_uint16_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_uint16(strtol($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_uint16_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtol($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_int16_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_int16(strtol($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_int16_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtol($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_uint32_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_uint32(strtoul($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_uint32_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtoul($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
fast_int32_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_int32(strtol($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_int32_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtol($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_uint64_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_uint64(strtoull($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_uint64_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtoull($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_int64_arg_list: WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_int64(strtoll($1.c_str(), 0, 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_int64_arg_list "," WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtoll($3.c_str(), 0, 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// I'm using path for the $Float constants so that tokens with dots will
|
|
Packit |
a4aae4 |
// parse. I could add a FLOAT token, and I might have to do that later on
|
|
Packit |
a4aae4 |
// when filters are added to the CE, but this will work for now.
|
|
Packit |
a4aae4 |
fast_float32_arg_list: path
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_float32(strtof($1.c_str(), 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_float32_arg_list "," path
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtof($3.c_str(), 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fast_float64_arg_list: path
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = evaluator.init_arg_list(dods_float64(strtod($1.c_str(), 0)));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| fast_float64_arg_list "," path
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1->push_back(strtod($3.c_str(), 0));
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
id : path
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| "/" path
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$.append("/");
|
|
Packit |
a4aae4 |
$$.append($2);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| group "/" path
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1.append("/");
|
|
Packit |
a4aae4 |
$1.append($3);
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
group : "/" name
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$.append("/");
|
|
Packit |
a4aae4 |
$$.append($2);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| group "/" name
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1.append(".");
|
|
Packit |
a4aae4 |
$1.append($3);
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
path : name
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| path "." name
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$1.append(".");
|
|
Packit |
a4aae4 |
$1.append($3);
|
|
Packit |
a4aae4 |
$$ = $1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Because some formats/datasets allow 'any' name for a variable, it's possible
|
|
Packit |
a4aae4 |
// that a variable name will be a number, etc. The grammar also allows STRING
|
|
Packit |
a4aae4 |
// to support "name"."name with spaces and dots (.)".x
|
|
Packit |
a4aae4 |
name : WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$=$1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| STRING
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$=$1;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%%
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Forward the error to the driver for handling. The location parameter
|
|
Packit |
a4aae4 |
// provides the line number and character position of the error.
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
libdap::D4FunctionParser::error(const location_type &l, const std::string &m)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
evaluator.error(l, m);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/* include for access to scanner.yylex */
|
|
Packit |
a4aae4 |
#include "D4FunctionScanner.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
|
|
Packit |
a4aae4 |
libdap::location *loc,
|
|
Packit |
a4aae4 |
libdap::D4FunctionScanner &scanner,
|
|
Packit |
a4aae4 |
libdap::D4FunctionEvaluator &evaluator)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (evaluator.trace_scanning())
|
|
Packit |
a4aae4 |
scanner.set_debug(true);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return( scanner.yylex(yylval, loc) );
|
|
Packit |
a4aae4 |
}
|