4488 lines
116 KiB
Plaintext
4488 lines
116 KiB
Plaintext
/*
|
|
* Copyright (C) 1999-2003 Rildo Pragana,
|
|
* Bernard Giroud, David Essex, Jim Noeth.
|
|
* Copyright (C) 1991,1993 Rildo Pragana.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this software; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
/*
|
|
** Parser for Cobol Compiler
|
|
**
|
|
*/
|
|
|
|
%{
|
|
//#define YYDEBUG 1
|
|
#define YYMAXDEPTH 1000
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
|
#if defined(SunOS)
|
|
va_list __builtin_va_alist;
|
|
#endif
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "htcoboly.h"
|
|
#include "htcoblib.h"
|
|
#include "htglobals.h"
|
|
|
|
/* #if 1 */
|
|
#if USE_PARSER_TEST_MODE
|
|
#define UNIMPLEMENTED(xyz)
|
|
#else
|
|
#define UNIMPLEMENTED(xyz) yyerror("`%s' is not currently implemented", xyz);
|
|
#endif
|
|
|
|
// walter
|
|
int fg=0, bg=0, co=0;
|
|
//struct lit *init_alphab=NULL, *init_alpha=NULL, *init_num=NULL, *init_numedt=NULL, *init_alphaedt=NULL;
|
|
// fim walter
|
|
extern int screen_io_enable,scr_line,scr_column;
|
|
extern int decimal_comma;
|
|
extern char currency_symbol;
|
|
extern int has_linkage;
|
|
extern int module_flag;
|
|
extern int nested_flag;
|
|
extern FILE *lexin;
|
|
extern FILE *o_src;
|
|
extern struct sym *screen_status_field; /* pointer to the screen status */
|
|
extern struct sym *cursor_field; /* pointer to the cursor field */
|
|
extern struct sym *curr_paragr,*curr_section;
|
|
extern struct sym *curr_field;
|
|
extern short curr_call_mode;
|
|
extern short curr_call_convention;
|
|
extern struct sym *pgm_id;
|
|
extern unsigned stack_offset; /* offset das variaveis na pilha */
|
|
extern unsigned global_offset; /* offset das variaveis globais (DATA) */
|
|
extern int paragr_num;
|
|
extern int loc_label;
|
|
extern char picture[];
|
|
extern int picix,piccnt,decimals,sign,v_flag,n_flag,pscale;
|
|
extern int at_linkage,stack_plus;
|
|
extern char *toktext;
|
|
extern int yylex(void);
|
|
extern struct index_to_table_list *index2table;
|
|
extern int pgm_segment;
|
|
extern int initial_flag;
|
|
extern struct lit *spe_lit_ZE;
|
|
extern struct lit *spe_lit_SP;
|
|
extern struct lit *spe_lit_LV;
|
|
extern struct lit *spe_lit_HV;
|
|
extern struct lit *spe_lit_QU;
|
|
|
|
struct sym *curr_file;
|
|
struct sym *alloc_filler( void );
|
|
int curr_division=0;
|
|
int need_subscripts=0;
|
|
static int is_var=0;
|
|
extern char *yytext;
|
|
extern int envdiv_bypass_save_sw;
|
|
|
|
extern int stabs_on_sw;
|
|
extern int HTG_prg_uses_fileio;
|
|
extern int HTG_prg_uses_term;
|
|
/* extern int HTG_prg_uses_dcall; */
|
|
|
|
unsigned long lbend, lbstart;
|
|
unsigned int perform_after_sw;
|
|
|
|
int write_advancing_sw;
|
|
int decl_lbl;
|
|
|
|
/* struct math_var *vl1, *vl2; */
|
|
struct math_ose *tmose=NULL;
|
|
struct ginfo *gic=NULL;
|
|
|
|
static void assert_numeric_sy (struct sym *sy);
|
|
static void assert_numeric_dest_sy (struct sym *sy);
|
|
|
|
static char err_msg_bad_form[] = "ill-formed %s statement";
|
|
%}
|
|
|
|
%union {
|
|
struct sym *sval; /* symbol */
|
|
int ival; /* int */
|
|
struct coord_pair pval; /* lin,col */
|
|
struct lit *lval; /* literal */
|
|
unsigned long dval; /* label definition, compacted */
|
|
struct ddval { /* dual label definition */
|
|
int lb1,lb2;
|
|
} ddval;
|
|
char *str;
|
|
struct vref *rval; /* variable reference (with subscripts) */
|
|
struct refmod *rmval; /* variable with RefMod specifier */
|
|
struct string_from *sfval; /* variable list in string statement */
|
|
struct unstring_delimited *udval;
|
|
struct unstring_destinations *udstval;
|
|
struct tallying_list *tlval;
|
|
struct tallying_for_list *tfval;
|
|
struct replacing_list *repval;
|
|
struct replacing_by_list *rbval;
|
|
struct converting_struct *cvval;
|
|
struct inspect_before_after *baval;
|
|
struct scr_info *sival;
|
|
struct perf_info *pfval;
|
|
struct perform_info *pfvals;
|
|
struct sortfile_node *snval;
|
|
struct selsubject *ssbjval;
|
|
struct math_var *mval; /* math variables container list */
|
|
struct math_ose *mose; /* math ON SIZE ERROR variables container */
|
|
struct ginfo *gic; /* generic container */
|
|
struct invalid_keys *iks; /* [NOT] INVALID KEY */
|
|
struct invalid_key_element *ike; /* [NOT] INVALID KEY */
|
|
struct condition condval;
|
|
struct list *lstval; /* generic container list */
|
|
struct gvar_list *glistval; /* generic variable list */
|
|
}
|
|
|
|
%nonassoc LOW_PREC
|
|
|
|
%token <str> IDSTRING
|
|
%token <sval> STRING VARIABLE VARCOND SUBSCVAR
|
|
%token <sval> LABELSTR CMD_LINE ENVIRONMENT_VARIABLE INKEY ESCKEY
|
|
%token <ival> CHAR MULTIPLIER
|
|
%token <ival> USAGENUM ZERONUM CONDITIONAL
|
|
%token <ival> TO IS ARE THRU THAN NO
|
|
%token <ival> COMMENTING DIRECTION READ WRITE INPUT_OUTPUT RELEASE
|
|
%token <lval> NLITERAL CLITERAL
|
|
%token <ival> PORTNUM DATE_TIME
|
|
|
|
%left '+' '-'
|
|
%left '*' '/'
|
|
%left POW_OP
|
|
|
|
%left OR
|
|
%left AND
|
|
%right NOT
|
|
|
|
%token ACCEPT ACCESS ADD ADDRESS ADVANCING AFTER ALL ALPHABET
|
|
%token ALPHABETIC ALPHABETIC_LOWER ALPHABETIC_UPPER ALPHANUMERIC
|
|
%token ALPHANUMERIC_EDITED ALSO ALTERNATE ANY AREA AREAS ASSIGN
|
|
%token AT AUTHOR AUTO
|
|
%token BACKGROUNDCOLOR BEFORE BELL BLANK BLINK BLOCK BOTTOM BY
|
|
%token CALL CALL_CONV_C CALL_CONV_STDCALL CALL_LOADLIB CANCEL CENTER CF CH
|
|
%token CHAIN CHAINING CHARACTER CHARACTERS CLASS CLOSE
|
|
%token CODE CODE_SET COLLATING COLOR COLUMN COLUMNS COMMA COMMON COMPUTE CONFIGURATION
|
|
%token CONSOLE CONTAINS CONTENT CONTINUE CONTROL CONTROLS CONVERTING
|
|
%token CORRESPONDING COUNT CURRENCY CURSOR
|
|
%token DATA DATE_COMPILED DATE_WRITTEN DE DEBUGGING DECIMAL_POINT
|
|
%token DECLARATIVES DELETE DELIMITED DELIMITER DEPENDING DETAIL DISPLAY
|
|
%token DISPLAY_SCREEN DIVIDE DIVISION DOWN DUPLICATES DYNAMIC
|
|
%token ELSE END END_ACCEPT END_ADD END_CALL END_CALL_LOADLIB END_CHAIN END_COMPUTE END_DELETE
|
|
%token END_DISPLAY END_DIVIDE END_EVALUATE END_IF END_MULTIPLY END_OF_PAGE
|
|
%token END_PERFORM END_READ END_RETURN END_REWRITE END_SEARCH END_START
|
|
%token END_STRINGCMD END_SUBTRACT END_UNSTRING END_WRITE ENVIRONMENT
|
|
%token EOL EOS ERASE ERROR_TOK EVALUATE EXCEPTION EXIT EXTEND
|
|
%token EXTERNAL
|
|
%token FALSE_TOK FD FILE_CONTROL FILE_ID FILE_TOK FILLER FINAL FIRST
|
|
%token FOOTING FOR FOREGROUNDCOLOR FROM FULL FUNCTION
|
|
%token GENERATE GIVING GLOBAL GO GOBACK GROUP
|
|
%token HEADING HIGHLIGHT HIGHVALUES
|
|
%token IDENTIFICATION IF IGNORE IN INDEXED INDICATE INITIALIZE INITIAL_TOK
|
|
%token INITIATE INPUT INSPECT INSTALLATION INTO INVALID I_O I_O_CONTROL
|
|
%token JUSTIFIED
|
|
%token KEY
|
|
%token LABEL LAST LEADING LEFT LENGTH LIMIT LIMITS LINAGE LINE LINES LINKAGE LISTSEP
|
|
%token LOCK LOWER LOWLIGHT LOWVALUES LPAR
|
|
%token MERGE MINUS MODE MOVE MULTIPLE MULTIPLY
|
|
%token NATIVE NEGATIVE NEXT NOECHO NOT NOTEXCEP NULL_TOK NUMBER NUMBERS
|
|
%token NUMERIC NUMERIC_EDITED
|
|
%token OBJECT_COMPUTER OCCURS OF OFF OMITTED ON ONLY OPEN OPTIONAL ORDER
|
|
%token ORGANIZATION OTHER OUTPUT OVERFLOW_TOK
|
|
%token PADDING PAGE PAGE_COUNTER PARAGRAPH PERFORM PF PH PICTURE PLUS POINTER POSITION
|
|
%token POSITIVE PREVIOUS PROCEDURE PROCEED PROGRAM PROGRAM_ID
|
|
%token QUOTES
|
|
%token RANDOM RD READY RECORD RECORDS REDEFINES REEL REFERENCE RELATIVE
|
|
%token REMAINDER REMOVAL RENAMES REPLACING REPORT REPORTS REQUIRED RESERVE RESET
|
|
%token RETURN RETURNING REVERSEVIDEO REWIND REWRITE RF RH RIGHT ROUNDED RUN
|
|
%token SAME SCREEN SD SEARCH SECTION SECURE SECURITY SELECT SENTENCE SEPARATE
|
|
%token SEQUENCE SEQUENTIAL SET SIGN SIZE SORT SORT_MERGE SOURCE SOURCE_COMPUTER
|
|
%token SPACES SPECIAL_NAMES STANDARD STANDARD_1 STANDARD_2 START STATUS
|
|
%token STD_ERROR STD_OUTPUT STOP STRINGCMD SUBTRACT SUM SYNCHRONIZED
|
|
%token TALLYING TAPE TCOBPROTO1 TCOBPROTO2 TERMINATE TEST THEN TIMES TOKDUMMY
|
|
%token TOP TRACE TRAILING TRUE_TOK TYPE
|
|
%token UNDERLINE UNIT UNLOCK UNSTRING UNTIL UP UPDATE UPON UPPER USAGE USE USING
|
|
%token VALUE VALUES VARYING
|
|
%token WHEN WITH WORKING_STORAGE
|
|
%token ZERO
|
|
|
|
%right OF
|
|
%nonassoc PERIOD_TOK
|
|
|
|
%type <ival> sync_options
|
|
%type <ival> organization_options access_options open_mode
|
|
%type <ival> integer cond_op conditional before_after
|
|
%type <ival> IF ELSE usage read_next_opt
|
|
%type <ival> multiplier_opt using_options using_parameters
|
|
%type <dval> if_part
|
|
%type <sval> anystring name name_var gname gname_opt def_name_opt def_name procedure_section
|
|
%type <sval> field_description label filename data_name noallname paragraph assign_clause
|
|
%type <lval> literal gliteral without_all_literal all_literal special_literal
|
|
%type <lval> nliteral
|
|
%type <sval> perform_thru_opt write_options
|
|
%type <sval> read_into_opt write_from_opt release_from_opt
|
|
%type <sval> variable perform_range perform_options name_or_lit delimited_by
|
|
%type <sval> string_with_pointer
|
|
%type <sval> switches_details
|
|
%type <ival> all_opt with_duplicates with_test_opt optional_opt
|
|
%type <rval> subscript subscripts
|
|
%type <sfval> string_from_list string_from
|
|
%type <sval> unstring_count_opt unstring_delim_opt unstring_tallying
|
|
%type <udval> unstring_delimited_vars unstring_delimited
|
|
%type <udstval> unstring_destinations unstring_dest_var
|
|
%type <baval> inspect_before_after
|
|
%type <tlval> tallying_list tallying_clause
|
|
%type <tfval> tallying_for_list
|
|
%type <ival> replacing_kind plus_minus_opt
|
|
%type <repval> replacing_list replacing_clause
|
|
%type <rbval> replacing_by_list
|
|
%type <cvval> converting_clause
|
|
%type <sval> var_or_nliteral read_key_opt
|
|
%type <sival> screen_clauses
|
|
%type <ival> /*screen_attribs */screen_attrib sign_clause separate_opt screen_attribx
|
|
%type <ival> report_clause_column_is report_clause_column_orientation
|
|
%type <sval> variable_indexed search_varying_opt key_is_opt
|
|
%type <dval> search search_all search_when search_when_list search_at_end
|
|
%type <ival> parm_type sign_condition class_condition
|
|
%type <sval> intrinsic_parm_list intrinsic_parm
|
|
%type <sval> parm_list parameter expr expr_opt
|
|
%type <sval> cond_name thru_gname_opt
|
|
%type <pfval> perform_after
|
|
%type <pfvals> perform_after_opt
|
|
%type <ival> ext_cond extended_cond_op
|
|
%type <sval> returning_options
|
|
%type <snval> sort_file_list sort_input sort_output merge_using
|
|
%type <ival> not_opt selection_subject selection_object when_case
|
|
%type <ssbjval> selection_subject_set
|
|
%type <sval> screen_to_name
|
|
%type <lval> signed_nliteral
|
|
%type <ival> sentence_or_nothing when_case_list
|
|
%type <ival> rounded_opt
|
|
%type <mval> var_list_name var_list_gname
|
|
%type <mose> on_size_error_opt on_size_error
|
|
%type <ival> address_of_opt display_upon display_line_options
|
|
%type <sval> set_variable set_variable_or_nlit set_target add_to_opt
|
|
%type <sval> name_list string_list
|
|
%type <condval> condition implied_op_condition
|
|
%type <sval> qualified_var unqualified_var
|
|
/*%type <ival> end_program_opt program_sequence nested_program*/
|
|
%type <ival> program_sequences program_sequence
|
|
%type <lval> from_rec_varying to_rec_varying
|
|
%type <sval> depend_rec_varying
|
|
%type <sval> file_description redefines_var
|
|
%type <ival> on_exception_or_overflow on_not_exception
|
|
%type <gic> on_end read_at_end_opt
|
|
%type <iks> read_invalid_key_opt
|
|
%type <ike> read_invalid_key read_not_invalid_key
|
|
%type <iks> invalid_key_opt
|
|
%type <ike> invalid_key_sentence not_invalid_key_sentence
|
|
%type <sval> start_body
|
|
%type <ival> accept_display_options accept_display_option
|
|
%type <ival> with_lock_opt close_options_opt
|
|
%type <lstval> goto_label_list goto_label
|
|
%type <glistval> gname_list name_var_list use_phrase_option
|
|
%type <glistval> sort_keys sort_key sort_keys_names sort_keys_idx sort_key_idx sort_keys_names_idx
|
|
|
|
%%
|
|
|
|
/************ Parser for Cobol Source **************/
|
|
/*
|
|
COMPILATION UNIT STRUCTURE
|
|
*/
|
|
root_: program_sequences { gen_main_rtn(); }
|
|
;
|
|
program_sequences:
|
|
program { pgm_segment++; $$=1; }
|
|
| program_sequence { $$=1 ; }
|
|
| program_sequence program { $$=1 ; }
|
|
/*
|
|
program_sequence program_sequence end_program_opt
|
|
{ pgm_segment++; if (!($1|$3)) yyerror("END PROGRAM expected"); $$=$3; }
|
|
| program_sequence program_sequence
|
|
{ pgm_segment++; if ($1) yyerror("too many END PROGRAM"); $$=1; }
|
|
*/
|
|
;
|
|
program_sequence:
|
|
program end_program { pgm_segment++ ; $$ = 1; }
|
|
| program { pgm_segment++ ; nested_flag = 1; } program_sequence end_program { $$ = 1; }
|
|
| program_sequence program end_program {pgm_segment++ ; nested_flag = 1; $$ = 1; }
|
|
/*
|
|
| program_sequence program { yyerror("aaaaaaa"); $$ = 1; }
|
|
| program program_sequence { yyerror("aaaaaaaaaa") ; $$ = 1; }
|
|
*/
|
|
;
|
|
/*end_program_opt:
|
|
* nothing * { $$=0; }
|
|
| end_program { $$=1; }
|
|
;*/
|
|
end_program:
|
|
END PROGRAM
|
|
{ clear_symtab(); clear_offsets();
|
|
curr_division= CDIV_IDENT; }
|
|
IDSTRING
|
|
{ curr_division = CDIV_COMMENT; }
|
|
;
|
|
/*
|
|
* MAIN PROGRAM STRUCTURE
|
|
*/
|
|
program:
|
|
identification_division
|
|
environment_division_opt
|
|
data_division_opt
|
|
procedure_division_opt
|
|
;
|
|
/*
|
|
* IDENTIFICATION DIVISION
|
|
*/
|
|
identification_division: IDENTIFICATION DIVISION PERIOD_TOK
|
|
PROGRAM_ID PERIOD_TOK
|
|
{
|
|
curr_division = CDIV_IDENT;
|
|
}
|
|
IDSTRING
|
|
{
|
|
curr_division = CINITIAL;
|
|
if (pgm_header($7) != 0) {
|
|
yyerror("Invalid character(s) in PROGRAM-ID name");
|
|
/* YYABORT; */
|
|
}
|
|
}
|
|
programid_opts_opt PERIOD_TOK
|
|
{
|
|
define_special_fields();
|
|
}
|
|
identification_division_options_opt
|
|
;
|
|
programid_opts_opt:
|
|
/*nothing */
|
|
| is_opt INITIAL_TOK programid_program_opt { initial_flag=1; }
|
|
| is_opt COMMON programid_program_opt { UNIMPLEMENTED("PROGRAM-ID ... COMMON clause") }
|
|
;
|
|
programid_program_opt:
|
|
| PROGRAM { }
|
|
;
|
|
identification_division_options_opt:
|
|
/*nothing */
|
|
| identification_division_options_opt identification_division_option
|
|
;
|
|
identification_division_option:
|
|
AUTHOR PERIOD_TOK { curr_division = CDIV_COMMENT1; }
|
|
| DATE_WRITTEN PERIOD_TOK { curr_division = CDIV_COMMENT1; }
|
|
| DATE_COMPILED PERIOD_TOK { curr_division = CDIV_COMMENT1; }
|
|
| INSTALLATION PERIOD_TOK { curr_division = CDIV_COMMENT1; }
|
|
| SECURITY PERIOD_TOK { curr_division = CDIV_COMMENT1; }
|
|
;
|
|
/*
|
|
* ENVIRONMENT DIVISION
|
|
*/
|
|
environment_division_opt:
|
|
ENVIRONMENT DIVISION PERIOD_TOK
|
|
{
|
|
curr_division = CDIV_ENVIR;
|
|
}
|
|
configuration_opt
|
|
input_output_opt
|
|
{
|
|
curr_division = CINITIAL;
|
|
}
|
|
| /*nothing */
|
|
;
|
|
/*
|
|
* CONFIGURATION SECTION
|
|
*/
|
|
configuration_opt:
|
|
CONFIGURATION SECTION PERIOD_TOK configuration_section
|
|
| /*nothing */
|
|
;
|
|
configuration_section:
|
|
configuration_section configuration_option { }
|
|
| /* nothing */ { }
|
|
;
|
|
configuration_option:
|
|
SOURCE_COMPUTER PERIOD_TOK
|
|
{ envdiv_bypass_save_sw=1; }
|
|
STRING debug_mode_opt PERIOD_TOK
|
|
{ envdiv_bypass_save_sw=0; }
|
|
| OBJECT_COMPUTER PERIOD_TOK
|
|
{ envdiv_bypass_save_sw=1; }
|
|
STRING program_collating_opt PERIOD_TOK
|
|
{ envdiv_bypass_save_sw=0; }
|
|
| SPECIAL_NAMES PERIOD_TOK special_names_opt
|
|
| error { yyerror("invalid format in CONFIGURATION SECTION"); }
|
|
;
|
|
program_collating_opt:
|
|
PROGRAM collating_sequence
|
|
| /* nothing */
|
|
;
|
|
collating_sequence:
|
|
collating_opt SEQUENCE is_opt STRING
|
|
;
|
|
collating_opt: COLLATING { }
|
|
| /* nothing */ { }
|
|
;
|
|
debug_mode_opt:
|
|
with_opt DEBUGGING MODE { stabs_on_sw = 1; }
|
|
| /* nothing */ { }
|
|
;
|
|
special_names_opt:
|
|
/* nothing */
|
|
| special_names PERIOD_TOK
|
|
| error { yyerror("invalid format in SPECIAL-NAMES clause");}
|
|
;
|
|
special_names:
|
|
special_name
|
|
| special_names special_name
|
|
;
|
|
special_name:
|
|
/*special_name_opt*/
|
|
/*symbolic_characters_opt*/
|
|
switches_details_list
|
|
| alphabet_details /* parsed but unimplemented */
|
|
| currency_details
|
|
| decimal_point_details
|
|
| screen_status_details
|
|
| cursor_details
|
|
| special_name_class
|
|
/* | error { yyerror("invalid format in SPECIAL-NAMES clause");} */
|
|
/* | DATA DIVISION { yyerror("missing period in SPECIAL-NAMES clause");} */
|
|
;
|
|
currency_details:
|
|
CURRENCY sign_opt is_opt CLITERAL {
|
|
currency_symbol = $<lval>4->name[0];
|
|
}
|
|
;
|
|
sign_opt:
|
|
SIGN
|
|
| /* nothing */
|
|
;
|
|
special_name_class:
|
|
CLASS STRING is_opt special_name_class_item_list {}
|
|
;
|
|
special_name_class_item_list:
|
|
special_name_class_item {}
|
|
| special_name_class_item_list special_name_class_item {}
|
|
;
|
|
special_name_class_item:
|
|
CLITERAL {}
|
|
| CLITERAL THRU CLITERAL {}
|
|
;
|
|
|
|
decimal_point_details:
|
|
DECIMAL_POINT is_opt COMMA {
|
|
decimal_comma=1; }
|
|
;
|
|
screen_status_details:
|
|
DISPLAY_SCREEN STATUS is_opt STRING
|
|
{ screen_status_field=$4; }
|
|
;
|
|
cursor_details:
|
|
CURSOR is_opt STRING
|
|
{ cursor_field=$3; }
|
|
;
|
|
switches_details_list:
|
|
| switches_details_list switches_details
|
|
;
|
|
switches_details:
|
|
STRING is_opt STRING
|
|
{if ($1->name[0] != 'S' || $1->name[1] != 'W')
|
|
yyerror("Invalid switch name");
|
|
define_switch_field($3, $1);}
|
|
switch_on_opt switch_off_opt
|
|
{ close_fields();}
|
|
;
|
|
switch_on_opt:
|
|
ON status_opt is_opt STRING {save_switch_value($4, 1);}
|
|
| /* nothing */
|
|
;
|
|
switch_off_opt:
|
|
OFF status_opt is_opt STRING {save_switch_value($4, 0);}
|
|
| /* nothing */
|
|
;
|
|
status_opt:
|
|
STATUS
|
|
| /* nothing */
|
|
;
|
|
alphabet_details:
|
|
ALPHABET STRING is_opt alphabet_type
|
|
{
|
|
$2->defined=1;
|
|
UNIMPLEMENTED("Alphabet clause")
|
|
}
|
|
;
|
|
alphabet_type:
|
|
NATIVE { }
|
|
| STANDARD_1 { }
|
|
| STANDARD_2 { }
|
|
| alphabet_literal_list { }
|
|
;
|
|
alphabet_literal_list:
|
|
alphabet_literal_item
|
|
| alphabet_literal_list alphabet_literal_item
|
|
;
|
|
alphabet_literal_item:
|
|
without_all_literal { }
|
|
| without_all_literal THRU without_all_literal { }
|
|
| without_all_literal alphabet_also_list { }
|
|
;
|
|
alphabet_also_list:
|
|
ALSO without_all_literal
|
|
| alphabet_also_list ALSO without_all_literal
|
|
;
|
|
/*
|
|
* INPUT OUTPUT SECTION
|
|
*/
|
|
input_output_opt:
|
|
INPUT_OUTPUT SECTION PERIOD_TOK input_output_section { }
|
|
| /*nothing */
|
|
;
|
|
input_output_section:
|
|
file_control_paragraph i_o_control_paragraph { }
|
|
| error { yyerror("INPUT-OUTPUT SECTION format wrong"); }
|
|
;
|
|
file_control_paragraph:
|
|
FILE_CONTROL PERIOD_TOK file_control { }
|
|
;
|
|
i_o_control_paragraph: /* nothing */
|
|
| I_O_CONTROL PERIOD_TOK i_o_control_opt { }
|
|
;
|
|
|
|
/*
|
|
* FILE CONTROL ENTRY
|
|
*/
|
|
file_control:
|
|
file_select
|
|
| file_control file_select
|
|
;
|
|
|
|
file_select:
|
|
SELECT optional_opt def_name
|
|
{
|
|
$3->type='F'; /* mark as file variable */
|
|
curr_file=$3;
|
|
$3->pic=0; /* suppose not indexed yet */
|
|
$3->defined=1;
|
|
$3->parent=NULL; /* assume no STATUS yet
|
|
this is "file status" var in files */
|
|
$3->organization = 2;
|
|
$3->access_mode = 1;
|
|
$3->times=-1;
|
|
$3->alternate=NULL; /* reset alternate key list */
|
|
$3->flags.optional=$2; /* according to keyword */
|
|
$3->refmod_redef.declarative=NULL; /* no declarative yet */
|
|
}
|
|
select_clauses PERIOD_TOK
|
|
{
|
|
if ((curr_file->organization==ORG_INDEXED) &&
|
|
!(curr_file->ix_desc)) {
|
|
yyerror("indexed file must have a record key");
|
|
YYABORT;
|
|
}
|
|
}
|
|
;
|
|
select_clauses:
|
|
select_clauses select_clause
|
|
| /* nothing */
|
|
;
|
|
select_clause:
|
|
organization_opt is_opt organization_options
|
|
{ curr_file->organization=$3; }
|
|
| ASSIGN to_opt assign_clause { curr_file->filenamevar=$3;}
|
|
| ACCESS mode_opt is_opt access_options
|
|
{
|
|
/*{ curr_file->access_mode=$4; }*/
|
|
if (curr_file->access_mode < 5) {
|
|
curr_file->access_mode=$4;
|
|
}
|
|
else {
|
|
curr_file->access_mode = $4 + 5;
|
|
}
|
|
}
|
|
| file_opt STATUS is_opt STRING { curr_file->parent=$4; }
|
|
| RECORD key_opt is_opt STRING { curr_file->ix_desc=$4; }
|
|
| RELATIVE key_opt is_opt STRING { curr_file->ix_desc=$4; }
|
|
| ALTERNATE RECORD key_opt is_opt STRING
|
|
with_duplicates { add_alternate_key($5,$6); }
|
|
| RESERVE NLITERAL areas_opt
|
|
| error { yyerror("invalid clause in select"); }
|
|
;
|
|
file_opt:
|
|
FILE_TOK
|
|
| /* nothing */
|
|
;
|
|
organization_opt:
|
|
ORGANIZATION { }
|
|
| /* nothing */
|
|
;
|
|
assign_clause: PORTNUM { $$=NULL; }
|
|
| filename { $$=$1; }
|
|
| PORTNUM filename { $$=$2; }
|
|
| EXTERNAL filename
|
|
{
|
|
curr_file->access_mode = curr_file->access_mode + 5;
|
|
$$=$2;
|
|
}
|
|
| error { yyerror("Invalid ASSIGN clause in SELECT statement"); }
|
|
;
|
|
with_duplicates:
|
|
with_opt DUPLICATES { $$=1; }
|
|
| /* nothing */ { $$=0; }
|
|
;
|
|
optional_opt:
|
|
OPTIONAL { $$=1; }
|
|
| /* nothing */ { $$=0; }
|
|
;
|
|
areas_opt: AREA
|
|
| AREAS
|
|
| /* nothing */
|
|
;
|
|
is_opt:
|
|
IS { }
|
|
| /* nothing */
|
|
;
|
|
are_opt:
|
|
ARE { }
|
|
| /* nothing */
|
|
;
|
|
mode_opt:
|
|
MODE
|
|
| /* nothing */
|
|
;
|
|
organization_options:
|
|
INDEXED { $$=1; }
|
|
| SEQUENTIAL { $$=2; }
|
|
| RELATIVE { $$=3; }
|
|
| LINE SEQUENTIAL { $$=4; }
|
|
| anystring { yyerror("invalid option, %s",$1->name); }
|
|
;
|
|
access_options:
|
|
SEQUENTIAL { $$=1; }
|
|
| DYNAMIC { $$=2; }
|
|
| RANDOM { $$=3; }
|
|
| anystring
|
|
{ yyerror("invalid access option, %s", $1->name); }
|
|
;
|
|
|
|
/* I-O CONTROL paragraph */
|
|
i_o_control_opt: /* nothing */
|
|
| i_o_control_list PERIOD_TOK { UNIMPLEMENTED("I-O-CONTROL paragraph") }
|
|
|
|
;
|
|
i_o_control_list:
|
|
i_o_control_clause
|
|
| i_o_control_list i_o_control_clause
|
|
;
|
|
i_o_control_clause:
|
|
i_o_control_same_clause
|
|
| i_o_control_multiple_file_tape_clause
|
|
;
|
|
i_o_control_same_clause:
|
|
SAME same_clause_options are_opta for_opt string_list
|
|
;
|
|
same_clause_options: /* nothing */
|
|
| RECORD { }
|
|
| SORT { }
|
|
| SORT_MERGE { }
|
|
;
|
|
i_o_control_multiple_file_tape_clause:
|
|
MULTIPLE FILE_TOK tape_opt contains_opt i_o_control_multiple_file_list
|
|
;
|
|
i_o_control_multiple_file_list:
|
|
i_o_control_multiple_file
|
|
| i_o_control_multiple_file_list i_o_control_multiple_file
|
|
;
|
|
i_o_control_multiple_file:
|
|
STRING i_o_control_multiple_file_position_opt { }
|
|
;
|
|
i_o_control_multiple_file_position_opt:
|
|
| POSITION integer { }
|
|
;
|
|
tape_opt:
|
|
TAPE
|
|
| /* nothing */
|
|
;
|
|
are_opta:
|
|
AREA
|
|
| /* nothing */
|
|
;
|
|
for_opt:
|
|
FOR
|
|
| /* nothing */
|
|
;
|
|
string_list:
|
|
STRING { $$ = $1; }
|
|
| string_list STRING { $$ = $2; }
|
|
| error { yyerror("string expected"); }
|
|
;
|
|
name_list:
|
|
variable { $$ = (struct sym *)chain_var($1); }
|
|
| name_list variable { $$ = (struct sym *)chain_var($2); }
|
|
| error { yyerror("variable expected"); }
|
|
;
|
|
/* end enviroment division */
|
|
|
|
/*
|
|
* DATA DIVISION
|
|
*/
|
|
data_division_opt:
|
|
DATA DIVISION PERIOD_TOK
|
|
{ curr_division = CDIV_DATA; }
|
|
file_section_opt
|
|
working_storage_opt
|
|
linkage_section_opt
|
|
report_section_opt
|
|
screen_section_opt
|
|
{ curr_division = CINITIAL; }
|
|
| /* nothing */
|
|
;
|
|
/*
|
|
* FILE SECTION
|
|
*/
|
|
file_section_opt:
|
|
FILE_TOK SECTION PERIOD_TOK { curr_field=NULL; }
|
|
file_section { close_fields(); }
|
|
| /* nothing */
|
|
;
|
|
/*
|
|
* WORKING STORAGE SECTION
|
|
*/
|
|
working_storage_opt:
|
|
WORKING_STORAGE SECTION PERIOD_TOK { curr_field=NULL; }
|
|
working_storage_section { close_fields(); }
|
|
| /* nothing */
|
|
;
|
|
/*
|
|
* LINKAGE SECTION
|
|
*/
|
|
linkage_section_opt:
|
|
LINKAGE SECTION PERIOD_TOK { at_linkage=1; curr_field=NULL; has_linkage++; }
|
|
linkage_section { close_fields(); at_linkage=0; }
|
|
| /* nothing */
|
|
;
|
|
|
|
/*
|
|
* COMMUNICATION SECTION
|
|
*/
|
|
|
|
/* Not Implemented */
|
|
|
|
/*
|
|
* REPORT SECTION
|
|
*/
|
|
/* Work in progress - not finished */
|
|
report_section_opt:
|
|
REPORT SECTION PERIOD_TOK
|
|
report_sections { }
|
|
| /* nothing */
|
|
;
|
|
report_sections:
|
|
report_sections report_section
|
|
| /* nothing */
|
|
;
|
|
report_section:
|
|
RD
|
|
{ /*curr_division = CDIV_FD;*/ }
|
|
STRING
|
|
{
|
|
$3->type='W';
|
|
$3->picstr = 0;
|
|
$3->parent = 0;
|
|
$3->clone = 0;
|
|
$3->times = -1;
|
|
curr_division = CDIV_PROC;
|
|
UNIMPLEMENTED("Report Section")
|
|
}
|
|
report_controls PERIOD_TOK
|
|
{
|
|
curr_division = CDIV_DATA;
|
|
}
|
|
report_description
|
|
{
|
|
/* update_report_field($4); */
|
|
/* define_field(1,$4); */
|
|
}
|
|
;
|
|
report_controls: /* nothing */
|
|
| report_controls report_control
|
|
;
|
|
report_control: is_opt GLOBAL { }
|
|
| CODE gliteral { }
|
|
| report_controls_control { }
|
|
| report_controls_page { }
|
|
;
|
|
report_controls_control:
|
|
control_is_are final_opt report_break_list
|
|
;
|
|
report_controls_page:
|
|
PAGE limit_is_are_opt integer line_lines_opt
|
|
heading_opt
|
|
first_detail_opt last_detail_opt
|
|
footing_opt
|
|
;
|
|
heading_opt: /* nothing */
|
|
| HEADING is_opt integer
|
|
;
|
|
line_lines_opt:
|
|
lines_opt
|
|
| LINE
|
|
;
|
|
lines_opt:
|
|
/* nothing */
|
|
| LINES
|
|
;
|
|
control_is_are:
|
|
CONTROL is_opt
|
|
| CONTROLS are_opt
|
|
;
|
|
limit_is_are_opt:
|
|
/* nothing */
|
|
| LIMIT IS
|
|
| LIMITS ARE
|
|
;
|
|
footing_opt:
|
|
/* nothing */
|
|
| FOOTING is_opt integer
|
|
;
|
|
last_detail_opt:
|
|
/* nothing */
|
|
| LAST DETAIL is_opt integer
|
|
;
|
|
first_detail_opt:
|
|
/* nothing */
|
|
| FIRST DETAIL is_opt integer
|
|
;
|
|
final_opt:
|
|
/* nothing */
|
|
| FINAL
|
|
;
|
|
report_break_list:
|
|
/* nothing */
|
|
| report_break_list name { $2->defined=1; }
|
|
;
|
|
report_description:
|
|
report_item
|
|
| report_description report_item
|
|
;
|
|
report_item:
|
|
integer def_name_opt
|
|
{
|
|
if ($2 == NULL) {
|
|
$2 = alloc_filler();
|
|
picix=piccnt=v_flag=n_flag=decimals=pscale=0;
|
|
picture[picix]=0;
|
|
}
|
|
define_field($1,$2);
|
|
curr_division = CDIV_DATA;
|
|
}
|
|
report_clauses PERIOD_TOK
|
|
{
|
|
update_report_field($2);
|
|
curr_division = CDIV_DATA;
|
|
}
|
|
;
|
|
report_clauses:
|
|
report_clause
|
|
| report_clauses report_clause
|
|
;
|
|
report_clause:
|
|
report_clause_line { }
|
|
| report_clause_next_group { }
|
|
| report_clause_type { }
|
|
| report_clause_usage_display { }
|
|
| report_clause_picture { }
|
|
| report_clause_sign_is { }
|
|
| report_clause_justified { }
|
|
| report_clause_blank_zero { }
|
|
| report_clause_column { }
|
|
| report_clause_svs { }
|
|
| report_clause_group_indicate { }
|
|
;
|
|
report_clause_type:
|
|
TYPE is_opt report_clause_type2 { }
|
|
;
|
|
report_clause_type2:
|
|
REPORT HEADING { }
|
|
| PAGE HEADING { }
|
|
| CONTROL HEADING { curr_division = CDIV_PROC; }
|
|
name_final_opt { curr_division = CDIV_DATA; }
|
|
| DETAIL { }
|
|
| CONTROL FOOTING { curr_division = CDIV_PROC; }
|
|
name_final_opt { curr_division = CDIV_DATA; }
|
|
| PAGE FOOTING { }
|
|
| REPORT FOOTING { }
|
|
| RH { }
|
|
| PH { }
|
|
| CH { curr_division = CDIV_PROC; }
|
|
name_final_opt { curr_division = CDIV_DATA; }
|
|
| DE { }
|
|
| CF { curr_division = CDIV_PROC; }
|
|
name_final_opt { curr_division = CDIV_DATA; }
|
|
| PF { }
|
|
| RF { }
|
|
;
|
|
report_clause_sign_is:
|
|
SIGN is_opt leading_trailing SEPARATE character_opt { }
|
|
| leading_trailing SEPARATE character_opt { }
|
|
;
|
|
report_clause_picture:
|
|
PICTURE
|
|
{
|
|
curr_division = CDIV_PIC;
|
|
}
|
|
is_opt picture { curr_division = CDIV_DATA; }
|
|
;
|
|
report_clause_usage_display:
|
|
USAGE is_opt DISPLAY { }
|
|
| DISPLAY { }
|
|
;
|
|
report_clause_justified:
|
|
JUSTIFIED right_opt
|
|
;
|
|
report_clause_next_group:
|
|
NEXT GROUP is_opt integer_on_next_page
|
|
;
|
|
report_clause_line:
|
|
report_clause_line_is integer ON NEXT PAGE { }
|
|
| report_clause_line_is integer NEXT PAGE { }
|
|
| report_clause_line_is integer { }
|
|
| report_clause_line_is PLUS integer { }
|
|
;
|
|
report_clause_line_is:
|
|
LINE is_are_opt
|
|
| LINE NUMBER is_opt
|
|
| LINE NUMBERS are_opt
|
|
| LINES are_opt
|
|
;
|
|
report_clause_column:
|
|
report_clause_column_is integer { }
|
|
;
|
|
report_clause_column_is:
|
|
COLUMN report_clause_column_orientation is_are_opt { $$=$2; }
|
|
| COLUMN NUMBER report_clause_column_orientation is_opt { $$=$3; }
|
|
| COLUMN NUMBERS report_clause_column_orientation are_opt { $$=$3; }
|
|
| COLUMNS report_clause_column_orientation are_opt { $$=$2; }
|
|
;
|
|
report_clause_column_orientation:
|
|
/* nothing */ { $$=0; }
|
|
| LEFT { $$=0; }
|
|
| CENTER { $$=1; }
|
|
| RIGHT { $$=2; }
|
|
;
|
|
is_are_opt:
|
|
/* nothing */
|
|
| IS { }
|
|
| ARE { }
|
|
;
|
|
report_clause_svs: SOURCE
|
|
{ curr_division = CDIV_PROC; }
|
|
is_opt gname_page_counter
|
|
{ curr_division = CDIV_DATA; }
|
|
| VALUE is_opt literal { }
|
|
| SUM { curr_division = CDIV_PROC; }
|
|
gname_list { curr_division = CDIV_DATA; }
|
|
upon_opt reset_opt { }
|
|
;
|
|
gname_page_counter: gname { }
|
|
| PAGE_COUNTER { }
|
|
;
|
|
report_clause_group_indicate:
|
|
| GROUP indicate_opt { }
|
|
;
|
|
report_clause_blank_zero:
|
|
BLANK when_opt ZERO { }
|
|
;
|
|
indicate_opt:
|
|
| INDICATE { }
|
|
;
|
|
upon_opt:
|
|
| UPON gname_list { }
|
|
;
|
|
reset_opt:
|
|
| RESET gname { }
|
|
| RESET FINAL { }
|
|
;
|
|
number_opt:
|
|
| NUMBER { }
|
|
;
|
|
leading_trailing:
|
|
LEADING { }
|
|
| TRAILING { }
|
|
;
|
|
right_opt:
|
|
| RIGHT { }
|
|
;
|
|
name_final_opt:
|
|
gname { }
|
|
| FINAL { }
|
|
;
|
|
integer_on_next_page:
|
|
integer { }
|
|
| PLUS integer { }
|
|
| NEXT PAGE { }
|
|
;
|
|
of_opt:
|
|
OF
|
|
| /* nothing */
|
|
;
|
|
/* end report section */
|
|
|
|
/*
|
|
* SCREEN SECTION
|
|
*/
|
|
|
|
screen_section_opt:
|
|
SCREEN SECTION PERIOD_TOK
|
|
{
|
|
screen_io_enable++;
|
|
curr_field=NULL;
|
|
HTG_prg_uses_term = 1;
|
|
}
|
|
screen_section { close_fields(); }
|
|
| /* nothing */
|
|
;
|
|
|
|
/*
|
|
* SCREEN SECTION DESCRIPTION ENTRY
|
|
*/
|
|
screen_section:
|
|
screen_section screen_item
|
|
| /* nothing */
|
|
;
|
|
screen_item:
|
|
integer def_name_opt
|
|
{
|
|
if ($2 == NULL) {
|
|
$2 = alloc_filler();
|
|
}
|
|
picix=piccnt=v_flag=n_flag=decimals=pscale=0;
|
|
picture[picix]=0;
|
|
define_field($1,$2);
|
|
}
|
|
screen_clauses PERIOD_TOK { update_screen_field($2,$4); }
|
|
;
|
|
screen_clauses:
|
|
screen_clauses LINE { curr_division = CDIV_PROC; }
|
|
number_is_opt
|
|
plus_minus_opt
|
|
name_or_lit { curr_division = CDIV_DATA;
|
|
scr_set_line($1,$6,$5); $$=$1; }
|
|
| screen_clauses COLUMN { curr_division = CDIV_PROC; }
|
|
number_is_opt
|
|
plus_minus_opt
|
|
name_or_lit { curr_division = CDIV_DATA;
|
|
scr_set_column($1,$6,$5); $$=$1; }
|
|
| screen_clauses
|
|
with_opt screen_attrib { $1->attr |= $3; $$=$1; }
|
|
| screen_clauses with_opt FOREGROUNDCOLOR { curr_division = CDIV_PROC; }
|
|
name_or_lit { curr_division = CDIV_DATA;
|
|
$1->color = NULL;
|
|
$1->foreground = $5; $$=$1; }
|
|
| screen_clauses with_opt BACKGROUNDCOLOR { curr_division = CDIV_PROC; }
|
|
name_or_lit { curr_division = CDIV_DATA;
|
|
$1->color = NULL;
|
|
$1->background = $5; $$=$1; }
|
|
| screen_clauses with_opt COLOR { curr_division = CDIV_PROC; }
|
|
name_or_lit { curr_division = CDIV_DATA;
|
|
$1->foreground = NULL;
|
|
$1->background = NULL;
|
|
$1->color = $5; $$=$1; }
|
|
| screen_clauses
|
|
screen_source_destination
|
|
| screen_clauses
|
|
value_is_are gliteral { curr_field->value = $3; $$=$1; }
|
|
| screen_clauses pictures
|
|
| screen_clauses SIZE { curr_division = CDIV_PROC; }
|
|
name_or_lit { curr_division = CDIV_DATA;
|
|
$1->size = $4; $$=$1; }
|
|
| /* nothing */ { $$ = alloc_scr_info(); }
|
|
;
|
|
screen_source_destination:
|
|
USING { curr_division = CDIV_PROC; }
|
|
name_or_lit {
|
|
curr_division = CDIV_DATA;
|
|
$<sival>0->from = $<sival>0->to = $3;
|
|
}
|
|
| FROM { curr_division = CDIV_PROC; }
|
|
name_or_lit
|
|
screen_to_name {
|
|
curr_division = CDIV_DATA;
|
|
$<sival>0->from = $3; $<sival>0->to = $4;
|
|
}
|
|
| TO { curr_division = CDIV_PROC; }
|
|
name {
|
|
curr_division = CDIV_DATA;
|
|
$<sival>0->from = NULL; $<sival>0->to = $3;
|
|
}
|
|
;
|
|
screen_to_name:
|
|
/* nothing */ { $$=NULL; }
|
|
| TO name { $$ = $2; }
|
|
;
|
|
screen_attrib:
|
|
BLANK SCREEN { $$ = SCR_BLANK_SCREEN; }
|
|
| BLANK LINE { $$ = SCR_BLANK_LINE; }
|
|
| ERASE EOL { $$ = SCR_ERASE_EOL; }
|
|
| ERASE EOS { $$ = SCR_ERASE_EOS; }
|
|
| ERASE { $$ = SCR_ERASE_EOL; }
|
|
| with_opt BELL { $$ = SCR_BELL; }
|
|
| sign_clause { $$ = $1; }
|
|
| FULL { $$ = SCR_FULL; }
|
|
| REQUIRED { $$ = SCR_REQUIRED; }
|
|
| SECURE { $$ = SCR_SECURE; }
|
|
| AUTO { $$ = SCR_AUTO; }
|
|
| JUSTIFIED RIGHT { $$ = SCR_JUST_RIGHT; }
|
|
| JUSTIFIED LEFT { $$ = SCR_JUST_LEFT; }
|
|
| BLINK { $$ = SCR_BLINK; }
|
|
| REVERSEVIDEO { $$ = SCR_REVERSE_VIDEO; }
|
|
| UNDERLINE { $$ = SCR_UNDERLINE; }
|
|
| LOWLIGHT { $$ = SCR_LOWLIGHT; }
|
|
| HIGHLIGHT { $$ = SCR_HIGHLIGHT; }
|
|
| BLANK when_opt ZERO { $$ = SCR_BLANK_WHEN_ZERO; }
|
|
| with_opt NOECHO { $$ = SCR_NOECHO; }
|
|
| with_opt UPDATE { $$ = SCR_UPDATE; }
|
|
| with_opt NO ADVANCING { $$ = SCR_NO_ADVANCING; }
|
|
| UPPER { $$ = SCR_UPPER; }
|
|
| LOWER { $$ = SCR_LOWER; }
|
|
;
|
|
/* wakter */
|
|
screen_attribx:
|
|
BLANK SCREEN { $$ = SCR_BLANK_SCREEN; }
|
|
| BLANK LINE { $$ = SCR_BLANK_LINE; }
|
|
| ERASE EOL { $$ = SCR_ERASE_EOL; }
|
|
| ERASE EOS { $$ = SCR_ERASE_EOS; }
|
|
| ERASE { $$ = SCR_ERASE_EOL; }
|
|
| with_opt BELL { $$ = SCR_BELL; }
|
|
| sign_clause { $$ = $1; }
|
|
| FULL { $$ = SCR_FULL; }
|
|
| REQUIRED { $$ = SCR_REQUIRED; }
|
|
| SECURE { $$ = SCR_SECURE; }
|
|
| AUTO { $$ = SCR_AUTO; }
|
|
| JUSTIFIED RIGHT { $$ = SCR_JUST_RIGHT; }
|
|
| JUSTIFIED LEFT { $$ = SCR_JUST_LEFT; }
|
|
| BLINK { $$ = SCR_BLINK; }
|
|
| REVERSEVIDEO { $$ = SCR_REVERSE_VIDEO; }
|
|
| UNDERLINE { $$ = SCR_UNDERLINE; }
|
|
| LOWLIGHT { $$ = SCR_LOWLIGHT; }
|
|
| HIGHLIGHT { $$ = SCR_HIGHLIGHT; }
|
|
| BLANK when_opt ZERO { $$ = SCR_BLANK_WHEN_ZERO; }
|
|
| with_opt NOECHO { $$ = SCR_NOECHO; }
|
|
| with_opt UPDATE { $$ = SCR_UPDATE; }
|
|
| with_opt NO ADVANCING { $$ = SCR_NO_ADVANCING; }
|
|
| UPPER { $$ = SCR_UPPER; }
|
|
| LOWER { $$ = SCR_LOWER; }
|
|
| FOREGROUNDCOLOR integer { $$ = 0; fg = $2; }
|
|
| BACKGROUNDCOLOR integer { $$ = 0; bg = $2; }
|
|
;
|
|
/* fim walter */
|
|
sign_clause:
|
|
sign_is_opt LEADING separate_opt
|
|
{ $$ = SCR_SIGN_LEADING | $3; }
|
|
| sign_is_opt TRAILING separate_opt
|
|
{ $$ = $3; }
|
|
;
|
|
separate_opt:
|
|
SEPARATE character_opt { $$ = SCR_SIGN_SEPARATE; }
|
|
| /* nothing */ { $$ = 0; }
|
|
;
|
|
character_opt:
|
|
CHARACTER
|
|
| /* nothing */
|
|
;
|
|
sign_is_opt:
|
|
SIGN is_opt
|
|
| is_opt
|
|
;
|
|
plus_minus_opt:
|
|
PLUS { $$ = 1; }
|
|
| '+' { $$ = 1; }
|
|
| MINUS { $$ = -1; }
|
|
| '-' { $$ = -1; }
|
|
| /* nothing */ { $$ = 0; }
|
|
;
|
|
number_is_opt:
|
|
NUMBER is_opt
|
|
| /* nothing */
|
|
;
|
|
/* end screen section */
|
|
|
|
/*
|
|
* File description entry
|
|
*/
|
|
file_section:
|
|
file_section FD
|
|
{ curr_division = CDIV_FD; }
|
|
STRING
|
|
{ curr_division = CDIV_DATA; }
|
|
file_description_fd_clauses PERIOD_TOK
|
|
{
|
|
curr_field=NULL;
|
|
if ($4->filenamevar == NULL) {
|
|
yyerror("External file name not defined for file %s", $4->name);
|
|
}
|
|
}
|
|
file_description
|
|
{
|
|
close_fields();
|
|
alloc_file_entry($4);
|
|
gen_fdesc($4,$9);
|
|
}
|
|
| file_section SD { curr_division = CDIV_FD; }
|
|
STRING { curr_division = CDIV_DATA; }
|
|
file_description_sd_clauses PERIOD_TOK
|
|
{
|
|
$4->organization=2;
|
|
curr_field=NULL;
|
|
}
|
|
file_description
|
|
{
|
|
close_fields();
|
|
alloc_file_entry($4);
|
|
$4->sort_file = 1;
|
|
gen_fdesc($4,$9);
|
|
}
|
|
| error { yyerror("missing or invalid file description entry"); }
|
|
| /* nothing */
|
|
;
|
|
file_description:
|
|
field_description { $$=$1; }
|
|
| file_description field_description
|
|
{
|
|
if (($2 != NULL) && ($2->level == 1)) {
|
|
/* multiple 01 records (for a file descriptor) */
|
|
$2->redefines=$1;
|
|
$$=$2;
|
|
}
|
|
else
|
|
$$=$1;
|
|
}
|
|
;
|
|
/*
|
|
* DATA DESCRIPTION ENTRY
|
|
*/
|
|
field_description:
|
|
integer def_name_opt
|
|
{
|
|
picix=piccnt=v_flag=n_flag=decimals=pscale=0;
|
|
if ($1 == 78) {
|
|
yyerror("level 78 not supported");
|
|
}
|
|
if ($2==NULL) {
|
|
define_field($1,alloc_filler());
|
|
}
|
|
else {
|
|
define_field($1,$2);
|
|
}
|
|
}
|
|
data_clauses PERIOD_TOK
|
|
{
|
|
$$=$2;
|
|
if (($$ == NULL) || ($$->level != 66))
|
|
update_field(curr_field);
|
|
}
|
|
;
|
|
data_clauses:
|
|
/* nothing */
|
|
| data_clauses data_clause
|
|
| data_clauses redefines_clause
|
|
;
|
|
redefines_clause:
|
|
REDEFINES
|
|
{ curr_division = CDIV_PROC; /* parsing variable */ }
|
|
redefines_var
|
|
{
|
|
curr_division = CDIV_DATA;
|
|
if ($<sval>-2 != NULL) {
|
|
$<sval>-2->redefines = lookup_for_redefines($3);
|
|
}
|
|
else {
|
|
yywarn("cannot redefine an unnamed field");
|
|
}
|
|
}
|
|
;
|
|
redefines_var:
|
|
VARIABLE { $$=$1; }
|
|
| SUBSCVAR { $$=$1; }
|
|
;
|
|
data_clause:
|
|
array_options
|
|
| pictures
|
|
| usage_option
|
|
| sign_clause {
|
|
curr_field->flags.separate_sign = ($1 & SCR_SIGN_SEPARATE) ? 1 : 0;
|
|
curr_field->flags.leading_sign = ($1 & SCR_SIGN_LEADING) ? 1 : 0; }
|
|
| value_option
|
|
| SYNCHRONIZED sync_options {curr_field->flags.sync=1;}
|
|
| JUSTIFIED sync_options {if ($2 != 2) curr_field->flags.just_r=1;}
|
|
| is_opt EXTERNAL {save_named_sect(curr_field);}
|
|
| is_opt GLOBAL {}
|
|
| BLANK when_opt ZERO { curr_field->flags.blank=1; }
|
|
| RENAMES { curr_division = CDIV_PROC /* for parsing variable */; }
|
|
variable thru_gname_opt
|
|
{ curr_division = CDIV_DATA;
|
|
update_renames_field($3, $4);}
|
|
;
|
|
sync_options:
|
|
/* nothing */ {$$=0;}
|
|
| LEFT {$$=2;}
|
|
| RIGHT {$$=1;}
|
|
;
|
|
thru_gname_opt: /* nothing */ { $$ = NULL;}
|
|
| THRU variable { $$ = $2;}
|
|
;
|
|
|
|
/* OCCURS clause */
|
|
array_options:
|
|
OCCURS integer times_opt
|
|
{ curr_field->times = $2; curr_field->occurs_flg++; }
|
|
indexed_by_opt
|
|
| OCCURS integer TO integer times_opt DEPENDING
|
|
{ curr_division = CDIV_PROC; /* needed for parsing variable */ }
|
|
on_opt gname
|
|
{
|
|
curr_division = CDIV_DATA;
|
|
create_occurs_info($2,$4,$9);
|
|
}
|
|
indexed_by_opt
|
|
;
|
|
key_is_opt:
|
|
DIRECTION key_opt is_opt STRING
|
|
{
|
|
$4->level=0;
|
|
if ($1 == ASCENDING) {
|
|
$4->level=-1;
|
|
}
|
|
if ($1 == DESCENDING) {
|
|
$4->level=-2;
|
|
}
|
|
$$=$4;
|
|
}
|
|
| { $$=NULL; }
|
|
;
|
|
indexed_by_opt:
|
|
key_is_opt INDEXED by_opt index_name_list
|
|
{
|
|
/*define_implicit_field($4, $1, curr_field->times);*/
|
|
/* Fix Me: Does not work, thus dup vars can be defined
|
|
if ($4->defined) {
|
|
yyerror("variable redefined, '%s'",$4->name);
|
|
$4->defined=1;
|
|
}
|
|
else {
|
|
define_implicit_field($4, $1, curr_field->times);
|
|
} */
|
|
}
|
|
| /* nothing */
|
|
;
|
|
index_name_list:
|
|
def_name
|
|
{
|
|
define_implicit_field($1, $<sval>-2, curr_field->times);
|
|
/* Fix Me: Does not work, thus dup vars can be defined
|
|
if ($4->defined) {
|
|
yyerror("variable redefined, '%s'",$4->name);
|
|
$4->defined=1;
|
|
}
|
|
else {
|
|
define_implicit_field($4, $1, curr_field->times);
|
|
} */
|
|
}
|
|
| index_name_list def_name
|
|
{
|
|
define_implicit_field($2,$<sval>-2,curr_field->times);
|
|
}
|
|
;
|
|
|
|
/* USAGE clause */
|
|
|
|
usage_option :
|
|
usage_opt is_opt usage { set_usage(curr_field, $3); }
|
|
;
|
|
usage:
|
|
USAGENUM { $$=$1; }
|
|
| DISPLAY { $$=USAGE_DISPLAY; }
|
|
| POINTER { $$=USAGE_POINTER; }
|
|
;
|
|
|
|
/* VALUE clause */
|
|
|
|
value_option:
|
|
value_is_are value_list
|
|
;
|
|
value_is_are:
|
|
VALUE is_opt
|
|
| VALUES are_opt
|
|
;
|
|
value_list:
|
|
value
|
|
| value_list comma_opt value
|
|
;
|
|
value:
|
|
gliteral { set_variable_values($1,$1); }
|
|
| gliteral THRU gliteral
|
|
{
|
|
set_variable_values($1,$3);
|
|
}
|
|
;
|
|
|
|
/* Pictures clause */
|
|
|
|
pictures:
|
|
PICTURE
|
|
{
|
|
curr_division = CDIV_PIC;
|
|
/* first pic char found */
|
|
picix=piccnt=v_flag=n_flag=decimals=pscale=0;
|
|
picture[picix]=0;
|
|
}
|
|
is_opt picture
|
|
{
|
|
/* finish picture */
|
|
picture[picix+2]=0;
|
|
curr_field->decimals=decimals;
|
|
curr_field->pscale=pscale;
|
|
if (curr_field->type == DTYPE_DISPLAY && piccnt > 18) {
|
|
yyerror("Maximum elementary numeric item size of %s > 18 digits exceeded", curr_field->name);
|
|
}
|
|
if (curr_field->type == DTYPE_ALPHANUMERIC && piccnt > 12750) {
|
|
yyerror("Maximum elementary alphanumeric item size of %s > 12750 exceeded", curr_field->name);
|
|
}
|
|
}
|
|
;
|
|
picture: /* nothing */
|
|
| picture pic_elem
|
|
;
|
|
pic_elem:
|
|
CHAR multiplier_opt
|
|
{
|
|
if (!save_pic_char ( $1, $2 )) {
|
|
yyerror("invalid char in picture");
|
|
YYERROR;
|
|
}
|
|
}
|
|
;
|
|
multiplier_opt:
|
|
/* nothing */ { $$ = 1; }
|
|
| MULTIPLIER { $$ = $1; }
|
|
;
|
|
|
|
/* File description entry */
|
|
file_description_fd_clauses:
|
|
| file_description_fd_clauses file_description_fd_clause
|
|
;
|
|
file_description_sd_clauses:
|
|
| file_description_sd_clauses file_description_sd_clause
|
|
;
|
|
file_description_fd_clause:
|
|
is_opt EXTERNAL { $<sval>0->type = 'K'; }
|
|
| is_opt GLOBAL { $<sval>0->type = 'J'; }
|
|
| file_description_clause_block
|
|
| file_description_clause_record
|
|
| file_description_clause_label
|
|
| file_description_clause_value
|
|
| file_description_clause_data
|
|
| file_description_clause_report
|
|
| file_description_clause_linage
|
|
| file_description_clause_code_set
|
|
;
|
|
file_description_sd_clause:
|
|
file_description_clause_record
|
|
| file_description_clause_data
|
|
;
|
|
|
|
file_description_clause_block:
|
|
BLOCK contains_opt integer
|
|
to_integer_opt chars_or_recs_opt
|
|
{
|
|
/* unimplemented - clause ignored */
|
|
}
|
|
;
|
|
file_description_clause_record:
|
|
RECORD contains_opt integer
|
|
to_rec_varying character_opts
|
|
{
|
|
if ($4 != NULL) {
|
|
UNIMPLEMENTED ("RECORD CONTAINS integer1 TO integer2 CHARACTERS clause")
|
|
/* unimplemented */
|
|
}
|
|
}
|
|
| RECORD is_opt VARYING in_opt size_opt
|
|
from_rec_varying to_rec_varying character_opts
|
|
depend_rec_varying
|
|
{
|
|
if ($9 != NULL) {
|
|
set_rec_varying_info( $<sval>-2,$6,$7,$9 );
|
|
}
|
|
else {
|
|
yyerror("clause \'DEPENDING ON data-name-1\' is missing");
|
|
}
|
|
}
|
|
;
|
|
file_description_clause_label:
|
|
LABEL record_is_are std_or_omitt { /* obsolete */ }
|
|
;
|
|
file_description_clause_value:
|
|
VALUE OF FILE_ID is_opt filename
|
|
{
|
|
if ($<sval>-2->filenamevar != NULL) {
|
|
yyerror("Re-defining file name defined in SELECT statement");
|
|
}
|
|
else {
|
|
$<sval>-2->filenamevar = $<sval>5;
|
|
}
|
|
}
|
|
;
|
|
file_description_clause_data:
|
|
DATA record_is_are var_strings { /* obsolete */ }
|
|
;
|
|
file_description_clause_report:
|
|
report_is_are STRING { save_report( $2,$<sval>0 ); }
|
|
;
|
|
file_description_clause_code_set:
|
|
CODE_SET is_opt STRING
|
|
{ UNIMPLEMENTED ("Code-set is alphabet") /* unimplemented */ }
|
|
;
|
|
file_description_clause_linage:
|
|
LINAGE is_opt data_name lines_opt
|
|
file_description_clause_linage_footing
|
|
file_description_clause_linage_top
|
|
file_description_clause_linage_bottom
|
|
{ UNIMPLEMENTED ("Linage is clause") /* unimplemented */ }
|
|
;
|
|
file_description_clause_linage_footing:
|
|
| with_opt FOOTING at_opt data_name { /* unimplemented */ }
|
|
;
|
|
file_description_clause_linage_top:
|
|
| lines_at_opt TOP data_name { /* unimplemented */ }
|
|
;
|
|
file_description_clause_linage_bottom:
|
|
| lines_at_opt BOTTOM data_name { /* unimplemented */ }
|
|
;
|
|
lines_at_opt: /* nothing */
|
|
| LINES
|
|
| LINES AT
|
|
| AT
|
|
;
|
|
report_is_are: REPORT is_opt
|
|
| REPORTS are_opt
|
|
;
|
|
var_strings: STRING { }
|
|
| var_strings STRING { }
|
|
;
|
|
chars_or_recs_opt:
|
|
/* nothing */
|
|
| CHARACTERS
|
|
| RECORDS
|
|
;
|
|
to_integer_opt: /* nothing */
|
|
| TO integer { }
|
|
;
|
|
depend_rec_varying: { $$ = NULL; }
|
|
| DEPENDING on_opt STRING { $$ = $3; }
|
|
;
|
|
from_rec_varying:
|
|
/* nothing */ { $$ = NULL; }
|
|
| from_opt nliteral { $$ = $2; }
|
|
;
|
|
from_opt:
|
|
FROM
|
|
| /* nothing */
|
|
;
|
|
to_rec_varying:
|
|
/* nothing */ { $$ = NULL; }
|
|
| TO nliteral { $$ = $2; }
|
|
;
|
|
record_is_are:
|
|
RECORD is_opt
|
|
| RECORDS are_opt
|
|
;
|
|
std_or_omitt:
|
|
STANDARD
|
|
| OMITTED
|
|
;
|
|
usage_opt:
|
|
/* nothing */
|
|
| USAGE
|
|
;
|
|
times_opt:
|
|
/* nothing */
|
|
| TIMES
|
|
;
|
|
when_opt:
|
|
/* nothing */
|
|
| WHEN
|
|
;
|
|
contains_opt:
|
|
/* nothing */
|
|
| CONTAINS
|
|
;
|
|
character_opts:
|
|
/* nothing */
|
|
| CHARACTERS
|
|
;
|
|
order_opt:
|
|
/* nothing */
|
|
| ORDER
|
|
;
|
|
data_opt:
|
|
/* nothing */
|
|
| DATA
|
|
;
|
|
/*
|
|
* DATA DIVISION - working storage section
|
|
*/
|
|
working_storage_section:
|
|
working_storage_section
|
|
field_description
|
|
| /* nothing */
|
|
;
|
|
/*
|
|
* DATA DIVISION - linkage section
|
|
*/
|
|
linkage_section:
|
|
/* nothing */
|
|
| linkage_section
|
|
field_description
|
|
;
|
|
/*
|
|
procedure_division:
|
|
| procedure_division procedure_decl
|
|
;
|
|
*/
|
|
/*
|
|
* PROCEDURE DIVISION
|
|
*/
|
|
procedure_division_opt:
|
|
PROCEDURE DIVISION
|
|
{
|
|
curr_division = CDIV_PROC;
|
|
}
|
|
using_parameters PERIOD_TOK
|
|
{
|
|
proc_header($4);
|
|
}
|
|
declaratives_opt
|
|
procedure_division
|
|
{
|
|
/* close procedure_division sections & paragraphs */
|
|
close_section(); /* this also closes paragraph */
|
|
resolve_labels();
|
|
proc_trail($4);
|
|
}
|
|
| /* nothing */
|
|
;
|
|
procedure_division:
|
|
| procedure_division procedure_decl
|
|
;
|
|
procedure_decl:
|
|
procedure_section { close_section(); open_section($1); }
|
|
| paragraph { close_paragr(); open_paragr($1); }
|
|
| {free_expr_list(); stabs_line();} statements PERIOD_TOK
|
|
/* | {free_expr_list(); stabs_line();} statements */
|
|
| error { yyerror("unknown or wrong statement"); } PERIOD_TOK
|
|
| PERIOD_TOK { }
|
|
;
|
|
/* Procedure Division Declaratives */
|
|
declaratives_opt:
|
|
DECLARATIVES PERIOD_TOK
|
|
{
|
|
decl_lbl=loc_label++;
|
|
gen_jmplabel(decl_lbl);
|
|
}
|
|
declaratives_procedure
|
|
declaratives_division
|
|
END DECLARATIVES PERIOD_TOK
|
|
{
|
|
gen_dstlabel(decl_lbl);
|
|
}
|
|
| /* nothing */
|
|
;
|
|
declaratives_division:
|
|
| declaratives_division declaratives_decl
|
|
/* | declaratives_division procedure_decl */
|
|
;
|
|
|
|
declaratives_decl:
|
|
declaratives_procedure
|
|
| paragraph { close_paragr(); open_paragr($1); }
|
|
| {free_expr_list(); stabs_line();} statements PERIOD_TOK
|
|
| error { yyerror("unknown or wrong statement"); } PERIOD_TOK
|
|
/* | PERIOD_TOK { } */
|
|
;
|
|
|
|
declaratives_procedure:
|
|
procedure_section
|
|
{
|
|
close_section();
|
|
open_section($1);
|
|
}
|
|
use_phrase
|
|
| error { yyerror("section name expected"); }
|
|
;
|
|
use_phrase:
|
|
USE AFTER use_phrase_exception_error PROCEDURE on_opt use_phrase_option PERIOD_TOK
|
|
{ /* mark_decl_list($6); */ }
|
|
| error { yyerror("use statement expected"); }
|
|
;
|
|
use_phrase_exception_error: EXCEPTION
|
|
| ERROR_TOK
|
|
| STANDARD EXCEPTION
|
|
| STANDARD ERROR_TOK
|
|
;
|
|
use_phrase_option:
|
|
gname_list { $$=$1; }
|
|
| open_mode
|
|
{
|
|
$$=NULL;
|
|
UNIMPLEMENTED ("Declaratives open-mode clause")
|
|
/* unimplemented */
|
|
}
|
|
;
|
|
|
|
/* Procedure division sections and paragraphs */
|
|
|
|
procedure_section:
|
|
LABELSTR SECTION PERIOD_TOK
|
|
{
|
|
struct sym *lab=$1;
|
|
if (lab->defined != 0) {
|
|
lab = install(lab->name,SYTB_LAB,2);
|
|
}
|
|
lab->defined = 1;
|
|
$$=lab;
|
|
}
|
|
;
|
|
paragraph:
|
|
LABELSTR dot_or_eos
|
|
{
|
|
struct sym *lab=$1;
|
|
if (lab->defined != 0) {
|
|
if ((lab=lookup_label(lab,curr_section))==NULL) {
|
|
lab = install($1->name,SYTB_LAB,2);
|
|
}
|
|
}
|
|
lab->parent = curr_section;
|
|
lab->defined=1;
|
|
$$=lab;
|
|
}
|
|
;
|
|
dot_or_eos:
|
|
'.'
|
|
| PERIOD_TOK
|
|
;
|
|
|
|
/*
|
|
* PROCEDURE DIVISION - COBOL verbs
|
|
*/
|
|
|
|
statement_list:
|
|
statements { }
|
|
;
|
|
statements:
|
|
statement
|
|
| statements statement
|
|
;
|
|
statement:
|
|
move_statement
|
|
| initialize_statement
|
|
| compute_statement
|
|
| add_statement
|
|
| subtract_statement
|
|
| multiply_statement
|
|
| divide_statement
|
|
| accept_statement
|
|
| display_statement
|
|
| open_statement
|
|
| close_statement
|
|
| read_statement
|
|
| return_statement
|
|
| release_statement
|
|
| write_statement
|
|
| rewrite_statement
|
|
| delete_statement
|
|
| start_statement
|
|
| perform_statement
|
|
| goto_statement
|
|
| exit_statement
|
|
| stop_statement
|
|
| call_statement
|
|
| call_loadlib_statement
|
|
| chain_statement
|
|
| set_statement
|
|
| sort_statement
|
|
| merge_statement
|
|
| inspect_statement
|
|
| string_statement
|
|
| unstring_statement
|
|
| initiate_statement
|
|
| generate_statement
|
|
| terminate_statement
|
|
| proto_statement
|
|
| trace_statement
|
|
| goback_statement
|
|
| cancel_statement
|
|
| unlock_statement
|
|
| if_statement
|
|
| evaluate_statement
|
|
| search_statement
|
|
| CONTINUE { stabs_line(); }
|
|
/*
|
|
| NEXT SENTENCE { stabs_line(); }
|
|
*/
|
|
;
|
|
|
|
perform_statement:
|
|
PERFORM perform_options
|
|
;
|
|
if_statement:
|
|
if_part { gen_dstlabel($1); } end_if_opt
|
|
| if_part ELSE
|
|
{ $<dval>$=gen_passlabel(); gen_dstlabel($1); }
|
|
/* sentence { gen_dstlabel($<dval>3); } */
|
|
conditional_statement { gen_dstlabel($<dval>3); }
|
|
end_if_opt
|
|
;
|
|
search_statement:
|
|
SEARCH search end_search_opt
|
|
| SEARCH ALL search_all end_search_opt
|
|
;
|
|
evaluate_statement:
|
|
EVALUATE
|
|
{ $<ival>$ = gen_evaluate_start(); }
|
|
selection_subject_set
|
|
{ compute_subject_set_size($3); }
|
|
when_case_list
|
|
end_evaluate_or_eos
|
|
{ release_sel_subject($<ival>2,$3); }
|
|
;
|
|
end_evaluate_or_eos:
|
|
END_EVALUATE
|
|
| PERIOD_TOK
|
|
;
|
|
selection_subject_set:
|
|
{ $<sval>$=NULL; /* to store non-numeric symbols */ }
|
|
selection_subject { $$=save_sel_subject($2,NULL,$<sval>1); }
|
|
| selection_subject_set ALSO
|
|
{ $<sval>$=NULL; /* to store non-numeric symbols */ }
|
|
selection_subject
|
|
{ $$=save_sel_subject($4,$1,$<sval>3); }
|
|
;
|
|
selection_subject:
|
|
expr /* this already includes identifiers and literals */
|
|
{
|
|
if (push_expr($1))
|
|
$$=SSUBJ_EXPR;
|
|
else {
|
|
$<sval>0 = $1;
|
|
$$=SSUBJ_STR;
|
|
}
|
|
}
|
|
| condition { push_condition(); $$=SSUBJ_COND; }
|
|
| TRUE_TOK { $$=SSUBJ_TRUE; }
|
|
| FALSE_TOK { $$=SSUBJ_FALSE; }
|
|
;
|
|
when_case_list:
|
|
WHEN { $<ival>$ = loc_label++; /* mark end of "when" case */ }
|
|
{ $<ssbjval>$=$<ssbjval>-1; /* store inherited subject set */ }
|
|
when_case
|
|
sentence_or_nothing
|
|
{ $$=gen_end_when($<ival>-2,$<ival>2,$5); }
|
|
| when_case_list WHEN { $<ival>$ = loc_label++; }
|
|
{ $<ssbjval>$=$<ssbjval>-1; }
|
|
when_case
|
|
{ gen_bypass_when_case($1); }
|
|
sentence_or_nothing
|
|
{ $$=gen_end_when($<ival>-2,$<ival>3,$7); }
|
|
;
|
|
when_case:
|
|
{ $<sval>$ = NULL; }
|
|
selection_object
|
|
{
|
|
gen_when_check(0,$<ssbjval>0,$2,$<ival>-1,$<sval>1);
|
|
$$=0;
|
|
}
|
|
| when_case ALSO
|
|
{ $<sval>$ = NULL; }
|
|
selection_object
|
|
{
|
|
gen_when_check($1+1,$<ssbjval>0,$4,$<ival>-1,$<sval>3);
|
|
$$=$1+1;
|
|
}
|
|
| OTHER { $$=-1; }
|
|
;
|
|
selection_object:
|
|
ANY { $$=SOBJ_ANY; }
|
|
| TRUE_TOK { $$=SOBJ_TRUE; }
|
|
| FALSE_TOK { $$=SOBJ_FALSE; }
|
|
| not_opt expr
|
|
{
|
|
if (push_expr($2)) {
|
|
if ($1)
|
|
$$=SOBJ_NEGEXPR;
|
|
else
|
|
$$=SOBJ_EXPR;
|
|
}
|
|
else {
|
|
/* non-numeric comparation */
|
|
$<sval>0 = $2;
|
|
if ($1)
|
|
$$=SOBJ_NEGSTR;
|
|
else
|
|
$$=SOBJ_STR;
|
|
}
|
|
}
|
|
| not_opt expr THRU expr
|
|
{
|
|
if (push_expr($4) && push_expr($2)) {
|
|
if ($1)
|
|
$$=SOBJ_NEGRANGE;
|
|
else
|
|
$$=SOBJ_RANGE;
|
|
}
|
|
else {
|
|
yyerror("ranges only accepted for numeric variables");
|
|
}
|
|
}
|
|
| not_opt cond_name
|
|
{
|
|
gen_condition($2);
|
|
if ($1)
|
|
$$=SOBJ_NEGCOND;
|
|
else
|
|
$$=SOBJ_COND;
|
|
}
|
|
;
|
|
|
|
sentence_or_nothing:
|
|
/* nothing */ { $$ = 0; }
|
|
| conditional_statement { $$ = 1; }
|
|
;
|
|
|
|
if_part:
|
|
IF condition
|
|
{ $<dval>$=gen_testif(); }
|
|
end_then_opt
|
|
conditional_statement { $<dval>$=$<dval>3; }
|
|
/* sentence { $<dval>$=$<dval>3; }*/
|
|
;
|
|
|
|
/*
|
|
Fix me: This does not conform to the ANSI85 standard.
|
|
However, it does reduce the number of conflicts.
|
|
*/
|
|
conditional_statement: { stabs_line(); } statement_list
|
|
| { stabs_line(); } NEXT SENTENCE
|
|
/*
|
|
| { stabs_line(); } CONTINUE
|
|
*/
|
|
;
|
|
|
|
not_opt:
|
|
/* nothing */ { $$=0; }
|
|
| NOT { $$=1; }
|
|
;
|
|
end_if_opt:
|
|
| END_IF
|
|
;
|
|
end_then_opt:
|
|
| THEN
|
|
;
|
|
search:
|
|
variable_indexed
|
|
{
|
|
$<dval>$=loc_label++; /* determine END label name */
|
|
gen_marklabel();
|
|
/* yydebug=1; */
|
|
}
|
|
search_varying_opt
|
|
{
|
|
$<dval>$=loc_label++; /* determine search loop start label */
|
|
if ($3 == NULL) {
|
|
$3=determine_table_index_name($1);
|
|
if ($3 == NULL) {
|
|
yyerror("Unable to determine search index for table '%s'", $1->name);
|
|
}
|
|
}
|
|
gen_jmplabel($<dval>$); /* generate GOTO search loop start */
|
|
}
|
|
search_at_end
|
|
{
|
|
gen_jmplabel($<dval>2); /* generate GOTO END */
|
|
gen_dstlabel($<dval>4); /* generate search loop start label */
|
|
$<dval>$ = $<dval>2;
|
|
}
|
|
search_when_list
|
|
{
|
|
/* increment loop index, check for end */
|
|
gen_SearchLoopCheck($5, $3, $1);
|
|
|
|
gen_jmplabel($<dval>4); /* generate goto search loop start label */
|
|
gen_dstlabel($<dval>2); /* generate END label */
|
|
}
|
|
;
|
|
search_all:
|
|
variable_indexed
|
|
{
|
|
lbend=loc_label++; /* determine END label name */
|
|
gen_marklabel();
|
|
|
|
lbstart=loc_label++; /* determine search_all loop start label */
|
|
|
|
$<sval>$=determine_table_index_name($1);
|
|
if ($<sval>$ == NULL) {
|
|
yyerror("Unable to determine search index for table '%s'", $1->name);
|
|
}
|
|
else {
|
|
/* Initilize and store search table index boundaries */
|
|
Initialize_SearchAll_Boundaries($1, $<sval>$);
|
|
}
|
|
|
|
gen_jmplabel(lbstart); /* generate GOTO search_all loop start */
|
|
}
|
|
search_at_end
|
|
{
|
|
gen_jmplabel(lbend); /* generate GOTO END */
|
|
gen_dstlabel(lbstart); /* generate search loop start label */
|
|
}
|
|
search_all_when_list
|
|
{
|
|
/* adjust loop index, check for end */
|
|
gen_SearchAllLoopCheck($3, $<sval>2, $1, curr_field, lbstart, lbend);
|
|
}
|
|
;
|
|
|
|
search_varying_opt:
|
|
VARYING variable { $$=$2; }
|
|
| { $$=NULL; }
|
|
;
|
|
|
|
search_at_end:
|
|
at_opt END
|
|
{
|
|
$<dval>$=loc_label++; /* determine ATEND label name */
|
|
gen_dstlabel($<dval>$); /* determine ATEND label name */
|
|
}
|
|
statement_list
|
|
{
|
|
$<dval>$=$<dval>3;
|
|
}
|
|
|
|
|
{
|
|
$<dval>$=loc_label++; /* determine ATEND label name */
|
|
gen_dstlabel($<dval>$); /* determine ATEND label name */
|
|
}
|
|
;
|
|
|
|
search_when_list:
|
|
search_when { $$=$1; }
|
|
| search_when_list search_when { $$=$1; }
|
|
;
|
|
search_when:
|
|
WHEN
|
|
search_when_conditional
|
|
{ $<dval>$=gen_testif(); }
|
|
search_when_statement
|
|
{
|
|
$$ = $<dval>0;
|
|
gen_jmplabel($$); /* generate GOTO END */
|
|
gen_dstlabel($<dval>3);
|
|
}
|
|
;
|
|
|
|
search_when_statement:
|
|
statement_list
|
|
| NEXT SENTENCE
|
|
/*
|
|
| CONTINUE
|
|
*/
|
|
;
|
|
|
|
search_when_conditional:
|
|
/* name cond_op name { gen_compare($1,$2,$3); }
|
|
| name cond_op nliteral { gen_compare($1,$2,(struct sym *)$3); }
|
|
| name extended_cond_op name_or_lit { gen_compare($1,$2,$3); }
|
|
| name_or_lit extended_cond_op name { gen_compare($1,$2,$3); }
|
|
| nliteral cond_op nliteral {
|
|
gen_compare((struct sym *)$1,$2,(struct sym*)$3); } */
|
|
name_or_lit extended_cond_op name_or_lit { gen_compare($1,$2,$3); }
|
|
;
|
|
|
|
search_all_when_list:
|
|
search_all_when
|
|
| search_all_when_list search_all_when
|
|
;
|
|
search_all_when:
|
|
WHEN { curr_field = NULL; }
|
|
search_all_when_conditional
|
|
{ $<dval>$=gen_testif(); }
|
|
search_all_when_statement
|
|
{
|
|
gen_jmplabel(lbend); /* generate GOTO END */
|
|
gen_dstlabel($<dval>4);
|
|
}
|
|
;
|
|
|
|
search_all_when_statement:
|
|
statement_list
|
|
/* statement */
|
|
| NEXT SENTENCE
|
|
/*
|
|
| CONTINUE
|
|
*/
|
|
;
|
|
|
|
search_all_when_conditional:
|
|
variable is_opt CONDITIONAL to_opt variable
|
|
{
|
|
if ($3 != EQUAL)
|
|
yyerror("Only = conditional allowed in search all statement");
|
|
if (curr_field == NULL)
|
|
curr_field = $1;
|
|
gen_compare($1,$3,$5);
|
|
}
|
|
| variable is_opt CONDITIONAL to_opt literal
|
|
{
|
|
if ($3 != EQUAL)
|
|
yyerror("Only = conditional allowed in search all statement");
|
|
if (curr_field == NULL)
|
|
curr_field = $1;
|
|
gen_compare($1,$3,(struct sym *)$5);
|
|
}
|
|
| search_all_when_conditional AND { $<dval>$=gen_andstart(); }
|
|
search_all_when_conditional { gen_dstlabel($<dval>3); }
|
|
;
|
|
|
|
end_search_opt:
|
|
| END_SEARCH
|
|
;
|
|
|
|
unlock_statement:
|
|
UNLOCK name { gen_unlock($2); }
|
|
;
|
|
proto_statement:
|
|
TCOBPROTO1 gname { gen_tcob_proto1( $2 ); }
|
|
| TCOBPROTO2 gname gname { gen_tcob_proto2( $2,$3 ); }
|
|
;
|
|
trace_statement:
|
|
READY TRACE { }
|
|
| RESET TRACE { }
|
|
;
|
|
initiate_statement:
|
|
INITIATE name
|
|
;
|
|
generate_statement:
|
|
GENERATE name
|
|
;
|
|
terminate_statement:
|
|
TERMINATE name
|
|
;
|
|
cancel_statement:
|
|
CANCEL gname { gen_cancel($2); }
|
|
| CANCEL ALL { gen_cancel(NULL); }
|
|
;
|
|
|
|
/* MERGE statement */
|
|
merge_statement:
|
|
MERGE name sort_keys
|
|
{ sort_keys_append($2, $3); }
|
|
sort_collating_opt
|
|
{ gen_sort($2); }
|
|
merge_using
|
|
{ gen_sort_using($2, $7); }
|
|
sort_output
|
|
{
|
|
if ($9 != NULL) {
|
|
gen_sort_giving($2, $9);
|
|
}
|
|
}
|
|
;
|
|
merge_using:
|
|
USING sort_file_list { $$=$2; }
|
|
;
|
|
|
|
/* SORT statement */
|
|
sort_statement:
|
|
sort_file;
|
|
| sort_variable_indexed;
|
|
|
|
sort_file:
|
|
SORT name sort_keys
|
|
{ sort_keys_append($2, $3); }
|
|
sort_duplicates_opt sort_collating_opt
|
|
{ gen_sort($2); }
|
|
sort_input
|
|
{
|
|
if ($8 != NULL) {
|
|
gen_sort_using($2, $8);
|
|
}
|
|
}
|
|
sort_output
|
|
{
|
|
if ($10 != NULL) {
|
|
gen_sort_giving($2, $10);
|
|
}
|
|
}
|
|
;
|
|
|
|
sort_variable_indexed: // walter
|
|
SORT variable_indexed sort_keys_idx
|
|
{ sort_keys_append($2, $3); }
|
|
sort_duplicates_opt sort_collating_opt
|
|
{ gen_sort($2); }
|
|
;
|
|
|
|
sort_keys:
|
|
sort_key { $$=sort_keys_list_append(NULL, $1); }
|
|
| sort_keys sort_key { $$=sort_keys_list_append($1, $2); }
|
|
;
|
|
|
|
sort_keys_idx:
|
|
sort_key_idx { $$=sort_keys_list_append(NULL, $1); }
|
|
| sort_keys_idx sort_key_idx { $$=sort_keys_list_append($1, $2); }
|
|
;
|
|
|
|
sort_key:
|
|
on_opt DIRECTION key_opt sort_keys_names
|
|
{ $$=sort_key_list_create($4, $2); }
|
|
;
|
|
|
|
sort_key_idx:
|
|
on_opt DIRECTION key_opt sort_keys_names_idx
|
|
{ $$=sort_key_list_create($4, $2); }
|
|
;
|
|
|
|
sort_keys_names:
|
|
name { $$ = gvar_list_append(NULL, $1, source_lineno); }
|
|
| sort_keys_names name { $$ = gvar_list_append($1, $2, source_lineno); }
|
|
;
|
|
|
|
sort_keys_names_idx:
|
|
variable_indexed { $$ = gvar_list_append(NULL, $1, source_lineno); }
|
|
| sort_keys_names_idx variable_indexed { $$ = gvar_list_append($1, $2, source_lineno); }
|
|
;
|
|
|
|
sort_duplicates_opt:
|
|
| with_opt DUPLICATES in_opt order_opt
|
|
{
|
|
UNIMPLEMENTED ("SORT with duplicates in order clause")
|
|
/* unimplemented */
|
|
}
|
|
;
|
|
|
|
sort_collating_opt:
|
|
| collating_sequence
|
|
{ UNIMPLEMENTED ("SORT/MERGE collating sequence clause") /* unimplemented */ }
|
|
;
|
|
|
|
/* SORT and MERGE statement clauses */
|
|
sort_input:
|
|
INPUT PROCEDURE is_opt perform_range { $$=NULL; }
|
|
| USING sort_file_list { $$=$2; }
|
|
;
|
|
sort_output:
|
|
OUTPUT PROCEDURE is_opt perform_range { $$=NULL; }
|
|
| GIVING sort_file_list { $$=$2; }
|
|
;
|
|
sort_file_list:
|
|
name { $$ = alloc_sortfile_node($1); }
|
|
| sort_file_list name
|
|
{
|
|
$1->next = alloc_sortfile_node($2); $$=$1;
|
|
}
|
|
;
|
|
|
|
/* MOVE statement */
|
|
move_statement:
|
|
MOVE gname TO name_var_list { gen_moves($2, $4); }
|
|
| MOVE CORRESPONDING name_var TO name_var { gen_movecorr($3, $5); }
|
|
| MOVE LENGTH OF gname TO name_var { gen_movelength($4, $6); }
|
|
| MOVE gname TO { yyerror("Expected variable"); }
|
|
;
|
|
/* INITIALIZE statement walter 13-12-05 (_verb) gname_list removi o initialize_replacing_opt*/
|
|
initialize_statement:
|
|
/* INITIALIZE gname_list initialize_replacing_opt { gen_initializes_verb($2,init_alphab,init_alpha,init_alphaedt,init_num,init_numedt); } */
|
|
INITIALIZE gname_list initialize_replacing_opt { gen_initializes($2); }
|
|
| INITIALIZE { yyerror("INITIALIZE: expected a variable name");}
|
|
;
|
|
initialize_replacing_opt:
|
|
| REPLACING initialize_replacing_lists
|
|
{ UNIMPLEMENTED ("INITIALIZE ... REPLACING clause") }
|
|
;
|
|
initialize_replacing_lists:
|
|
initialize_replacing_list
|
|
| initialize_replacing_lists initialize_replacing_list
|
|
;
|
|
initialize_replacing_list:
|
|
initialize_type_list data_opt BY gname { /* not implimented */ }
|
|
;
|
|
initialize_type_list:
|
|
ALPHABETIC { }
|
|
| ALPHANUMERIC { }
|
|
| NUMERIC { }
|
|
| ALPHANUMERIC_EDITED { }
|
|
| NUMERIC_EDITED { }
|
|
;
|
|
|
|
/* Compute statement */
|
|
compute_statement:
|
|
COMPUTE compute_body end_compute_opt
|
|
| COMPUTE { yyerror(err_msg_bad_form, "COMPUTE");}
|
|
;
|
|
compute_body:
|
|
var_list_name CONDITIONAL expr on_size_error_opt
|
|
{
|
|
if ($2 != EQUAL)
|
|
yyerror("= expected");
|
|
else if ($4 == NULL)
|
|
gen_compute1($1, $3);
|
|
else
|
|
gen_compute2($1, $3, $4);
|
|
delete_mathvar_info($1);
|
|
if ($4 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
;
|
|
end_compute_opt:
|
|
/* nothing */
|
|
| END_COMPUTE
|
|
;
|
|
|
|
/* Add statement */
|
|
add_statement:
|
|
ADD add_body end_add_opt
|
|
| ADD { yyerror(err_msg_bad_form, "ADD");}
|
|
;
|
|
add_body:
|
|
var_list_gname TO var_list_name on_size_error_opt
|
|
{
|
|
gen_add1($1, $3, $4);
|
|
delete_mathvar_info($1);
|
|
delete_mathvar_info($3);
|
|
if ($4 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| var_list_gname add_to_opt GIVING var_list_name on_size_error_opt
|
|
{
|
|
gen_add2($1, $4, $2, $5);
|
|
delete_mathvar_info($1);
|
|
delete_mathvar_info($4);
|
|
if ($5 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| CORRESPONDING var_list_gname TO var_list_name rounded_opt on_size_error_opt
|
|
{
|
|
gen_addcorr1($2, $4, $5, $6);
|
|
delete_mathvar_info($2);
|
|
delete_mathvar_info($4);
|
|
if ($6 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
;
|
|
add_to_opt:
|
|
/* nothing */ { $$ = NULL; }
|
|
| TO gname { $$ = $2; }
|
|
;
|
|
end_add_opt:
|
|
/* nothing */
|
|
| END_ADD
|
|
;
|
|
|
|
/* Subtract statement */
|
|
|
|
subtract_statement:
|
|
SUBTRACT subtract_body end_subtract_opt
|
|
| SUBTRACT { yyerror(err_msg_bad_form, "SUBTRACT");}
|
|
;
|
|
subtract_body:
|
|
var_list_gname FROM var_list_name on_size_error_opt
|
|
{
|
|
gen_subtract1($1, $3, $4);
|
|
delete_mathvar_info($1);
|
|
delete_mathvar_info($3);
|
|
if ($4 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| var_list_gname FROM gname GIVING var_list_name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($3);
|
|
gen_subtract2($1, $5, $3, $6);
|
|
delete_mathvar_info($1);
|
|
delete_mathvar_info($5);
|
|
if ($6 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| CORRESPONDING var_list_gname FROM var_list_name rounded_opt on_size_error_opt
|
|
{
|
|
gen_subtractcorr1($2, $4, $5, $6);
|
|
delete_mathvar_info($2);
|
|
delete_mathvar_info($4);
|
|
if ($6 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
;
|
|
end_subtract_opt:
|
|
| END_SUBTRACT
|
|
;
|
|
|
|
/* Multiply statement */
|
|
|
|
multiply_statement:
|
|
MULTIPLY multiply_body end_multiply_opt
|
|
| MULTIPLY { yyerror(err_msg_bad_form, "MULTIPLY");}
|
|
;
|
|
multiply_body:
|
|
gname BY gname GIVING var_list_name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($1);
|
|
assert_numeric_sy($3);
|
|
gen_multiply2($5, $1, $3, $6);
|
|
delete_mathvar_info($5);
|
|
if ($6 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| gname BY var_list_name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($1);
|
|
gen_multiply1($3, $1, $4);
|
|
delete_mathvar_info($3);
|
|
if ($4 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
;
|
|
end_multiply_opt:
|
|
/* nothing */
|
|
| END_MULTIPLY
|
|
;
|
|
|
|
/* Divide statement */
|
|
|
|
divide_statement:
|
|
DIVIDE divide_body end_divide_opt
|
|
| DIVIDE { yyerror(err_msg_bad_form, "DIVIDE");}
|
|
;
|
|
divide_body:
|
|
gname BY gname GIVING var_list_name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($1);
|
|
assert_numeric_sy($3);
|
|
gen_divide2($5, $1, $3, $6);
|
|
delete_mathvar_info($5);
|
|
if ($6 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| gname BY gname GIVING name rounded_opt REMAINDER name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($1);
|
|
assert_numeric_sy($3);
|
|
assert_numeric_dest_sy($5);
|
|
gen_divide4($1, $3, $5, $8, $6, $9);
|
|
if ($9 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| gname INTO gname GIVING name rounded_opt REMAINDER name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($1);
|
|
assert_numeric_sy($3);
|
|
assert_numeric_dest_sy($5);
|
|
gen_divide4($3, $1, $5, $8, $6, $9);
|
|
if ($9 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| gname INTO gname GIVING var_list_name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($1);
|
|
assert_numeric_sy($3);
|
|
gen_divide2($5, $3, $1, $6);
|
|
delete_mathvar_info($5);
|
|
if ($6 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
| gname INTO var_list_name on_size_error_opt
|
|
{
|
|
assert_numeric_sy($1);
|
|
gen_divide1($3, $1, $4);
|
|
delete_mathvar_info($3);
|
|
if ($4 != NULL)
|
|
tmose = NULL;
|
|
}
|
|
;
|
|
end_divide_opt:
|
|
/* nothing */
|
|
| END_DIVIDE
|
|
;
|
|
|
|
/* Accept statement */
|
|
accept_statement:
|
|
accept_hardware /* Accept format 1 (hardware) */
|
|
| accept_chronological /* Accept format 2 (chronological) */
|
|
| accept_screen /* Accept format 3 (screen) */
|
|
| ACCEPT { yyerror(err_msg_bad_form, "ACCEPT");}
|
|
;
|
|
accept_hardware:
|
|
ACCEPT name FROM INKEY end_accept_opt { gen_accept_from_inkey($2); }
|
|
| ACCEPT name FROM INPUT STATUS end_accept_opt { gen_accept_from_inkey($2); }
|
|
| ACCEPT name FROM CMD_LINE end_accept_opt { gen_accept_from_cmdline($2); }
|
|
| ACCEPT name FROM ESCKEY end_accept_opt { gen_accept_from_escapekey($2); } /* walter */
|
|
| ACCEPT name FROM ENVIRONMENT_VARIABLE CLITERAL end_accept_opt
|
|
{
|
|
save_literal($5,'X');
|
|
$5->all=0;
|
|
gen_accept_env_var($2, $5);
|
|
}
|
|
;
|
|
accept_chronological:
|
|
ACCEPT name FROM DATE_TIME end_accept_opt
|
|
{
|
|
gen_accept_from_chron($2, $4, 0);
|
|
}
|
|
;
|
|
accept_screen:
|
|
ACCEPT name accept_display_options end_accept_opt
|
|
{
|
|
/* walter acrescentei co ao final de todo gen_accept( */
|
|
/* gen_accept($2, $3, 1); */
|
|
co = ((bg * 8) + fg);
|
|
gen_accept($2, $3, 1, co);
|
|
}
|
|
| ACCEPT name accept_display_options
|
|
on_opt EXCEPTION {
|
|
screen_io_enable++;
|
|
HTG_prg_uses_term = 1;
|
|
/* gen_accept($2, $3, 1); */
|
|
co = ((bg * 8) + fg);
|
|
gen_accept($2, $3, 1, co);
|
|
}
|
|
variable {
|
|
gen_store_fnres($7);
|
|
$<dval>$ = gen_check_zero();
|
|
}
|
|
statement_list { gen_dstlabel($<dval>8); }
|
|
end_accept_opt
|
|
;
|
|
end_accept_opt:
|
|
/* Nothing */
|
|
| END_ACCEPT
|
|
;
|
|
|
|
/* Display statement */
|
|
display_statement:
|
|
display_line
|
|
| display_screen
|
|
| DISPLAY { yyerror(err_msg_bad_form, "DISPLAY");}
|
|
;
|
|
display_line:
|
|
DISPLAY display_varlist display_upon display_line_options end_display_opt
|
|
/* walter acrescentei 0 */
|
|
{ gen_display_line($3, $4, 0); }
|
|
;
|
|
display_screen:
|
|
DISPLAY display_varlist accept_display_options end_display_opt
|
|
{
|
|
/* walter acrescentei co ao final de todo gen_accept( */
|
|
/* gen_accept($2, $3, 1); */
|
|
co = ((bg * 8) + fg);
|
|
gen_display_screen($3, co); }
|
|
;
|
|
display_varlist:
|
|
gname { put_disp_list($1); }
|
|
| display_varlist sep_opt gname { put_disp_list($3); }
|
|
;
|
|
display_upon:
|
|
UPON CONSOLE { $$ = 1; }
|
|
| UPON STD_OUTPUT { $$ = 1; }
|
|
| UPON STD_ERROR { $$ = 2; }
|
|
;
|
|
display_line_options:
|
|
/* nothing */ { $$ = 0; }
|
|
| display_line_options with_opt NO ADVANCING { $$ = $1 | SCR_NO_ADVANCING; }
|
|
| display_line_options with_opt ERASE { $$ = $1 | SCR_ERASE_EOL; }
|
|
| display_line_options with_opt ERASE EOS { $$ = $1 | SCR_ERASE_EOS; }
|
|
| display_line_options with_opt ERASE EOL { $$ = $1 | SCR_ERASE_EOL; }
|
|
| display_line_options with_opt ERASE SCREEN { $$ = $1 | SCR_ERASE_EOS; }
|
|
;
|
|
end_display_opt:
|
|
/* Nothing */
|
|
| END_DISPLAY
|
|
;
|
|
/* common options for display and accept */
|
|
/*line_position:
|
|
| at_opt scr_line scr_position { }
|
|
| scr_line_position { }
|
|
;*/
|
|
scr_line:
|
|
LINE number_opt expr
|
|
{
|
|
screen_io_enable++;
|
|
HTG_prg_uses_term = 1;
|
|
push_expr($3);
|
|
gen_gotoy_expr();
|
|
}
|
|
;
|
|
scr_position:
|
|
COLUMN number_opt expr
|
|
{
|
|
screen_io_enable++;
|
|
HTG_prg_uses_term = 1;
|
|
push_expr($3);
|
|
gen_gotox_expr();
|
|
}
|
|
| POSITION expr
|
|
{
|
|
screen_io_enable++;
|
|
HTG_prg_uses_term = 1;
|
|
push_expr($2);
|
|
gen_gotox_expr();
|
|
}
|
|
;
|
|
scr_line_position:
|
|
AT NLITERAL
|
|
{
|
|
screen_io_enable++;
|
|
HTG_prg_uses_term = 1;
|
|
scr_push_display_position($2);
|
|
}
|
|
| AT variable
|
|
{
|
|
screen_io_enable++;
|
|
HTG_prg_uses_term = 1;
|
|
scr_push_display_position($2);
|
|
}
|
|
;
|
|
accept_display_options:
|
|
/* walter acrescentei co = 0 */
|
|
/* nothing */ { fg = 0; bg = 0; $$ = 0; }
|
|
| accept_display_options accept_display_option { $$ = $1 | $2; }
|
|
;
|
|
accept_display_option:
|
|
with_opt screen_attribx { $$ = $2; }
|
|
| scr_line { $$ = 0; }
|
|
| scr_position { $$ = 0; }
|
|
| scr_line_position { $$ = 0; }
|
|
/* walter
|
|
| FOREGROUNDCOLOR integer { $$ = 0; fg = $2; }
|
|
| BACKGROUNDCOLOR integer { $$ = 0; bg = $2; } */
|
|
;
|
|
/* Open statement */
|
|
open_statement:
|
|
OPEN open_options { HTG_prg_uses_fileio = 1; }
|
|
| OPEN { yyerror(err_msg_bad_form, "OPEN");}
|
|
;
|
|
open_options:
|
|
open_mode open_varlist { }
|
|
| open_options open_mode open_varlist { }
|
|
;
|
|
/* OPENMD { $$ = $1; } */
|
|
open_mode:
|
|
INPUT { $$=1; }
|
|
| I_O { $$=2; }
|
|
| OUTPUT { $$=3; }
|
|
| EXTEND { $$=4; }
|
|
| error { yyerror("invalid OPEN mode"); }
|
|
;
|
|
open_varlist:
|
|
name { gen_open($<ival>0, $<sval>1); }
|
|
| open_varlist sep_opt name { gen_open($<ival>0, $<sval>3); }
|
|
;
|
|
|
|
/* Close statement */
|
|
|
|
close_statement:
|
|
CLOSE close_files
|
|
| CLOSE { yyerror(err_msg_bad_form, "CLOSE");}
|
|
;
|
|
close_files:
|
|
close_file
|
|
| close_files sep_opt close_file
|
|
;
|
|
close_file:
|
|
name close_options_opt { gen_close($1); }
|
|
;
|
|
close_options_opt:
|
|
close_options
|
|
{
|
|
$$=0;
|
|
UNIMPLEMENTED ("CLOSE options clause")
|
|
}
|
|
| with_lock_opt { $$=$1; }
|
|
;
|
|
close_options:
|
|
with_opt NO REWIND { }
|
|
| REEL { }
|
|
| UNIT { }
|
|
| REEL for_opt REMOVAL { }
|
|
| UNIT for_opt REMOVAL { }
|
|
;
|
|
with_lock_opt:
|
|
with_opt LOCK { $$=1; }
|
|
| with_opt IGNORE LOCK { $$=2; }
|
|
| /* nothing */ { $$=0; }
|
|
;
|
|
|
|
/* Return statements */
|
|
|
|
return_statement:
|
|
RETURN return_body end_return_opt
|
|
| RETURN { yyerror(err_msg_bad_form, "RETURN");}
|
|
;
|
|
return_body:
|
|
name
|
|
record_opt
|
|
read_into_opt
|
|
{
|
|
if (gen_reads($1, $3, NULL, 1, 4, 0) != 0) {
|
|
YYABORT;
|
|
}
|
|
}
|
|
| name
|
|
record_opt
|
|
read_into_opt
|
|
read_at_end_opt
|
|
{
|
|
if (gen_reads($1, $3, NULL, 1, 5, 0) != 0) {
|
|
YYABORT;
|
|
}
|
|
else {
|
|
ginfo_container4($4);
|
|
gic = NULL;
|
|
}
|
|
}
|
|
;
|
|
|
|
/* Read statements */
|
|
|
|
read_statement:
|
|
READ read_body end_read_opt { }
|
|
| READ { yyerror(err_msg_bad_form, "READ");}
|
|
;
|
|
read_body:
|
|
name
|
|
read_next_opt
|
|
record_opt
|
|
read_into_opt
|
|
with_lock_opt
|
|
read_key_opt
|
|
{
|
|
if (gen_reads($1, $4, $6, $2, 0, $5) != 0) {
|
|
YYABORT;
|
|
}
|
|
else {
|
|
gen_perform_decl($1);
|
|
}
|
|
}
|
|
| name
|
|
read_next_opt
|
|
record_opt
|
|
read_into_opt
|
|
with_lock_opt
|
|
read_key_opt
|
|
read_at_end_opt
|
|
{
|
|
if (gen_reads($1, $4, $6, $2, 1, $5) != 0) {
|
|
YYABORT;
|
|
}
|
|
else {
|
|
ginfo_container4($7);
|
|
gen_perform_decl($1);
|
|
gic = NULL;
|
|
}
|
|
}
|
|
| name
|
|
read_next_opt
|
|
record_opt
|
|
read_into_opt
|
|
with_lock_opt
|
|
read_key_opt
|
|
read_invalid_key_opt
|
|
{
|
|
if (gen_reads($1, $4, $6, $2, 2, $5) != 0) {
|
|
YYABORT;
|
|
}
|
|
else {
|
|
gen_test_invalid_keys ($7, $1, 23);
|
|
gen_perform_decl($1);
|
|
}
|
|
}
|
|
;
|
|
read_next_opt:
|
|
/* nothing */ { $$ = 0; }
|
|
| NEXT { $$ = 1; }
|
|
| PREVIOUS { $$ = 2; }
|
|
;
|
|
read_into_opt:
|
|
/* nothing */ { $$ = NULL; }
|
|
| INTO name { $$ = $2; }
|
|
;
|
|
read_key_opt:
|
|
/* nothing */ { $$ = NULL; }
|
|
| KEY is_opt name { $$ = $3; }
|
|
;
|
|
read_at_end_opt:
|
|
NOT at_opt on_end
|
|
{
|
|
ginfo_container2($3, 2);
|
|
$$=ginfo_container3($3, 2);
|
|
}
|
|
| AT on_end
|
|
{
|
|
ginfo_container2($2, 1);
|
|
$$=ginfo_container3($2, 1);
|
|
}
|
|
| on_end
|
|
{
|
|
ginfo_container2($1, 1);
|
|
$$=ginfo_container3($1, 1);
|
|
}
|
|
| AT on_end NOT at_opt
|
|
{
|
|
ginfo_container2($2, 1);
|
|
}
|
|
on_end
|
|
{
|
|
ginfo_container2($6, 2);
|
|
$$=ginfo_container3($6, 3);
|
|
}
|
|
| on_end NOT at_opt
|
|
{
|
|
ginfo_container2($1, 1);
|
|
}
|
|
on_end
|
|
{
|
|
ginfo_container2($5, 2);
|
|
$$=ginfo_container3($5, 3);
|
|
}
|
|
;
|
|
on_end:
|
|
END
|
|
{
|
|
if ( gic == NULL ) {
|
|
gic=ginfo_container0();
|
|
}
|
|
$<gic>$=ginfo_container1(gic);
|
|
stabs_line();
|
|
}
|
|
statement_list
|
|
{
|
|
$$=$<gic>2;
|
|
}
|
|
;
|
|
read_invalid_key_opt:
|
|
read_invalid_key { $$ = gen_invalid_keys ($1, NULL); }
|
|
| read_not_invalid_key { $$ = gen_invalid_keys (NULL, $1); }
|
|
| read_invalid_key read_not_invalid_key { $$ = gen_invalid_keys ($1, $2); }
|
|
;
|
|
read_invalid_key:
|
|
INVALID key_opt { $<ike>$ = gen_before_invalid_key (); }
|
|
statement_list { $$ = gen_after_invalid_key ($<ike>3); }
|
|
;
|
|
read_not_invalid_key:
|
|
NOT INVALID key_opt { $<ike>$ = gen_before_invalid_key (); }
|
|
statement_list { $$ = gen_after_invalid_key ($<ike>4); }
|
|
;
|
|
end_read_opt:
|
|
/* nothing */
|
|
| END_READ
|
|
;
|
|
end_return_opt:
|
|
/* nothing */
|
|
| END_RETURN
|
|
;
|
|
|
|
/* Release statement */
|
|
|
|
release_statement:
|
|
RELEASE name release_from_opt
|
|
{
|
|
gen_release($2, $3);
|
|
}
|
|
;
|
|
release_from_opt:
|
|
/* nothing */ { $$ = NULL; }
|
|
| FROM gname { $$ = $2; }
|
|
;
|
|
|
|
/* Write statement */
|
|
|
|
write_statement:
|
|
WRITE name write_from_opt write_options
|
|
{
|
|
if ($2->level != 1)
|
|
yyerror("variable %s could not be used for WRITE", $2->name);
|
|
gen_write($2, $4, $3, write_advancing_sw);
|
|
}
|
|
invalid_key_opt
|
|
end_write_opt {gen_test_invalid_keys ($6, $2, 22);}
|
|
;
|
|
write_from_opt:
|
|
/* nothing */ { $$ = NULL; }
|
|
| FROM gname { $$ = $2; }
|
|
;
|
|
write_options:
|
|
/* nothing */ { $$ = NULL; write_advancing_sw = 0; }
|
|
| before_after advancing_opt gname line_lines_opt
|
|
{
|
|
/* gen_loadvar($3); */
|
|
$$ = $3;
|
|
write_advancing_sw = $1;
|
|
}
|
|
| before_after advancing_opt PAGE
|
|
{
|
|
write_advancing_sw = -$1;
|
|
$$ = NULL;
|
|
}
|
|
;
|
|
end_write_opt:
|
|
/* nothing */
|
|
| END_WRITE
|
|
;
|
|
|
|
/* Rewrite statement */
|
|
|
|
rewrite_statement:
|
|
REWRITE name write_from_opt
|
|
{
|
|
if ($2->level != 1)
|
|
yyerror("variable %s could not be used for REWRITE", $2->name);
|
|
gen_rewrite($2, $3);
|
|
}
|
|
invalid_key_opt
|
|
end_rewrite_opt {gen_test_invalid_keys ($5, $2, 22);}
|
|
;
|
|
end_rewrite_opt:
|
|
/* nothing */
|
|
| END_REWRITE
|
|
;
|
|
|
|
/* Delete statement */
|
|
|
|
delete_statement:
|
|
DELETE name record_opt { gen_delete($2); }
|
|
invalid_key_opt
|
|
end_delete_opt {gen_test_invalid_keys ($5, $2, 23);}
|
|
;
|
|
end_delete_opt:
|
|
/* nothing */
|
|
| END_DELETE
|
|
;
|
|
|
|
/* Start statement */
|
|
|
|
start_statement:
|
|
START start_body
|
|
invalid_key_opt {gen_test_invalid_keys ($3, $2, 23);}
|
|
end_start_opt
|
|
;
|
|
start_body:
|
|
name { gen_start($1,0,NULL); $$ = $1;}
|
|
| name KEY is_opt cond_op name { gen_start($1,$4,$5); $$ = $1;}
|
|
;
|
|
end_start_opt:
|
|
/* nothing */
|
|
| END_START
|
|
;
|
|
|
|
/*
|
|
GO TO statements
|
|
Format 1: Unconditional
|
|
Format 2: Conditional (DEPENDING ON)
|
|
Format 3: Altered (Paragraph-name. GO TO.) - not implemented
|
|
*/
|
|
goto_statement:
|
|
GO to_opt goto_label { gen_goto($3); }
|
|
| GO to_opt goto_label_list DEPENDING on_opt variable
|
|
{
|
|
if (is_numeric_sy($6))
|
|
gen_goto_depending($3, $6);
|
|
else yyerror("variable '%s' must be numeric", $6->name);
|
|
}
|
|
;
|
|
goto_label: label { $$ = insert_list(NULL, $1); }
|
|
;
|
|
goto_label_list:
|
|
label { $$ = insert_list(NULL, $1); }
|
|
| goto_label_list label { $$ = insert_list($1, $2); }
|
|
| goto_label_list LISTSEP label { $$ = insert_list($1, $3); }
|
|
;
|
|
|
|
/* CALL statement */
|
|
call_statement:
|
|
CALL { curr_call_mode=CM_REF; }
|
|
call_convention_opt
|
|
gname
|
|
using_options
|
|
returning_options
|
|
{ $<ival>$ = loc_label++; /* exception check */ }
|
|
{ $<ival>$ = loc_label++; /* not exception check */ }
|
|
{
|
|
$<ival>$ = emt_call((struct lit *)$4, $5, $<ival>7, $<ival>8, $6);
|
|
/* gen_store_fnres($6); */
|
|
/* If paramater is a variable then dynamic link libs are required */
|
|
/*
|
|
if ($4->litflag == 0 ) {
|
|
HTG_prg_uses_dcall = 1;
|
|
}
|
|
*/
|
|
}
|
|
on_exception_or_overflow
|
|
on_not_exception { check_call_except($10, $11, $<ival>7, $<ival>8, $<ival>9); }
|
|
end_call_opt
|
|
| CALL { yyerror(err_msg_bad_form, "CALL"); }
|
|
;
|
|
|
|
call_convention_opt: { curr_call_convention = 0; }
|
|
| CALL_CONV_C { curr_call_convention = 0; }
|
|
| CALL_CONV_STDCALL { curr_call_convention = 1; }
|
|
/* | CALL_CONV_STDCALL { yyerror("STDCALL (WINAPI) convention is not implimented"); }*/
|
|
;
|
|
|
|
/* CALL-LOADLIB statement */
|
|
call_loadlib_statement:
|
|
CALL_LOADLIB
|
|
gname
|
|
{
|
|
emt_call_loadlib((struct lit *)$2);
|
|
}
|
|
end_call_loadlib_opt
|
|
| CALL_LOADLIB { yyerror(err_msg_bad_form, "CALL-LOADLIB"); }
|
|
;
|
|
|
|
/* END-CALL-LOADLIB */
|
|
end_call_loadlib_opt: END_CALL_LOADLIB { }
|
|
| { }
|
|
;
|
|
|
|
/* CHAIN statement */
|
|
chain_statement:
|
|
CHAIN { curr_call_mode=CM_CHAIN; }
|
|
gname
|
|
using_options { $<ival>$ = loc_label++; /* exception check */ }
|
|
{ $<ival>$ = gen_chain($3,$4,$<ival>5); }
|
|
on_exception_or_overflow
|
|
{/* check_call_except($9,$10,$<ival>6,$<ival>7,$<ival>8);*/ }
|
|
end_chain_opt
|
|
| CHAIN { yyerror(err_msg_bad_form, "CHAIN"); }
|
|
;
|
|
|
|
/* EXIT statement */
|
|
exit_statement:
|
|
EXIT { gen_exit(0); }
|
|
| EXIT PARAGRAPH { gen_exit(0); }
|
|
| EXIT PROGRAM { gen_exit(1); }
|
|
;
|
|
|
|
/* Stop statement */
|
|
stop_statement:
|
|
STOP RUN { gen_stoprun(); }
|
|
| STOP stop_literal
|
|
{
|
|
struct sym *sy;
|
|
/* walter acrescentei 0 ao final */
|
|
gen_display_line(2, SCR_NO_ADVANCING, 0);
|
|
sy = define_temp_field(DTYPE_ALPHANUMERIC,1);
|
|
/* walter acrescentei 0 ao final
|
|
gen_accept(sy, 0, 1); */
|
|
gen_accept(sy, 0, 1, 0);
|
|
}
|
|
;
|
|
stop_literal:
|
|
CLITERAL
|
|
{
|
|
save_literal($1,'X');
|
|
$1->all=0;
|
|
put_disp_list((struct sym *)$1);
|
|
}
|
|
| NLITERAL
|
|
{
|
|
save_literal($1,'X');
|
|
$1->all=0;
|
|
put_disp_list((struct sym *)$1);
|
|
}
|
|
;
|
|
|
|
/* Goback statement */
|
|
goback_statement:
|
|
GOBACK { gen_goback(); }
|
|
;
|
|
|
|
var_list_name: name rounded_opt sep_opt
|
|
{
|
|
$$ = create_mathvar_info(NULL, $1, $2);
|
|
}
|
|
| var_list_name name rounded_opt sep_opt
|
|
{
|
|
$$ = create_mathvar_info($1, $2, $3);
|
|
}
|
|
;
|
|
|
|
var_list_gname: gname sep_opt
|
|
{
|
|
$$ = create_mathvar_info(NULL, $1, 0);
|
|
}
|
|
| var_list_gname gname sep_opt
|
|
{
|
|
$$ = create_mathvar_info($1, $2, 0);
|
|
}
|
|
;
|
|
|
|
rounded_opt:
|
|
/* Nothing */ { $$=0; }
|
|
| ROUNDED { $$=1; }
|
|
;
|
|
|
|
on_size_error_opt:
|
|
/* nothing */
|
|
{
|
|
$$=NULL;
|
|
}
|
|
| NOT on_opt SIZE
|
|
on_size_error
|
|
{
|
|
$$=math_on_size_error4($4, 2);
|
|
}
|
|
| on_opt SIZE
|
|
on_size_error
|
|
{
|
|
$$=math_on_size_error4($3, 1);
|
|
}
|
|
| on_opt SIZE
|
|
on_size_error
|
|
NOT on_opt SIZE
|
|
{
|
|
$3->lbl1=$3->ose;
|
|
}
|
|
on_size_error
|
|
{
|
|
$$=math_on_size_error4($8, 3);
|
|
}
|
|
;
|
|
|
|
on_size_error:
|
|
ERROR_TOK
|
|
{
|
|
if ( tmose == NULL ) {
|
|
tmose=math_on_size_error0();
|
|
$<mose>$=math_on_size_error1(tmose);
|
|
}
|
|
else {
|
|
$<mose>$=math_on_size_error1(tmose);
|
|
}
|
|
stabs_line();
|
|
}
|
|
statement_list
|
|
{
|
|
math_on_size_error2(tmose);
|
|
$<mose>$=$<mose>2;
|
|
}
|
|
;
|
|
|
|
size_opt:
|
|
/* nothing */
|
|
| SIZE
|
|
;
|
|
end_call_opt:
|
|
/* nothing */
|
|
| END_CALL
|
|
;
|
|
end_chain_opt:
|
|
/* nothing */
|
|
| END_CHAIN
|
|
;
|
|
|
|
/* SET statement */
|
|
set_statement:
|
|
SET set_list ;
|
|
set_list:
|
|
set_target TO address_of_opt set_variable_or_nlit
|
|
{ gen_set_list($1,SET_TO,$4,0,$3); }
|
|
| set_target UP BY var_or_nliteral
|
|
{ gen_set_list($1,SET_UP_BY,$4,0,0); }
|
|
| set_target DOWN BY var_or_nliteral
|
|
{ gen_set_list($1,SET_DOWN_BY,$4,0,0); }
|
|
| address_of_opt variable TO address_of_opt set_variable
|
|
{ gen_set($2,SET_TO,$5,$1,$4); }
|
|
;
|
|
|
|
set_target:
|
|
/* variable { $$ = $1; } */
|
|
name_list { $$ = $1; }
|
|
| cond_name { $$ = (struct sym *)chain_var($1); }
|
|
;
|
|
|
|
set_variable:
|
|
variable { $$ = $1; }
|
|
| NULL_TOK { $$ = NULL; }
|
|
;
|
|
|
|
set_variable_or_nlit:
|
|
name_or_lit { $$ = $1; }
|
|
| ON { $$ = (struct sym *)define_num_lit(1); }
|
|
| OFF { $$ = (struct sym *)spe_lit_ZE; }
|
|
| NULL_TOK { $$ = NULL; }
|
|
| TRUE_TOK
|
|
{
|
|
$$ = (struct sym *)1;
|
|
/* no (struct sym *) may have this value! */
|
|
}
|
|
;
|
|
|
|
address_of_opt:
|
|
/* nothing */ { $$ = 0; }
|
|
| ADDRESS of_opt { $$ = 1; }
|
|
;
|
|
|
|
/* String and Unstring statements */
|
|
|
|
string_statement:
|
|
STRINGCMD string_from_list
|
|
INTO name string_with_pointer {
|
|
gen_stringcmd( $2, $4, $5 );
|
|
}
|
|
on_overflow_opt
|
|
end_stringcmd_opt
|
|
;
|
|
unstring_statement:
|
|
UNSTRING name
|
|
unstring_delimited
|
|
INTO unstring_destinations
|
|
string_with_pointer
|
|
unstring_tallying {
|
|
gen_unstring( $2, $3, $5, $6, $7 );
|
|
}
|
|
on_overflow_opt
|
|
end_unstring_opt
|
|
;
|
|
unstring_delimited:
|
|
DELIMITED by_opt unstring_delimited_vars { $$=$3; }
|
|
| /* nothing */ { $$=NULL; }
|
|
;
|
|
unstring_delimited_vars:
|
|
all_opt gname { $$=alloc_unstring_delimited($1,$2); }
|
|
| unstring_delimited_vars OR all_opt gname {
|
|
struct unstring_delimited *ud;
|
|
ud=alloc_unstring_delimited($3,$4);
|
|
ud->next = $1;
|
|
$$=ud;
|
|
}
|
|
;
|
|
unstring_destinations:
|
|
unstring_dest_var { $$=$1; }
|
|
| unstring_destinations sep_opt
|
|
unstring_dest_var {
|
|
$3->next = $1;
|
|
$$ = $3;
|
|
}
|
|
;
|
|
unstring_dest_var:
|
|
name unstring_delim_opt unstring_count_opt {
|
|
$$ = alloc_unstring_dest( $1, $2, $3 );
|
|
}
|
|
;
|
|
unstring_delim_opt:
|
|
/* nothing */ { $$=NULL; }
|
|
| DELIMITER in_opt name { $$=$3; }
|
|
;
|
|
unstring_count_opt:
|
|
/* nothing */ { $$=NULL; }
|
|
| COUNT in_opt name { $$=$3; }
|
|
;
|
|
unstring_tallying:
|
|
/* nothing */ { $$=NULL; }
|
|
| TALLYING in_opt name { $$=$3; }
|
|
;
|
|
all_opt:
|
|
/* nothing */ { $$=0; }
|
|
| ALL { $$=1; }
|
|
;
|
|
on_overflow_opt:
|
|
{ curr_division = CDIV_EXCEPTION; }
|
|
on_overflow
|
|
on_not_overflow
|
|
{ curr_division = CDIV_PROC; }
|
|
;
|
|
on_exception_or_overflow:
|
|
on_opt exception_or_overflow { $<ival>$ = begin_on_except(); }
|
|
statement_list { gen_jmplabel($<dval>0); $$=$<ival>3; }
|
|
| /* nothing */ { $$ = 0; }
|
|
;
|
|
exception_or_overflow:
|
|
EXCEPTION
|
|
| OVERFLOW_TOK
|
|
;
|
|
on_not_exception:
|
|
NOT on_opt EXCEPTION { $<ival>$ = begin_on_except(); }
|
|
statement_list { gen_jmplabel($<dval>-1); $$=$<ival>4; }
|
|
| /* nothing */ { $$ = 0; }
|
|
;
|
|
on_overflow:
|
|
on_opt OVERFLOW_TOK { $<dval>$ = gen_at_end(1); }
|
|
statement_list { gen_dstlabel($<dval>3); }
|
|
| /* nothing */
|
|
;
|
|
on_not_overflow:
|
|
not_excep on_opt OVERFLOW_TOK { $<dval>$ = gen_at_end(0); }
|
|
statement_list { gen_dstlabel($<dval>4); }
|
|
| /* nothing */
|
|
;
|
|
|
|
invalid_key_opt:
|
|
invalid_key_sentence {$$ = gen_invalid_keys($1, NULL);}
|
|
| not_invalid_key_sentence {$$ = gen_invalid_keys(NULL, $1);}
|
|
| invalid_key_sentence not_invalid_key_sentence
|
|
{$$ = gen_invalid_keys($1, $2);}
|
|
| { $$ = NULL;}
|
|
;
|
|
invalid_key_sentence:
|
|
INVALID key_opt { $<ike>$ = gen_before_invalid_key(); }
|
|
statement_list { $$ = gen_after_invalid_key($<ike>3); }
|
|
;
|
|
not_invalid_key_sentence:
|
|
not_excep INVALID key_opt { $<ike>$ = gen_before_invalid_key(); }
|
|
statement_list { $$ = gen_after_invalid_key($<ike>4); }
|
|
;
|
|
not_excep:
|
|
NOTEXCEP
|
|
| NOT
|
|
;
|
|
string_with_pointer:
|
|
with_opt POINTER name { $$ = $3; }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
string_from_list:
|
|
string_from { $$ = $1; }
|
|
| string_from_list sep_opt string_from {
|
|
$3->next = $1;
|
|
$$ = $3;
|
|
}
|
|
| error { yyerror("variable expected"); }
|
|
;
|
|
string_from:
|
|
gname {
|
|
/* Item with no DELIMITED BY section implies use delimiter of next item */
|
|
$$ = alloc_string_from( $1, (struct sym *)-1 );
|
|
}
|
|
| gname DELIMITED by_opt delimited_by {
|
|
$$ = alloc_string_from( $1, $4 );
|
|
}
|
|
;
|
|
delimited_by:
|
|
gname { $$=$1; }
|
|
| SIZE { $$=NULL; }
|
|
| error { yyerror("SIZE or identifier expected"); }
|
|
;
|
|
end_stringcmd_opt:
|
|
/* nothing */
|
|
| END_STRINGCMD
|
|
;
|
|
end_unstring_opt:
|
|
/* nothing */
|
|
| END_UNSTRING
|
|
;
|
|
|
|
/* INSPECT statement */
|
|
inspect_statement:
|
|
INSPECT
|
|
name
|
|
tallying_clause { gen_inspect($2,(void *)$3,0); }
|
|
replacing_clause { gen_inspect($2,(void *)$5,1); }
|
|
| INSPECT
|
|
name
|
|
converting_clause { gen_inspect($2,(void *)$3,2); }
|
|
;
|
|
converting_clause:
|
|
CONVERTING
|
|
noallname TO noallname inspect_before_after {
|
|
$$ = alloc_converting_struct($2,$4,$5);
|
|
}
|
|
;
|
|
tallying_clause:
|
|
TALLYING tallying_list { $$=$2; }
|
|
| /* nothing */ { $$=NULL; }
|
|
;
|
|
tallying_list:
|
|
tallying_list
|
|
name FOR tallying_for_list {
|
|
$$ = alloc_tallying_list($1,$2,$4); }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
tallying_for_list:
|
|
tallying_for_list
|
|
CHARACTERS inspect_before_after {
|
|
$$ = alloc_tallying_for_list($1,INSPECT_CHARACTERS,NULL,$3); }
|
|
| tallying_for_list
|
|
ALL noallname inspect_before_after {
|
|
$$ = alloc_tallying_for_list($1,INSPECT_ALL,$3,$4); }
|
|
| tallying_for_list
|
|
LEADING noallname inspect_before_after {
|
|
$$ = alloc_tallying_for_list($1,INSPECT_LEADING,$3,$4); }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
replacing_clause:
|
|
REPLACING
|
|
replacing_list { $$ = $2; }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
replacing_list:
|
|
replacing_list
|
|
CHARACTERS BY noallname inspect_before_after {
|
|
$$ = alloc_replacing_list($1,INSPECT_CHARACTERS,NULL,$4,$5); }
|
|
| replacing_list
|
|
replacing_kind replacing_by_list {
|
|
$$ = alloc_replacing_list($1,$2,$3,NULL,NULL); }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
replacing_by_list:
|
|
replacing_by_list
|
|
noallname BY noallname inspect_before_after {
|
|
$$ = alloc_replacing_by_list($1,$2,$4,$5); }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
replacing_kind:
|
|
ALL { $$ = INSPECT_ALL; }
|
|
| LEADING { $$ = INSPECT_LEADING; }
|
|
| TRAILING { $$ = INSPECT_TRAILING; }
|
|
| FIRST { $$ = INSPECT_FIRST; }
|
|
;
|
|
inspect_before_after:
|
|
inspect_before_after
|
|
BEFORE initial_opt noallname
|
|
{ $$ = alloc_inspect_before_after($1,1,$4); }
|
|
| inspect_before_after
|
|
AFTER initial_opt noallname
|
|
{ $$ = alloc_inspect_before_after($1,2,$4); }
|
|
| /* nothing */ { $$ = alloc_inspect_before_after(NULL,0,NULL); }
|
|
;
|
|
initial_opt:
|
|
INITIAL_TOK
|
|
| /* nothing */
|
|
;
|
|
|
|
expr:
|
|
gname { $$ = $1; }
|
|
| expr '*' expr { $$ =
|
|
(struct sym *)create_expr('*',(struct expr *)$1,(struct expr *)$3); }
|
|
| expr '/' expr { $$ =
|
|
(struct sym *)create_expr('/',(struct expr *)$1,(struct expr *)$3); }
|
|
| expr '+' expr { $$ =
|
|
(struct sym *)create_expr('+',(struct expr *)$1,(struct expr *)$3); }
|
|
| expr '-' expr { $$ =
|
|
(struct sym *)create_expr('-',(struct expr *)$1,(struct expr *)$3); }
|
|
| expr POW_OP expr { $$ =
|
|
(struct sym *)create_expr('^',(struct expr *)$1,(struct expr *)$3); }
|
|
| '(' expr ')' { $$=$2; }
|
|
;
|
|
/* expr_opt will be NULL or a (struct sym *) pointer if the expression
|
|
was given, otherwise it will be valued -1 */
|
|
expr_opt:
|
|
/* nothing */ { $$ = (struct sym *)-1; }
|
|
| expr { $$ = $1; }
|
|
;
|
|
using_options:
|
|
/* nothing */ { $$=0; }
|
|
| USING { $<ival>$=0; /* to save how many parameters */ }
|
|
dummy { $<ival>$=CALL; }
|
|
parm_list { $$=$<ival>2; } /* modified to signal calling pgm */
|
|
;
|
|
returning_options:
|
|
/* nothing */ { $$=0; }
|
|
| RETURNING variable { $$=$2; }
|
|
| GIVING variable { $$=$2; }
|
|
;
|
|
dummy: /* nothing */ ;
|
|
|
|
using_parameters: /* defined at procedure division */
|
|
/* nothing */ { $$=0; }
|
|
| USING gname_list { gen_save_usings($2); $$=1; }
|
|
| CHAINING gname_list { gen_save_chainings($2); $$=2; }
|
|
;
|
|
|
|
parm_list:
|
|
parm_list sep_opt parameter
|
|
{ if ($<ival>0 == USING)
|
|
gen_save_using($<sval>3);
|
|
else if ($<ival>0 == CALL) {
|
|
gen_push_using($<sval>3);
|
|
}
|
|
}
|
|
| parameter
|
|
{ if ($<ival>0 == USING)
|
|
gen_save_using($<sval>1);
|
|
else if ($<ival>0 == CALL) {
|
|
gen_push_using($<sval>1);
|
|
}
|
|
}
|
|
;
|
|
parameter:
|
|
gname {$$=$1;
|
|
if ($$->litflag==1) {
|
|
struct lit *lp=(struct lit *)$$;
|
|
lp->call_mode=curr_call_mode;
|
|
}
|
|
else
|
|
$$->call_mode=curr_call_mode;
|
|
}
|
|
/*| BY parm_type gname*/
|
|
| by_opt parm_type gname
|
|
{ if ( curr_call_mode == CM_CHAIN )
|
|
yyerror("parameter types not allowed on CHAIN");
|
|
else
|
|
{
|
|
$$=$3;
|
|
curr_call_mode=$<ival>2;
|
|
if ($$->litflag==1) {
|
|
struct lit *lp=(struct lit *)$$;
|
|
lp->call_mode=curr_call_mode;
|
|
}
|
|
else
|
|
$$->call_mode=curr_call_mode;
|
|
}
|
|
}
|
|
/* | OMITTED
|
|
{ $$=save_special_literal('0','9', "%ZEROS%");
|
|
$$->call_mode=CM_VAL;
|
|
} */
|
|
;
|
|
parm_type:
|
|
REFERENCE {$$=CM_REF;}
|
|
| VALUE {$$=CM_VAL;}
|
|
| CONTENT {$$=CM_CONT;}
|
|
/* | DESCRIPTOR {$$=CM_CONT;}*/
|
|
;
|
|
intrinsic_parm_list:
|
|
intrinsic_parm_list sep_opt intrinsic_parm
|
|
{ gen_push_using($<sval>3); }
|
|
| intrinsic_parm { gen_push_using($<sval>1); }
|
|
;
|
|
intrinsic_parm:
|
|
gname {$$=$1;$$->call_mode=CM_REF;}
|
|
;
|
|
perform_range: label perform_thru_opt
|
|
{
|
|
gen_perform_thru($1,$2);
|
|
$$ = ($2 == NULL) ? $1 : $2;
|
|
}
|
|
;
|
|
perform_options: perform_statements END_PERFORM { $$ = NULL; }
|
|
| gname TIMES
|
|
{
|
|
gen_push_int($1);
|
|
$<dval>$=gen_marklabel();
|
|
gen_perform_test_counter($<dval>$);
|
|
}
|
|
perform_statements
|
|
{
|
|
gen_perform_times($<dval>3);
|
|
}
|
|
END_PERFORM { $$ = NULL; }
|
|
| with_test_opt UNTIL
|
|
{
|
|
if ($1 == 2) {
|
|
$<ddval>$.lb2=gen_passlabel();
|
|
}
|
|
$<ddval>$.lb1=gen_marklabel();
|
|
}
|
|
condition
|
|
{
|
|
$<ddval>$.lb1=gen_orstart();
|
|
if ($1 == 2) {
|
|
$<ddval>$.lb2=gen_passlabel();
|
|
gen_dstlabel($<ddval>3.lb2);
|
|
}
|
|
}
|
|
perform_statements
|
|
{
|
|
if ($1 == 2) {
|
|
gen_jmplabel($<ddval>3.lb1);
|
|
gen_dstlabel($<ddval>5.lb2);
|
|
gen_jmplabel($<ddval>3.lb2);
|
|
gen_dstlabel($<ddval>5.lb1);
|
|
}
|
|
else {
|
|
gen_jmplabel($<ddval>3.lb1);
|
|
gen_dstlabel($<ddval>5.lb1);
|
|
}
|
|
}
|
|
END_PERFORM { $$ = NULL; }
|
|
| with_test_opt VARYING name FROM gname by_opt gname UNTIL
|
|
{
|
|
/*
|
|
Check if initailization of the 'VARYING identifier' is required.
|
|
Initailization of the 'VARYING identifier' is not neccessary if
|
|
it is the same as the 'FROM identifier'.
|
|
*/
|
|
if ($5->litflag == '1') {
|
|
gen_move($5,$3);
|
|
}
|
|
else {
|
|
if(strcmp($5->name, $3->name) != 0) {
|
|
gen_move($5,$3);
|
|
}
|
|
}
|
|
/* BEFORE=1 AFTER=2 */
|
|
if ($1 == 2) {
|
|
$<ddval>$.lb2=gen_passlabel();
|
|
}
|
|
$<ddval>$.lb1=gen_marklabel();
|
|
}
|
|
condition
|
|
{
|
|
$<dval>$=gen_orstart();
|
|
/* BEFORE=1 AFTER=2 */
|
|
if ($1 == 2) {
|
|
gen_add($7,$3,0);
|
|
gen_dstlabel($<ddval>9.lb2);
|
|
}
|
|
}
|
|
perform_after_opt
|
|
perform_statements
|
|
{
|
|
int i;
|
|
struct perf_info *rf;
|
|
/*struct perform_info *rpi;*/
|
|
char *vn;
|
|
|
|
/* Check for duplicate variables in VARYING/AFTER */
|
|
if ($12 != NULL) {
|
|
if ((vn = check_perform_variables($3, $12)) != NULL) {
|
|
yyerror("Duplicate variable '%s' in VARYING/AFTER clause", vn);
|
|
}
|
|
}
|
|
|
|
if ($1 == 2) {
|
|
if ($12 != NULL) {
|
|
for (i=5; i>=0; i--) {
|
|
rf = $12->pf[i];
|
|
if (rf != NULL) {
|
|
gen_jmplabel(rf->ljmp);
|
|
gen_dstlabel(rf->lend);
|
|
}
|
|
}
|
|
}
|
|
gen_jmplabel($<ddval>9.lb1);
|
|
gen_dstlabel($<dval>11);
|
|
}
|
|
else {
|
|
if ($12 != NULL) {
|
|
for (i=5; i>=0; i--) {
|
|
rf = $12->pf[i];
|
|
if (rf != NULL) {
|
|
gen_add(rf->pname1, rf->pname2, 0);
|
|
gen_jmplabel(rf->ljmp);
|
|
gen_dstlabel(rf->lend);
|
|
}
|
|
}
|
|
}
|
|
gen_add($7,$3,0);
|
|
gen_jmplabel($<ddval>9.lb1);
|
|
gen_dstlabel($<dval>11);
|
|
}
|
|
}
|
|
END_PERFORM { $$ = NULL; }
|
|
| label perform_thru_opt
|
|
{
|
|
gen_perform_thru($1,$2);
|
|
$$ = NULL;
|
|
}
|
|
| label perform_thru_opt with_test_opt UNTIL
|
|
{
|
|
$<dval>$=gen_marklabel();
|
|
/* BEFORE=1 AFTER=2 */
|
|
if ($3 == 2) {
|
|
gen_perform_thru($1,$2);
|
|
}
|
|
}
|
|
condition
|
|
{
|
|
unsigned long lbl;
|
|
lbl=gen_orstart();
|
|
/* BEFORE=1 AFTER=2 */
|
|
if ($3 == 1) {
|
|
gen_perform_thru($1,$2);
|
|
}
|
|
gen_jmplabel($<dval>5);
|
|
gen_dstlabel(lbl);
|
|
}
|
|
| label perform_thru_opt gname TIMES
|
|
{
|
|
unsigned long lbl;
|
|
gen_push_int($3);
|
|
lbl = gen_marklabel();
|
|
gen_perform_test_counter(lbl);
|
|
gen_perform_thru($1,$2);
|
|
gen_perform_times(lbl);
|
|
}
|
|
| label perform_thru_opt with_test_opt VARYING name
|
|
FROM gname by_opt gname UNTIL
|
|
{
|
|
/*
|
|
Check if initailization of the 'VARYING identifier' is required.
|
|
Initailization of the 'VARYING identifier' is not neccessary if
|
|
it is the same as the 'FROM identifier'.
|
|
*/
|
|
if ($7->litflag == '1') {
|
|
gen_move($7,$5);
|
|
}
|
|
else {
|
|
if(strcmp($7->name, $5->name) != 0) {
|
|
gen_move($7,$5);
|
|
}
|
|
}
|
|
if ($3 == 2) {
|
|
$<ddval>$.lb2=gen_passlabel();
|
|
}
|
|
$<ddval>$.lb1 = gen_marklabel();
|
|
}
|
|
condition
|
|
{
|
|
$<dval>$ = gen_orstart();
|
|
/* BEFORE=1 AFTER=2 */
|
|
if ($3 == 2) {
|
|
gen_add($9,$5, 0);
|
|
gen_dstlabel($<ddval>11.lb2);
|
|
}
|
|
}
|
|
perform_after_opt
|
|
{
|
|
int i;
|
|
struct perf_info *rf;
|
|
/*struct perform_info *rpi;*/
|
|
char *vn = NULL;
|
|
|
|
/* Check for duplicate varaibles in VARYING/AFTER */
|
|
if ($14 != NULL) {
|
|
if ((vn = check_perform_variables($5, $14)) != NULL) {
|
|
yyerror("Duplicate variable '%s' in VARYING/AFTER clause", vn);
|
|
}
|
|
}
|
|
gen_perform_thru($1,$2);
|
|
/* BEFORE=1 AFTER=2 */
|
|
if ($3 == 2) {
|
|
if ($14 != NULL) {
|
|
for (i=5; i>=0; i--) {
|
|
rf = $14->pf[i];
|
|
if (rf != NULL) {
|
|
gen_jmplabel(rf->ljmp);
|
|
gen_dstlabel(rf->lend);
|
|
}
|
|
}
|
|
}
|
|
gen_jmplabel($<dval>11);
|
|
gen_dstlabel($<dval>13);
|
|
}
|
|
else {
|
|
if ($14 != NULL) {
|
|
for (i=5; i>=0; i--) {
|
|
rf = $14->pf[i];
|
|
if (rf != NULL) {
|
|
gen_add(rf->pname1, rf->pname2, 0);
|
|
gen_jmplabel(rf->ljmp);
|
|
gen_dstlabel(rf->lend);
|
|
}
|
|
}
|
|
}
|
|
gen_add($9,$5,0);
|
|
gen_jmplabel($<dval>11);
|
|
gen_dstlabel($<dval>13);
|
|
}
|
|
$$ = NULL;
|
|
}
|
|
;
|
|
|
|
perform_thru_opt:
|
|
/* nothing */ { $$ = NULL; }
|
|
| THRU label { $$ = $2;}
|
|
;
|
|
with_test_opt: { $<ival>$=1; perform_after_sw=1; }
|
|
| with_opt TEST before_after
|
|
{
|
|
$$=$3;
|
|
perform_after_sw=$3;
|
|
}
|
|
;
|
|
perform_after_opt: /* nothing */ { $$=NULL; }
|
|
| AFTER perform_after
|
|
{
|
|
$<pfvals>$=create_perform_info();
|
|
$<pfvals>$->pf[0] = $2;
|
|
$$=$<pfvals>$;
|
|
}
|
|
| AFTER perform_after AFTER perform_after
|
|
{
|
|
$<pfvals>$=create_perform_info();
|
|
$<pfvals>$->pf[0] = $2;
|
|
$<pfvals>$->pf[1] = $4;
|
|
$$=$<pfvals>$;
|
|
}
|
|
| AFTER perform_after AFTER perform_after
|
|
AFTER perform_after
|
|
{
|
|
$<pfvals>$=create_perform_info();
|
|
$<pfvals>$->pf[0] = $2;
|
|
$<pfvals>$->pf[1] = $4;
|
|
$<pfvals>$->pf[2] = $6;
|
|
$$=$<pfvals>$;
|
|
}
|
|
| AFTER perform_after AFTER perform_after
|
|
AFTER perform_after AFTER perform_after
|
|
{
|
|
$<pfvals>$=create_perform_info();
|
|
$<pfvals>$->pf[0] = $2;
|
|
$<pfvals>$->pf[1] = $4;
|
|
$<pfvals>$->pf[2] = $6;
|
|
$<pfvals>$->pf[3] = $8;
|
|
$$=$<pfvals>$;
|
|
}
|
|
| AFTER perform_after AFTER perform_after AFTER perform_after
|
|
AFTER perform_after AFTER perform_after
|
|
{
|
|
$<pfvals>$=create_perform_info();
|
|
$<pfvals>$->pf[0] = $2;
|
|
$<pfvals>$->pf[1] = $4;
|
|
$<pfvals>$->pf[2] = $6;
|
|
$<pfvals>$->pf[3] = $8;
|
|
$<pfvals>$->pf[4] = $10;
|
|
$$=$<pfvals>$;
|
|
}
|
|
| AFTER perform_after AFTER perform_after AFTER perform_after
|
|
AFTER perform_after AFTER perform_after AFTER perform_after
|
|
{
|
|
$<pfvals>$=create_perform_info();
|
|
$<pfvals>$->pf[0] = $2;
|
|
$<pfvals>$->pf[1] = $4;
|
|
$<pfvals>$->pf[2] = $6;
|
|
$<pfvals>$->pf[3] = $8;
|
|
$<pfvals>$->pf[4] = $10;
|
|
$<pfvals>$->pf[5] = $12;
|
|
$$=$<pfvals>$;
|
|
}
|
|
;
|
|
perform_after: name FROM gname
|
|
by_opt gname UNTIL
|
|
{
|
|
/*
|
|
Check if initailization of the 'VARYING identifier' is required.
|
|
Initailization of the 'VARYING identifier' is not neccessary if
|
|
it is the same as the 'FROM identifier'.
|
|
*/
|
|
if ($3->litflag == '1') {
|
|
gen_move($3,$1);
|
|
}
|
|
else {
|
|
if(strcmp($3->name, $1->name) != 0) {
|
|
gen_move($3,$1);
|
|
}
|
|
}
|
|
/* BEFORE=1 AFTER=2 */
|
|
if (perform_after_sw == 2) {
|
|
$<ddval>$.lb2=gen_passlabel();
|
|
}
|
|
$<ddval>$.lb1 = gen_marklabel();
|
|
}
|
|
condition
|
|
{
|
|
unsigned long lbl;
|
|
lbl=gen_orstart();
|
|
/* BEFORE=1 AFTER=2 */
|
|
if (perform_after_sw == 2) {
|
|
gen_add($5,$1,0);
|
|
gen_dstlabel($<ddval>7.lb2);
|
|
$$ = create_perf_info($5, $1, $<ddval>7.lb1, lbl);
|
|
}
|
|
else {
|
|
$$ = create_perf_info($5, $1, $<ddval>7.lb1, lbl);
|
|
}
|
|
}
|
|
;
|
|
perform_statements: {stabs_line();} statement_list
|
|
/*
|
|
| { stabs_line(); } CONTINUE
|
|
*/
|
|
;
|
|
before_after:
|
|
BEFORE { $$=1; }
|
|
| AFTER { $$=2; }
|
|
;
|
|
condition:
|
|
expr extended_cond_op
|
|
{
|
|
if ($2 & COND_UNARY) {
|
|
if ($2 & COND_CLASS) {
|
|
gen_class_check($1,$2);
|
|
}
|
|
else {
|
|
struct sym *sy = (struct sym *)save_special_literal('0','9', "%ZEROS%");
|
|
gen_compare($1,$2&~COND_UNARY,sy);
|
|
}
|
|
}
|
|
}
|
|
expr_opt
|
|
{
|
|
if ($2 & COND_UNARY) {
|
|
if ((int)$4 != -1) {
|
|
yyerror("class or sign conditions are unary");
|
|
}
|
|
}
|
|
else {
|
|
if ((int)$4 == -1) {
|
|
yyerror("expression expected in a binary condition");
|
|
}
|
|
else {
|
|
gen_compare($1,$2,$4);
|
|
}
|
|
}
|
|
$$.sy=$1; /* for implied operands */
|
|
$$.oper=$2;
|
|
}
|
|
| NOT condition { gen_not(); $$=$2; }
|
|
| condition
|
|
AND
|
|
{ $<dval>$=gen_andstart(); }
|
|
implied_op_condition
|
|
{ gen_dstlabel($<dval>3); $$=$4; }
|
|
| condition
|
|
OR
|
|
{ $<dval>$=gen_orstart(); }
|
|
implied_op_condition
|
|
{ gen_dstlabel($<dval>3); $$=$4; }
|
|
| '(' condition ')' { $$ = $2; }
|
|
| cond_name
|
|
{
|
|
/*if ($1->level != 88)
|
|
yyerror("condition unknown");*/
|
|
gen_condition($1);
|
|
$$.sy=NULL;
|
|
$$.oper=0;
|
|
}
|
|
;
|
|
implied_op_condition:
|
|
condition { $$ = $1; }
|
|
| cond_op expr
|
|
{
|
|
if ($<condval>-2.sy == NULL) {
|
|
yyerror("invalid implied condition");
|
|
}
|
|
else {
|
|
gen_compare($<condval>-2.sy,$1,$2);
|
|
}
|
|
$$.sy = $<condval>-2.sy;
|
|
$$.oper = $1;
|
|
}
|
|
| expr
|
|
{ /* implied both the first operand and the operator */
|
|
if (($<condval>-2.sy == NULL)||
|
|
($<condval>-2.oper & COND_UNARY)) {
|
|
yyerror("invalid implied condition");
|
|
}
|
|
else {
|
|
gen_compare($<condval>-2.sy,$<condval>-2.oper,$1);
|
|
}
|
|
$$.sy = $<condval>-2.sy;
|
|
$$.oper = $<condval>-2.oper;
|
|
}
|
|
;
|
|
sign_condition:
|
|
POSITIVE { $$=GREATER; }
|
|
| NEGATIVE { $$=LESS; }
|
|
| ZERO { $$=EQUAL; }
|
|
;
|
|
class_condition:
|
|
NUMERIC { $$=CLASS_NUMERIC; }
|
|
| ALPHABETIC { $$=CLASS_ALPHABETIC; }
|
|
| ALPHABETIC_LOWER { $$=CLASS_ALPHABETIC_LOWER; }
|
|
| ALPHABETIC_UPPER { $$=CLASS_ALPHABETIC_UPPER; }
|
|
;
|
|
extended_cond_op:
|
|
IS ext_cond { $$ = $2; }
|
|
| IS NOT ext_cond { $$ = $3 ^ 7; }
|
|
| IS ext_cond OR ext_cond { $$ = $2 | $4; }
|
|
| ext_cond { $$ = $1; }
|
|
| NOT is_opt ext_cond { $$ = $3 ^ 7; }
|
|
| ext_cond OR ext_cond { $$ = $1 | $3; }
|
|
;
|
|
ext_cond:
|
|
conditional { $$ = $1; }
|
|
| class_condition { $$ = $1 | COND_UNARY | COND_CLASS; }
|
|
| sign_condition { $$ = $1 | COND_UNARY; }
|
|
;
|
|
cond_op:
|
|
conditional { $$ = $1; }
|
|
| NOT conditional { $$ = $2 ^ 7; }
|
|
| conditional OR conditional { $$ = $1 | $3; }
|
|
;
|
|
conditional:
|
|
CONDITIONAL than_to_opt { $$ = $1; }
|
|
;
|
|
comma_opt: /* nothing */
|
|
| ','
|
|
;
|
|
sep_opt:
|
|
/* nothing */
|
|
| LISTSEP
|
|
;
|
|
/* this token doesn't really exists, but forces look ahead
|
|
to keep line numbers synchronized with our position
|
|
because we need to generate correct debug stabs */
|
|
/*
|
|
dummy_opt:
|
|
/ nothing /
|
|
| TOKDUMMY
|
|
;
|
|
*/
|
|
key_opt:
|
|
/* nothing */
|
|
| KEY
|
|
;
|
|
advancing_opt:
|
|
/* nothing */
|
|
| ADVANCING
|
|
;
|
|
than_to_opt:
|
|
/* nothing */
|
|
| TO { }
|
|
| THAN { }
|
|
;
|
|
record_opt:
|
|
/* nothing */
|
|
| RECORD
|
|
;
|
|
at_opt: /* nothing */
|
|
| AT
|
|
;
|
|
in_opt: /* nothing */
|
|
| IN
|
|
;
|
|
in_of:
|
|
IN
|
|
| OF
|
|
;
|
|
by_opt: /* nothing */
|
|
| BY
|
|
;
|
|
with_opt:
|
|
/* nothing */
|
|
| WITH
|
|
;
|
|
on_opt:
|
|
/* nothing */
|
|
| ON
|
|
;
|
|
gname_opt:
|
|
gname { $$ = $1; }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
to_opt: /* nothing */
|
|
| TO { }
|
|
;
|
|
name_var_list:
|
|
name_var { $$ = gvar_list_append(NULL, $1, source_lineno); }
|
|
| name_var_list sep_opt name_var
|
|
{ $$ = gvar_list_append($1, $3, source_lineno); }
|
|
;
|
|
gname_list:
|
|
gname { $$ = gvar_list_append(NULL, $1, source_lineno); }
|
|
| gname_list sep_opt gname
|
|
{ $$ = gvar_list_append($1, $3, source_lineno); }
|
|
;
|
|
gname: name {
|
|
/*if (!is_variable($1)) {
|
|
yyerror("The symbol \"%s\" is not an allowed argument here", $1->name);
|
|
}*/
|
|
$$ = $1; }
|
|
| gliteral { $$ = (struct sym *)$1;}
|
|
| FUNCTION LABELSTR '(' {
|
|
$2->type = 'f'; /* function type */
|
|
$<ival>$=CALL;
|
|
}
|
|
intrinsic_parm_list ')' {
|
|
$$ = gen_intrinsic_call((struct sym *)$2);
|
|
}
|
|
| FUNCTION LABELSTR {
|
|
$2->type = 'f'; /* function type */
|
|
$<ival>$=CALL;
|
|
$$ = gen_intrinsic_call((struct sym *)$2);
|
|
}
|
|
;
|
|
name_or_lit:
|
|
name { $$ = $1; }
|
|
| literal { $$ = (struct sym *)$1; }
|
|
;
|
|
noallname:
|
|
name { $$ = $1; }
|
|
| without_all_literal { $$ = (struct sym *)$1; }
|
|
;
|
|
gliteral:
|
|
without_all_literal
|
|
| all_literal
|
|
;
|
|
without_all_literal:
|
|
literal { $$=$1; }
|
|
| special_literal { $$=$1; }
|
|
;
|
|
all_literal:
|
|
ALL literal { $2->all=1; $$=$2; }
|
|
| ALL special_literal { $$=$2; }
|
|
;
|
|
special_literal:
|
|
SPACES { $$=spe_lit_SP; }
|
|
| ZERO { $$=spe_lit_ZE; }
|
|
| QUOTES { $$=spe_lit_QU; }
|
|
| HIGHVALUES { $$=spe_lit_HV; }
|
|
| LOWVALUES { $$=spe_lit_LV; }
|
|
;
|
|
var_or_nliteral:
|
|
variable { $$ = $1; }
|
|
| nliteral { $$ = (struct sym *)$1; }
|
|
;
|
|
nliteral:
|
|
signed_nliteral { save_literal($1,'9'); $1->all = 0; $$=$1; }
|
|
;
|
|
literal:
|
|
signed_nliteral { save_literal($1,'9'); $1->all=0; $$=$1; }
|
|
| CLITERAL { save_literal($1,'X'); $1->all=0; $$=$1; }
|
|
;
|
|
signed_nliteral:
|
|
NLITERAL { check_decimal_point($1); $$=$1; }
|
|
| '+' NLITERAL { check_decimal_point($2); $$=$2; }
|
|
| '-' NLITERAL
|
|
{
|
|
check_decimal_point($2);
|
|
invert_literal_sign( $2 );
|
|
$$=$2;
|
|
}
|
|
;
|
|
def_name_opt:
|
|
def_name { $$ = $1; }
|
|
| /* nothing */ { $$ = NULL; }
|
|
;
|
|
def_name:
|
|
STRING
|
|
{
|
|
if ($1->defined)
|
|
yyerror("variable redefined, %s",$1->name);
|
|
$1->defined=1;
|
|
$$=$1;
|
|
}
|
|
| FILLER { $<sval>$=alloc_filler(); }
|
|
;
|
|
variable_indexed:
|
|
SUBSCVAR
|
|
{
|
|
if ($1->occurs_flg == 0 && !in_occurs($1)) // walter
|
|
yyerror("\"%s\" is not an indexed variable ", $1->name);
|
|
$$=$1;
|
|
}
|
|
;
|
|
|
|
/*variable:
|
|
VARIABLE { $$=$1; }
|
|
| VARIABLE in_of subs_var {
|
|
struct sym *v;
|
|
v=lookup_variable($1,$3);
|
|
if ($$==NULL)
|
|
yyerror("\"%s\" is not child of \"%s\"",$1,$3);
|
|
if ($3->litflag==2) {
|
|
((struct vref *)$3)->sym = v;
|
|
$$ = $3;
|
|
}
|
|
else {
|
|
$$ = v;
|
|
}
|
|
}
|
|
| LABELSTR { yyerror("%s is not a defined variable",$1->name); }
|
|
; */
|
|
filename:
|
|
literal { $$=(struct sym *)$1; }
|
|
| STRING {$$=$1; }
|
|
;
|
|
data_name:
|
|
literal { $$=(struct sym *)$1; }
|
|
| STRING {$$=$1; }
|
|
;
|
|
cond_name:
|
|
VARCOND '(' { curr_division = CDIV_SUBSCRIPTS; }
|
|
subscripts ')' {
|
|
curr_division = CDIV_PROC;
|
|
$$ = (struct sym *)create_subscripted_var( $1, $4 );
|
|
/*check_subscripts($$);*/
|
|
}
|
|
| VARCOND { $<sval>$=$1; }
|
|
;
|
|
name:
|
|
variable '(' gname ':' gname_opt ')' {
|
|
$$=(struct sym *)create_refmoded_var($1, $3, $5); check_refmods((struct sym *)$$);
|
|
is_var=1;
|
|
}
|
|
| variable { is_var=1; }
|
|
| LABELSTR { yyerror("Invalid argument expecting variable"); is_var=2; }
|
|
;
|
|
name_var:
|
|
gname {
|
|
if (!is_var)
|
|
yyerror("Invalid argument expecting variable");
|
|
is_var=0;
|
|
}
|
|
;
|
|
/*subs_var:
|
|
variable
|
|
| subscripted_variable
|
|
;
|
|
subscripted_variable:
|
|
SUBSCVAR '(' { curr_division = CDIV_SUBSCRIPTS; }
|
|
subscripts ')' {
|
|
curr_division = CDIV_PROC;
|
|
$$ = (struct sym *)create_subscripted_var( $1, $4 );
|
|
check_subscripts($$);
|
|
}
|
|
| SUBSCVAR in_of subs_var '(' { curr_division = CDIV_SUBSCRIPTS; }
|
|
subscripts ')' {
|
|
curr_division = CDIV_PROC;
|
|
$$ = (struct sym *)create_subscripted_var(
|
|
lookup_variable($1,$3), $6 );
|
|
check_subscripts($$);
|
|
}
|
|
;
|
|
*/
|
|
variable:
|
|
qualified_var
|
|
{
|
|
$$=$1;
|
|
if (need_subscripts && $1->occurs_flg == 0) {
|
|
/* verify if the variable is present in the same area of occurs clause */
|
|
if(!in_occurs($1)) {
|
|
yyerror("this variable \'%s\' must be subscripted or indexed", $1->name);
|
|
need_subscripts=0;
|
|
}
|
|
}
|
|
}
|
|
| qualified_var LPAR
|
|
{ curr_division = CDIV_SUBSCRIPTS; }
|
|
subscripts ')'
|
|
{
|
|
curr_division = CDIV_PROC;
|
|
$$ = (struct sym *)create_subscripted_var( $1, $4 );
|
|
check_subscripts($$);
|
|
}
|
|
;
|
|
qualified_var:
|
|
unqualified_var
|
|
{
|
|
$$=$1;
|
|
if ($1->clone != 0)
|
|
yyerror("this variable \'%s\' must be qualified", $1->name);
|
|
}
|
|
| unqualified_var in_of qualified_var
|
|
{
|
|
$$=lookup_parent($1,$3);
|
|
if ($$ == NULL) {
|
|
yyerror("this variable \'%s\' is not defined in '%s'", $1->name, $3->name);
|
|
$$=$1;
|
|
}
|
|
}
|
|
;
|
|
unqualified_var:
|
|
VARIABLE
|
|
{
|
|
if (($1->defined == 0) && ($1->type == 0))
|
|
{
|
|
yyerror("Undefined variable \'%s\' found", $1->name);
|
|
}
|
|
$$=$1;
|
|
}
|
|
| SUBSCVAR { need_subscripts=1; $$=$1; }
|
|
;
|
|
subscripts:
|
|
subscript { $$ = $1; }
|
|
| subscripts comma_opt subscript { $$ = add_subscript( $1, $3 ); }
|
|
;
|
|
subscript:
|
|
gname { $$ = create_subscript( $1 ); }
|
|
| subscript '+' gname { $$ = add_subscript_item( $1, '+', $3 ); }
|
|
| subscript '-' gname { $$ = add_subscript_item( $1, '-', $3 ); }
|
|
;
|
|
integer:
|
|
signed_nliteral
|
|
{
|
|
char *s;
|
|
$$=0;
|
|
s=$1->name;
|
|
while (isdigit(*s))
|
|
$$ = $$ * 10 + *s++ - '0';
|
|
if (*s)
|
|
yyerror("only integers accepted here");
|
|
}
|
|
;
|
|
label:
|
|
LABELSTR in_of LABELSTR
|
|
{
|
|
struct sym *lab=$1;
|
|
struct sym *sec=$3;
|
|
if (sec->defined == 0) {
|
|
sec->defined = 2;
|
|
sec->parent = NULL;
|
|
} else {
|
|
if ((sec=lookup_label($3,NULL))==NULL) {
|
|
sec = install($3->name,SYTB_LAB,2);
|
|
sec->defined=2;
|
|
sec->parent = NULL;
|
|
}
|
|
}
|
|
|
|
if (lab->defined == 0) {
|
|
lab->defined = 2;
|
|
lab->parent = $3;
|
|
} else {
|
|
if ((lab=lookup_label($1,$3))==NULL) {
|
|
lab = install($1->name,SYTB_LAB,2);
|
|
lab->defined=2;
|
|
lab->parent = $3;
|
|
}
|
|
}
|
|
$$ = lab;
|
|
}
|
|
| LABELSTR
|
|
{
|
|
struct sym *lab=$1;
|
|
if (lab->defined == 0) {
|
|
lab->defined = 2;
|
|
lab->parent = curr_section;
|
|
}
|
|
else {
|
|
if ((lab=lookup_label(lab,curr_section))==NULL) {
|
|
lab = install($1->name,SYTB_LAB,2);
|
|
lab->defined=2;
|
|
lab->parent = curr_section;
|
|
}
|
|
}
|
|
$$ = lab;
|
|
}
|
|
| NLITERAL {$$=define_label((struct sym *)$1,1,NULL,0);}
|
|
| NLITERAL in_of NLITERAL {$$=define_label((struct sym *)$1,1,(struct sym *)$3,1);}
|
|
| NLITERAL in_of LABELSTR {$$=define_label((struct sym *)$1,1,$3,0);}
|
|
;
|
|
anystring:
|
|
STRING
|
|
| LABELSTR
|
|
;
|
|
%%
|
|
|
|
/*
|
|
** Yacc auxiliary routines
|
|
*/
|
|
|
|
/* ***********************************************
|
|
* hterror is called where yyerror is normally *
|
|
* called within the parser, but it also passes*
|
|
* an error number and severity. The error *
|
|
* number identifies the longer description of *
|
|
* the error message in the compiler document- *
|
|
* ation. The severity is used to set the *
|
|
* return code that the compiler will return. *
|
|
***********************************************/
|
|
void hterror(int erno, int severity, char *s,...)
|
|
{
|
|
HTG_temporary_error_code = erno;
|
|
HTG_temporary_severity = severity;
|
|
|
|
yyerror(s);
|
|
|
|
HTG_temporary_error_code = 256;
|
|
HTG_temporary_severity = 8;
|
|
return;
|
|
}
|
|
|
|
void yywarn(char *s,...)
|
|
{
|
|
va_list ap;
|
|
va_start (ap, s);
|
|
HTG_temporary_severity = 4;
|
|
yyerror(s, ap);
|
|
va_end(ap);
|
|
HTG_temporary_severity = 8;
|
|
}
|
|
|
|
|
|
extern FILE *o_lst;
|
|
|
|
void yyerror(char *s,...)
|
|
{
|
|
char buff1[BUFSIZ], buff2[BUFSIZ];
|
|
const char *label;
|
|
va_list argptr;
|
|
int slen=0;
|
|
|
|
/* Determine the type of the error */
|
|
switch (HTG_temporary_severity)
|
|
{
|
|
case TCOB_SEVERITY_INFO:
|
|
label = "info: ";
|
|
break;
|
|
|
|
case TCOB_SEVERITY_WARN:
|
|
label = "warning: ";
|
|
if (HTG_RETURN_CODE < 4)
|
|
HTG_RETURN_CODE = 4;
|
|
wrncnt++;
|
|
break;
|
|
|
|
case TCOB_SEVERITY_ERROR:
|
|
label = "error: ";
|
|
if (HTG_RETURN_CODE < 8)
|
|
HTG_RETURN_CODE = 8;
|
|
errcnt++;
|
|
break;
|
|
|
|
default:
|
|
label = "error: ";
|
|
if (HTG_RETURN_CODE < HTG_temporary_severity)
|
|
HTG_RETURN_CODE = HTG_temporary_severity;
|
|
errcnt++;
|
|
break;
|
|
}
|
|
/* Build the error message */
|
|
va_start(argptr,s);
|
|
vsprintf (buff1, s, argptr);
|
|
va_end (argptr);
|
|
|
|
/* Display the error */
|
|
slen = strlen(yytext);
|
|
if (slen != 0) {
|
|
sprintf (buff2, "%s:%6d: %s%s, on or before \'%s\'\n",
|
|
source_filename, source_lineno, label, buff1, yytext);
|
|
}
|
|
else {
|
|
sprintf (buff2, "%s:%6d: %s%s\n",
|
|
source_filename, source_lineno, label, buff1);
|
|
}
|
|
fputs (buff2, stderr);
|
|
if (HTG_list_flag)
|
|
fputs (buff2, o_lst);
|
|
|
|
}
|
|
|
|
static void
|
|
assert_numeric_sy (struct sym *sy)
|
|
{
|
|
if (!is_numeric_sy(sy))
|
|
yyerror("invalid (non numeric) variable or literal \'%s\' used in arithmetic verb", sy->name);
|
|
}
|
|
|
|
static void
|
|
assert_numeric_dest_sy (struct sym *sy)
|
|
{
|
|
if (!is_numeric_dest_sy(sy))
|
|
yyerror("invalid destination variable \'%s\' used in arithmetic verb", sy->name);
|
|
}
|