|
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 |
// Please read the full copyright statement in the file COPYRIGHT_URI.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Authors:
|
|
Packit |
a4aae4 |
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/*
|
|
Packit |
a4aae4 |
Grammar for the DDS. This grammar can be used with the bison parser
|
|
Packit |
a4aae4 |
generator to build a parser for the DDS. It assumes that a scanner called
|
|
Packit |
a4aae4 |
`ddslex()' exists and returns several token types (see das.tab.h)
|
|
Packit |
a4aae4 |
in addition to several single character token types. The matched lexeme
|
|
Packit |
a4aae4 |
for an ID is stored by the scanner in a global char * `ddslval'.
|
|
Packit |
a4aae4 |
Because the scanner returns a value via this global and because the parser
|
|
Packit |
a4aae4 |
stores ddslval (not the information pointed to), the values of rule
|
|
Packit |
a4aae4 |
components must be stored as they are parsed and used once accumulated at
|
|
Packit |
a4aae4 |
or near the end of a rule. If ddslval returned a value (instead of a
|
|
Packit |
a4aae4 |
pointer to a value) this would not be necessary.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
jhrg 8/29/94
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%code requires {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "config_dap.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <cstring>
|
|
Packit |
a4aae4 |
#include <cassert>
|
|
Packit |
a4aae4 |
#include <iostream>
|
|
Packit |
a4aae4 |
#include <stack>
|
|
Packit |
a4aae4 |
#include <sstream>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "Byte.h"
|
|
Packit |
a4aae4 |
#include "Int16.h"
|
|
Packit |
a4aae4 |
#include "UInt16.h"
|
|
Packit |
a4aae4 |
#include "Int32.h"
|
|
Packit |
a4aae4 |
#include "UInt32.h"
|
|
Packit |
a4aae4 |
#include "Float32.h"
|
|
Packit |
a4aae4 |
#include "Float64.h"
|
|
Packit |
a4aae4 |
#include "Str.h"
|
|
Packit |
a4aae4 |
#include "Url.h"
|
|
Packit |
a4aae4 |
#include "Array.h"
|
|
Packit |
a4aae4 |
#include "Structure.h"
|
|
Packit |
a4aae4 |
#include "Sequence.h"
|
|
Packit |
a4aae4 |
#include "Grid.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "DDS.h"
|
|
Packit |
a4aae4 |
#include "Error.h"
|
|
Packit |
a4aae4 |
#include "parser.h"
|
|
Packit |
a4aae4 |
#include "util.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace std;
|
|
Packit |
a4aae4 |
using namespace libdap;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// These macros are used to access the `arguments' passed to the parser. A
|
|
Packit |
a4aae4 |
// pointer to an error object and a pointer to an integer status variable are
|
|
Packit |
a4aae4 |
// passed in to the parser within a structure (which itself is passed as a
|
|
Packit |
a4aae4 |
// pointer). Note that the ERROR macro explicitly casts OBJ to an ERROR *.
|
|
Packit |
a4aae4 |
// ERROR is no longer used. These parsers now signal problems by throwing
|
|
Packit |
a4aae4 |
// exceptions. 5/22/2002 jhrg
|
|
Packit |
a4aae4 |
#define DDS_OBJ(arg) ((DDS *)((parser_arg *)(arg))->_object)
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// #define YYPARSE_PARAM arg
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
extern int dds_line_num; /* defined in dds.lex */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // code requires
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%code {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// No global static objects in the dap library! 1/24/2000 jhrg
|
|
Packit |
a4aae4 |
static stack<BaseType *> *ctor;
|
|
Packit |
a4aae4 |
static BaseType *current;
|
|
Packit |
a4aae4 |
static string *id;
|
|
Packit |
a4aae4 |
static Part part = nil; /* Part is defined in BaseType */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
static const char *NO_DDS_MSG =
|
|
Packit |
a4aae4 |
"The descriptor object returned from the dataset was null.\n\
|
|
Packit |
a4aae4 |
Check that the URL is correct.";
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
static const char *BAD_DECLARATION =
|
|
Packit |
a4aae4 |
"In the dataset descriptor object: Expected a variable declaration\n\
|
|
Packit |
a4aae4 |
(e.g., Int32 i;). Make sure that the variable name is not the name\n\
|
|
Packit |
a4aae4 |
of a datatype and that the Array: and Maps: sections of a Grid are\n\
|
|
Packit |
a4aae4 |
labeled properly.";
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int ddslex();
|
|
Packit |
a4aae4 |
void ddserror(parser_arg *arg, const string &s /*char *s*/);
|
|
Packit |
a4aae4 |
void error_exit_cleanup();
|
|
Packit |
a4aae4 |
void add_entry(DDS &table, stack<BaseType *> **ctor, BaseType **current,
|
|
Packit |
a4aae4 |
Part p);
|
|
Packit |
a4aae4 |
void invalid_declaration(parser_arg *arg, string semantic_err_msg,
|
|
Packit |
a4aae4 |
char *type, char *name);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // code
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%require "2.4"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%parse-param {parser_arg *arg}
|
|
Packit |
a4aae4 |
%name-prefix "dds"
|
|
Packit |
a4aae4 |
%defines
|
|
Packit |
a4aae4 |
%debug
|
|
Packit |
a4aae4 |
%verbose
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%expect 52
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%union {
|
|
Packit |
a4aae4 |
bool boolean;
|
|
Packit |
a4aae4 |
char word[ID_MAX];
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%token <word> SCAN_WORD
|
|
Packit |
a4aae4 |
%token <word> SCAN_DATASET
|
|
Packit |
a4aae4 |
%token <word> SCAN_LIST
|
|
Packit |
a4aae4 |
%token <word> SCAN_SEQUENCE
|
|
Packit |
a4aae4 |
%token <word> SCAN_STRUCTURE
|
|
Packit |
a4aae4 |
%token <word> SCAN_FUNCTION
|
|
Packit |
a4aae4 |
%token <word> SCAN_GRID
|
|
Packit |
a4aae4 |
%token <word> SCAN_BYTE
|
|
Packit |
a4aae4 |
%token <word> SCAN_INT16
|
|
Packit |
a4aae4 |
%token <word> SCAN_UINT16
|
|
Packit |
a4aae4 |
%token <word> SCAN_INT32
|
|
Packit |
a4aae4 |
%token <word> SCAN_UINT32
|
|
Packit |
a4aae4 |
%token <word> SCAN_FLOAT32
|
|
Packit |
a4aae4 |
%token <word> SCAN_FLOAT64
|
|
Packit |
a4aae4 |
%token <word> SCAN_STRING
|
|
Packit |
a4aae4 |
%token <word> SCAN_URL
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%type <boolean> datasets dataset declarations array_decl name
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%type <word> declaration base_type structure sequence grid var var_name
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%%
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
start:
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
/* On entry to the parser, make the BaseType stack.
|
|
Packit |
a4aae4 |
I use if (!ctor) here because in the tab.cc file,
|
|
Packit |
a4aae4 |
this is a case block in a switch, so it could be
|
|
Packit |
a4aae4 |
run more than once, causing the storage to be
|
|
Packit |
a4aae4 |
overwritten. jhrg 6/26/15 */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!ctor)
|
|
Packit |
a4aae4 |
ctor = new stack<BaseType *>;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
datasets
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
delete ctor; ctor = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
datasets: dataset
|
|
Packit |
a4aae4 |
| datasets dataset
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
dataset: SCAN_DATASET '{' declarations '}' name ';'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = $3 && $5;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| error
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, NO_DDS_MSG, dds_line_num, $<word>1);
|
|
Packit |
a4aae4 |
error_exit_cleanup();
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
declarations: /* empty */
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
| declaration { $$ = true; }
|
|
Packit |
a4aae4 |
| declarations declaration { $$ = true; }
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/* This non-terminal is here only to keep types like `List List Int32' from
|
|
Packit |
a4aae4 |
parsing. DODS does not allow Lists of Lists. Those types make translation
|
|
Packit |
a4aae4 |
to/from arrays too hard.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
NB: I removed the List type from DAP years ago. jhrg 6/26/15 */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
declaration: base_type var ';'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
string smsg;
|
|
Packit |
a4aae4 |
if (current->check_semantics(smsg)) {
|
|
Packit |
a4aae4 |
add_entry(*DDS_OBJ(arg), &ctor, ¤t, part);
|
|
Packit |
a4aae4 |
} else {
|
|
Packit |
a4aae4 |
invalid_declaration((parser_arg *)arg, smsg, $1, $2);
|
|
Packit |
a4aae4 |
error_exit_cleanup();
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
strncpy($$,$2,ID_MAX);
|
|
Packit |
a4aae4 |
$$[ID_MAX-1] = '\0';
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
| structure '{' declarations '}'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if( current ) delete current ;
|
|
Packit |
a4aae4 |
current = ctor->top();
|
|
Packit |
a4aae4 |
ctor->pop();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
var ';'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
string smsg;
|
|
Packit |
a4aae4 |
if (current->check_semantics(smsg)) {
|
|
Packit |
a4aae4 |
add_entry(*DDS_OBJ(arg), &ctor, ¤t, part);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
invalid_declaration((parser_arg *)arg, smsg, $1, $6);
|
|
Packit |
a4aae4 |
error_exit_cleanup();
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
strncpy($$,$6,ID_MAX);
|
|
Packit |
a4aae4 |
$$[ID_MAX-1] = '\0';
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
| sequence '{' declarations '}'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if( current ) delete current ;
|
|
Packit |
a4aae4 |
current = ctor->top();
|
|
Packit |
a4aae4 |
ctor->pop();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
var ';'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
string smsg;
|
|
Packit |
a4aae4 |
if (current->check_semantics(smsg)) {
|
|
Packit |
a4aae4 |
add_entry(*DDS_OBJ(arg), &ctor, ¤t, part);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
invalid_declaration((parser_arg *)arg, smsg, $1, $6);
|
|
Packit |
a4aae4 |
error_exit_cleanup();
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
strncpy($$,$6,ID_MAX);
|
|
Packit |
a4aae4 |
$$[ID_MAX-1] = '\0';
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
| grid '{' SCAN_WORD ':'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (is_keyword(string($3), "array")) {
|
|
Packit |
a4aae4 |
part = libdap::array;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
ostringstream msg;
|
|
Packit |
a4aae4 |
msg << BAD_DECLARATION;
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, msg.str().c_str(), dds_line_num, $3);
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
declaration SCAN_WORD ':'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (is_keyword(string($7), "maps")) {
|
|
Packit |
a4aae4 |
part = maps;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
ostringstream msg;
|
|
Packit |
a4aae4 |
msg << BAD_DECLARATION;
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, msg.str().c_str(), dds_line_num, $7);
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
declarations '}'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if( current ) delete current ;
|
|
Packit |
a4aae4 |
current = ctor->top();
|
|
Packit |
a4aae4 |
ctor->pop();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
var ';'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
string smsg;
|
|
Packit |
a4aae4 |
if (current->check_semantics(smsg)) {
|
|
Packit |
a4aae4 |
part = nil;
|
|
Packit |
a4aae4 |
add_entry(*DDS_OBJ(arg), &ctor, ¤t, part);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
invalid_declaration((parser_arg *)arg, smsg, $1, $13);
|
|
Packit |
a4aae4 |
error_exit_cleanup();
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
strncpy($$,$13,ID_MAX);
|
|
Packit |
a4aae4 |
$$[ID_MAX-1] = '\0';
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
| error
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ostringstream msg;
|
|
Packit |
a4aae4 |
msg << BAD_DECLARATION;
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, msg.str().c_str(), dds_line_num, $<word>1);
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
structure: SCAN_STRUCTURE
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ctor->push(DDS_OBJ(arg)->get_factory()->NewStructure());
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
sequence: SCAN_SEQUENCE
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ctor->push(DDS_OBJ(arg)->get_factory()->NewSequence());
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
grid: SCAN_GRID
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ctor->push(DDS_OBJ(arg)->get_factory()->NewGrid());
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
base_type: SCAN_BYTE { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewByte(); }
|
|
Packit |
a4aae4 |
| SCAN_INT16 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt16(); }
|
|
Packit |
a4aae4 |
| SCAN_UINT16 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt16(); }
|
|
Packit |
a4aae4 |
| SCAN_INT32 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt32(); }
|
|
Packit |
a4aae4 |
| SCAN_UINT32 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt32(); }
|
|
Packit |
a4aae4 |
| SCAN_FLOAT32 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat32(); }
|
|
Packit |
a4aae4 |
| SCAN_FLOAT64 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat64(); }
|
|
Packit |
a4aae4 |
| SCAN_STRING { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewStr(); }
|
|
Packit |
a4aae4 |
| SCAN_URL { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUrl(); }
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
var: var_name { current->set_name($1); }
|
|
Packit |
a4aae4 |
| var array_decl
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
var_name: SCAN_WORD | SCAN_BYTE | SCAN_INT16 | SCAN_INT32 | SCAN_UINT16
|
|
Packit |
a4aae4 |
| SCAN_UINT32 | SCAN_FLOAT32 | SCAN_FLOAT64 | SCAN_STRING
|
|
Packit |
a4aae4 |
| SCAN_URL | SCAN_STRUCTURE | SCAN_SEQUENCE | SCAN_GRID
|
|
Packit |
a4aae4 |
| SCAN_LIST
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
array_decl: '[' SCAN_WORD ']'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (!check_int32($2)) {
|
|
Packit |
a4aae4 |
string msg = "In the dataset descriptor object:\n";
|
|
Packit |
a4aae4 |
msg += "Expected an array subscript.\n";
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, msg.c_str(), dds_line_num, $2);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
if (current->type() == dods_array_c && check_int32($2)) {
|
|
Packit |
a4aae4 |
((Array *)current)->append_dim(atoi($2));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
Array *a = DDS_OBJ(arg)->get_factory()->NewArray();
|
|
Packit |
a4aae4 |
a->add_var(current);
|
|
Packit |
a4aae4 |
a->append_dim(atoi($2));
|
|
Packit |
a4aae4 |
if( current ) delete current ;
|
|
Packit |
a4aae4 |
current = a;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
$$ = true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
| '[' SCAN_WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (!id) id = new string($2);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
'=' SCAN_WORD
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (!check_int32($5)) {
|
|
Packit |
a4aae4 |
string msg = "In the dataset descriptor object:\n";
|
|
Packit |
a4aae4 |
msg += "Expected an array subscript.\n";
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, msg.c_str(), dds_line_num, $5);
|
|
Packit |
a4aae4 |
error_exit_cleanup();
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
if (current->type() == dods_array_c) {
|
|
Packit |
a4aae4 |
((Array *)current)->append_dim(atoi($5), *id);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
Array *a = DDS_OBJ(arg)->get_factory()->NewArray();
|
|
Packit |
a4aae4 |
a->add_var(current);
|
|
Packit |
a4aae4 |
a->append_dim(atoi($5), *id);
|
|
Packit |
a4aae4 |
if( current ) delete current ;
|
|
Packit |
a4aae4 |
current = a;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
delete id; id = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
']'
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
$$ = true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
| error
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ostringstream msg;
|
|
Packit |
a4aae4 |
msg << "In the dataset descriptor object:" << endl
|
|
Packit |
a4aae4 |
<< "Expected an array subscript." << endl;
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, msg.str().c_str(), dds_line_num, $<word>1);
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
name: var_name { (*DDS_OBJ(arg)).set_dataset_name($1); $$ = true;}
|
|
Packit |
a4aae4 |
| SCAN_DATASET { (*DDS_OBJ(arg)).set_dataset_name($1); $$ = true; }
|
|
Packit |
a4aae4 |
| error
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ostringstream msg;
|
|
Packit |
a4aae4 |
msg << "Error parsing the dataset name." << endl
|
|
Packit |
a4aae4 |
<< "The name may be missing or may contain an illegal character." << endl;
|
|
Packit |
a4aae4 |
parse_error((parser_arg *)arg, msg.str().c_str(), dds_line_num, $<word>1);
|
|
Packit |
a4aae4 |
YYABORT;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
%%
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/*
|
|
Packit |
a4aae4 |
This function must be defined. However, use the error reporting code in
|
|
Packit |
a4aae4 |
parser-utils.cc.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
ddserror(parser_arg *, const string &)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/*
|
|
Packit |
a4aae4 |
Error clean up. Call this before calling YYBORT. Don't call this on a
|
|
Packit |
a4aae4 |
normal exit.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void error_exit_cleanup()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
delete id;
|
|
Packit |
a4aae4 |
id = 0;
|
|
Packit |
a4aae4 |
delete current;
|
|
Packit |
a4aae4 |
current = 0;
|
|
Packit |
a4aae4 |
delete ctor;
|
|
Packit |
a4aae4 |
ctor = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/*
|
|
Packit |
a4aae4 |
Invalid declaration message.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void invalid_declaration(parser_arg *arg, string semantic_err_msg, char *type, char *name)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ostringstream msg;
|
|
Packit |
a4aae4 |
msg << "In the dataset descriptor object: `" << type << " " << name << "'" << endl << "is not a valid declaration."
|
|
Packit |
a4aae4 |
<< endl << semantic_err_msg;
|
|
Packit |
a4aae4 |
parse_error((parser_arg *) arg, msg.str().c_str(), dds_line_num);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/*
|
|
Packit |
a4aae4 |
Add the variable pointed to by CURRENT to either the topmost ctor object on
|
|
Packit |
a4aae4 |
the stack CTOR or to the dataset variable table TABLE if CTOR is empty. If
|
|
Packit |
a4aae4 |
it exists, the current ctor object is popped off the stack and assigned to
|
|
Packit |
a4aae4 |
CURRENT.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
NB: the ctor stack is popped for arrays because they are ctors which
|
|
Packit |
a4aae4 |
contain only a single variable. For other ctor types, several variables may
|
|
Packit |
a4aae4 |
be members and the parse rule (see `declaration' above) determines when to
|
|
Packit |
a4aae4 |
pop the stack.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Returns: void
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void add_entry(DDS &table, stack<BaseType *> **ctor, BaseType **current, Part part)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (!*ctor)
|
|
Packit |
a4aae4 |
*ctor = new stack<BaseType *> ;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!(*ctor)->empty()) { /* must be parsing a ctor type */
|
|
Packit |
a4aae4 |
(*ctor)->top()->add_var(*current, part);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
const Type &ctor_type = (*ctor)->top()->type();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (ctor_type == dods_array_c) {
|
|
Packit |
a4aae4 |
if (*current)
|
|
Packit |
a4aae4 |
delete *current;
|
|
Packit |
a4aae4 |
*current = (*ctor)->top();
|
|
Packit |
a4aae4 |
(*ctor)->pop();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Return here to avoid deleting the new value of 'current.'
|
|
Packit |
a4aae4 |
return;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
table.add_var(*current);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (*current)
|
|
Packit |
a4aae4 |
delete *current;
|
|
Packit |
a4aae4 |
*current = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|