Files
SAPFOR/dvm/fdvm/trunk/parser/ftn.gram

4591 lines
137 KiB
Plaintext
Raw Normal View History

2023-09-14 19:43:13 +03:00
%{
#include <string.h>
#include "inc.h"
#include "extern.h"
#include "defines.h"
#include "fdvm.h"
#include "fm.h"
/* We may use builtin alloca */
#include "compatible.h"
#ifdef _NEEDALLOCAH_
# include <alloca.h>
#endif
#define EXTEND_NODE 2 /* move the definition to h/ files. */
extern PTR_BFND global_bfnd, pred_bfnd;
extern PTR_SYMB star_symb;
extern PTR_SYMB global_list;
extern PTR_TYPE global_bool;
extern PTR_TYPE global_int;
extern PTR_TYPE global_float;
extern PTR_TYPE global_double;
extern PTR_TYPE global_char;
extern PTR_TYPE global_string;
extern PTR_TYPE global_string_2;
extern PTR_TYPE global_complex;
extern PTR_TYPE global_dcomplex;
extern PTR_TYPE global_gate;
extern PTR_TYPE global_event;
extern PTR_TYPE global_sequence;
extern PTR_TYPE global_default;
extern PTR_LABEL thislabel;
extern PTR_CMNT comments, cur_comment;
extern PTR_BFND last_bfnd;
extern PTR_TYPE impltype[];
extern int nioctl;
extern int maxdim;
extern long yystno; /* statement label */
extern char stmtbuf[]; /* input buffer */
extern char *commentbuf; /* comments buffer from scanner */
extern PTR_BLOB head_blob;
extern PTR_BLOB cur_blob;
extern PTR_TYPE vartype; /* variable type */
extern int end_group;
extern char saveall;
extern int privateall;
extern int needkwd;
extern int implkwd;
extern int opt_kwd_hedr;
/* added for FORTRAN 90 */
extern PTR_LLND first_unresolved_call;
extern PTR_LLND last_unresolved_call;
extern int data_stat;
extern char yyquote;
extern int warn_all;
extern int statement_kind; /* kind of statement: 1 - HPF-DVM-directive, 0 - Fortran statement*/
int extend_flag = 0;
static int do_name_err;
static int ndim; /* number of dimension */
/*!!! hpf */
static int explicit_shape; /* 1 if shape specification is explicit */
/* static int varleng;*/ /* variable size */
static int lastwasbranch = NO; /* set if last stmt was a branch stmt */
static int thiswasbranch = NO; /* set if this stmt is a branch stmt */
static PTR_SYMB type_var = SMNULL;
static PTR_LLND stat_alloc = LLNULL; /* set if ALLOCATE/DEALLOCATE stmt has STAT-clause*/
/* static int subscripts_status = 0; */
static int type_options,type_opt; /* The various options used to declare a name -
RECURSIVE, POINTER, OPTIONAL etc. */
static PTR_BFND module_scope;
static int position = IN_OUTSIDE;
static int attr_ndim; /* number of dimensions in DIMENSION (array_spec)
attribute declaration */
static PTR_LLND attr_dims; /* low level representation of array_spec in
DIMENSION (array_spec) attribute declarartion. */
static int in_vec = NO; /* set if processing array constructor */
%}
%union {
int token;
char charv;
char *charp;
PTR_BFND bf_node;
PTR_LLND ll_node;
PTR_SYMB symbol;
PTR_TYPE data_type;
PTR_HASH hash_entry;
PTR_LABEL label;
}
/*
* gram.head
*
* First part of the Fortran grammar
*
*/
/* Specify precedences and associativities. */
%left COMMA
%nonassoc COLON
%right EQUAL
%left DEFINED_OPERATOR
%left BINARY_OP
%left EQV NEQV
%left OR XOR
%left AND
%left NOT
%nonassoc LT GT LE GE EQ NE
%left DSLASH
%left PLUS MINUS
%left ASTER SLASH
%right DASTER
%nonassoc UNARY_OP
%start program
%type <token> addop stop att_type
%type <charv> letter
%type <charp> filename
%type <hash_entry> name opt_unit_name
%type <symbol> progname blokname args arg arglist call comblock namelist_group
%type <bf_node> program stat spec exec iffable goto logif
%type <bf_node> dcl implicit data common dimension external intrinsic attrib
%type <bf_node> equivalence namelist type_dcl end_type static
%type <bf_node> intent optional public private sequence allocatable pointer target
%type <ll_node> implist impitem
%type <ll_node> paramlist paramitem
%type <ll_node> dim dims dimlist ubound funarglist funarg funargs opt_expr var
%type <ll_node> labellist expr uexpr lhs simple_const lengspec substring
%type <ll_node> complex_const vec triplet
%type <ll_node> dospec use_name_list
%type <symbol> do_var
%type <label> dotarget
%type <symbol> funcname typedfunc procname
%type <ll_node> equivset equivlist
%type <ll_node> savelist saveitem
/* FORTRAN 90 */
%type <hash_entry> defined_op intrinsic_op operator construct_name
%type <bf_node> case whereable interface use_stat forall
%type <ll_node> forall_list forall_expr opt_forall_cond
%type <bf_node> module_proc_stmt do_while plain_do
%type <ll_node> opt_result_clause case_selector case_value_range
%type <ll_node> case_value_range_list proper_lengspec
%type <symbol> opt_construct_name
%type <symbol> module_name
%type <ll_node> selector initial_value clause opt_while
%type <ll_node> options attr_spec_list attr_spec intent_spec access_spec
%type <ll_node> string_constant structure_component opt_substring
%type <ll_node> array_ele_substring_func_ref ident array_element
%type <ll_node> subscript_list asubstring equi_object
%type <ll_node> allocation_list allocate_object_list
%type <ll_node> allocate_object pointer_name_list rename_list rename_name use_name
%type <ll_node> only_list only_name proc_name_list construct_name_colon
%type <ll_node> kind numeric_bool_const integer_constant proc_attr
/*
* used by I/O statement
*/
%type <bf_node> io read write print iofmove iofctl fmkwd ctlkwd inquire
%type <ll_node> fexpr unpar_fexpr
%type <ll_node> ioctl ctllist ioclause nameeq inlist inelt
%type <ll_node> outlist out2 other infmt
%type <ll_node> label letgroups letgroup let
%type <ll_node> callarglist callarg
%type <data_type> typename typespec type type_implicit
%type <label> thislabel
%type <ll_node> dataimplieddo dlist dataelt datasubs datarange
%type <ll_node> iconexprlist opticonexpr iconexpr iconterm
%type <ll_node> iconfactor iconprimary
%type <symbol> dataname d_name
/*
*
* used by HPF and FDVM
*/
%type <bf_node> dvm_specification dvm_combined_dir dvm_pointer dvm_heap
%type <bf_node> dvm_template dvm_processors dvm_indirect_group dvm_remote_group
%type <bf_node> dvm_task dvm_inherit dvm_new_value
%type <bf_node> dvm_dynamic dvm_align dvm_realign align_directive_stuff
%type <bf_node> dvm_distribute dvm_redistribute dvm_exec
%type <bf_node> dvm_parallel_on dvm_remote_access
%type <bf_node> dvm_shadow_group dvm_shadow_start dvm_shadow_wait dvm_shadow
%type <bf_node> dvm_reduction_group dvm_reduction_start dvm_reduction_wait
%type <bf_node> dvm_task_region dvm_end_task_region dvm_map dvm_on dvm_end_on
%type <bf_node> dvm_reset dvm_prefetch dvm_indirect_access hpf_independent
%type <bf_node> dvm_debug_dir dvm_enddebug_dir dvm_traceon_dir dvm_traceoff_dir
%type <bf_node> dvm_interval_dir dvm_endinterval_dir dvm_exit_interval_dir dvm_barrier_dir dvm_check
%type <bf_node> dvm_io_mode_dir dvm_shadow_add dvm_localize
%type <bf_node> dvm_cp_create dvm_cp_load dvm_cp_save dvm_cp_wait dvm_template_create dvm_template_delete
%type <bf_node> dvm_asyncid dvm_f90 dvm_asynchronous dvm_endasynchronous dvm_asyncwait
%type <bf_node> dvm_consistent_group dvm_consistent_start dvm_consistent_wait dvm_consistent
%type <ll_node> dist_name dist_name_list dist_format dist_format_list
%type <ll_node> distributee pointer_ar_elem
%type <ll_node> dist_format_clause opt_dist_format_clause shadow_width
%type <ll_node> opt_spec dvm_attribute_list dvm_attribute
%type <ll_node> new_spec reduction_spec shadow_spec remote_access_spec
%type <ll_node> spec_list par_spec indirect_access_spec across_spec stage_spec
%type <ll_node> in_out_across opt_in_out
%type <ll_node> dependent_array_list dependent_array dependence dependence_list
%type <ll_node> variable_list reduction_list shadow_list distribute_cycles
%type <ll_node> reduction reduction_op loc_op array_ident array_ident_list shadow
%type <ll_node> dyn_array_name_list dyn_array_name
%type <ll_node> heap_array_name_list heap_array_name
%type <ll_node> align_base align_subscript_list par_subscript_list par_subscript
%type <ll_node> remote_data_list remote_data remote_index_list remote_index
%type <ll_node> dim_ident_list dim_ident align_subscript
%type <ll_node> realignee_list alignee realignee
%type <ll_node> dummy_array_name_list dummy_array_name
%type <ll_node> ident_list sh_array_name
%type <ll_node> shadow_attr_stuff sh_width sh_width_list
%type <ll_node> pointer_var pointer_var_list dimension_list
%type <ll_node> interval_number fragment_number
%type <ll_node> task task_array opt_private_spec async
%type <ll_node> indirect_list indirect_reference opt_onto opt_on hpf_reduction_spec
%type <ll_node> debparamlist debparam async_id_list async_id high_section
%type <ll_node> section_spec_list section_spec section ar_section low_section
%type <ll_node> consistent_spec consistent_array_name_list consistent_array_name
%type <ll_node> mode_list mode_spec opt_mode
%type <ll_node> derived_spec derived_elem derived_elem_list target_spec
%type <ll_node> derived_subscript derived_subscript_list opt_plus_shadow plus_shadow shadow_id
%type <ll_node> template_ref template_obj shadow_axis shadow_axis_list opt_include_to
%type <ll_node> localize_target target_subscript target_subscript_list aster_expr dummy_ident
%type <ll_node> template_list tie_spec tied_array_list
%type <symbol> processors_name align_base_name
%type <symbol> shadow_group_name reduction_group_name reduction_group indirect_group_name task_name
%type <symbol> remote_group_name group_name array_name async_ident consistent_group_name consistent_group
%type <symbol> derived_target
/* FORTRAN OPENMPDVM*/
%type <bf_node> omp_specification_directive omp_threadprivate_directive
%type <bf_node> omp_execution_directive omp_section_directive
%type <bf_node> omp_parallel_begin_directive omp_parallel_end_directive
%type <bf_node> omp_sections_begin_directive omp_sections_end_directive
%type <bf_node> omp_do_begin_directive omp_do_end_directive
%type <bf_node> omp_single_begin_directive omp_single_end_directive
%type <bf_node> omp_workshare_begin_directive omp_workshare_end_directive
%type <bf_node> omp_parallel_do_begin_directive omp_parallel_do_end_directive
%type <bf_node> omp_parallel_sections_begin_directive omp_parallel_sections_end_directive
%type <bf_node> omp_parallel_workshare_begin_directive omp_parallel_workshare_end_directive
%type <bf_node> omp_master_begin_directive omp_master_end_directive
%type <bf_node> omp_ordered_begin_directive omp_ordered_end_directive
%type <bf_node> omp_barrier_directive omp_atomic_directive omp_flush_directive
%type <bf_node> omp_critical_begin_directive omp_critical_end_directive ompdvm_onethread
%type <ll_node> parallel_clause_list parallel_clause
%type <ll_node> ompprivate_clause ompfirstprivate_clause
%type <ll_node> omplastprivate_clause ompcopyin_clause
%type <ll_node> ompshared_clause ompdefault_clause
%type <ll_node> def_expr ompif_clause ompnumthreads_clause
%type <ll_node> ompreduction_clause ompreduction ompreduction_vars
%type <ll_node> ompreduction_op
%type <ll_node> sections_clause_list sections_clause
%type <ll_node> do_clause_list do_clause omp_variable_list
%type <ll_node> omp_common_var omp_variable_list_in_par
%type <ll_node> ompordered_clause ompschedule_clause ompschedule_op
%type <ll_node> single_clause_list single_clause
%type <ll_node> end_single_clause_list end_single_clause
%type <ll_node> ompcopyprivate_clause ompnowait_clause
%type <ll_node> paralleldo_clause_list paralleldo_clause
/* FORTRAN ACC */
%type <bf_node> acc_directive acc_region acc_end_region acc_checksection acc_end_checksection
%type <bf_node> acc_get_actual acc_actual acc_routine
%type <ll_node> opt_clause acc_clause_list acc_clause data_clause async_clause targets_clause
%type <ll_node> acc_var_list computer_list computer opt_targets_clause
/* new clauses for PARALLEL directive */
%type <ll_node> private_spec cuda_block_spec sizelist
/* SAPFOR */
%type <bf_node> spf_directive spf_analysis spf_parallel spf_transform spf_parallel_reg spf_end_parallel_reg
%type <bf_node> spf_checkpoint
%type <ll_node> analysis_spec_list analysis_spec analysis_reduction_spec analysis_private_spec analysis_parameter_spec
%type <ll_node> parallel_spec_list parallel_spec parallel_shadow_spec parallel_across_spec parallel_remote_access_spec
%type <ll_node> transform_spec_list transform_spec array_element_list spf_parameter_list spf_parameter
%type <ll_node> characteristic characteristic_list opt_clause_apply_region opt_clause_apply_fragment
%type <ll_node> checkpoint_spec checkpoint_spec_list spf_type_list spf_type interval_spec unroll_list
%type <symbol> region_name
%{
void add_scope_level();
void delete_beyond_scope_level();
PTR_HASH look_up_sym();
PTR_HASH just_look_up_sym();
PTR_HASH just_look_up_sym_in_scope();
PTR_HASH look_up_op();
PTR_SYMB make_constant();
PTR_SYMB make_scalar();
PTR_SYMB make_array();
PTR_SYMB make_pointer();
PTR_SYMB make_function();
PTR_SYMB make_external();
PTR_SYMB make_intrinsic();
PTR_SYMB make_procedure();
PTR_SYMB make_process();
PTR_SYMB make_program();
PTR_SYMB make_module();
PTR_SYMB make_common();
PTR_SYMB make_parallel_region();
PTR_SYMB make_derived_type();
PTR_SYMB make_local_entity();
PTR_SYMB make_global_entity();
PTR_TYPE make_type_node();
PTR_TYPE lookup_type(), make_type();
void process_type();
void process_interface();
void bind();
void late_bind_if_needed();
PTR_SYMB component();
PTR_SYMB lookup_type_symbol();
PTR_SYMB resolve_overloading();
PTR_BFND cur_scope();
PTR_BFND subroutine_call();
PTR_BFND process_call();
PTR_LLND deal_with_options();
PTR_LLND intrinsic_op_node();
PTR_LLND defined_op_node();
int is_substring_ref();
int is_array_section_ref();
PTR_LLND dim_expr();
PTR_BFND exit_stat();
PTR_BFND make_do();
PTR_BFND make_pardo();
PTR_BFND make_enddoall();
PTR_TYPE install_array();
PTR_SYMB install_entry();
void install_param_list();
PTR_LLND construct_entry_list();
void copy_sym_data();
PTR_LLND check_and_install();
PTR_HASH look_up();
PTR_BFND get_bfnd();
PTR_BLOB make_blob();
PTR_LABEL make_label();
PTR_LABEL make_label_node();
int is_interface_stat();
PTR_LLND make_llnd ();
PTR_LLND make_llnd_label ();
PTR_TYPE make_sa_type();
PTR_SYMB procedure_call();
PTR_BFND proc_list();
PTR_SYMB set_id_list();
PTR_LLND set_ll_list();
PTR_LLND add_to_lowLevelList(), add_to_lowList();
PTR_BFND set_stat_list() ;
PTR_BLOB follow_blob();
PTR_SYMB proc_decl_init();
PTR_CMNT make_comment();
PTR_HASH correct_symtab();
char *copyn();
char *convic();
char *StringConcatenation();
int atoi();
PTR_BFND make_logif();
PTR_BFND make_if();
PTR_BFND make_forall();
void startproc();
void match_parameters();
void make_else();
void make_elseif();
void make_endif();
void make_elsewhere();
void make_elsewhere_mask();
void make_endwhere();
void make_endforall();
void make_endselect();
void make_extend();
void make_endextend();
void make_section();
void make_section_extend();
void doinclude();
void endproc();
void err();
void execerr();
void flline();
void warn();
void warn1();
void newprog();
void set_type();
void dclerr();
void enddcl();
void install_const();
void setimpl();
void copy_module_scope();
void delete_symbol();
void replace_symbol_in_expr();
long convci();
void set_expr_type();
void errstr();
void yyerror();
void set_blobs();
void make_loop();
void startioctl();
void endioctl();
void redefine_func_arg_type();
int isResultVar();
2023-12-06 11:55:35 +03:00
int yylex();
2023-09-14 19:43:13 +03:00
/* used by FORTRAN M */
PTR_BFND make_processdo();
PTR_BFND make_processes();
PTR_BFND make_endprocesses();
PTR_BFND make_endparallel();/*OMP*/
PTR_BFND make_parallel();/*OMP*/
PTR_BFND make_endsingle();/*OMP*/
PTR_BFND make_single();/*OMP*/
PTR_BFND make_endmaster();/*OMP*/
PTR_BFND make_master();/*OMP*/
PTR_BFND make_endordered();/*OMP*/
PTR_BFND make_ordered();/*OMP*/
PTR_BFND make_endcritical();/*OMP*/
PTR_BFND make_critical();/*OMP*/
PTR_BFND make_endsections();/*OMP*/
PTR_BFND make_sections();/*OMP*/
PTR_BFND make_ompsection();/*OMP*/
PTR_BFND make_endparallelsections();/*OMP*/
PTR_BFND make_parallelsections();/*OMP*/
PTR_BFND make_endworkshare();/*OMP*/
PTR_BFND make_workshare();/*OMP*/
PTR_BFND make_endparallelworkshare();/*OMP*/
PTR_BFND make_parallelworkshare();/*OMP*/
%}
%%
program: { $$ = BFNULL; }
| program stat EOLN
{ $$ = set_stat_list($1,$2); }
;
stat: thislabel entry cmnt
{ lastwasbranch = NO; $$ = BFNULL; }
| thislabel spec cmnt
{
if ($2 != BFNULL)
{
$2->label = $1;
$$ = $2;
if (is_openmp_stmt) { /*OMP*/
is_openmp_stmt = 0;
if($2) { /*OMP*/
if ($2->decl_specs != -BIT_OPENMP) $2->decl_specs = BIT_OPENMP; /*OMP*/
} /*OMP*/
} /*OMP*/
}
}
| thislabel exec cmnt
{ PTR_BFND p;
if(lastwasbranch && ! thislabel)
/*if (warn_all)
warn("statement cannot be reached", 36);*/
lastwasbranch = thiswasbranch;
thiswasbranch = NO;
if($2) $2->label = $1;
if($1 && $2) $1->statbody = $2; /*8.11.06 podd*/
if($1) {
/*$1->statbody = $2;*/ /*8.11.06 podd*/
if($1->labtype == LABFORMAT)
err("label already that of a format",39);
else
$1->labtype = LABEXEC;
}
if (is_openmp_stmt) { /*OMP*/
is_openmp_stmt = 0;
if($2) { /*OMP*/
if ($2->decl_specs != -BIT_OPENMP) $2->decl_specs = BIT_OPENMP; /*OMP*/
} /*OMP*/
} /*OMP*/
for (p = pred_bfnd; $1 &&
((p->variant == FOR_NODE)||(p->variant == WHILE_NODE)) &&
(p->entry.for_node.doend) &&
(p->entry.for_node.doend->stateno == $1->stateno);
p = p->control_parent)
++end_group;
$$ = $2;
}
| thislabel INCLUDE filename
{ /* PTR_LLND p; */
doinclude( $3 );
/* p = make_llnd(fi, STRING_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = $3;
p->type = global_string;
$$ = get_bfnd(fi, INCLUDE_STAT, SMNULL, p, LLNULL); */
$$ = BFNULL;
}
| thislabel UNKNOWN
{
err("Unclassifiable statement", 10);
flline();
$$ = BFNULL;
};
| COMMENT
{ PTR_CMNT p;
PTR_BFND bif;
if (last_bfnd && last_bfnd->control_parent &&((last_bfnd->control_parent->variant == LOGIF_NODE)
||(last_bfnd->control_parent->variant == FORALL_STAT)))
bif = last_bfnd->control_parent;
else
bif = last_bfnd;
p=bif->entry.Template.cmnt_ptr;
if(p)
p->string = StringConcatenation(p->string,commentbuf);
else
{
p = make_comment(fi,commentbuf, FULL);
bif->entry.Template.cmnt_ptr = p;
}
$$ = BFNULL;
}
| error
{
flline(); needkwd = NO; inioctl = NO;
/*!!!*/
opt_kwd_ = NO; intonly = NO; opt_kwd_hedr = NO; opt_kwd_r = NO; as_op_kwd_= NO; optcorner = NO;
yyerrok; yyclearin; $$ = BFNULL;
}
;
thislabel: LABEL
{
if(yystno)
{
$$ = thislabel = make_label_node(fi,yystno);
thislabel->scope = cur_scope();
if (thislabel->labdefined && (thislabel->scope == cur_scope()))
errstr("Label %s already defined",convic(thislabel->stateno),40);
else
thislabel->labdefined = YES;
}
else
$$ = thislabel = LBNULL;
}
;
entry: PROGRAM new_prog progname
{ PTR_BFND p;
if (pred_bfnd != global_bfnd)
err("Misplaced PROGRAM statement", 33);
p = get_bfnd(fi,PROG_HEDR, $3, LLNULL, LLNULL, LLNULL);
$3->entry.prog_decl.prog_hedr=p;
set_blobs(p, global_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
position = IN_PROC;
}
| BLOCKDATA new_prog blokname
{ PTR_BFND q = BFNULL;
$3->variant = PROCEDURE_NAME;
$3->decl = YES; /* variable declaration has been seen. */
q = get_bfnd(fi,BLOCK_DATA, $3, LLNULL, LLNULL, LLNULL);
set_blobs(q, global_bfnd, NEW_GROUP1);
add_scope_level(q, NO);
}
| SUBROUTINE new_prog procname arglist
{
install_param_list($3, $4, LLNULL, PROCEDURE_NAME);
/* if there is only a control end the control parent is not set */
}
| proc_attr SUBROUTINE new_prog procname arglist
{ install_param_list($4, $5, LLNULL, PROCEDURE_NAME);
if($1->variant == RECURSIVE_OP)
$4->attr = $4->attr | RECURSIVE_BIT;
pred_bfnd->entry.Template.ll_ptr3 = $1;
}
| FUNCTION new_prog funcname arglist opt_result_clause
{
install_param_list($3, $4, $5, FUNCTION_NAME);
pred_bfnd->entry.Template.ll_ptr1 = $5;
}
| typedfunc arglist opt_result_clause
{
install_param_list($1, $2, $3, FUNCTION_NAME);
pred_bfnd->entry.Template.ll_ptr1 = $3;
}
| ENTRY name arglist opt_result_clause
{PTR_BFND p, bif;
PTR_SYMB q = SMNULL;
PTR_LLND l = LLNULL;
if(parstate==OUTSIDE || procclass==CLMAIN || procclass==CLBLOCK)
err("Misplaced ENTRY statement", 35);
bif = cur_scope();
if (bif->variant == FUNC_HEDR) {
q = make_function($2, bif->entry.Template.symbol->type, LOCAL);
l = construct_entry_list(q, $3, FUNCTION_NAME);
}
else if ((bif->variant == PROC_HEDR) ||
(bif->variant == PROS_HEDR) || /* added for FORTRAN M */
(bif->variant == PROG_HEDR)) {
q = make_procedure($2,LOCAL);
l = construct_entry_list(q, $3, PROCEDURE_NAME);
}
p = get_bfnd(fi,ENTRY_STAT, q, l, $4, LLNULL);
set_blobs(p, pred_bfnd, SAME_GROUP);
q->decl = YES; /*4.02.03*/
q->entry.proc_decl.proc_hedr = p; /*5.02.03*/
}
| MODULE new_prog name
{ PTR_SYMB s;
PTR_BFND p;
/*
s = make_global_entity($3, MODULE_NAME, global_default, NO);
s->decl = YES;
p = get_bfnd(fi, MODULE_STMT, s, LLNULL, LLNULL, LLNULL);
s->entry.Template.func_hedr = p;
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
*/
/*position = IN_MODULE;*/
s = make_module($3);
s->decl = YES; /* variable declaration has been seen. */
if (pred_bfnd != global_bfnd)
err("Misplaced MODULE statement", 33);
p = get_bfnd(fi, MODULE_STMT, s, LLNULL, LLNULL, LLNULL);
s->entry.Template.func_hedr = p; /* !!!????*/
set_blobs(p, global_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
position = IN_MODULE; /*IN_PROC*/
privateall = 0;
}
;
new_prog: { newprog();
if (position == IN_OUTSIDE)
position = IN_PROC;
else if (position != IN_INTERNAL_PROC){
if(!is_interface_stat(pred_bfnd))
position--;
}
else {
if(!is_interface_stat(pred_bfnd))
err("Internal procedures can not contain procedures",304);
}
}
;
proc_attr: RECURSIVE needkeyword
{ $$ = make_llnd(fi, RECURSIVE_OP, LLNULL, LLNULL, SMNULL); }
| PURE needkeyword
{ $$ = make_llnd(fi, PURE_OP, LLNULL, LLNULL, SMNULL); }
| ELEMENTAL needkeyword
{ $$ = make_llnd(fi, ELEMENTAL_OP, LLNULL, LLNULL, SMNULL); }
;
procname: name
{ PTR_BFND p;
$$ = make_procedure($1, LOCAL);
$$->decl = YES; /* variable declaration has been seen. */
/* if (pred_bfnd != global_bfnd)
{
err("Misplaced SUBROUTINE statement", 34);
}
*/
p = get_bfnd(fi,PROC_HEDR, $$, LLNULL, LLNULL, LLNULL);
$$->entry.proc_decl.proc_hedr = p;
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
}
;
funcname: name
{ PTR_BFND p;
$$ = make_function($1, TYNULL, LOCAL);
$$->decl = YES; /* variable declaration has been seen. */
/* if (pred_bfnd != global_bfnd)
err("Misplaced FUNCTION statement", 34); */
p = get_bfnd(fi,FUNC_HEDR, $$, LLNULL, LLNULL, LLNULL);
$$->entry.func_decl.func_hedr = p;
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
}
;
typedfunc: type FUNCTION new_prog name
{ PTR_BFND p;
PTR_LLND l;
$$ = make_function($4, $1, LOCAL);
$$->decl = YES; /* variable declaration has been seen. */
l = make_llnd(fi, TYPE_OP, LLNULL, LLNULL, SMNULL);
l->type = $1;
p = get_bfnd(fi,FUNC_HEDR, $$, LLNULL, l, LLNULL);
$$->entry.func_decl.func_hedr = p;
/* if (pred_bfnd != global_bfnd)
err("Misplaced FUNCTION statement", 34);*/
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
/*
$$ = make_function($4, $1, LOCAL);
$$->decl = YES;
p = get_bfnd(fi,FUNC_HEDR, $$, LLNULL, LLNULL, LLNULL);
if (pred_bfnd != global_bfnd)
errstr("cftn.gram: misplaced SUBROUTINE statement.");
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
*/
}
| type proc_attr FUNCTION new_prog name
{ PTR_BFND p;
PTR_LLND l;
$$ = make_function($5, $1, LOCAL);
$$->decl = YES; /* variable declaration has been seen. */
if($2->variant == RECURSIVE_OP)
$$->attr = $$->attr | RECURSIVE_BIT;
l = make_llnd(fi, TYPE_OP, LLNULL, LLNULL, SMNULL);
l->type = $1;
/* if (pred_bfnd != global_bfnd)
err("Misplaced FUNCTION statement", 34);*/
p = get_bfnd(fi,FUNC_HEDR, $$, LLNULL, l, $2);
$$->entry.func_decl.func_hedr = p;
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
}
| proc_attr FUNCTION new_prog name
{ PTR_BFND p;
$$ = make_function($4, TYNULL, LOCAL);
$$->decl = YES; /* variable declaration has been seen. */
if($1->variant == RECURSIVE_OP)
$$->attr = $$->attr | RECURSIVE_BIT;
/*if (pred_bfnd != global_bfnd)
err("Misplaced FUNCTION statement",34);*/
p = get_bfnd(fi,FUNC_HEDR, $$, LLNULL, LLNULL, $1);
$$->entry.func_decl.func_hedr = p;
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
}
| proc_attr type FUNCTION new_prog name
{ PTR_BFND p;
PTR_LLND l;
$$ = make_function($5, $2, LOCAL);
$$->decl = YES; /* variable declaration has been seen. */
if($1->variant == RECURSIVE_OP)
$$->attr = $$->attr | RECURSIVE_BIT;
l = make_llnd(fi, TYPE_OP, LLNULL, LLNULL, SMNULL);
l->type = $2;
/* if (pred_bfnd != global_bfnd)
err("Misplaced FUNCTION statement",34);*/
p = get_bfnd(fi,FUNC_HEDR, $$, LLNULL, l, $1);
$$->entry.func_decl.func_hedr = p;
set_blobs(p, pred_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
}
;
opt_result_clause: needkeyword keywordoff
{ $$ = LLNULL; }
| needkeyword RESULT LEFTPAR name RIGHTPAR
{ PTR_SYMB s;
s = make_scalar($4, TYNULL, LOCAL);
$$ = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
}
;
name: IDENTIFIER
{ $$ = look_up_sym(yytext); }
;
progname: { $$ = make_program(look_up_sym("_MAIN")); }
| name
{
$$ = make_program($1);
$$->decl = YES; /* variable declaration has been seen. */
}
;
blokname: { $$ = make_program(look_up_sym("_BLOCK")); }
| name
{
$$ = make_program($1);
$$->decl = YES; /* variable declaration has been seen. */
}
;
arglist:
{ $$ = SMNULL; }
| LEFTPAR RIGHTPAR
{ $$ = SMNULL; }
| LEFTPAR args RIGHTPAR
{ $$ = $2; }
;
args: arg
| args COMMA arg
{ $$ = set_id_list($1, $3); }
;
arg: name
{
$$ = make_scalar($1, TYNULL, IO);
}
| ASTER
{ $$ = make_scalar(look_up_sym("*"), TYNULL, IO); } /*star_symb*/
;
filename: CHAR_CONSTANT
{ char *s;
s = copyn(yyleng+1, yytext);
s[yyleng] = '\0';
$$ = s;
}
;
needkeyword:
{ needkwd = 1; }
;
keywordoff:
{ needkwd = NO; }
;
/* The scanner checks if the keyword is ONLY. */
keyword_if_colon_follow:
{ colon_flag = YES; }
;
/*
* Grammar for declarations
*/
spec: type_dcl
| end_type
| dcl
| common
| dimension
| dvm_specification /* FDVM */
| external
| intrinsic
| equivalence
| implicit
| attrib
| namelist
| data
| SAVE in_dcl
{
saveall = YES;
$$ = get_bfnd(fi,SAVE_DECL, SMNULL, LLNULL, LLNULL, LLNULL);
}
| SAVE in_dcl opt_double_colon savelist
{
$$ = get_bfnd(fi,SAVE_DECL, SMNULL, $4, LLNULL, LLNULL);
}
| FORMAT inside
{ PTR_LLND p;
p = make_llnd(fi,STMT_STR, LLNULL, LLNULL, SMNULL);
p->entry.string_val = copys(stmtbuf);
$$ = get_bfnd(fi,FORMAT_STAT, SMNULL, p, LLNULL, LLNULL);
}
| PARAMETER in_dcl LEFTPAR paramlist RIGHTPAR
{ $$ = get_bfnd(fi,PARAM_DECL, SMNULL, $4, LLNULL, LLNULL); }
| intent
| optional
| public
| private
| sequence
| allocatable
| pointer
| target
| interface
| use_stat
| module_proc_stmt
| static
;
interface: INTERFACE in_dcl
{ $$ = get_bfnd(fi, INTERFACE_STMT, SMNULL, LLNULL, LLNULL, LLNULL);
add_scope_level($$, NO);
}
| INTERFACE in_dcl name
{ PTR_SYMB s;
s = make_procedure($3, LOCAL);
s->variant = INTERFACE_NAME;
$$ = get_bfnd(fi, INTERFACE_STMT, s, LLNULL, LLNULL, LLNULL);
add_scope_level($$, NO);
}
| INTERFACEOPERATOR in_dcl LEFTPAR operator RIGHTPAR
{ PTR_SYMB s;
s = make_function($4, global_default, LOCAL);
s->variant = INTERFACE_NAME;
$$ = get_bfnd(fi, INTERFACE_OPERATOR, s, LLNULL, LLNULL, LLNULL);
add_scope_level($$, NO);
}
| INTERFACEASSIGNMENT in_dcl LEFTPAR EQUAL RIGHTPAR
{ PTR_SYMB s;
s = make_procedure(look_up_sym("="), LOCAL);
s->variant = INTERFACE_NAME;
$$ = get_bfnd(fi, INTERFACE_ASSIGNMENT, s, LLNULL, LLNULL, LLNULL);
add_scope_level($$, NO);
}
| ENDINTERFACE opt_unit_name
{ parstate = INDCL;
$$ = get_bfnd(fi, CONTROL_END, SMNULL, LLNULL, LLNULL, LLNULL);
/*process_interface($$);*/ /*podd 01.02.03*/
delete_beyond_scope_level(pred_bfnd);
}
;
defined_op: DEFINED_OPERATOR
{ $$ = look_up_sym(yytext); }
;
operator: defined_op
{ $$ = $1; }
| intrinsic_op
{ $$ = $1; }
;
intrinsic_op: PLUS
{ $$ = look_up_op(PLUS); }
| MINUS
{ $$ = look_up_op(MINUS); }
| ASTER
{ $$ = look_up_op(ASTER); }
| DASTER
{ $$ = look_up_op(DASTER); }
| SLASH
{ $$ = look_up_op(SLASH); }
| DSLASH
{ $$ = look_up_op(DSLASH); }
| AND
{ $$ = look_up_op(AND); }
| OR
{ $$ = look_up_op(OR); }
| XOR
{ $$ = look_up_op(XOR); }
| NOT
{ $$ = look_up_op(NOT); }
| EQ
{ $$ = look_up_op(EQ); }
| NE
{ $$ = look_up_op(NE); }
| GT
{ $$ = look_up_op(GT); }
| GE
{ $$ = look_up_op(GE); }
| LT
{ $$ = look_up_op(LT); }
| LE
{ $$ = look_up_op(LE); }
| NEQV
{ $$ = look_up_op(NEQV); }
| EQV
{ $$ = look_up_op(EQV); }
;
type_dcl: TYPE_DECL in_dcl opt_double_colon name
{
PTR_SYMB s;
type_var = s = make_derived_type($4, TYNULL, LOCAL);
$$ = get_bfnd(fi, STRUCT_DECL, s, LLNULL, LLNULL, LLNULL);
add_scope_level($$, NO);
}
| TYPE_DECL COMMA in_dcl needkeyword access_spec opt_double_colon name
{ PTR_SYMB s;
type_var = s = make_derived_type($7, TYNULL, LOCAL);
s->attr = s->attr | type_opt;
$$ = get_bfnd(fi, STRUCT_DECL, s, $5, LLNULL, LLNULL);
add_scope_level($$, NO);
}
;
end_type: ENDTYPE in_dcl
{
$$ = get_bfnd(fi, CONTROL_END, SMNULL, LLNULL, LLNULL, LLNULL);
if (type_var != SMNULL)
process_type(type_var, $$);
type_var = SMNULL;
delete_beyond_scope_level(pred_bfnd);
}
| ENDTYPE in_dcl name
{
$$ = get_bfnd(fi, CONTROL_END, SMNULL, LLNULL, LLNULL, LLNULL);
if (type_var != SMNULL)
process_type(type_var, $$);
type_var = SMNULL;
delete_beyond_scope_level(pred_bfnd);
}
;
dcl: type options name in_dcl dims lengspec initial_value
{
PTR_LLND q, r, l;
/* PTR_SYMB s;*/
PTR_TYPE t;
int type_opts;
vartype = $1;
if($6 && vartype->variant != T_STRING)
errstr("Non character entity %s has length specification",$3->ident,41);
t = make_type_node(vartype, $6);
type_opts = type_options;
if ($5) type_opts = type_opts | DIMENSION_BIT;
if ($5)
q = deal_with_options($3, t, type_opts, $5, ndim, $7, $5);
else q = deal_with_options($3, t, type_opts, attr_dims, attr_ndim, $7, $5);
r = make_llnd(fi, EXPR_LIST, q, LLNULL, SMNULL);
l = make_llnd(fi, TYPE_OP, LLNULL, LLNULL, SMNULL);
l->type = vartype;
$$ = get_bfnd(fi,VAR_DECL, SMNULL, r, l, $2);
}
| dcl COMMA name dims lengspec initial_value
{
PTR_LLND q, r;
/* PTR_SYMB s;*/
PTR_TYPE t;
int type_opts;
if($5 && vartype->variant != T_STRING)
errstr("Non character entity %s has length specification",$3->ident,41);
t = make_type_node(vartype, $5);
type_opts = type_options;
if ($4) type_opts = type_opts | DIMENSION_BIT;
if ($4)
q = deal_with_options($3, t, type_opts, $4, ndim, $6, $4);
else q = deal_with_options($3, t, type_opts, attr_dims, attr_ndim, $6, $4);
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
options:
{ $$ = LLNULL; }
| COLON COLON
{ $$ = LLNULL; }
| COMMA needkeyword attr_spec_list COLON COLON
{ $$ = $3; }
;
attr_spec_list: attr_spec
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| attr_spec_list COMMA needkeyword attr_spec
{ $$ = set_ll_list($1, $4, EXPR_LIST); }
;
attr_spec: PARAMETER
{ type_options = type_options | PARAMETER_BIT;
$$ = make_llnd(fi, PARAMETER_OP, LLNULL, LLNULL, SMNULL);
}
| access_spec
{ $$ = $1; }
| ALLOCATABLE
{ type_options = type_options | ALLOCATABLE_BIT;
$$ = make_llnd(fi, ALLOCATABLE_OP, LLNULL, LLNULL, SMNULL);
}
| DIMENSION dims
{ type_options = type_options | DIMENSION_BIT;
attr_ndim = ndim;
attr_dims = $2;
$$ = make_llnd(fi, DIMENSION_OP, $2, LLNULL, SMNULL);
}
| EXTERNAL
{ type_options = type_options | EXTERNAL_BIT;
$$ = make_llnd(fi, EXTERNAL_OP, LLNULL, LLNULL, SMNULL);
}
| INTENT LEFTPAR intent_spec RIGHTPAR
{ $$ = $3; }
| INTRINSIC
{ type_options = type_options | INTRINSIC_BIT;
$$ = make_llnd(fi, INTRINSIC_OP, LLNULL, LLNULL, SMNULL);
}
| OPTIONAL
{ type_options = type_options | OPTIONAL_BIT;
$$ = make_llnd(fi, OPTIONAL_OP, LLNULL, LLNULL, SMNULL);
}
| POINTER
{ type_options = type_options | POINTER_BIT;
$$ = make_llnd(fi, POINTER_OP, LLNULL, LLNULL, SMNULL);
}
| SAVE
{ type_options = type_options | SAVE_BIT;
$$ = make_llnd(fi, SAVE_OP, LLNULL, LLNULL, SMNULL);
}
| STATIC
{ type_options = type_options | SAVE_BIT;
$$ = make_llnd(fi, STATIC_OP, LLNULL, LLNULL, SMNULL);
}
| TARGET
{ type_options = type_options | TARGET_BIT;
$$ = make_llnd(fi, TARGET_OP, LLNULL, LLNULL, SMNULL);
}
;
intent_spec: needkeyword IN
{ type_options = type_options | IN_BIT; type_opt = IN_BIT;
$$ = make_llnd(fi, IN_OP, LLNULL, LLNULL, SMNULL);
}
| needkeyword OUT
{ type_options = type_options | OUT_BIT; type_opt = OUT_BIT;
$$ = make_llnd(fi, OUT_OP, LLNULL, LLNULL, SMNULL);
}
| needkeyword INOUT
{ type_options = type_options | INOUT_BIT; type_opt = INOUT_BIT;
$$ = make_llnd(fi, INOUT_OP, LLNULL, LLNULL, SMNULL);
}
;
access_spec: PUBLIC
{ type_options = type_options | PUBLIC_BIT;
type_opt = PUBLIC_BIT;
$$ = make_llnd(fi, PUBLIC_OP, LLNULL, LLNULL, SMNULL);
}
| PRIVATE
{ type_options = type_options | PRIVATE_BIT;
type_opt = PRIVATE_BIT;
$$ = make_llnd(fi, PRIVATE_OP, LLNULL, LLNULL, SMNULL);
}
;
intent: INTENT in_dcl LEFTPAR intent_spec RIGHTPAR opt_double_colon name
{
PTR_LLND q, r;
PTR_SYMB s;
s = make_scalar($7, TYNULL, LOCAL);
s->attr = s->attr | type_opt;
q = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
$$ = get_bfnd(fi, INTENT_STMT, SMNULL, r, $4, LLNULL);
}
| intent COMMA name
{
PTR_LLND q, r;
PTR_SYMB s;
s = make_scalar($3, TYNULL, LOCAL);
s->attr = s->attr | type_opt;
q = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
optional: OPTIONAL in_dcl opt_double_colon name
{
PTR_LLND q, r;
PTR_SYMB s;
s = make_scalar($4, TYNULL, LOCAL);
s->attr = s->attr | OPTIONAL_BIT;
q = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
$$ = get_bfnd(fi, OPTIONAL_STMT, SMNULL, r, LLNULL, LLNULL);
}
| optional COMMA name
{
PTR_LLND q, r;
PTR_SYMB s;
s = make_scalar($3, TYNULL, LOCAL);
s->attr = s->attr | OPTIONAL_BIT;
q = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
static: STATIC in_dcl opt_double_colon var
{
PTR_LLND r;
PTR_SYMB s;
s = $4->entry.Template.symbol;
s->attr = s->attr | SAVE_BIT;
r = make_llnd(fi,EXPR_LIST, $4, LLNULL, SMNULL);
$$ = get_bfnd(fi, STATIC_STMT, SMNULL, r, LLNULL, LLNULL);
}
| static COMMA var
{
PTR_LLND r;
PTR_SYMB s;
s = $3->entry.Template.symbol;
s->attr = s->attr | SAVE_BIT;
r = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
private: PRIVATE in_dcl
{
privateall = 1;
$$ = get_bfnd(fi, PRIVATE_STMT, SMNULL, LLNULL, LLNULL, LLNULL);
}
| PRIVATE in_dcl opt_double_colon private_attr use_name_list
{
/*type_options = type_options | PRIVATE_BIT;*/
$$ = get_bfnd(fi, PRIVATE_STMT, SMNULL, $5, LLNULL, LLNULL);
}
;
private_attr:
{type_opt = PRIVATE_BIT;}
;
sequence: SEQUENCE in_dcl
{
$$ = get_bfnd(fi, SEQUENCE_STMT, SMNULL, LLNULL, LLNULL, LLNULL);
}
public: PUBLIC in_dcl
{
/*saveall = YES;*/ /*14.03.03*/
$$ = get_bfnd(fi, PUBLIC_STMT, SMNULL, LLNULL, LLNULL, LLNULL);
}
| PUBLIC in_dcl opt_double_colon public_attr use_name_list
{
/*type_options = type_options | PUBLIC_BIT;*/
$$ = get_bfnd(fi, PUBLIC_STMT, SMNULL, $5, LLNULL, LLNULL);
}
public_attr:
{type_opt = PUBLIC_BIT;}
;
type: typespec opt_key_hedr selector opt_key_hedr
{
type_options = 0;
/* following block added by dbg */
ndim = 0;
attr_ndim = 0;
attr_dims = LLNULL;
/* end section added by dbg */
$$ = make_type_node($1, $3);
}
| TYPE LEFTPAR name RIGHTPAR opt_key_hedr
{ PTR_TYPE t;
type_options = 0;
ndim = 0;
attr_ndim = 0;
attr_dims = LLNULL;
t = lookup_type($3);
vartype = t;
$$ = make_type_node(t, LLNULL);
}
;
opt_key_hedr:
{opt_kwd_hedr = YES;}
;
attrib: att_type name
{ PTR_TYPE p;
PTR_LLND q;
PTR_SYMB s;
s = $2->id_attr;
if (s)
s->attr = $1;
else {
p = undeftype ? global_unknown : impltype[*$2->ident - 'a'];
s = install_entry($2, SOFT);
s->attr = $1;
set_type(s, p, LOCAL);
}
q = make_llnd(fi,VAR_REF, LLNULL, LLNULL, $2->id_attr);
q = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
$$ = get_bfnd(fi,ATTR_DECL, SMNULL, q, LLNULL, LLNULL);
}
| attrib COMMA name
{ PTR_TYPE p;
PTR_LLND q, r;
PTR_SYMB s;
int att;
att = $1->entry.Template.ll_ptr1->entry.Template.ll_ptr1->
entry.Template.symbol->attr;
s = $3->id_attr;
if (s)
s->attr = att;
else {
p = undeftype ? global_unknown : impltype[*$3->ident - 'a'];
s = install_entry($3, SOFT);
s->attr = att;
set_type(s, p, LOCAL);
}
q = make_llnd(fi,VAR_REF, LLNULL, LLNULL, $3->id_attr);
for (r = $1->entry.Template.ll_ptr1;
r->entry.list.next;
r = r->entry.list.next) ;
r->entry.list.next = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
}
;
att_type: GLOBAL_A
{ $$ = ATT_GLOBAL; }
| CLUSTER
{ $$ = ATT_CLUSTER; }
;
/*
opt_attr:
| TASK_GLOBAL
| PROCESS_GLOBAL
| TASK_CLUSTER
| PROCESS_CLUSTER
;
*/
typespec: typename
{
/* varleng = ($1<0 || $1==TYLONG ? 0 : typesize[$1]); */
vartype = $1;
}
;
typename: INTEGER { $$ = global_int; }
| REAL { $$ = global_float; }
| COMPLEX { $$ = global_complex; }
| DOUBLEPRECISION { $$ = global_double; }
| DOUBLECOMPLEX { $$ = global_dcomplex; }
| LOGICAL { $$ = global_bool; }
| CHARACTER { $$ = global_string; }
;
lengspec:
{ $$ = LLNULL; }
| proper_lengspec
{ $$ = $1; }
;
proper_lengspec: ASTER intonlyon integer_constant intonlyoff opt_key_hedr
{ $$ = make_llnd(fi, LEN_OP, $3, LLNULL, SMNULL); }
| ASTER intonlyon LEFTPAR intonlyoff ASTER RIGHTPAR
{ PTR_LLND l;
l = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
l->entry.string_val = (char *)"*";
$$ = make_llnd(fi, LEN_OP, l,l, SMNULL);
}
| ASTER intonlyon LEFTPAR intonlyoff expr RIGHTPAR
{$$ = make_llnd(fi, LEN_OP, $5, $5, SMNULL);}
;
selector:
{ $$ = LLNULL; }
| proper_lengspec
{ $$ = $1; }
| LEFTPAR in_ioctl clause end_ioctl RIGHTPAR
{ /*$$ = make_llnd(fi, PAREN_OP, $2, LLNULL, SMNULL);*/ $$ = $3; }
| LEFTPAR in_ioctl clause end_ioctl COMMA in_ioctl clause end_ioctl RIGHTPAR
/* | LEFTPAR in_ioctl clause COMMA clause RIGHTPAR
{ PTR_LLND l;
l = make_llnd(fi, CONS, $2, $4, SMNULL);
$$ = make_llnd(fi, PAREN_OP, l, LLNULL, SMNULL);}
*/
{ if($7->variant==LENGTH_OP && $3->variant==$7->variant)
$7->variant=KIND_OP;
$$ = make_llnd(fi, CONS, $3, $7, SMNULL);
}
;
clause: expr
{ if(vartype->variant == T_STRING)
$$ = make_llnd(fi,LENGTH_OP,$1,LLNULL,SMNULL);
else
$$ = make_llnd(fi,KIND_OP,$1,LLNULL,SMNULL);
}
| ASTER
{ PTR_LLND l;
l = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
l->entry.string_val = (char *)"*";
$$ = make_llnd(fi,LENGTH_OP,l,LLNULL,SMNULL);
}
| nameeq expr
{ /* $$ = make_llnd(fi, SPEC_PAIR, $2, LLNULL, SMNULL); */
char *q;
q = $1->entry.string_val;
if (strcmp(q, "len") == 0)
$$ = make_llnd(fi,LENGTH_OP,$2,LLNULL,SMNULL);
else
$$ = make_llnd(fi,KIND_OP,$2,LLNULL,SMNULL);
}
| nameeq ASTER
{ PTR_LLND l;
l = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
l->entry.string_val = (char *)"*";
$$ = make_llnd(fi,LENGTH_OP,l,LLNULL,SMNULL);
}
;
end_ioctl:
{endioctl();}
;
/*
int_nameeq_on:
{ intonly = inioctl = YES; }
;
int_nameeq_off:
{ intonly = inioctl = NO; }
;
*/
initial_value:
{ $$ = LLNULL; }
| EQUAL expr
{ $$ = $2; }
| POINT_TO expr
{ $$ = make_llnd(fi, POINTST_OP, LLNULL, $2, SMNULL); }
;
dimension: DIMENSION opt_double_colon in_dcl name dims
{ PTR_SYMB s;
PTR_LLND q, r;
if(! $5) {
err("No dimensions in DIMENSION statement", 42);
}
if(statement_kind == 1) /*DVM-directive*/
err("No shape specification", 65);
s = make_array($4, TYNULL, $5, ndim, LOCAL);
s->attr = s->attr | DIMENSION_BIT;
q = make_llnd(fi,ARRAY_REF, $5, LLNULL, s);
s->type->entry.ar_decl.ranges = $5;
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
$$ = get_bfnd(fi,DIM_STAT, SMNULL, r, LLNULL, LLNULL);
}
| dimension COMMA name dims
{ PTR_SYMB s;
PTR_LLND q, r;
if(! $4) {
err("No dimensions in DIMENSION statement", 42);
}
s = make_array($3, TYNULL, $4, ndim, LOCAL);
s->attr = s->attr | DIMENSION_BIT;
q = make_llnd(fi,ARRAY_REF, $4, LLNULL, s);
s->type->entry.ar_decl.ranges = $4;
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
allocatable: ALLOCATABLE in_dcl opt_double_colon var
/* ALLOCATABLE in_dcl opt_double_colon name dims lengspec*/
{/* PTR_SYMB s;*/
PTR_LLND r;
/*if(!$5) {
err("No dimensions in ALLOCATABLE statement",305);
}
s = make_array($4, TYNULL, $5, ndim, LOCAL);
s->attr = s->attr | ALLOCATABLE_BIT;
q = make_llnd(fi,ARRAY_REF, $5, LLNULL, s);
s->type->entry.ar_decl.ranges = $5;
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
*/
$4->entry.Template.symbol->attr = $4->entry.Template.symbol->attr | ALLOCATABLE_BIT;
r = make_llnd(fi,EXPR_LIST, $4, LLNULL, SMNULL);
$$ = get_bfnd(fi, ALLOCATABLE_STMT, SMNULL, r, LLNULL, LLNULL);
}
| allocatable COMMA var
/*allocatable COMMA name dims lengspec */
{ /*PTR_SYMB s;*/
PTR_LLND r;
/* if(! $4) {
err("No dimensions in ALLOCATABLE statement",305);
}
s = make_array($3, TYNULL, $4, ndim, LOCAL);
s->attr = s->attr | ALLOCATABLE_BIT;
q = make_llnd(fi,ARRAY_REF, $4, LLNULL, s);
s->type->entry.ar_decl.ranges = $4;
r = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
*/
$3->entry.Template.symbol->attr = $3->entry.Template.symbol->attr | ALLOCATABLE_BIT;
r = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
pointer: POINTER in_dcl opt_double_colon var
{ PTR_SYMB s;
PTR_LLND r;
/* if(! $5) {
err("No dimensions in POINTER statement",306);
}
s = make_array($4, TYNULL, $5, ndim, LOCAL);
s->attr = s->attr | POINTER_BIT;
q = make_llnd(fi,ARRAY_REF, $5, LLNULL, s);
s->type->entry.ar_decl.ranges = $5;
*/
/*s = make_pointer( $4->entry.Template.symbol->parent, TYNULL, LOCAL);*/ /*17.02.03*/
/*$4->entry.Template.symbol->attr = $4->entry.Template.symbol->attr | POINTER_BIT;*/
s = $4->entry.Template.symbol; /*17.02.03*/
s->attr = s->attr | POINTER_BIT;
r = make_llnd(fi,EXPR_LIST, $4, LLNULL, SMNULL);
$$ = get_bfnd(fi, POINTER_STMT, SMNULL, r, LLNULL, LLNULL);
}
| pointer COMMA var
{ PTR_SYMB s;
PTR_LLND r;
/* if(! $4) {
err("No dimensions in POINTER statement",306);
}
s = make_array($3, TYNULL, $4, ndim, LOCAL);
s->attr = s->attr | POINTER_BIT;
q = make_llnd(fi,ARRAY_REF, $4, LLNULL, s);
s->type->entry.ar_decl.ranges = $4;
*/
/*s = make_pointer( $3->entry.Template.symbol->parent, TYNULL, LOCAL);*/ /*17.02.03*/
/*$3->entry.Template.symbol->attr = $3->entry.Template.symbol->attr | POINTER_BIT;*/
s = $3->entry.Template.symbol; /*17.02.03*/
s->attr = s->attr | POINTER_BIT;
r = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
target: TARGET in_dcl opt_double_colon var
{/* PTR_SYMB s;*/
PTR_LLND r;
/* if(! $5) {
err("No dimensions in TARGET statement",307);
}
s = make_array($4, TYNULL, $5, ndim, LOCAL);
s->attr = s->attr | TARGET_BIT;
q = make_llnd(fi,ARRAY_REF, $5, LLNULL, s);
s->type->entry.ar_decl.ranges = $5;
*/
$4->entry.Template.symbol->attr = $4->entry.Template.symbol->attr | TARGET_BIT;
r = make_llnd(fi,EXPR_LIST, $4, LLNULL, SMNULL);
$$ = get_bfnd(fi, TARGET_STMT, SMNULL, r, LLNULL, LLNULL);
}
| target COMMA var
{ /*PTR_SYMB s;*/
PTR_LLND r;
/* if(! $4) {
err("No dimensions in TARGET statement",307);
}
s = make_array($3, TYNULL, $4, ndim, LOCAL);
s->attr = s->attr | TARGET_BIT;
q = make_llnd(fi,ARRAY_REF, $4, LLNULL, s);
s->type->entry.ar_decl.ranges = $4;
*/
$3->entry.Template.symbol->attr = $3->entry.Template.symbol->attr | TARGET_BIT;
r = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(r, $1->entry.Template.ll_ptr1);
}
;
common: COMMON in_dcl var
{ PTR_LLND p, q;
p = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
q = make_llnd(fi,COMM_LIST, p, LLNULL, SMNULL);
$$ = get_bfnd(fi,COMM_STAT, SMNULL, q, LLNULL, LLNULL);
}
| COMMON in_dcl comblock var
{ PTR_LLND p, q;
p = make_llnd(fi,EXPR_LIST, $4, LLNULL, SMNULL);
q = make_llnd(fi,COMM_LIST, p, LLNULL, $3);
$$ = get_bfnd(fi,COMM_STAT, SMNULL, q, LLNULL, LLNULL);
}
| common opt_comma comblock opt_comma var
{ PTR_LLND p, q;
p = make_llnd(fi,EXPR_LIST, $5, LLNULL, SMNULL);
q = make_llnd(fi,COMM_LIST, p, LLNULL, $3);
add_to_lowList(q, $1->entry.Template.ll_ptr1);
}
| common COMMA var
{ PTR_LLND p, r;
p = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
/*q = make_llnd(fi,COMM_LIST, p, LLNULL, SMNULL);*/
for (r = $1->entry.Template.ll_ptr1;
r->entry.list.next;
r = r->entry.list.next);
add_to_lowLevelList(p, r->entry.Template.ll_ptr1);
}
;
namelist: NAMELIST in_dcl namelist_group ident
{ PTR_LLND q, r;
q = make_llnd(fi,EXPR_LIST, $4, LLNULL, SMNULL);
r = make_llnd(fi,NAMELIST_LIST, q, LLNULL, $3);
$$ = get_bfnd(fi,NAMELIST_STAT, SMNULL, r, LLNULL, LLNULL);
}
| namelist opt_comma namelist_group opt_comma ident
{ PTR_LLND q, r;
q = make_llnd(fi,EXPR_LIST, $5, LLNULL, SMNULL);
r = make_llnd(fi,NAMELIST_LIST, q, LLNULL, $3);
add_to_lowList(r, $1->entry.Template.ll_ptr1);
}
| namelist COMMA ident
{ PTR_LLND q, r;
q = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
for (r = $1->entry.Template.ll_ptr1;
r->entry.list.next;
r = r->entry.list.next);
add_to_lowLevelList(q, r->entry.Template.ll_ptr1);
}
;
namelist_group: SLASH name SLASH
{ $$ = make_local_entity($2, NAMELIST_NAME,global_default,LOCAL); }
;
comblock: DSLASH
{ $$ = NULL; /*make_common(look_up_sym("*"));*/ }
| SLASH name SLASH
{ $$ = make_common($2); }
;
var: name dims
{ PTR_SYMB s;
if($2) {
s = make_array($1, TYNULL, $2, ndim, LOCAL);
s->attr = s->attr | DIMENSION_BIT;
s->type->entry.ar_decl.ranges = $2;
$$ = make_llnd(fi,ARRAY_REF, $2, LLNULL, s);
}
else {
s = make_scalar($1, TYNULL, LOCAL);
$$ = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
}
}
;
external: EXTERNAL in_dcl opt_double_colon name
{ PTR_LLND p, q;
PTR_SYMB s;
s = make_external($4, TYNULL);
s->attr = s->attr | EXTERNAL_BIT;
q = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
p = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
$$ = get_bfnd(fi,EXTERN_STAT, SMNULL, p, LLNULL, LLNULL);
}
| external COMMA name
{ PTR_LLND p, q;
PTR_SYMB s;
s = make_external($3, TYNULL);
s->attr = s->attr | EXTERNAL_BIT;
p = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
q = make_llnd(fi,EXPR_LIST, p, LLNULL, SMNULL);
add_to_lowLevelList(q, $1->entry.Template.ll_ptr1);
}
;
intrinsic: INTRINSIC in_dcl opt_double_colon name
{ PTR_LLND p, q;
PTR_SYMB s;
s = make_intrinsic($4, TYNULL); /*make_function($3, TYNULL, NO);*/
s->attr = s->attr | INTRINSIC_BIT;
q = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
p = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
$$ = get_bfnd(fi,INTRIN_STAT, SMNULL, p,
LLNULL, LLNULL);
}
| intrinsic COMMA name
{ PTR_LLND p, q;
PTR_SYMB s;
s = make_intrinsic($3, TYNULL); /* make_function($3, TYNULL, NO);*/
s->attr = s->attr | INTRINSIC_BIT;
p = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
q = make_llnd(fi,EXPR_LIST, p, LLNULL, SMNULL);
add_to_lowLevelList(q, $1->entry.Template.ll_ptr1);
}
;
equivalence: EQUIVALENCE in_dcl equivset
{
$$ = get_bfnd(fi,EQUI_STAT, SMNULL, $3,
LLNULL, LLNULL);
}
| equivalence COMMA equivset
{
add_to_lowLevelList($3, $1->entry.Template.ll_ptr1);
}
;
equivset: LEFTPAR equivlist RIGHTPAR
{
$$ = make_llnd(fi,EQUI_LIST, $2, LLNULL, SMNULL);
}
;
equivlist: equi_object COMMA equi_object
{ PTR_LLND p;
p = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
$$ = make_llnd(fi,EXPR_LIST, $1, p, SMNULL);
}
| equivlist COMMA equi_object
{ PTR_LLND p;
p = make_llnd(fi,EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(p, $1);
}
;
equi_object: name
{ PTR_SYMB s;
s=make_scalar($1,TYNULL,LOCAL);
$$ = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
s->attr = s->attr | EQUIVALENCE_BIT;
/*$$=$1; $$->entry.Template.symbol->attr = $$->entry.Template.symbol->attr | EQUIVALENCE_BIT; */
}
| name LEFTPAR subscript_list RIGHTPAR
{ PTR_SYMB s;
s=make_array($1,TYNULL,LLNULL,0,LOCAL);
$$ = make_llnd(fi,ARRAY_REF, $3, LLNULL, s);
s->attr = s->attr | EQUIVALENCE_BIT;
/*$$->entry.Template.symbol->attr = $$->entry.Template.symbol->attr | EQUIVALENCE_BIT; */
}
/* { $$ = $1;
$$->entry.Template.symbol->attr = $$->entry.Template.symbol->attr | EQUIVALENCE_BIT;
$$->variant == ARRAY_REF;
$$->entry.Template.ll_ptr1 = $3;
}
*/
;
| asubstring
;
data: data1
{ PTR_LLND p;
data_stat = NO;
p = make_llnd(fi,STMT_STR, LLNULL, LLNULL,
SMNULL);
p->entry.string_val = copys(stmtbuf);
$$ = get_bfnd(fi,DATA_DECL, SMNULL, p, LLNULL, LLNULL);
}
data1: DATA inside data_in datapair
| data1 opt_comma datapair
;
data_in:
{data_stat = YES;}
;
in_data:
{
if (parstate == OUTSIDE)
{ PTR_BFND p;
p = get_bfnd(fi,PROG_HEDR,
make_program(look_up_sym("_MAIN")),
LLNULL, LLNULL, LLNULL);
set_blobs(p, global_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
position = IN_PROC;
/*parstate = INDCL;*/
}
if(parstate < INDCL)
{
/* enddcl();*/
parstate = INDCL;
}
}
;
datapair: datalvals SLASH datarvals SLASH
;
datalvals: datalval
| datalvals COMMA datalval
;
datarvals: datarval
| datarvals COMMA datarval
;
datalval: data_null dataname
| data_null dataname datasubs
| data_null dataname datarange
| data_null dataname datasubs datarange
| data_null dataimplieddo
;
data_null:
{;}
;
d_name: name
{ $$= make_scalar($1, TYNULL, LOCAL);}
;
dataname: name
{ $$= make_scalar($1, TYNULL, LOCAL);
$$->attr = $$->attr | DATA_BIT;
}
;
datasubs: LEFTPAR iconexprlist RIGHTPAR
{ $$ = make_llnd(fi, DATA_SUBS, $2, LLNULL, SMNULL); }
;
datarange: LEFTPAR opticonexpr COLON opticonexpr RIGHTPAR
{ $$ = make_llnd(fi, DATA_RANGE, $2, $4, SMNULL); }
;
iconexprlist: iconexpr
{ $$ = $1; }
| iconexprlist COMMA iconexpr
{ $$ = add_to_lowLevelList($3, $1); }
;
opticonexpr:
{ $$ = LLNULL; }
| iconexpr
{ $$ = $1; }
;
dataimplieddo: LEFTPAR dlist COMMA d_name EQUAL iconexprlist RIGHTPAR
{$$= make_llnd(fi, DATA_IMPL_DO, $2, $6, $4); }
;
dlist: dataelt
{ $$ = $1; }
| dlist COMMA dataelt
{ $$ = add_to_lowLevelList($3, $1); }
;
dataelt: dataname datasubs
{ $$ = make_llnd(fi, DATA_ELT, $2, LLNULL, $1); }
| dataname datarange
{ $$ = make_llnd(fi, DATA_ELT, $2, LLNULL, $1); }
| dataname datasubs datarange
{
$2->entry.Template.ll_ptr2 = $3;
$$ = make_llnd(fi, DATA_ELT, $2, LLNULL, $1);
}
| dataimplieddo
{ $$ = make_llnd(fi, DATA_ELT, $1, LLNULL, SMNULL); }
;
datarval: datavalue
| data_null d_name ASTER datavalue
| unsignedint ASTER datavalue
;
datavalue: data_null d_name
| int_const
| real_const
| complex_const_data
| TTRUE
| TTRUE UNDER kind
| FFALSE
| FFALSE UNDER kind
| CHAR_CONSTANT
/* | STRING */
/* | bit_const */
| BOZ_const
| data_null ident LEFTPAR in_ioctl funarglist RIGHTPAR
{if($2->entry.Template.symbol->variant != TYPE_NAME)
errstr("Undefined type %s",$2->entry.Template.symbol->ident,319);
}
;
BOZ_const: BOZ_CONSTANT
;
int_const: unsignedint
| PLUS unsignedint
| MINUS unsignedint
;
unsignedint: INT_CONSTANT
| INT_CONSTANT UNDER kind
;
real_const: unsignedreal
| PLUS unsignedreal
| MINUS unsignedreal
;
unsignedreal: REAL_CONSTANT
| REAL_CONSTANT UNDER kind
| DP_CONSTANT
| DP_CONSTANT UNDER kind
;
complex_const_data: LEFTPAR complex_part COMMA complex_part RIGHTPAR
;
complex_part: real_const
| int_const
;
/*
bit_const:HEX_CONSTANT { $$ = mkbitcon(4, yyleng, yytext); }
| OCT_CONSTANT { $$ = mkbitcon(3, yyleng, yytext); }
| BITCON { $$ = mkbitcon(1, yyleng, yytext); }
;
*/
iconexpr: iconterm
{ $$ = make_llnd(fi,ICON_EXPR, $1, LLNULL, SMNULL); }
| PLUS iconterm
{
PTR_LLND p;
p = intrinsic_op_node("+", UNARY_ADD_OP, $2, LLNULL);
$$ = make_llnd(fi,ICON_EXPR, p, LLNULL, SMNULL);
}
| MINUS iconterm
{
PTR_LLND p;
p = intrinsic_op_node("-", MINUS_OP, $2, LLNULL);
$$ = make_llnd(fi,ICON_EXPR, p, LLNULL, SMNULL);
}
| iconexpr PLUS iconterm
{
PTR_LLND p;
p = intrinsic_op_node("+", ADD_OP, $1, $3);
$$ = make_llnd(fi,ICON_EXPR, p, LLNULL, SMNULL);
}
| iconexpr MINUS iconterm
{
PTR_LLND p;
p = intrinsic_op_node("-", SUBT_OP, $1, $3);
$$ = make_llnd(fi,ICON_EXPR, p, LLNULL, SMNULL);
}
;
iconterm: iconfactor
{ $$ = $1; }
| iconterm ASTER iconfactor
{ $$ = intrinsic_op_node("*", MULT_OP, $1, $3); }
| iconterm SLASH iconfactor
{ $$ = intrinsic_op_node("/", DIV_OP, $1, $3); }
;
iconfactor: iconprimary
{ $$ = $1; }
| iconprimary DASTER iconfactor
{ $$ = intrinsic_op_node("**", EXP_OP, $1, $3); }
;
iconprimary: INT_CONSTANT
{
PTR_LLND p;
p = make_llnd(fi,INT_VAL, LLNULL, LLNULL, SMNULL);
p->entry.ival = atoi(yytext);
p->type = global_int;
$$ = make_llnd(fi,EXPR_LIST, p, LLNULL, SMNULL);
}
| d_name
{
PTR_LLND p;
p = make_llnd(fi,VAR_REF, LLNULL, LLNULL, $1);
$$ = make_llnd(fi,EXPR_LIST, p, LLNULL, SMNULL);
}
| LEFTPAR iconexpr RIGHTPAR
{
$$ = make_llnd(fi,EXPR_LIST, $2, LLNULL, SMNULL);
}
;
savelist: saveitem
{ $$ = make_llnd(fi,EXPR_LIST, $1, LLNULL, SMNULL); }
| savelist COMMA saveitem
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
saveitem: var
{ $$ = $1;
$$->entry.Template.symbol->attr = $$->entry.Template.symbol->attr | SAVE_BIT;
}
| comblock
{ $$ = make_llnd(fi,COMM_LIST, LLNULL, LLNULL, $1);
$$->entry.Template.symbol->attr = $$->entry.Template.symbol->attr | SAVE_BIT;
}
;
use_name_list: use_key_word use_name no_use_key_word
{ $$ = set_ll_list($2, LLNULL, EXPR_LIST); }
| use_name_list COMMA use_key_word use_name no_use_key_word
{ $$ = set_ll_list($1, $4, EXPR_LIST); }
;
use_key_word:
{ as_op_kwd_ = YES; }
;
no_use_key_word:
{ as_op_kwd_ = NO; }
;
use_name: name
{
PTR_SYMB s;
s = make_scalar($1, TYNULL, LOCAL);
s->attr = s->attr | type_opt;
$$ = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
}
| OPERATOR LEFTPAR operator RIGHTPAR
{ PTR_SYMB s;
s = make_function($3, global_default, LOCAL);
s->variant = INTERFACE_NAME;
s->attr = s->attr | type_opt;
$$ = make_llnd(fi,OPERATOR_OP, LLNULL, LLNULL, s);
}
| ASSIGNMENT LEFTPAR EQUAL RIGHTPAR
{ PTR_SYMB s;
s = make_procedure(look_up_sym("="), LOCAL);
s->variant = INTERFACE_NAME;
s->attr = s->attr | type_opt;
$$ = make_llnd(fi,ASSIGNMENT_OP, LLNULL, LLNULL, s);
}
;
paramlist:paramitem
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| paramlist COMMA paramitem
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
paramitem: name EQUAL expr
{ PTR_SYMB p;
/* The check if name and expr have compatible types has
not been done yet. */
p = make_constant($1, TYNULL);
p->attr = p->attr | PARAMETER_BIT;
p->entry.const_value = $3;
$$ = make_llnd(fi,CONST_REF, LLNULL, LLNULL, p);
}
;
module_proc_stmt: MODULE_PROCEDURE proc_name_list
{ $$ = get_bfnd(fi, MODULE_PROC_STMT, SMNULL, $2, LLNULL, LLNULL); }
proc_name_list: name
{ PTR_SYMB s;
PTR_LLND q;
s = make_function($1, TYNULL, LOCAL);
s->variant = ROUTINE_NAME;
q = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
$$ = make_llnd(fi,EXPR_LIST, q, LLNULL, SMNULL);
}
| proc_name_list COMMA name
{ PTR_LLND p, q;
PTR_SYMB s;
s = make_function($3, TYNULL, LOCAL);
s->variant = ROUTINE_NAME;
p = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
q = make_llnd(fi,EXPR_LIST, p, LLNULL, SMNULL);
add_to_lowLevelList(q, $1);
}
;
use_stat: USE in_dcl module_name
{ $$ = get_bfnd(fi, USE_STMT, $3, LLNULL, LLNULL, LLNULL);
/*add_scope_level($3->entry.Template.func_hedr, YES);*/ /*17.06.01*/
copy_module_scope($3,LLNULL); /*17.03.03*/
colon_flag = NO;
}
| USE in_dcl module_name COMMA keyword_if_colon_follow rename_list
{ $$ = get_bfnd(fi, USE_STMT, $3, $6, LLNULL, LLNULL);
/*add_scope_level(module_scope, YES); *//* 17.06.01*/
copy_module_scope($3,$6); /*17.03.03 */
colon_flag = NO;
}
| USE in_dcl module_name COMMA keyword_if_colon_follow ONLY
{ PTR_LLND l;
l = make_llnd(fi, ONLY_NODE, LLNULL, LLNULL, SMNULL);
$$ = get_bfnd(fi, USE_STMT, $3, l, LLNULL, LLNULL);
}
| USE in_dcl module_name COMMA keyword_if_colon_follow ONLY only_list
{ PTR_LLND l;
l = make_llnd(fi, ONLY_NODE, $7, LLNULL, SMNULL);
$$ = get_bfnd(fi, USE_STMT, $3, l, LLNULL, LLNULL);
}
;
module_name: name
{
if ($1->id_attr == SMNULL)
warn1("Unknown module %s", $1->ident,308);
$$ = make_global_entity($1, MODULE_NAME, global_default, NO);
module_scope = $$->entry.Template.func_hedr;
}
;
only_list: only_name
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| only_list COMMA only_name
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
only_name: rename_name
{ $$ = $1; }
| name
{ PTR_HASH oldhash,copyhash;
PTR_SYMB oldsym, newsym;
PTR_LLND m;
oldhash = just_look_up_sym_in_scope(module_scope, $1->ident);
if (oldhash == HSNULL) {
errstr("Unknown identifier %s.", $1->ident,309);
$$= LLNULL;
}
else {
oldsym = oldhash->id_attr;
copyhash=just_look_up_sym_in_scope(cur_scope(), $1->ident);
if( copyhash && copyhash->id_attr && copyhash->id_attr->entry.Template.tag==module_scope->id)
{
newsym = copyhash->id_attr;
newsym->entry.Template.tag = 0;
}
else
{
newsym = make_local_entity($1, oldsym->variant, oldsym->type,LOCAL);
/* copies data in entry.Template structure and attr */
copy_sym_data(oldsym, newsym);
/*newsym->entry.Template.base_name = oldsym;*//*19.03.03*/
}
/* l = make_llnd(fi, VAR_REF, LLNULL, LLNULL, oldsym);*/
m = make_llnd(fi, VAR_REF, LLNULL, LLNULL, newsym);
$$ = make_llnd(fi, RENAME_NODE, m, LLNULL, oldsym);
}
}
;
rename_list: rename_name
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| rename_list COMMA rename_name
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
rename_name: name POINT_TO name
{ PTR_HASH oldhash,copyhash;
PTR_SYMB oldsym, newsym;
PTR_LLND l, m;
oldhash = just_look_up_sym_in_scope(module_scope, $3->ident);
if (oldhash == HSNULL) {
errstr("Unknown identifier %s", $3->ident,309);
$$= LLNULL;
}
else {
oldsym = oldhash->id_attr;
copyhash = just_look_up_sym_in_scope(cur_scope(), $3->ident);
if(copyhash && copyhash->id_attr && copyhash->id_attr->entry.Template.tag==module_scope->id)
{
delete_symbol(copyhash->id_attr);
copyhash->id_attr = SMNULL;
}
newsym = make_local_entity($1, oldsym->variant, oldsym->type, LOCAL);
/* copies data in entry.Template structure and attr */
copy_sym_data(oldsym, newsym);
/*newsym->entry.Template.base_name = oldsym;*//*19.03.03*/
l = make_llnd(fi, VAR_REF, LLNULL, LLNULL, oldsym);
m = make_llnd(fi, VAR_REF, LLNULL, LLNULL, newsym);
$$ = make_llnd(fi, RENAME_NODE, m, l, SMNULL);
}
}
;
/*
in_param: inside
{
if(parstate > INDCL)
dclerr("parameter statement out of order", SMNULL);
}
;
*/
dims:
{ ndim = 0; explicit_shape = 1; $$ = LLNULL; }
| LEFTPAR dimlist RIGHTPAR
{ $$ = $2; }
;
dimlist: { ndim = 0; explicit_shape = 1;} dim
{
$$ = make_llnd(fi,EXPR_LIST, $2, LLNULL, SMNULL);
$$->type = global_default;
}
| dimlist COMMA dim
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
dim: ubound
{
if(ndim == maxdim)
err("Too many dimensions", 43);
else if(ndim < maxdim)
$$ = $1;
++ndim;
}
| COLON
{
if(ndim == maxdim)
err("Too many dimensions", 43);
else if(ndim < maxdim)
$$ = make_llnd(fi, DDOT, LLNULL, LLNULL, SMNULL);
++ndim;
explicit_shape = 0;
}
| expr COLON
{
if(ndim == maxdim)
err("Too many dimensions", 43);
else if(ndim < maxdim)
$$ = make_llnd(fi,DDOT, $1, LLNULL, SMNULL);
++ndim;
explicit_shape = 0;
}
| expr COLON ubound
{
if(ndim == maxdim)
err("Too many dimensions", 43);
else if(ndim < maxdim)
$$ = make_llnd(fi,DDOT, $1, $3, SMNULL);
++ndim;
}
;
ubound: ASTER
{
$$ = make_llnd(fi,STAR_RANGE, LLNULL, LLNULL, SMNULL);
$$->type = global_default;
explicit_shape = 0;
}
| expr
;
labellist: label
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| labellist COMMA label
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
label: INT_CONSTANT
{PTR_LABEL p;
p = make_label_node(fi,convci(yyleng, yytext));
p->scope = cur_scope();
$$ = make_llnd_label(fi,LABEL_REF, p);
}
;
implicit: IMPLICIT in_dcl implist
{ /*PTR_LLND l;*/
/* l = make_llnd(fi, EXPR_LIST, $3, LLNULL, SMNULL);*/
$$ = get_bfnd(fi,IMPL_DECL, SMNULL, $3, LLNULL, LLNULL);
redefine_func_arg_type();
}
/*
| implicit COMMA implist
{ PTR_LLND l;
l = make_llnd(fi, EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(l, $1->entry.Template.ll_ptr1);
}
*/
| IMPLICITNONE
{ /*undeftype = YES;
setimpl(TYNULL, (int)'a', (int)'z'); FB COMMENTED---> NOT QUITE RIGHT BUT AVOID PB WITH COMMON*/
$$ = get_bfnd(fi,IMPL_DECL, SMNULL, LLNULL, LLNULL, LLNULL);
}
;
implist: impitem
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| implist COMMA impitem
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
impitem: imptype LEFTPAR letgroups RIGHTPAR
{
$$ = make_llnd(fi, IMPL_TYPE, $3, LLNULL, SMNULL);
$$->type = vartype;
}
/* | imptype
{
$$ = make_llnd(fi, IMPL_TYPE, LLNULL, LLNULL, SMNULL);
$$->type = vartype;
}
*/ /*30.10.03*/
;
/* The draft specification leads to big trouble. Check that up. */
/* For the time being. */
imptype: { implkwd = YES; } type_implicit
{ vartype = $2; }
;
type_implicit: STAT typename
{ $$ = $2; }
| type
{ $$ = $1;}
;
/* Not used.
in_implicit: inside
{
if (parstate >= INDCL)
dclerr("implicit statement out of order", SMNULL);
}
;
*/
letgroups: letgroup
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| letgroups COMMA letgroup
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
letgroup: letter
{
setimpl(vartype, (int)$1, (int)$1);
$$ = make_llnd(fi,CHAR_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.cval = $1;
}
| letter MINUS letter
{ PTR_LLND p,q;
setimpl(vartype, (int)$1, (int)$3);
p = make_llnd(fi,CHAR_VAL, LLNULL, LLNULL, SMNULL);
p->entry.cval = $1;
q = make_llnd(fi,CHAR_VAL, LLNULL, LLNULL, SMNULL);
q->entry.cval = $3;
$$= make_llnd(fi,DDOT, p, q, SMNULL);
}
;
letter: IDENTIFIER
{
if(yyleng!=1 || yytext[0]<'a' || yytext[0]>'z')
{
err("IMPLICIT item must be single letter", 37);
$$ = '\0';
}
else $$ = yytext[0];
}
;
inside:
{
if (parstate == OUTSIDE)
{ PTR_BFND p;
p = get_bfnd(fi,PROG_HEDR,
make_program(look_up_sym("_MAIN")),
LLNULL, LLNULL, LLNULL);
set_blobs(p, global_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
position = IN_PROC;
parstate = INSIDE;
}
}
;
in_dcl:
{ switch(parstate)
{
case OUTSIDE:
{ PTR_BFND p;
p = get_bfnd(fi,PROG_HEDR,
make_program(look_up_sym("_MAIN")),
LLNULL, LLNULL, LLNULL);
set_blobs(p, global_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
position = IN_PROC;
parstate = INDCL; }
break;
case INSIDE: parstate = INDCL;
case INDCL: break;
case INDATA:
/* err(
"Statement order error: declaration after DATA or function statement",
29);*/
break;
default:
err("Declaration among executables", 30);
}
}
;
opt_double_colon:
| COLON COLON
;
/*
* Grammar for expressions
*/
funarglist:
{ $$ = LLNULL; endioctl(); }
| funargs
{ $$ = $1; endioctl();}
;
funarg: expr
{ $$ = $1; }
| triplet
{ $$ = $1; }
| nameeq expr
{ PTR_LLND l;
l = make_llnd(fi, KEYWORD_ARG, $1, $2, SMNULL);
l->type = $2->type;
$$ = l;
}
;
funargs: in_ioctl funarg
{ $$ = set_ll_list($2, LLNULL, EXPR_LIST);
endioctl();
}
| funargs COMMA in_ioctl funarg
{ $$ = set_ll_list($1, $4, EXPR_LIST);
endioctl();
}
;
subscript_list: expr
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| subscript_list COMMA expr
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
expr: uexpr
{ $$ = $1; }
| LEFTPAR expr RIGHTPAR
{ $$ = $2; }
| complex_const
{ $$ = $1; }
;
uexpr: lhs
{ $$ = $1; }
| simple_const
{ $$ = $1; }
/* | string_constant opt_substring
{ $$ = make_llnd(fi, ARRAY_OP, $1, $2, SMNULL); }
*/ | vec
{ $$ = $1; }
| expr PLUS expr %prec PLUS
{ $$ = intrinsic_op_node("+", ADD_OP, $1, $3); }
| expr MINUS expr %prec PLUS
{ $$ = intrinsic_op_node("-", SUBT_OP, $1, $3); }
| expr ASTER expr
{ $$ = intrinsic_op_node("*", MULT_OP, $1, $3); }
| expr SLASH expr
{ $$ = intrinsic_op_node("/", DIV_OP, $1, $3); }
| expr DASTER expr
{ $$ = intrinsic_op_node("**", EXP_OP, $1, $3); }
| defined_op expr %prec UNARY_OP
{ $$ = defined_op_node($1, $2, LLNULL); }
| PLUS expr %prec ASTER
{ $$ = intrinsic_op_node("+", UNARY_ADD_OP, $2, LLNULL); }
| MINUS expr %prec ASTER
{ $$ = intrinsic_op_node("-", MINUS_OP, $2, LLNULL); }
| expr EQ expr %prec EQ
{ $$ = intrinsic_op_node(".eq.", EQ_OP, $1, $3); }
| expr GT expr %prec EQ
{ $$ = intrinsic_op_node(".gt.", GT_OP, $1, $3); }
| expr LT expr %prec EQ
{ $$ = intrinsic_op_node(".lt.", LT_OP, $1, $3); }
| expr GE expr %prec EQ
{ $$ = intrinsic_op_node(".ge.", GTEQL_OP, $1, $3); }
| expr LE expr %prec EQ
{ $$ = intrinsic_op_node(".ge.", LTEQL_OP, $1, $3); }
| expr NE expr %prec EQ
{ $$ = intrinsic_op_node(".ne.", NOTEQL_OP, $1, $3); }
| expr EQV expr
{ $$ = intrinsic_op_node(".eqv.", EQV_OP, $1, $3); }
| expr NEQV expr
{ $$ = intrinsic_op_node(".neqv.", NEQV_OP, $1, $3); }
| expr XOR expr
{ $$ = intrinsic_op_node(".xor.", XOR_OP, $1, $3); }
| expr OR expr
{ $$ = intrinsic_op_node(".or.", OR_OP, $1, $3); }
| expr AND expr
{ $$ = intrinsic_op_node(".and.", AND_OP, $1, $3); }
| NOT expr
{ $$ = intrinsic_op_node(".not.", NOT_OP, $2, LLNULL); }
| expr DSLASH expr
{ $$ = intrinsic_op_node("//", CONCAT_OP, $1, $3); }
| expr defined_op expr %prec BINARY_OP
{ $$ = defined_op_node($2, $1, $3); }
;
addop: PLUS { $$ = ADD_OP; }
| MINUS { $$ = SUBT_OP; }
;
/*
relop: EQ { $$ = EQ_OP; }
| GT { $$ = GT_OP; }
| LT { $$ = LT_OP; }
| GE { $$ = GTEQL_OP; }
| LE { $$ = LTEQL_OP; }
| NE { $$ = NOTEQL_OP; }
;
*/
ident: name
{ PTR_SYMB s;
PTR_TYPE t;
/* PTR_LLND l;*/
if (!(s = $1->id_attr))
{
s = make_scalar($1, TYNULL, LOCAL);
s->decl = SOFT;
}
switch (s->variant)
{
case CONST_NAME:
$$ = make_llnd(fi,CONST_REF,LLNULL,LLNULL, s);
t = s->type;
if ((t != TYNULL) &&
((t->variant == T_ARRAY) || (t->variant == T_STRING) ))
$$->variant = ARRAY_REF;
$$->type = t;
break;
case DEFAULT: /* if common region with same name has been
declared. */
s = make_scalar($1, TYNULL, LOCAL);
s->decl = SOFT;
case VARIABLE_NAME:
$$ = make_llnd(fi,VAR_REF,LLNULL,LLNULL, s);
t = s->type;
if (t != TYNULL) {
if ((t->variant == T_ARRAY) || (t->variant == T_STRING) ||
((t->variant == T_POINTER) && (t->entry.Template.base_type->variant == T_ARRAY) ) )
$$->variant = ARRAY_REF;
/* if (t->variant == T_DERIVED_TYPE)
$$->variant = RECORD_REF; */
}
$$->type = t;
break;
case TYPE_NAME:
$$ = make_llnd(fi,TYPE_REF,LLNULL,LLNULL, s);
$$->type = s->type;
break;
case INTERFACE_NAME:
$$ = make_llnd(fi, INTERFACE_REF,LLNULL,LLNULL, s);
$$->type = s->type;
break;
case FUNCTION_NAME:
if(isResultVar(s)) {
$$ = make_llnd(fi,VAR_REF,LLNULL,LLNULL, s);
t = s->type;
if (t != TYNULL) {
if ((t->variant == T_ARRAY) || (t->variant == T_STRING) ||
((t->variant == T_POINTER) && (t->entry.Template.base_type->variant == T_ARRAY) ) )
$$->variant = ARRAY_REF;
}
$$->type = t;
break;
}
default:
$$ = make_llnd(fi,VAR_REF,LLNULL,LLNULL, s);
$$->type = s->type;
break;
}
/* if ($$->variant == T_POINTER) {
l = $$;
$$ = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$$->type = l->type->entry.Template.base_type;
}
*/ /*11.02.03*/
}
;
lhs: ident
{ PTR_SYMB s;
$$ = $1;
s= $$->entry.Template.symbol;
if ((($1->variant == VAR_REF) || ($1->variant == ARRAY_REF)) && (s->scope !=cur_scope())) /*global_bfnd*/
{
if(((s->variant == FUNCTION_NAME) && (!isResultVar(s))) || (s->variant == PROCEDURE_NAME) || (s->variant == ROUTINE_NAME))
{ s = $$->entry.Template.symbol = make_scalar(s->parent, TYNULL, LOCAL);
$$->type = s->type;
}
}
}
| structure_component
{ $$ = $1; }
| array_ele_substring_func_ref
{ $$ = $1; }
;
array_ele_substring_func_ref: ident LEFTPAR in_ioctl funarglist RIGHTPAR
{ int num_triplets;
PTR_SYMB s; /*, sym;*/
/* PTR_LLND l; */
PTR_TYPE tp;
/* l = $1; */
s = $1->entry.Template.symbol;
/* Handle variable to function conversion. */
if (($1->variant == VAR_REF) &&
(((s->variant == VARIABLE_NAME) && (s->type) &&
(s->type->variant != T_ARRAY)) ||
(s->variant == ROUTINE_NAME))) {
s = $1->entry.Template.symbol = make_function(s->parent, TYNULL, LOCAL);
$1->variant = FUNC_CALL;
}
if (($1->variant == VAR_REF) && (s->variant == FUNCTION_NAME)) {
if(isResultVar(s))
$1->variant = ARRAY_REF;
else
$1->variant = FUNC_CALL;
}
if (($1->variant == VAR_REF) && (s->variant == PROGRAM_NAME)) {
errstr("The name '%s' is invalid in this context",s->ident,285);
$1->variant = FUNC_CALL;
}
/* l = $1; */
num_triplets = is_array_section_ref($4);
switch ($1->variant)
{
case TYPE_REF:
$1->variant = STRUCTURE_CONSTRUCTOR;
$1->entry.Template.ll_ptr1 = $4;
$$ = $1;
$$->type = lookup_type(s->parent);
/* $$ = make_llnd(fi, STRUCTURE_CONSTRUCTOR, $1, $4, SMNULL);
$$->type = $1->type;*//*18.02.03*/
break;
case INTERFACE_REF:
/* sym = resolve_overloading(s, $4);
if (sym != SMNULL)
{
l = make_llnd(fi, FUNC_CALL, $4, LLNULL, sym);
l->type = sym->type;
$$ = $1; $$->variant = OVERLOADED_CALL;
$$->entry.Template.ll_ptr1 = l;
$$->type = sym->type;
}
else {
errstr("can't resolve call %s", s->ident,310);
}
break;
*/ /*podd 01.02.03*/
$1->variant = FUNC_CALL;
case FUNC_CALL:
$1->entry.Template.ll_ptr1 = $4;
$$ = $1;
if(s->type)
$$->type = s->type;
else
$$->type = global_default;
/*late_bind_if_needed($$);*/ /*podd 02.02.23*/
break;
case DEREF_OP:
case ARRAY_REF:
/* array element */
if (num_triplets == 0) {
if ($4 == LLNULL) {
s = $1->entry.Template.symbol = make_function(s->parent, TYNULL, LOCAL);
s->entry.func_decl.num_output = 1;
$1->variant = FUNC_CALL;
$$ = $1;
} else if ($1->type->variant == T_STRING) {
PTR_LLND temp = $4;
int num_input = 0;
while (temp) {
++num_input;
temp = temp->entry.Template.ll_ptr2;
}
$1->entry.Template.ll_ptr1 = $4;
s = $1->entry.Template.symbol = make_function(s->parent, TYNULL, LOCAL);
s->entry.func_decl.num_output = 1;
s->entry.func_decl.num_input = num_input;
$1->variant = FUNC_CALL;
$$ = $1;
} else {
$1->entry.Template.ll_ptr1 = $4;
$$ = $1;
$$->type = $1->type->entry.ar_decl.base_type;
}
}
/* substring */
else if ((num_triplets == 1) &&
($1->type->variant == T_STRING)) {
/*
$1->entry.Template.ll_ptr1 = $4;
$$ = $1; $$->type = global_string;
*/
$$ = make_llnd(fi,
ARRAY_OP, LLNULL, LLNULL, SMNULL);
$$->entry.Template.ll_ptr1 = $1;
$$->entry.Template.ll_ptr2 = $4->entry.Template.ll_ptr1;
$$->type = global_string;
}
/* array section */
else {
$1->entry.Template.ll_ptr1 = $4;
$$ = $1; tp = make_type(fi, T_ARRAY); /**18.03.17*/
tp->entry.ar_decl.base_type = $1->type->entry.ar_decl.base_type; /**18.03.17 $1->type */
tp->entry.ar_decl.num_dimensions = num_triplets;
$$->type = tp;
}
break;
default:
if($1->entry.Template.symbol)
errstr("Can't subscript %s",$1->entry.Template.symbol->ident, 44);
else
err("Can't subscript",44);
}
/*if ($$->variant == T_POINTER) {
l = $$;
$$ = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$$->type = l->type->entry.Template.base_type;
}
*/ /*11.02.03*/
endioctl();
}
| ident LEFTPAR in_ioctl funarglist RIGHTPAR substring
{ int num_triplets;
PTR_SYMB s;
PTR_LLND l;
s = $1->entry.Template.symbol;
/* if ($1->type->variant == T_POINTER) {
l = $1;
$1 = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$1->type = l->type->entry.Template.base_type;
} */
if (($1->type->variant != T_ARRAY) ||
($1->type->entry.ar_decl.base_type->variant != T_STRING)) {
errstr("Can't take substring of %s", s->ident, 45);
}
else {
num_triplets = is_array_section_ref($4);
/* array element */
if (num_triplets == 0) {
$1->entry.Template.ll_ptr1 = $4;
/* $1->entry.Template.ll_ptr2 = $6;*/
/* $$ = $1;*/
l=$1;
/*$$->type = $1->type->entry.ar_decl.base_type;*/
l->type = global_string; /**18.03.17* $1->type->entry.ar_decl.base_type;*/
}
/* array section */
else {
$1->entry.Template.ll_ptr1 = $4;
/*$1->entry.Template.ll_ptr2 = $6;
$$ = $1; $$->type = make_type(fi, T_ARRAY);
$$->type->entry.ar_decl.base_type = $1->type;
$$->type->entry.ar_decl.num_dimensions = num_triplets;
*/
l = $1; l->type = make_type(fi, T_ARRAY);
l->type->entry.ar_decl.base_type = global_string; /**18.03.17* $1->type*/
l->type->entry.ar_decl.num_dimensions = num_triplets;
}
$$ = make_llnd(fi, ARRAY_OP, l, $6, SMNULL);
$$->type = l->type;
/* if ($$->variant == T_POINTER) {
l = $$;
$$ = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$$->type = l->type->entry.Template.base_type;
}
*/ /*11.02.03*/
}
endioctl();
}
| structure_component LEFTPAR funarglist RIGHTPAR
{ int num_triplets;
PTR_LLND l,l1,l2;
PTR_TYPE tp;
/* if ($1->variant == T_POINTER) {
l = $1;
$1 = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$1->type = l->type->entry.Template.base_type;
} */
num_triplets = is_array_section_ref($3);
$$ = $1;
l2 = $1->entry.Template.ll_ptr2;
l1 = $1->entry.Template.ll_ptr1;
if(l2 && l2->type->variant == T_STRING)/*substring*/
if(num_triplets == 1){
l = make_llnd(fi, ARRAY_OP, LLNULL, LLNULL, SMNULL);
l->entry.Template.ll_ptr1 = l2;
l->entry.Template.ll_ptr2 = $3->entry.Template.ll_ptr1;
l->type = global_string;
$$->entry.Template.ll_ptr2 = l;
} else
err("Can't subscript",44);
else if (l2 && l2->type->variant == T_ARRAY) {
if(num_triplets > 0) { /*array section*/
tp = make_type(fi,T_ARRAY);
tp->entry.ar_decl.base_type = $1->type->entry.ar_decl.base_type;
tp->entry.ar_decl.num_dimensions = num_triplets;
$$->type = tp;
l2->entry.Template.ll_ptr1 = $3;
l2->type = $$->type;
}
else { /*array element*/
l2->type = l2->type->entry.ar_decl.base_type;
l2->entry.Template.ll_ptr1 = $3;
if(l1->type->variant != T_ARRAY)
$$->type = l2->type;
}
} else
{err("Can't subscript",44); /*fprintf(stderr,"%d %d",$1->variant,l2);*/}
/*errstr("Can't subscript %s",l2->entry.Template.symbol->ident,441);*/
}
| structure_component LEFTPAR funarglist RIGHTPAR substring
{ int num_triplets;
PTR_LLND l,q;
/* if ($1->variant == T_POINTER) {
l = $1;
$1 = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$1->type = l->type->entry.Template.base_type;
} */
$$ = $1;
if (($1->type->variant != T_ARRAY) &&
($1->type->entry.ar_decl.base_type->variant != T_STRING)) {
err("Can't take substring",45);
}
else {
num_triplets = is_array_section_ref($3);
l = $1->entry.Template.ll_ptr2;
if(l) {
/* array element */
if (num_triplets == 0) {
l->entry.Template.ll_ptr1 = $3;
l->type = global_string;
}
/* array section */
else {
l->entry.Template.ll_ptr1 = $3;
l->type = make_type(fi, T_ARRAY);
l->type->entry.ar_decl.base_type = global_string;
l->type->entry.ar_decl.num_dimensions = num_triplets;
}
q = make_llnd(fi, ARRAY_OP, l, $5, SMNULL);
q->type = l->type;
$$->entry.Template.ll_ptr2 = q;
if($1->entry.Template.ll_ptr1->type->variant != T_ARRAY)
$$->type = q->type;
}
}
}
;
structure_component: lhs PERCENT IDENTIFIER
{ PTR_TYPE t;
PTR_SYMB field;
/* PTR_BFND at_scope;*/
PTR_LLND l;
/* if ($1->variant == T_POINTER) {
l = $1;
$1 = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$1->type = l->type->entry.Template.base_type;
} */
t = $1->type;
if (( ( ($1->variant == VAR_REF)
|| ($1->variant == CONST_REF)
|| ($1->variant == ARRAY_REF)
|| ($1->variant == RECORD_REF)) && (t->variant == T_DERIVED_TYPE))
||((($1->variant == ARRAY_REF) || ($1->variant == RECORD_REF)) && (t->variant == T_ARRAY) &&
(t = t->entry.ar_decl.base_type) && (t->variant == T_DERIVED_TYPE)))
{
t->name = lookup_type_symbol(t->name);
if ((field = component(t->name, yytext))) {
l = make_llnd(fi, VAR_REF, LLNULL, LLNULL, field);
l->type = field->type;
if(field->type->variant == T_ARRAY || field->type->variant == T_STRING)
l->variant = ARRAY_REF;
$$ = make_llnd(fi, RECORD_REF, $1, l, SMNULL);
if($1->type->variant != T_ARRAY)
$$->type = field->type;
else {
$$->type = make_type(fi,T_ARRAY);
if(field->type->variant != T_ARRAY)
$$->type->entry.ar_decl.base_type = field->type;
else
$$->type->entry.ar_decl.base_type = field->type->entry.ar_decl.base_type;
$$->type->entry.ar_decl.num_dimensions = t->entry.ar_decl.num_dimensions;
}
}
else
errstr("Illegal component %s", yytext,311);
}
else
errstr("Can't take component %s", yytext,311);
}
/* if ($$->variant == T_POINTER) {
l = $$;
$$ = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$$->type = l->type->entry.Template.base_type;
}
}
else errstr("Can't take component of %s", yytext, 311);
*/
;
array_element: ident
{ $$ = $1;}
| structure_component
{$$ = $1;}
| ident LEFTPAR in_ioctl funarglist RIGHTPAR
{ int num_triplets;
PTR_TYPE tp;
/* PTR_LLND l;*/
if ($1->type->variant == T_ARRAY)
{
num_triplets = is_array_section_ref($4);
/* array element */
if (num_triplets == 0) {
$1->entry.Template.ll_ptr1 = $4;
$$ = $1;
$$->type = $1->type->entry.ar_decl.base_type;
}
/* substring */
/* else if ((num_triplets == 1) &&
($1->type->variant == T_STRING)) {
$1->entry.Template.ll_ptr1 = $4;
$$ = $1; $$->type = global_string;
} */ /*podd*/
/* array section */
else {
$1->entry.Template.ll_ptr1 = $4;
$$ = $1; tp = make_type(fi, T_ARRAY);
tp->entry.ar_decl.base_type = $1->type->entry.ar_decl.base_type; /**18.03.17* $1->type */
tp->entry.ar_decl.num_dimensions = num_triplets;
$$->type = tp;
}
}
else err("can't subscript",44);
/* if ($$->variant == T_POINTER) {
l = $$;
$$ = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$$->type = l->type->entry.Template.base_type;
}
*/ /*11.02.03*/
endioctl();
}
| structure_component LEFTPAR funarglist RIGHTPAR
{ int num_triplets;
PTR_LLND l,l1,l2;
/* if ($1->variant == T_POINTER) {
l = $1;
$1 = make_llnd(fi, DEREF_OP, l, LLNULL, SMNULL);
$1->type = l->type->entry.Template.base_type;
} */
num_triplets = is_array_section_ref($3);
$$ = $1;
l2 = $1->entry.Template.ll_ptr2;
l1 = $1->entry.Template.ll_ptr1;
if(l2 && l2->type->variant == T_STRING)/*substring*/
if(num_triplets == 1){
l = make_llnd(fi, ARRAY_OP, LLNULL, LLNULL, SMNULL);
l->entry.Template.ll_ptr1 = l2;
l->entry.Template.ll_ptr2 = $3->entry.Template.ll_ptr1;
l->type = global_string;
$$->entry.Template.ll_ptr2 = l;
} else
err("Can't subscript",44);
else if (l2 && l2->type->variant == T_ARRAY) {
if(num_triplets > 0) { /*array section*/
$$->type = make_type(fi,T_ARRAY);
$$->type->entry.ar_decl.base_type = l2->type->entry.ar_decl.base_type;
$$->type->entry.ar_decl.num_dimensions = num_triplets;
l2->entry.Template.ll_ptr1 = $3;
l2->type = $$->type;
}
else { /*array element*/
l2->type = l2->type->entry.ar_decl.base_type;
l2->entry.Template.ll_ptr1 = $3;
if(l1->type->variant != T_ARRAY)
$$->type = l2->type;
}
} else
err("Can't subscript",44);
}
;
asubstring: ident substring
{
if ($1->type->variant == T_STRING) {
$1->entry.Template.ll_ptr1 = $2;
$$ = $1; $$->type = global_string;
}
else errstr("can't subscript of %s", $1->entry.Template.symbol->ident,44);
}
;
opt_substring:
{ $$ = LLNULL; }
| substring
{ $$ = $1; }
;
substring: LEFTPAR opt_expr COLON opt_expr RIGHTPAR
{ $$ = make_llnd(fi, DDOT, $2, $4, SMNULL); }
;
opt_expr:
{ $$ = LLNULL; }
| expr
{ $$ = $1; }
;
simple_const: numeric_bool_const
{ $$ = $1;}
| numeric_bool_const UNDER kind
{ PTR_TYPE t;
t = make_type_node($1->type, $3);
$$ = $1;
$$->type = t;
}
| integer_constant
{ $$ = $1; }
| integer_constant UNDER kind
{ PTR_TYPE t;
t = make_type_node($1->type, $3);
$$ = $1;
$$->type = t;
}
| string_constant opt_substring
{
if ($2 != LLNULL)
{
$$ = make_llnd(fi, ARRAY_OP, $1, $2, SMNULL);
$$->type = global_string;
}
else
$$ = $1;
}
;
numeric_bool_const:
TTRUE
{
$$ = make_llnd(fi,BOOL_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.bval = 1;
$$->type = global_bool;
}
| FFALSE
{
$$ = make_llnd(fi,BOOL_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.bval = 0;
$$->type = global_bool;
}
| REAL_CONSTANT
{
$$ = make_llnd(fi,FLOAT_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.string_val = copys(yytext);
$$->type = global_float;
}
| DP_CONSTANT
{
$$ = make_llnd(fi,DOUBLE_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.string_val = copys(yytext);
$$->type = global_double;
}
;
integer_constant: INT_CONSTANT
{
$$ = make_llnd(fi,INT_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.ival = atoi(yytext);
$$->type = global_int;
}
;
string_constant: CHAR_CONSTANT
{ PTR_TYPE t;
PTR_LLND p,q;
$$ = make_llnd(fi,STRING_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.string_val = copys(yytext);
if(yyquote=='\"')
t = global_string_2;
else
t = global_string;
p = make_llnd(fi,INT_VAL, LLNULL, LLNULL, SMNULL);
p->entry.ival = yyleng;
p->type = global_int;
q = make_llnd(fi, LEN_OP, p, LLNULL, SMNULL);
$$->type = make_type_node(t, q);
}
| ident UNDER CHAR_CONSTANT
{ PTR_TYPE t;
$$ = make_llnd(fi,STRING_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.string_val = copys(yytext);
if(yyquote=='\"')
t = global_string_2;
else
t = global_string;
$$->type = make_type_node(t, $1);
}
| integer_constant UNDER CHAR_CONSTANT
{ PTR_TYPE t;
$$ = make_llnd(fi,STRING_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.string_val = copys(yytext);
if(yyquote=='\"')
t = global_string_2;
else
t = global_string;
$$->type = make_type_node(t, $1);
}
;
complex_const: LEFTPAR uexpr COMMA uexpr RIGHTPAR
{
$$ = make_llnd(fi,COMPLEX_VAL, $2, $4, SMNULL);
$$->type = global_complex;
}
;
kind: ident
{ $$ = $1;}
| integer_constant
{ $$ = $1; }
;
/*
section: LEFTPAR triplets RIGHTPAR
{ $$ = $2; }
;
triplets:triplet
{ $$ = make_llnd(fi,EXPR_LIST, $1, LLNULL, SMNULL); }
| triplets COMMA triplet
{ $$ = set_ll_list($1, $3, EXPR_LIST); }*/
/* I changed uexpr to expr in below rule and triplet rules.
Don't know why Daya wrote it as uexpr. Srinivas. */
/* | triplets COMMA expr
{ $$ = set_ll_list($1, $3, EXPR_LIST); } */
/* Deleted. Purpose unknown. Srinivas.
| expr COMMA triplets
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;*/
triplet: expr COLON expr
{ $$ = make_llnd(fi,DDOT,$1,$3,SMNULL); }
| expr COLON
{ $$ = make_llnd(fi,DDOT,$1,LLNULL,SMNULL); }
| expr COLON expr COLON expr
{ $$ = make_llnd(fi,DDOT,make_llnd(fi,DDOT,$1,$3,SMNULL),$5,SMNULL); }
| expr COLON COLON expr
{ $$ = make_llnd(fi,DDOT,make_llnd(fi,DDOT,$1,LLNULL,SMNULL),$4,SMNULL); }
| COLON expr COLON expr
{ $$ = make_llnd(fi,DDOT, make_llnd(fi,DDOT,LLNULL,$2,SMNULL),$4,SMNULL); }
| COLON COLON expr
{ $$ = make_llnd(fi,DDOT,make_llnd(fi,DDOT,LLNULL,LLNULL,SMNULL),$3,SMNULL); }
| COLON expr
{ $$ = make_llnd(fi,DDOT,LLNULL,$2,SMNULL); }
| COLON
{ $$ = make_llnd(fi,DDOT,LLNULL,LLNULL,SMNULL); }
;
vec: LEFTAB end_ioctl {in_vec=YES;} outlist {in_vec=NO;} RIGHTAB
{ PTR_TYPE array_type;
$$ = make_llnd (fi,CONSTRUCTOR_REF,$4,LLNULL,SMNULL);
/*$$->type = $2->type;*/ /*28.02.03*/
array_type = make_type(fi, T_ARRAY);
array_type->entry.ar_decl.num_dimensions = 1;
if($4->type->variant == T_ARRAY)
array_type->entry.ar_decl.base_type = $4->type->entry.ar_decl.base_type;
else
array_type->entry.ar_decl.base_type = $4->type;
$$->type = array_type;
}
;
allocate_object: ident
{ $$ = $1; }
| structure_component
{ $$ = $1; }
;
/*
allocation_list: ident
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| structure_component
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
allocation_list: allocate_object
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
*/
/*allocation_list: array_element
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| allocation_list COMMA opt_key_word array_element
{ $$ = set_ll_list($1, $4, EXPR_LIST); opt_kwd_ = NO; }
| allocation_list COMMA opt_key_word STAT EQUAL ident
{ stat_alloc = $6; }
;
*/
allocation_list: array_element
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| allocation_list COMMA in_ioctl array_element
{ $$ = set_ll_list($1, $4, EXPR_LIST); endioctl(); }
| allocation_list COMMA in_ioctl nameeq ident
{ stat_alloc = make_llnd(fi, SPEC_PAIR, $4, $5, SMNULL);
endioctl();
}
;
/*allocate_object_list: allocate_object
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| allocate_object_list COMMA opt_key_word allocate_object
{ $$ = set_ll_list($1, $4, EXPR_LIST); opt_kwd_ = NO; }
| allocate_object_list COMMA opt_key_word STAT EQUAL ident
{ stat_alloc = $6; }
;
*/
allocate_object_list: allocate_object
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| allocate_object_list COMMA in_ioctl allocate_object
{ $$ = set_ll_list($1, $4, EXPR_LIST); endioctl(); }
| allocate_object_list COMMA in_ioctl nameeq ident
{ stat_alloc = make_llnd(fi, SPEC_PAIR, $4, $5, SMNULL);
endioctl();
}
;
/*
opt_stat_spec:
{ $$ = LLNULL; }
| COMMA needkeyword STAT EQUAL ident
{ $$ = $5; }
;
*/
stat_spec:
{stat_alloc = LLNULL;}
;
pointer_name_list: ident
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| pointer_name_list COMMA ident
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
/*
* Grammar for executable statements
*/
exec: iffable
{ $$ = $1; }
| whereable
{ $$ = $1; }
| plain_do
{ $$ = $1; }
| construct_name_colon plain_do
{
$$ = $2;
$$->entry.Template.ll_ptr3 = $1;
}
/*
| PLAINDO end_spec intonlyon dotarget intonlyoff opt_comma do_var EQUAL expr COMMA expr
{
if(!$4){
err("No label in DO statement");
$$ = BFNULL;
}
else {
if( $4->labdefined)
execerr("no backward DO loops", (char *)NULL);
$$ = make_do(FOR_NODE, $4, $7, $9, $11, NULL);
}
}
| PLAINDO end_spec intonlyon dotarget intonlyoff opt_comma do_var EQUAL expr COMMA expr COMMA expr
{
if(!$4){
err("No label in DO statement");
$$ = BFNULL;
}
else {
if( $4->labdefined)
execerr("no backward DO loops", (char *)NULL);
$$ = make_do(FOR_NODE, $4, $7, $9, $11, $13);
}
}
*/
/* PROCESSDO added for FORTRAN M
| opt_construct_name_colon PROCESSDO end_spec intonlyon dotarget intonlyoff opt_comma do_var EQUAL expr COMMA expr
{
if( !do_name_err ) {
if($5 && $5->labdefined)
err("No backward DO loops", 46);
$$ = make_processdo(PROCESS_DO_STAT, $5, $8, $10, $12, NULL);
$$->entry.Template.ll_ptr3 = $1;
}
}
| opt_construct_name_colon PROCESSDO end_spec intonlyon dotarget intonlyoff opt_comma do_var EQUAL expr COMMA expr COMMA expr
{
if( !do_name_err ) {
if($5 && $5->labdefined)
err("No backward DO loops", 46);
$$ = make_processdo(PROCESS_DO_STAT, $5, $8, $10, $12, $14);
$$->entry.Template.ll_ptr3 = $1;
}
}
*/
| ENDUNIT end_spec opt_unit_name
{ PTR_BFND biff;
$$ = get_bfnd(fi,CONTROL_END, SMNULL, LLNULL, LLNULL, LLNULL);
bind();
biff = cur_scope();
if ((biff->variant == FUNC_HEDR) || (biff->variant == PROC_HEDR)
|| (biff->variant == PROS_HEDR)
|| (biff->variant == PROG_HEDR)
|| (biff->variant == BLOCK_DATA)) {
if(biff->control_parent == global_bfnd) position = IN_OUTSIDE;
else if(!is_interface_stat(biff->control_parent)) position++;
} else if (biff->variant == MODULE_STMT)
position = IN_OUTSIDE;
else err("Unexpected END statement read", 52);
/* FB ADDED set the control parent so the empty function unparse right*/
if ($$)
$$->control_parent = biff;
delete_beyond_scope_level(pred_bfnd);
}
| ENDDO end_spec opt_construct_name
/* { $$ = get_bfnd(fi,CONTROL_END, SMNULL, LLNULL, LLNULL, LLNULL);}*/
/* Had to be changed to accomodate PCF's do loops. */
{
make_extend($3);
$$ = BFNULL;
/* delete_beyond_scope_level(pred_bfnd); */
}
/* ENDPROCESSDO was added by C.Y.Chen
| ENDPROCESSDO end_spec
{ $$ = make_enddoall(); }
*/
/* end module is bit different. So shouldn't have end_spec. */
/* It may be better to move it to spec. */
| ENDMODULE opt_unit_name
{ $$ = get_bfnd(fi,CONTROL_END, SMNULL, LLNULL, LLNULL, LLNULL);
bind();
delete_beyond_scope_level(pred_bfnd);
position = IN_OUTSIDE;
}
/*
| opt_construct_name_colon DOWHILE end_spec needkeyword intonlyon dotarget intonlyoff WHILE LEFTPAR expr RIGHTPAR */
| do_while
{ $$ = $1; }
| construct_name_colon do_while
{
$$ = $2;
$$->entry.Template.ll_ptr3 = $1;
}
/* | CDOALL do_var EQUAL expr COMMA expr
{$$ = make_do(CDOALL_NODE, NULL, $2, $4, $6, NULL);
add_scope_level($$, NO);
}
| CDOALL do_var EQUAL expr COMMA expr COMMA expr
{$$ = make_do(CDOALL_NODE, NULL, $2, $4, $6, $8);
add_scope_level($$, NO);
}
| SDOALL do_var EQUAL expr COMMA expr
{$$ = make_do(SDOALL_NODE, NULL, $2, $4, $6, NULL);
add_scope_level($$, NO);
}
| SDOALL do_var EQUAL expr COMMA expr COMMA expr
{$$ = make_do(SDOALL_NODE, NULL, $2, $4, $6, $8);
add_scope_level($$, NO);
}
| DOACROSS do_var EQUAL expr COMMA expr
{$$ = make_do(DOACROSS_NODE, NULL, $2, $4, $6, NULL);
add_scope_level($$, NO);
}
| DOACROSS do_var EQUAL expr COMMA expr COMMA expr
{$$ = make_do(DOACROSS_NODE, NULL, $2, $4, $6, $8);
add_scope_level($$, NO);
}
| CDOACROSS do_var EQUAL expr COMMA expr
{$$ = make_do(CDOACROSS_NODE, NULL, $2, $4, $6, NULL);
add_scope_level($$, NO);
}
| CDOACROSS do_var EQUAL expr COMMA expr COMMA expr
{$$ = make_do(CDOACROSS_NODE, NULL, $2, $4, $6, $8);
add_scope_level($$, NO);
}
| LOOP
{
make_loop();
$$ = BFNULL;
}
| enddoall
{ $$ = make_enddoall();
delete_beyond_scope_level(pred_bfnd);
}
*/
| logif iffable
{ thiswasbranch = NO;
$1->variant = LOGIF_NODE;
$$ = make_logif($1, $2);
set_blobs($1, pred_bfnd, SAME_GROUP);
}
| logif THEN
{
$$ = $1;
set_blobs($$, pred_bfnd, NEW_GROUP1);
}
| construct_name_colon logif THEN
{
$$ = $2;
$$->entry.Template.ll_ptr3 = $1;
set_blobs($$, pred_bfnd, NEW_GROUP1);
}
/* | CONSTRUCT_ID COLON logif THEN
{ PTR_SYMB s;
PTR_LLND l;
s = make_local_entity(look_up_sym(yytext), CONSTRUCT_NAME, global_default, LOCAL);
l = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
* $$ = make_if($3); *
$3->entry.Template.ll_ptr3 = l;
$$ = $3;
set_blobs($$, pred_bfnd, NEW_GROUP1);
}
*/
| ELSEIF end_spec LEFTPAR expr RIGHTPAR THEN opt_construct_name
{ make_elseif($4,$7); lastwasbranch = NO; $$ = BFNULL;}
| ELSE end_spec opt_construct_name
{ make_else($3); lastwasbranch = NO; $$ = BFNULL; }
| ENDIF end_spec opt_construct_name
{ make_endif($3); $$ = BFNULL; }
| case
{ $$ = $1; }
| CONTAINS end_spec
{ $$ = get_bfnd(fi, CONTAINS_STMT, SMNULL, LLNULL, LLNULL, LLNULL); }
| forall iffable
{ thiswasbranch = NO;
$1->variant = FORALL_STAT;
$$ = make_logif($1, $2);
set_blobs($1, pred_bfnd, SAME_GROUP);
}
| forall
{ $$ = $1; }
| construct_name_colon forall
{ $$ = $2; $$->entry.Template.ll_ptr3 = $1;}
| ENDFORALL end_spec opt_construct_name
{ make_endforall($3); $$ = BFNULL; }
| dvm_exec
{ $$ = $1; }
| acc_directive
{ $$ = $1; }
| spf_directive
{ $$ = $1; }
;
/*
do_while: DOWHILE end_spec LEFTPAR expr RIGHTPAR
{
$$ = make_do(WHILE_NODE, LBNULL, SMNULL, $4, LLNULL, LLNULL);
}
| DOWHILE end_spec intonlyon dotarget intonlyoff needkeyword WHILE LEFTPAR expr RIGHTPAR
{
if($4 && $4->labdefined)
execerr("no backward DO loops", (char *)NULL);
$$ = make_do(WHILE_NODE, $4, SMNULL, $9, LLNULL, LLNULL);
}
| DOWHILE end_spec intonlyon dotarget intonlyoff
{
if( $4 && $4->labdefined)
err("No backward DO loops", 46);
$$ = make_do(WHILE_NODE, $4, SMNULL, LLNULL, LLNULL, LLNULL);
}
;
*/
do_while: DOWHILE end_spec LEFTPAR expr RIGHTPAR
{
/* if($5 && $5->labdefined)
execerr("no backward DO loops", (char *)NULL); */
$$ = make_do(WHILE_NODE, LBNULL, SMNULL, $4, LLNULL, LLNULL);
/*$$->entry.Template.ll_ptr3 = $1;*/
}
| DOWHILE end_spec intonlyon dotarget intonlyoff opt_key_word opt_while
{
if( $4 && $4->labdefined)
err("No backward DO loops", 46);
$$ = make_do(WHILE_NODE, $4, SMNULL, $7, LLNULL, LLNULL);
}
;
opt_while:
{ $$ = LLNULL; }
| COMMA needkeyword WHILE LEFTPAR expr RIGHTPAR
{ $$ = $5;}
| WHILE LEFTPAR expr RIGHTPAR
{ $$ = $3;}
;
plain_do: PLAINDO end_spec intonlyon dotarget intonlyoff opt_comma do_var EQUAL expr COMMA expr
{
if( $4 && $4->labdefined)
err("No backward DO loops", 46);
$$ = make_do(FOR_NODE, $4, $7, $9, $11, LLNULL);
}
| PLAINDO end_spec intonlyon dotarget intonlyoff opt_comma do_var EQUAL expr COMMA expr COMMA expr
{
if( $4 && $4->labdefined)
err("No backward DO loops", 46);
$$ = make_do(FOR_NODE, $4, $7, $9, $11, $13);
}
;
case: CASE end_spec case_selector opt_construct_name
{ $$ = get_bfnd(fi, CASE_NODE, $4, $3, LLNULL, LLNULL); }
| DEFAULT_CASE end_spec opt_construct_name
{ /*PTR_LLND p;*/
/* p = make_llnd(fi, DEFAULT, LLNULL, LLNULL, SMNULL); */
$$ = get_bfnd(fi, DEFAULT_NODE, $3, LLNULL, LLNULL, LLNULL); }
| ENDSELECT end_spec opt_construct_name
{ make_endselect($3); $$ = BFNULL; }
/* { $$ = get_bfnd(fi, CONTROL_END, $3, LLNULL, LLNULL, LLNULL); }*/
| SELECT end_spec needkeyword CASE LEFTPAR expr RIGHTPAR
{ $$ = get_bfnd(fi, SWITCH_NODE, SMNULL, $6, LLNULL, LLNULL) ; }
| construct_name_colon SELECT end_spec needkeyword CASE LEFTPAR expr RIGHTPAR
{ $$ = get_bfnd(fi, SWITCH_NODE, SMNULL, $7, LLNULL, $1) ; }
;
case_selector: LEFTPAR case_value_range_list RIGHTPAR
{ $$ = $2; }
/* | DEFAULT_CASE
{ $$ = make_llnd(fi, DEFAULT, LLNULL, LLNULL, SMNULL); }
*/ ;
case_value_range: expr
{ $$ = $1; }
| expr COLON
{ $$ = make_llnd(fi, DDOT, $1, LLNULL, SMNULL); }
| COLON expr
{ $$ = make_llnd(fi, DDOT, LLNULL, $2, SMNULL); }
| expr COLON expr
{ $$ = make_llnd(fi, DDOT, $1, $3, SMNULL); }
;
case_value_range_list: case_value_range
{ $$ = make_llnd(fi, EXPR_LIST, $1, LLNULL, SMNULL); }
| case_value_range_list COMMA case_value_range
{ PTR_LLND p;
p = make_llnd(fi, EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(p, $1);
}
;
opt_construct_name:
{ $$ = SMNULL; }
| name
{ $$ = make_local_entity($1, CONSTRUCT_NAME, global_default,
LOCAL); }
;
opt_unit_name:
{$$ = HSNULL;}
| name
{ $$ = $1;}
;
construct_name: CONSTRUCT_ID
{$$ = look_up_sym(yytext);}
;
construct_name_colon: construct_name COLON
{ PTR_SYMB s;
s = make_local_entity( $1, CONSTRUCT_NAME, global_default, LOCAL);
$$ = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
}
;
/*
opt_construct_name_colon:
{ $$ = LLNULL; }
| construct_name COLON
{ PTR_SYMB s;
s = make_local_entity( $1, CONSTRUCT_NAME, global_default, LOCAL);
$$ = make_llnd(fi, VAR_REF, LLNULL, LLNULL, s);
}
;
*/
/*
optkeyword:
{opt_kwd_ = YES;}
;
*/
logif: LOGICALIF end_spec LEFTPAR expr RIGHTPAR
{ $$ = make_if($4); }
;
forall: FORALL end_spec LEFTPAR forall_list opt_forall_cond RIGHTPAR
{ $$ = make_forall($4,$5); }
;
forall_list: forall_expr
{ $$ = make_llnd(fi, EXPR_LIST, $1, LLNULL, SMNULL); }
| forall_list COMMA forall_expr
{ PTR_LLND p;
p = make_llnd(fi, EXPR_LIST, $3, LLNULL, SMNULL);
add_to_lowLevelList(p, $1);
}
;
forall_expr: do_var EQUAL triplet
{$$ = make_llnd(fi, FORALL_OP, $3, LLNULL, $1); }
;
opt_forall_cond:
{ $$=LLNULL;}
| COMMA expr
{ $$=$2;}
;
/*
enddoall: ENDCDOALL
| ENDSDOALL
| ENDDOACROSS
| ENDCDOACROSS
;
*/
do_var: name
{ PTR_SYMB s;
s = $1->id_attr;
if (!s || s->variant == DEFAULT)
{
s = make_scalar($1, TYNULL, LOCAL);
s->decl = SOFT;
}
$$ = s;
}
;
dospec: do_var EQUAL expr COMMA expr
/* name EQUAL expr COMMA expr*/ /*16.02.03*/
{ PTR_SYMB s;
PTR_LLND l;
int vrnt;
/* s = make_scalar($1, TYNULL, LOCAL);*/ /*16.02.03*/
s = $1;
if (s->variant != CONST_NAME) {
if(in_vec)
vrnt=SEQ;
else
vrnt=DDOT;
l = make_llnd(fi, SEQ, make_llnd(fi, vrnt, $3, $5, SMNULL),
LLNULL, SMNULL);
$$ = make_llnd(fi,IOACCESS, LLNULL, l, s);
do_name_err = NO;
}
else {
err("Symbolic constant not allowed as DO variable", 47);
do_name_err = YES;
}
}
| do_var EQUAL expr COMMA expr COMMA expr
/*name EQUAL expr COMMA expr COMMA expr*/ /*16.02.03*/
{ PTR_SYMB s;
PTR_LLND l;
int vrnt;
/*s = make_scalar($1, TYNULL, LOCAL);*/ /*16.02.03*/
s = $1;
if( s->variant != CONST_NAME ) {
if(in_vec)
vrnt=SEQ;
else
vrnt=DDOT;
l = make_llnd(fi, SEQ, make_llnd(fi, vrnt, $3, $5, SMNULL), $7,
SMNULL);
$$ = make_llnd(fi,IOACCESS, LLNULL, l, s);
do_name_err = NO;
}
else {
err("Symbolic constant not allowed as DO variable", 47);
do_name_err = YES;
}
}
;
dotarget: { $$ = LBNULL; }
| INT_CONSTANT
{
$$ = make_label_node(fi,convci(yyleng, yytext));
$$->scope = cur_scope();
}
;
whereable: ENDWHERE end_spec opt_construct_name
{ make_endwhere($3); $$ = BFNULL; }
| ELSEWHERE end_spec opt_construct_name
{ make_elsewhere($3); lastwasbranch = NO; $$ = BFNULL; }
| ELSEWHERE end_spec LEFTPAR expr RIGHTPAR opt_construct_name
{ make_elsewhere_mask($4,$6); lastwasbranch = NO; $$ = BFNULL; }
| WHERE end_spec LEFTPAR expr RIGHTPAR
{ $$ = get_bfnd(fi, WHERE_BLOCK_STMT, SMNULL, $4, LLNULL, LLNULL); }
| construct_name_colon WHERE end_spec LEFTPAR expr RIGHTPAR
{ $$ = get_bfnd(fi, WHERE_BLOCK_STMT, SMNULL, $5, LLNULL, $1); }
;
iffable: let expr EQUAL expr
/* let lhs EQUAL expr */
{ PTR_LLND p, r;
PTR_SYMB s1, s2 = SMNULL, s3, arg_list;
PTR_HASH hash_entry;
/* if (just_look_up_sym("=") != HSNULL) {
p = intrinsic_op_node("=", EQUAL, $2, $4);
$$ = get_bfnd(fi, OVERLOADED_ASSIGN_STAT, SMNULL, p, $2, $4);
}
else */ if ($2->variant == FUNC_CALL) {
if(parstate==INEXEC){
err("Declaration among executables", 30);
/* $$=BFNULL;*/
$$ = get_bfnd(fi,STMTFN_STAT, SMNULL, $2, LLNULL, LLNULL);
}
else {
$2->variant = STMTFN_DECL;
/* $2->entry.Template.ll_ptr2 = $4; */
if( $2->entry.Template.ll_ptr1) {
r = $2->entry.Template.ll_ptr1->entry.Template.ll_ptr1;
if(r->variant != VAR_REF && r->variant != ARRAY_REF){
err("A dummy argument of a statement function must be a scalar identifier", 333);
s1 = SMNULL;
}
else
s1 = r ->entry.Template.symbol;
} else
s1 = SMNULL;
if (s1)
s1->scope = cur_scope();
$$ = get_bfnd(fi,STMTFN_STAT, SMNULL, $2, LLNULL, LLNULL);
add_scope_level($$, NO);
arg_list = SMNULL;
if (s1)
{
/*arg_list = SMNULL;*/
p = $2->entry.Template.ll_ptr1;
while (p != LLNULL)
{
/* if (p->entry.Template.ll_ptr1->variant != VAR_REF) {
errstr("cftn.gram:1: illegal statement function %s.", $2->entry.Template.symbol->ident);
break;
}
*/
r = p->entry.Template.ll_ptr1;
if(r->variant != VAR_REF && r->variant != ARRAY_REF){
err("A dummy argument of a statement function must be a scalar identifier", 333);
break;
}
hash_entry = look_up_sym(r->entry.Template.symbol->parent->ident);
s3 = make_scalar(hash_entry, s1->type, IO);
replace_symbol_in_expr(s3,$4);
if (arg_list == SMNULL)
s2 = arg_list = s3;
else
{
s2->id_list = s3;
s2 = s3;
}
p = p->entry.Template.ll_ptr2;
}
}
$2->entry.Template.ll_ptr1 = $4;
install_param_list($2->entry.Template.symbol,
arg_list, LLNULL, FUNCTION_NAME);
delete_beyond_scope_level($$);
/* else
errstr("cftn.gram: Illegal statement function declaration %s.", $2->entry.Template.symbol->ident); */
}
}
else {
$$ = get_bfnd(fi,ASSIGN_STAT,SMNULL, $2, $4, LLNULL);
parstate = INEXEC;
}
}
| POINTERLET end_spec lhs POINT_TO expr
{ /*PTR_SYMB s;*/
/*s = make_scalar($2, TYNULL, LOCAL);*/
$$ = get_bfnd(fi, POINTER_ASSIGN_STAT, SMNULL, $3, $5, LLNULL);
}
/* | let lhs EQUAL vec
{ if ($2->variant == ARRAY_REF)
$$ = get_bfnd(fi,ASSIGN_STAT,SMNULL, $2, $4, LLNULL);
else err("Constructor reference");
}
*/ | ASSIGN end_spec label TO name
{ PTR_SYMB p;
p = make_scalar($5, TYNULL, LOCAL);
p->variant = LABEL_VAR;
$$ = get_bfnd(fi,ASSLAB_STAT, p, $3,LLNULL,LLNULL);
}
| CONTINUE end_spec
{ $$ = get_bfnd(fi,CONT_STAT,SMNULL,LLNULL,LLNULL,LLNULL); }
| goto
| io
{ inioctl = NO; }
| ARITHIF end_spec LEFTPAR expr RIGHTPAR label COMMA label COMMA label
{ PTR_LLND p;
p = make_llnd(fi,EXPR_LIST, $10, LLNULL, SMNULL);
p = make_llnd(fi,EXPR_LIST, $8, p, SMNULL);
$$= get_bfnd(fi,ARITHIF_NODE, SMNULL, $4,
make_llnd(fi,EXPR_LIST, $6, p, SMNULL), LLNULL);
thiswasbranch = YES;
}
| call
{
$$ = subroutine_call($1, LLNULL, LLNULL, PLAIN);
/* match_parameters($1, LLNULL);
$$= get_bfnd(fi,PROC_STAT, $1, LLNULL, LLNULL, LLNULL);
*/ endioctl();
}
| call LEFTPAR RIGHTPAR
{
$$ = subroutine_call($1, LLNULL, LLNULL, PLAIN);
/* match_parameters($1, LLNULL);
$$= get_bfnd(fi,PROC_STAT,$1,LLNULL,LLNULL,LLNULL);
*/ endioctl();
}
| call LEFTPAR callarglist RIGHTPAR
{
$$ = subroutine_call($1, $3, LLNULL, PLAIN);
/* match_parameters($1, $3);
$$= get_bfnd(fi,PROC_STAT,$1,$3,LLNULL,LLNULL);
*/ endioctl();
}
| RETURN end_spec opt_expr
{
$$ = get_bfnd(fi,RETURN_STAT,SMNULL,$3,LLNULL,LLNULL);
thiswasbranch = YES;
}
| stop end_spec opt_expr
{
$$ = get_bfnd(fi,$1,SMNULL,$3,LLNULL,LLNULL);
thiswasbranch = ($1 == STOP_STAT);
}
| CYCLE end_spec opt_construct_name
{ $$ = get_bfnd(fi, CYCLE_STMT, $3, LLNULL, LLNULL, LLNULL); }
| EXIT end_spec opt_construct_name
{ $$ = get_bfnd(fi, EXIT_STMT, $3, LLNULL, LLNULL, LLNULL); }
| ALLOCATE end_spec LEFTPAR stat_spec allocation_list RIGHTPAR
{ $$ = get_bfnd(fi, ALLOCATE_STMT, SMNULL, $5, stat_alloc, LLNULL); }
| DEALLOCATE end_spec LEFTPAR stat_spec allocate_object_list RIGHTPAR
{ $$ = get_bfnd(fi, DEALLOCATE_STMT, SMNULL, $5, stat_alloc , LLNULL); }
| NULLIFY end_spec LEFTPAR pointer_name_list RIGHTPAR
{ $$ = get_bfnd(fi, NULLIFY_STMT, SMNULL, $4, LLNULL, LLNULL); }
| WHERE_ASSIGN end_spec LEFTPAR expr RIGHTPAR lhs EQUAL expr
{ $$ = get_bfnd(fi, WHERE_NODE, SMNULL, $4, $6, $8); }
;
let: LET in_data
/*
{ if(parstate == OUTSIDE)
{ PTR_BFND p;
p = get_bfnd(fi,PROG_HEDR, make_program(look_up_sym("_MAIN")), LLNULL, LLNULL, LLNULL);
set_blobs(p, global_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
position = IN_PROC;
}
if(parstate < INDATA) enddcl();
parstate = INEXEC;
yystno = 0;
}
*/
{$$ = LLNULL;}
;
goto: PLAINGOTO end_spec label
{
$$=get_bfnd(fi,GOTO_NODE,SMNULL,LLNULL,LLNULL,(PTR_LLND)$3);
thiswasbranch = YES;
}
| ASSIGNGOTO end_spec name
{ PTR_SYMB p;
if($3->id_attr)
p = $3->id_attr;
else {
p = make_scalar($3, TYNULL, LOCAL);
p->variant = LABEL_VAR;
}
if(p->variant == LABEL_VAR) {
$$ = get_bfnd(fi,ASSGOTO_NODE,p,LLNULL,LLNULL,LLNULL);
thiswasbranch = YES;
}
else {
err("Must go to assigned variable", 48);
$$ = BFNULL;
}
}
| ASSIGNGOTO end_spec name opt_comma LEFTPAR labellist RIGHTPAR
{ PTR_SYMB p;
if($3->id_attr)
p = $3->id_attr;
else {
p = make_scalar($3, TYNULL, LOCAL);
p->variant = LABEL_VAR;
}
if (p->variant == LABEL_VAR) {
$$ = get_bfnd(fi,ASSGOTO_NODE,p,$6,LLNULL,LLNULL);
thiswasbranch = YES;
}
else {
err("Must go to assigned variable",48);
$$ = BFNULL;
}
}
| COMPGOTO end_spec LEFTPAR labellist RIGHTPAR opt_comma expr
{ $$ = get_bfnd(fi,COMGOTO_NODE, SMNULL, $4, $7, LLNULL); }
;
opt_comma:
| COMMA
;
call: CALL end_spec name in_ioctl
{ $$ = make_procedure($3, LOCAL); }
;
callarglist: in_ioctl callarg
{
$$ = set_ll_list($2, LLNULL, EXPR_LIST);
endioctl();
}
| callarglist COMMA in_ioctl callarg
{
$$ = set_ll_list($1, $4, EXPR_LIST);
endioctl();
}
;
callarg: expr
{ $$ = $1; }
| nameeq expr
{ $$ = make_llnd(fi, KEYWORD_ARG, $1, $2, SMNULL); }
| ASTER label
{ $$ = make_llnd(fi,LABEL_ARG,$2,LLNULL,SMNULL); }
;
stop: PAUSE { $$ = PAUSE_NODE; }
| STOP { $$ = STOP_STAT; }
;
/*
exprlist: expr
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); }
| exprlist COMMA expr
{ $$ = set_ll_list($1, $3, EXPR_LIST); }
;
*/
end_spec:
{ if(parstate == OUTSIDE)
{ PTR_BFND p;
p = get_bfnd(fi,PROG_HEDR, make_program(look_up_sym("_MAIN")), LLNULL, LLNULL, LLNULL);
set_blobs(p, global_bfnd, NEW_GROUP1);
add_scope_level(p, NO);
position = IN_PROC;
}
if(parstate < INDATA) enddcl();
parstate = INEXEC;
yystno = 0;
}
;
intonlyon:
{ intonly = YES; }
;
intonlyoff:
{ intonly = NO; }
;
/*
* Grammar for Input/Output statements
*/
io: iofmove ioctl
{ $1->entry.Template.ll_ptr2 = $2;
$$ = $1; }
| iofmove unpar_fexpr
{ PTR_LLND p, q = LLNULL;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
q->entry.string_val = (char *)"unit";
q->type = global_string;
p = make_llnd(fi, SPEC_PAIR, q, $2, SMNULL);
$1->entry.Template.ll_ptr2 = p;
endioctl();
$$ = $1; }
| iofmove ASTER
{ PTR_LLND p, q, r;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"*";
p->type = global_string;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
q->entry.string_val = (char *)"unit";
q->type = global_string;
r = make_llnd(fi, SPEC_PAIR, p, q, SMNULL);
$1->entry.Template.ll_ptr2 = r;
endioctl();
$$ = $1; }
| iofmove DASTER
{ PTR_LLND p, q, r;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"**";
p->type = global_string;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
q->entry.string_val = (char *)"unit";
q->type = global_string;
r = make_llnd(fi, SPEC_PAIR, p, q, SMNULL);
$1->entry.Template.ll_ptr2 = r;
endioctl();
$$ = $1; }
| iofctl ioctl
{ $1->entry.Template.ll_ptr2 = $2;
$$ = $1; }
| inquire
{ $$ = $1; }
| read ioctl
{ $1->entry.Template.ll_ptr2 = $2;
$$ = $1; }
| read infmt
{ $1->entry.Template.ll_ptr2 = $2;
$$ = $1; }
| read ioctl inlist
{ $1->entry.Template.ll_ptr2 = $2;
$1->entry.Template.ll_ptr1 = $3;
$$ = $1; }
| read infmt COMMA inlist
{ $1->entry.Template.ll_ptr2 = $2;
$1->entry.Template.ll_ptr1 = $4;
$$ = $1; }
/* | read ioctl COMMA inlist Not needed
{ $1->entry.Template.ll_ptr2 = $2;
$1->entry.Template.ll_ptr1 = $4;
$$ = $1; }
*/
| write ioctl
{ $1->entry.Template.ll_ptr2 = $2;
$$ = $1; }
| write ioctl outlist
{ $1->entry.Template.ll_ptr2 = $2;
$1->entry.Template.ll_ptr1 = $3;
$$ = $1; }
| print
{ $$ = $1; }
| print COMMA outlist
{ $1->entry.Template.ll_ptr1 = $3;
$$ = $1; }
;
iofmove: fmkwd end_spec start_ioctl
{ $$ = $1; }
;
fmkwd: BACKSPACE
{$$ = get_bfnd(fi, BACKSPACE_STAT, SMNULL, LLNULL, LLNULL, LLNULL);}
| REWIND
{$$ = get_bfnd(fi, REWIND_STAT, SMNULL, LLNULL, LLNULL, LLNULL);}
| ENDFILE
{$$ = get_bfnd(fi, ENDFILE_STAT, SMNULL, LLNULL, LLNULL, LLNULL);}
/* | SKIPPASTEOF
{$$ = get_bfnd(fi, SKIPPASTEOF_NODE, SMNULL, LLNULL, LLNULL, LLNULL); }
*/
;
iofctl: ctlkwd end_spec start_ioctl
{ $$ = $1; }
;
ctlkwd: OPEN
{$$ = get_bfnd(fi, OPEN_STAT, SMNULL, LLNULL, LLNULL, LLNULL);}
| CLOSE
{$$ = get_bfnd(fi, CLOSE_STAT, SMNULL, LLNULL, LLNULL, LLNULL);}
;
inquire: INQUIRE end_spec start_ioctl ioctl
{ $$ = get_bfnd(fi, INQUIRE_STAT, SMNULL, LLNULL, $4, LLNULL);}
| INQUIRE end_spec start_ioctl ioctl outlist
{ $$ = get_bfnd(fi, INQUIRE_STAT, SMNULL, $5, $4, LLNULL);}
;
infmt: unpar_fexpr
{ PTR_LLND p;
PTR_LLND q = LLNULL;
if ($1->variant == INT_VAL)
{
PTR_LABEL r;
r = make_label_node(fi, (long) $1->entry.ival);
r->scope = cur_scope();
p = make_llnd_label(fi, LABEL_REF, r);
}
else p = $1;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
q->entry.string_val = (char *)"fmt";
q->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, q, p, SMNULL);
endioctl();
}
| ASTER
{ PTR_LLND p;
PTR_LLND q;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"*";
p->type = global_string;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
q->entry.string_val = (char *)"fmt";
q->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, q, p, SMNULL);
endioctl();
}
;
ioctl: LEFTPAR fexpr RIGHTPAR
{ PTR_LLND p;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"unit";
p->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, p, $2, SMNULL);
endioctl();
}
| LEFTPAR ctllist RIGHTPAR
/*ioctl: LEFTPAR ctllist RIGHTPAR*/
{
$$ = $2;
endioctl();
}
;
ctllist: ioclause
{ $$ = $1; endioctl();}
| ctllist COMMA in_ioctl ioclause
{ $$ = set_ll_list($1, $4, EXPR_LIST); endioctl();}
;
ioclause: fexpr
{ PTR_LLND p;
PTR_LLND q;
nioctl++;
if ((nioctl == 2) && ($1->variant == INT_VAL))
{
PTR_LABEL r;
r = make_label_node(fi, (long) $1->entry.ival);
r->scope = cur_scope();
p = make_llnd_label(fi, LABEL_REF, r);
}
else p = $1;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
if (nioctl == 1)
q->entry.string_val = (char *)"unit";
else {
if(($1->variant == VAR_REF) && $1->entry.Template.symbol->variant == NAMELIST_NAME)
q->entry.string_val = (char *)"nml";
else
q->entry.string_val = (char *)"fmt";
}
q->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, q, p, SMNULL);
}
| ASTER
{ PTR_LLND p;
PTR_LLND q;
nioctl++;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"*";
p->type = global_string;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
if (nioctl == 1)
q->entry.string_val = (char *)"unit";
else q->entry.string_val = (char *)"fmt";
q->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, q, p, SMNULL);
}
| DASTER
{ PTR_LLND p;
PTR_LLND q;
nioctl++;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"**";
p->type = global_string;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
if (nioctl == 1)
q->entry.string_val = (char *)"unit";
else q->entry.string_val = (char *)"fmt";
q->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, q, p, SMNULL);
}
| nameeq expr
{
PTR_LLND p;
char *q;
q = $1->entry.string_val;
if ((strcmp(q, "end") == 0) || (strcmp(q, "err") == 0) || (strcmp(q, "eor") == 0) || ((strcmp(q,"fmt") == 0) && ($2->variant == INT_VAL)))
{
PTR_LABEL r;
r = make_label_node(fi, (long) $2->entry.ival);
r->scope = cur_scope();
p = make_llnd_label(fi, LABEL_REF, r);
}
else p = $2;
$$ = make_llnd(fi, SPEC_PAIR, $1, p, SMNULL); }
| nameeq ASTER
{ PTR_LLND p;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"*";
p->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, $1, p, SMNULL);
}
| nameeq DASTER
{ PTR_LLND p;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"*";
p->type = global_string;
$$ = make_llnd(fi, SPEC_PAIR, $1, p, SMNULL);
}
;
nameeq: NAMEEQ
{ $$ = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
$$->entry.string_val = copys(yytext);
$$->type = global_string;
}
;
read: READ end_spec start_ioctl
{$$ = get_bfnd(fi, READ_STAT, SMNULL, LLNULL, LLNULL, LLNULL);}
;
write: WRITE end_spec start_ioctl
{$$ = get_bfnd(fi, WRITE_STAT, SMNULL, LLNULL, LLNULL, LLNULL);}
;
print: PRINT end_spec fexpr start_ioctl
{
PTR_LLND p, q, l;
if ($3->variant == INT_VAL)
{
PTR_LABEL r;
r = make_label_node(fi, (long) $3->entry.ival);
r->scope = cur_scope();
p = make_llnd_label(fi, LABEL_REF, r);
}
else p = $3;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
q->entry.string_val = (char *)"fmt";
q->type = global_string;
l = make_llnd(fi, SPEC_PAIR, q, p, SMNULL);
$$ = get_bfnd(fi, PRINT_STAT, SMNULL, LLNULL, l, LLNULL);
endioctl();
}
| PRINT end_spec ASTER start_ioctl
{ PTR_LLND p, q, r;
p = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
p->entry.string_val = (char *)"*";
p->type = global_string;
q = make_llnd(fi, KEYWORD_VAL, LLNULL, LLNULL, SMNULL);
q->entry.string_val = (char *)"fmt";
q->type = global_string;
r = make_llnd(fi, SPEC_PAIR, q, p, SMNULL);
$$ = get_bfnd(fi, PRINT_STAT, SMNULL, LLNULL, r, LLNULL);
endioctl();
}
;
inlist: inelt
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST);}
| inlist COMMA inelt
{ $$ = set_ll_list($1, $3, EXPR_LIST);}
;
inelt: lhs
{ $$ = $1; }
| LEFTPAR inlist COMMA dospec RIGHTPAR
{
$4->entry.Template.ll_ptr1 = $2;
$$ = $4;
}
;
outlist: uexpr
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST); $$->type = $1->type;}
| other
{ $$ = $1; }
| out2
{ $$ = $1; }
;
out2: uexpr COMMA uexpr
{ $$ = set_ll_list($1, $3, EXPR_LIST); $$->type = $1->type;}
| uexpr COMMA other
{ $$ = set_ll_list($1, $3, EXPR_LIST); $$->type = $1->type;}
| other COMMA uexpr
{ $$ = set_ll_list($1, $3, EXPR_LIST); $$->type = $1->type;}
| other COMMA other
{ $$ = set_ll_list($1, $3, EXPR_LIST); $$->type = $1->type;}
| out2 COMMA uexpr
{ $$ = set_ll_list($1, $3, EXPR_LIST); $$->type = $1->type;}
| out2 COMMA other
{ $$ = set_ll_list($1, $3, EXPR_LIST); $$->type = $1->type;}
;
other: complex_const
{ $$ = set_ll_list($1, LLNULL, EXPR_LIST);
$$->type = global_complex; }
| LEFTPAR expr RIGHTPAR
{ $$ = set_ll_list($2, LLNULL, EXPR_LIST);
$$->type = $2->type; }
| LEFTPAR uexpr COMMA dospec RIGHTPAR
{
$4->entry.Template.ll_ptr1 = $2;
$$ = set_ll_list($4, LLNULL, EXPR_LIST);
$$->type = $2->type;
}
| LEFTPAR other COMMA dospec RIGHTPAR
{
$4->entry.Template.ll_ptr1 = $2;
$$ = set_ll_list($4, LLNULL, EXPR_LIST);
$$->type = $2->type;
}
| LEFTPAR out2 COMMA dospec RIGHTPAR
{
$4->entry.Template.ll_ptr1 = $2;
$$ = set_ll_list($4, LLNULL, EXPR_LIST);
$$->type = $2->type;
}
;
in_ioctl:
{ inioctl = YES; }
;
start_ioctl:
{ startioctl();}
;
/*
* used by I/O statement
*/
fexpr: unpar_fexpr
{ $$ = $1; }
| LEFTPAR fexpr RIGHTPAR
{ $$ = $2; }
;
unpar_fexpr: lhs
{ $$ = $1; }
| simple_const
{ $$ = $1; }
| fexpr addop fexpr %prec PLUS
{
$$ = make_llnd(fi,$2, $1, $3, SMNULL);
set_expr_type($$);
}
| fexpr ASTER fexpr
{
$$ = make_llnd(fi,MULT_OP, $1, $3, SMNULL);
set_expr_type($$);
}
| fexpr SLASH fexpr
{
$$ = make_llnd(fi,DIV_OP, $1, $3, SMNULL);
set_expr_type($$);
}
| fexpr DASTER fexpr
{
$$ = make_llnd(fi,EXP_OP, $1, $3, SMNULL);
set_expr_type($$);
}
| addop fexpr %prec ASTER
{
if($1 == SUBT_OP)
{
$$ = make_llnd(fi,SUBT_OP, $2, LLNULL, SMNULL);
set_expr_type($$);
}
else $$ = $2;
}
| fexpr DSLASH fexpr
{
$$ = make_llnd(fi,CONCAT_OP, $1, $3, SMNULL);
set_expr_type($$);
}
| IDENTIFIER EQUAL expr
{ $$ = LLNULL; }
;
cmnt: /* nothing */
{ comments = cur_comment = CMNULL; }
| COMMENT
{ PTR_CMNT p;
p = make_comment(fi,*commentbuf, HALF);
if (cur_comment)
cur_comment->next = p;
else {
if ((pred_bfnd->control_parent->variant == LOGIF_NODE) ||(pred_bfnd->control_parent->variant == FORALL_STAT))
pred_bfnd->control_parent->entry.Template.cmnt_ptr = p;
else last_bfnd->entry.Template.cmnt_ptr = p;
}
comments = cur_comment = CMNULL;
}
;