home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.parl.clemson.edu
/
2015-02-07.ftp.parl.clemson.edu.tar
/
ftp.parl.clemson.edu
/
pub
/
coven
/
coven-utils-1.1.tgz
/
coven-utils-1.1.tar
/
utils
/
coven-language
/
Coven_parser.y
< prev
next >
Wrap
Text File
|
2003-01-28
|
12KB
|
530 lines
/*
* (C) 2001 Clemson University
*
* See COPYING in top-level directory.
*/
%{
#include <Coven_lang.h>
#include <symbol.h>
#include <stringtbl.h>
sym_ent_p cur_mod_sym = NULL;
int mod_arg_pos = 0;
int num_mods = 0;
int num_consts = 0;
int num_master_threads = 0;
int num_slave_threads = 0;
int for_start_loop = 0;
int for_start[128];
int cur_mod_number = -1;
int loop_num = 0;
int depth_loop_num = 0;
int master_section = 1;
int master_thread = 0;
int slave_thread = 0;
mod_call *cur_mod_call = NULL;
mod_call *first_mod_call = NULL;
%}
%union{
int i;
double f;
char *c;
sym_ent *s;
argument_ent *a;
}
%token <i> MODULES
%token <i> CONSTANTS
%token <i> VARIABLES
%token <i> PROGRAM
%token <i> MODULE
%token <c> IDENTIFIER
%token <i> INPUT
%token <i> OUTPUT
%token <i> INOUT
%token <i> STATIC
%token <i> CONST
%token <i> BUFFER
%token <i> PARAMETER
%token <i> LBRACE
%token <i> RBRACE
%token <i> COMMA
%token <i> SEMICOLON
%token <i> THREAD
%token <i> PARALLEL
%token <c> STRING
%token <i> INTEGER
%token <f> FLOAT
%token <i> EQUALS
%token <i> IF
%token <i> LPAREN
%token <i> RPAREN
%token <i> ELSEIF
%token <i> ELSE
%token <i> WHILE
%token <i> FOR
%token <i> LT
%token <i> LEQ
%token <i> GT
%token <i> GEQ
%token <i> EQEQ
%token <i> NEQ
%token <i> PLUSPLUS
%token <i> MINUSMINUS
%token <i> PLUSEQ
%token <i> MINUSEQ
%type <i> coven_program, module_section, direction, mclass, .vclass., cmp_operator, for_last_seg
%type <f>
%type <c> mod_path, identifier, cvalue
%type <s> mod_decl, type, .list_of_mod_args., const_decl, var_decl
%type <a> mod_arg
%start coven_program
%%
identifier : IDENTIFIER
{
$$ = enter_string($1);
}
;
coven_program : {output_begin();}
module_section constants_section variables_section
program_section
;
/* --------------------------------------------------------------------------*/
/* BEGIN: MODULES section */
/* --------------------------------------------------------------------------*/
module_section : MODULES
{num_mods = 0; output_begin_mod_decls();}
LBRACE .list_of_mod_decls. RBRACE
{output_end_mod_decls(num_mods);}
;
.list_of_mod_decls. : /* empty */
| mod_decl .list_of_mod_decls.
;
mod_decl : MODULE identifier
{
$$ = symenter($2, NULL, TYPE_MODULE);
}
LBRACE mod_path .list_of_mod_args. RBRACE
{
$3->value.mod->path = $5;
$3->value.mod->args = $6;
$3->value.mod->times_called = 0;
output_mod_decl($3);
num_mods++;
}
;
mod_path : STRING
{$$ = enter_string($1); }
;
.list_of_mod_args. : /* empty */
{$$ = NULL;}
| COMMA mod_arg .list_of_mod_args.
{
/* $2 is the argument_ent returned by mod_arg */
$$ = symenter($2->name, $3, TYPE_ARGUMENT);
$$->value.arg = $2;
$$->next = $3;
}
;
mod_arg : direction mclass type identifier
{
$$ = (argument_ent_p)emalloc(sizeof(argument_ent));
$$->name = $4;
$$->direction = $1;
$$->mclass = $2;
$$->type = $3;
}
;
direction : INPUT
| OUTPUT
| INOUT
| STATIC
| CONST
;
mclass : BUFFER
| PARAMETER
;
type : identifier
{
sym_ent_p type_sym = lookup_type($1);
if(type_sym == NULL) {
yyerror("Unknown type");
exit(1);
}
$$ = lookup_type($1);
}
;
/* --------------------------------------------------------------------------*/
/* END: MODULES section */
/* --------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------*/
/* BEGIN: CONSTANTS section */
/* --------------------------------------------------------------------------*/
constants_section : CONSTANTS LBRACE
{
num_consts = 0;
output_begin_const_decls();
}
.list_of_const_decls. RBRACE
{
output_end_const_decls(num_consts);
}
;
.list_of_const_decls. : /* empty */
| const_decl .list_of_const_decls.
;
const_decl : type identifier EQUALS cvalue SEMICOLON
{
$$ = symenter($2, NULL, TYPE_CONST);
$$->value.con->type = $1;
$$->value.con->cvalue = $4;
output_const_decl($$);
num_consts ++;
}
;
cvalue : STRING
{
char *p;
p = (char*)emalloc(strlen($1)+1);
/* this is so that we strip the quotes from
* around it before we put it into the struct */
snprintf(p, strlen($1)-1, "%s", &($1[1]));
$$ = p;
}
| INTEGER
{
char *p;
p = (char*)emalloc(32);
snprintf(p, 32, "%d", $1);
$$ = p;
}
| FLOAT
{
char *p;
p = (char*)emalloc(32);
snprintf(p, 32, "%f", $1);
$$ = p;
}
;
/* --------------------------------------------------------------------------*/
/* END: CONSTANTS section */
/* --------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------*/
/* BEGIN: VARIABLES section */
/* --------------------------------------------------------------------------*/
variables_section : VARIABLES LBRACE .list_of_var_decls. RBRACE
;
.list_of_var_decls. : /* empty */
| var_decl .list_of_var_decls.
;
var_decl : .vclass. type identifier SEMICOLON
{
$$ = symenter($3, NULL, TYPE_VARIABLE);
$$->value.var->vclass = $1;
$$->value.var->type = $2;
}
;
.vclass. : { $$ = -1; } /* empty */
| BUFFER
;
/* --------------------------------------------------------------------------*/
/* END: VARIABLES section */
/* --------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------*/
/* BEGIN: PROGRAM section */
/* --------------------------------------------------------------------------*/
program_section : PROGRAM LBRACE list_of_pgm_decls RBRACE
{
output_all_mod_calls(first_mod_call);
output_program(master_thread,
slave_thread);
}
;
list_of_pgm_decls : pgm_decl
| list_of_pgm_decls pgm_decl
;
pgm_decl : sp_thread_decl
| parallel_decl
;
sp_thread_decl : thread_decl
| special_stmt
;
thread_decl : THREAD
{
/* we need to record which thread we're in here */
if(master_section) master_thread++;
else slave_thread++;
}
/* identifier */
LBRACE list_of_stmts RBRACE
;
/* require at least one thread section */
parallel_decl : PARALLEL
{
/* signify that we're no longer in a 'master proc'
* section of the program */
master_section = 0;
}
LBRACE list_of_threads RBRACE
{
/* and now we're back in one */
master_section = 1;
}
;
list_of_threads : sp_thread_decl
| list_of_threads sp_thread_decl
;
/* require at least one program module declaration */
list_of_stmts : stmt
| list_of_stmts stmt
;
special_stmt : if_stmt
| while_stmt
| for_stmt
;
stmt : mod_call
| special_stmt
| thread_decl
;
/* BEGIN: mod call */
mod_call : identifier
{
cur_mod_sym = symlook($1, NULL, TYPE_MODULE);
//sym_print(cur_mod_sym);
cur_mod_sym->value.mod->times_called ++;
output_start_mod_call(cur_mod_sym);
mod_arg_pos = 0;
}
LPAREN .list_ma_mod_args. RPAREN SEMICOLON
{
output_end_mod_call(cur_mod_sym);
cur_mod_number++;
/* we need to setup the head of the list */
if(cur_mod_call == NULL) {
cur_mod_call = (mod_call*)malloc(
sizeof(mod_call));
first_mod_call = cur_mod_call;
}
else {
mod_call *last_mod_call = cur_mod_call;
cur_mod_call = (mod_call*)malloc(
sizeof(mod_call));
last_mod_call->next = cur_mod_call;
}
/* record some information about this mod call */
cur_mod_call->name = cur_mod_sym->name;
cur_mod_call->proc = (char*)malloc(32);
if(master_section) {
strcpy(cur_mod_call->proc, "MASTER");
cur_mod_call->thread = master_thread;
}
else {
strcpy(cur_mod_call->proc, "SLAVE");
cur_mod_call->thread = slave_thread;
}
cur_mod_call->btable = (char*)malloc(128);
sprintf(cur_mod_call->btable, "&_%s_%d",
cur_mod_sym->name,
cur_mod_sym->value.mod->times_called);
cur_mod_call->loop = (char*)malloc(128);
if(for_start_loop == 1) {
for_start[loop_num] = cur_mod_number;
//printf("first mod call in a for loop, # = %d\n",
// for_start[loop_num]);
for_start_loop = 0;
sprintf(cur_mod_call->loop, "&_coven_loop_%d",
loop_num);
}
else {
/* if this is the end of a loop, then we'll
* overwrite this string later */
strcpy(cur_mod_call->loop, "NULL");
}
}
;
pgm_mod_arg : identifier
{
//printf("MOD ARG: %s\n", $1);
output_mod_binding(cur_mod_sym, mod_arg_pos, $1);
mod_arg_pos++;
}
;
/* ndebard:
we're gonna cut these other options out so that we can simplify
the compiler at this time */
/*
| STRING {printf("MOD ARG: string!\n");}
| INTEGER
| FLOAT
| inline_assignment
;
*/
.list_ma_mod_args. : /* empty */
| list_ma_mod_args
;
list_ma_mod_args : pgm_mod_arg
| list_ma_mod_args COMMA pgm_mod_arg
;
/*inline_assignment : identifier EQUALS identifier
;*/
/* END: mod call */
/* BEGIN: if statement */
if_stmt : IF LPAREN condition RPAREN LBRACE list_of_stmts RBRACE .else_if_list. .else_stmt.
;
/* we only allow if(variable) which implies if(variable != 0) */
condition : identifier
;
/* elses: they can be empty, because we may not HAVE elses */
.else_if_list. : /* emtpy */
| else_if_list
;
else_if_list : else_if_stmt
| else_if_list else_if_stmt
;
else_if_stmt : ELSEIF LPAREN condition RPAREN LBRACE list_of_stmts RBRACE
;
.else_stmt. : /* empty */
| ELSE LPAREN condition RPAREN LBRACE list_of_stmts RBRACE
;
/* END: if statement */
/* BEGIN: while statement */
while_stmt : WHILE LPAREN condition RPAREN LBRACE list_of_stmts RBRACE
;
/* END: while statement */
/* BEGIN: for statement */
for_stmt : FOR LPAREN identifier EQUALS INTEGER SEMICOLON
identifier cmp_operator identifier SEMICOLON
identifier for_last_seg RPAREN LBRACE
{ /* before for loop internals */
for_start_loop = 1;
loop_num++;
depth_loop_num++;
//printf("Starting for loop: loop# = %d, DLN = %d\n",
// loop_num, depth_loop_num);
}
list_of_stmts RBRACE
{ /* after for loop internals */
int start_val, inc_val, for_end;
char coven_cmp_str[64];
start_val = $5;
inc_val = $12;
sprintf(cur_mod_call->loop, "&_coven_loop_%d",
depth_loop_num);
//printf("For loop done, cur mod = %d\n",
// cur_mod_number);
for_end = cur_mod_number;
switch($8) {
case LT:
strcpy(coven_cmp_str, "COVEN_LT");
break;
case LEQ:
strcpy(coven_cmp_str, "COVEN_LEQ");
break;
case GT:
strcpy(coven_cmp_str, "COVEN_GT");
break;
case GEQ:
strcpy(coven_cmp_str, "COVEN_GEQ");
break;
case EQEQ:
strcpy(coven_cmp_str, "COVEN_EQ");
break;
case NEQ:
strcpy(coven_cmp_str, "COVEN_NEQ");
break;
}
output_loop(depth_loop_num, $3,
start_val, coven_cmp_str,
$9, inc_val, for_start[depth_loop_num], for_end);
for_start_loop = 0;
depth_loop_num--;
}
;
cmp_operator : LT
| LEQ
| GT
| GEQ
| EQEQ
| NEQ
;
for_last_seg : PLUSPLUS {$$ = 0;}
| MINUSMINUS {$$ = 0;}
| PLUSEQ INTEGER {$$ = $2;}
| MINUSEQ INTEGER {$$ = $2;}
;
/* END: for statement */
/* --------------------------------------------------------------------------*/
/* END: PROGRAM section */
/* --------------------------------------------------------------------------*/
%%
yywrap()
{
return 1;
}