2015-02-26 15:02:31 +00:00
|
|
|
%name-prefix="ADEF_"
|
|
|
|
%pure-parser
|
|
|
|
%locations
|
|
|
|
%parse-param {Trick::ADefParseContext* context}
|
|
|
|
%lex-param { void* scanner }
|
|
|
|
%{
|
|
|
|
|
|
|
|
/*
|
|
|
|
%debug
|
|
|
|
%error-verbose
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2015-06-01 15:28:29 +00:00
|
|
|
#include "trick/vval.h"
|
|
|
|
#include "trick/value.h"
|
|
|
|
#include "trick/var.h"
|
|
|
|
#include "trick/ADefParseContext.hh"
|
2015-02-26 15:02:31 +00:00
|
|
|
#include "adef_parser.tab.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
int ADEF_lex( YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner );
|
|
|
|
|
|
|
|
void ADEF_error( YYLTYPE* locp, Trick::ADefParseContext* context, const char* err) {
|
2015-03-25 17:05:25 +00:00
|
|
|
std::stringstream message;
|
|
|
|
message << "adef_parser PARSE-ERROR " << locp->first_line << ": " << err << ".";
|
|
|
|
Trick::MemoryManager::emitError(message.str());
|
2015-02-26 15:02:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define scanner context->scanner
|
|
|
|
#ifdef YYDEBUG
|
|
|
|
#undef YYDEBUG
|
|
|
|
#endif
|
|
|
|
#define YYDEBUG 1
|
|
|
|
%}
|
|
|
|
|
|
|
|
%start alloc_definition
|
|
|
|
|
|
|
|
%union {
|
|
|
|
char* sval ;
|
|
|
|
int ival ;
|
|
|
|
VALUE_LIST* value_list ;
|
|
|
|
}
|
|
|
|
|
|
|
|
%token <sval> NAME
|
|
|
|
%token <ival> TYPE
|
|
|
|
%token <ival> I_CON
|
|
|
|
|
|
|
|
%token END 0 "End of file"
|
|
|
|
|
|
|
|
%type <value_list> dim_list
|
|
|
|
%type <ival> pointers
|
|
|
|
%type <sval> opt_name user_defined_type
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
alloc_definition: TYPE pointers opt_name dim_list {
|
|
|
|
|
|
|
|
context->type = (TRICK_TYPE)$1;
|
|
|
|
context->user_type_name = "";
|
|
|
|
context->n_stars = $2;
|
|
|
|
if ($3 == NULL) {
|
|
|
|
context->var_name = "";
|
|
|
|
} else {
|
|
|
|
context->var_name = $3;
|
|
|
|
free($3) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
| user_defined_type pointers opt_name dim_list {
|
|
|
|
|
|
|
|
// TRICK_OPAQUE_TYPE means that the type is a user-defined type,
|
|
|
|
// the details of which will be determined later.
|
|
|
|
context->type = TRICK_OPAQUE_TYPE;
|
|
|
|
context->user_type_name = $1;
|
|
|
|
free($1) ;
|
|
|
|
context->n_stars = $2;
|
|
|
|
if ($3 == NULL) {
|
|
|
|
context->var_name = "";
|
|
|
|
} else {
|
|
|
|
context->var_name = $3;
|
|
|
|
free($3) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
opt_name: { $$ = NULL; }
|
|
|
|
| NAME { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
pointers: {
|
|
|
|
/*
|
|
|
|
* pointers counts how many pointer dims there are in a variable declaration
|
|
|
|
* the first rule handles no pointers, the next handles 1 or more pointers
|
|
|
|
*/
|
|
|
|
$$ = 0 ;
|
|
|
|
}
|
|
|
|
| pointers '*' {
|
|
|
|
$$++ ;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
user_defined_type: NAME {
|
|
|
|
$$ = $1;
|
|
|
|
}
|
|
|
|
| user_defined_type ':' ':' NAME {
|
|
|
|
size_t len;
|
|
|
|
len = strlen($1) + strlen($4) + (size_t)3;
|
|
|
|
$$ = (char*)malloc( (size_t)len);
|
|
|
|
strcpy($$, $1);
|
|
|
|
strcat($$, "::");
|
|
|
|
strcat($$, $4);
|
|
|
|
free($1);
|
|
|
|
free($4);
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
dim_list: {
|
|
|
|
/*
|
|
|
|
* These two rules handle C style array indexing. This rule
|
|
|
|
* handles no indexes, the second rule handles one or more other
|
|
|
|
* indexes.
|
|
|
|
*/
|
|
|
|
int ii ;
|
|
|
|
context->n_cdims = 0;
|
|
|
|
for ( ii = 0 ; ii < TRICK_MAX_INDEX ; ii++ ) {
|
|
|
|
context->cdims[ii] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
| dim_list '[' I_CON ']' {
|
|
|
|
if (context->n_cdims >= TRICK_MAX_INDEX ) {
|
|
|
|
context->error_str = "Too many array dimensions." ;
|
|
|
|
return(MM_TOO_MANY_ARRAY_DIMENSIONS) ;
|
|
|
|
}
|
|
|
|
context->cdims[ context->n_cdims ] = $3 ;
|
|
|
|
context->n_cdims++;
|
|
|
|
};
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
|