trick/trick_source/sim_services/MemoryManager/adef_parser.y

134 lines
3.3 KiB
Plaintext
Raw Normal View History

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>
#include <string.h>
2015-02-26 15:02:31 +00:00
#include "trick/vval.h"
#include "trick/value.h"
#include "trick/var.h"
#include "trick/ADefParseContext.hh"
#include "adef_parser.tab.hpp"
2015-02-26 15:02:31 +00:00
#pragma GCC diagnostic ignored "-Wunused-parameter"
2015-02-26 15:02:31 +00:00
using namespace std;
int ADEF_lex( YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner );
2015-02-26 15:02:31 +00:00
void ADEF_error( YYLTYPE* locp, Trick::ADefParseContext* context, const char* err) {
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_type_name
2015-02-26 15:02:31 +00:00
%%
alloc_definition: TYPE pointers opt_name dim_list {
context->type = (TRICK_TYPE)$1;
2015-02-26 15:02:31 +00:00
context->user_type_name = "";
context->n_stars = $2;
if ($3 == NULL) {
context->var_name = "";
} else {
context->var_name = $3;
free($3) ;
}
}
| user_type_name pointers opt_name dim_list {
2015-02-26 15:02:31 +00:00
// 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_type_name: NAME {
$$ = $1;
};
2015-02-26 15:02:31 +00:00
dim_list: {
/*
* These two rules handle C style array indexing. This rule
* handles no indexes, the second rule handles one or more other
* indexes.
2015-02-26 15:02:31 +00:00
*/
int ii ;
context->n_cdims = 0;
for ( ii = 0 ; ii < TRICK_MAX_INDEX ; ii++ ) {
context->cdims[ii] = 0;
}
2015-02-26 15:02:31 +00:00
}
| 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++;
};
%%