1079 lines
16 KiB
Plaintext
1079 lines
16 KiB
Plaintext
/*
|
|
** --- GRAMMAR.Y ------- REPORT RULE SYSTEM ---------------------------------
|
|
**
|
|
**
|
|
** REPORT specification
|
|
**
|
|
** adapted from Herrmann, Knut
|
|
** Technische Universitaet Dresden
|
|
** Sektion Informationsverarbeitung
|
|
** Diplomarbeit vom 25.Jan. 1986
|
|
**
|
|
** and DABA/REP for DABA1600
|
|
**
|
|
**
|
|
** Version: @(#)grammar.y 4.0 02/05/89
|
|
**
|
|
*/
|
|
|
|
/* COMMANDS */
|
|
%term ALL AS BIG CALL
|
|
%term CASE CLEAR COL COLUMN
|
|
%term COMPLEMENT DEFINE DO DOMAIN
|
|
%term ELSE END ENDA ENDC
|
|
%term ENDI ENDO ENDR ENDW
|
|
%term EXCEPTION FOR GROUPBEGIN GROUPEND
|
|
%term IF IN IS LENGTH
|
|
%term LINE NEW NEWLINE NEWPAGE
|
|
%term ON ONE OUT PAGE
|
|
%term PROC REPEAT REPORT RETURN
|
|
%term SEMICOL SET SPACE SWITCH
|
|
%term TERMINAL THEN TUPLE NVAR
|
|
%term WHILE
|
|
|
|
/* CONVERSION WORDS */
|
|
%term BYTE F_CHAR FORMAT GRAPHIC
|
|
%term INTEGER REAL WORD
|
|
|
|
/* FORMAT WORDS */
|
|
%term BATCH BEFORE DATE EXP
|
|
%term FROM_TO IGNORE NORM PIC
|
|
%term POINT SCALE WITH
|
|
|
|
/* CONSTANTS */
|
|
%term BCONST /* boolean const */
|
|
%term ICONST /* integer const */
|
|
%term LCONST /* long integer const */
|
|
%term NAME /* name const */
|
|
%term RCONST /* real const */
|
|
%term SCONST /* string const */
|
|
%term SYS_CONST
|
|
|
|
/* PUNCTUATION */
|
|
%term LPAREN RPAREN BGNCMNT ENDCMNT
|
|
|
|
/* OPERATORS */
|
|
%term AUOP /* ARITHMETIC UNARY OPERATORS */
|
|
%term ABOP /* ARITHMETIC BINARY OPERATORS */
|
|
%term ABIS /* BINARY ASSIGNMENT OPERATORS */
|
|
%term BDOP /* BOUNDS OPERATORS */
|
|
%term EOP /* EQUALITY OPERATORS */
|
|
%term LUOP /* LOGICAL BINARY OPERATORS */
|
|
%term LBOP /* LOGICAL BINARY OPERATORS */
|
|
|
|
/* DEFINE ASCENDING PRECEDENCE FOR OPERATORS */
|
|
%left LBOP
|
|
%left LUOP
|
|
%left AUOP
|
|
%left ABOP
|
|
%binary unaryop
|
|
|
|
|
|
%{
|
|
# include "rc.h"
|
|
|
|
/* FORMAT STRUCTURE (formatted output) */
|
|
static struct format Format;
|
|
extern char *RC_INIT_JUMP();
|
|
|
|
%}
|
|
|
|
|
|
%%
|
|
|
|
|
|
program : rep_kwd NAME desc fmt_def AS stmt_s report stmt_s SEMICOL
|
|
= {
|
|
RC_BYTE(rcRC_END);
|
|
rc_report($2);
|
|
}
|
|
| error
|
|
;
|
|
rep_kwd : DEFINE REPORT
|
|
| REPORT
|
|
;
|
|
desc : DOMAIN NAME
|
|
= {
|
|
S_desc = $2;
|
|
}
|
|
| /* empty */
|
|
= {
|
|
S_desc = "desc";
|
|
}
|
|
;
|
|
fmt_def : WITH fmt_s
|
|
| /* empty */
|
|
;
|
|
fmt_s : fmt
|
|
| fmt_s fmt
|
|
;
|
|
fmt : LINE ICONST
|
|
= {
|
|
R_lines = (int) $2;
|
|
}
|
|
| ALL LINE ICONST
|
|
= {
|
|
R_all_lines = (int) $3;
|
|
}
|
|
| COLUMN ICONST
|
|
= {
|
|
R_cols = (int) $2;
|
|
}
|
|
| FROM_TO PAGE ICONST
|
|
= {
|
|
if (!((int) $1))
|
|
R_first_page = (int) $3;
|
|
else
|
|
R_last_page = (int) $3;
|
|
}
|
|
| FROM_TO TUPLE ICONST
|
|
= {
|
|
if (!((int) $1))
|
|
R_from_tuple = (int) $3;
|
|
else
|
|
R_to_tuple = (int) $3;
|
|
}
|
|
| BIG
|
|
= {
|
|
R_big = TRUE;
|
|
}
|
|
| DEFINE NAME IS ICONST
|
|
= {
|
|
RC_MACRO($2, (int) $4);
|
|
}
|
|
| DEFINE DOMAIN ICONST IS dom_fmt ICONST
|
|
= {
|
|
RC_IDOM((int) $3, (int) $5, (int) $6);
|
|
}
|
|
| DEFINE DOMAIN NAME IS dom_fmt ICONST
|
|
= {
|
|
RC_NDOM($3, (int) $5, (int) $6);
|
|
}
|
|
| error
|
|
;
|
|
dom_fmt : INTEGER
|
|
| REAL
|
|
| F_CHAR
|
|
;
|
|
report : for_all print enda_kwd
|
|
= {
|
|
RC_BYTE(rcJUMP);
|
|
RC_JUMP($1);
|
|
R_for_all = R_rc - R_code;
|
|
}
|
|
;
|
|
for_all : fora_kwd stmt_s
|
|
;
|
|
print : tuple_s
|
|
| print tuple_s
|
|
;
|
|
tuple_s : tuple stmt_s
|
|
;
|
|
tuple : for1_kwd stmt_s end1_kwd
|
|
= {
|
|
RC_BYTE(rcEOTUP);
|
|
}
|
|
;
|
|
|
|
|
|
/* statements */
|
|
|
|
stmt_s : s_stmt
|
|
| /* empty */
|
|
;
|
|
s_stmt : s_stmt stmt
|
|
| stmt
|
|
;
|
|
/* ASSIGNMENT */
|
|
stmt : assign
|
|
|
|
/* PROCEDURE declaration */
|
|
| proc_hd stmt_s RETURN
|
|
= {
|
|
RC_BYTE(rcRETURN);
|
|
RC_UPDATE($1);
|
|
}
|
|
|
|
/* procedure CALL statement */
|
|
| call
|
|
= {
|
|
if (!Proc[((int) $1) - 1])
|
|
rc_error(3, $1);
|
|
else
|
|
{
|
|
RC_BYTE(rcCALL);
|
|
RC_JUMP(Proc[((int) $1) - 1]);
|
|
}
|
|
}
|
|
|
|
/* IF statement */
|
|
| if_cond if_then if_else endi_kwd
|
|
= {
|
|
RC_UPDATE($2);
|
|
}
|
|
|
|
/* WHILE statement */
|
|
| wh_cond wh_do endw_kwd
|
|
= {
|
|
/* jump to condition */
|
|
RC_BYTE(rcJUMP);
|
|
RC_JUMP($1 - 1);
|
|
/* update jump over WHILE */
|
|
RC_UPDATE($2);
|
|
}
|
|
|
|
/* REPEAT statement */
|
|
| repeat value stmt_s endr_kwd
|
|
= {
|
|
RC_BYTE(rcREPEAT);
|
|
RC_WORD((int) $2);
|
|
RC_JUMP($1);
|
|
}
|
|
|
|
/* CASE statement */
|
|
| case_hd case_s out endc_kwd
|
|
= {
|
|
rc_case($1);
|
|
}
|
|
|
|
/* ON statement */
|
|
| on_hd stmt_s endo_kwd
|
|
= {
|
|
RC_BYTE(rcRTTS);
|
|
RC_UPDATE($1); /* jump over exception */
|
|
}
|
|
|
|
/* TERMINAL statement */
|
|
| console
|
|
= {
|
|
Format.str_len = AAlength($1);
|
|
RC_BYTE(prINPUT);
|
|
RC_WORD(Format.str_len);
|
|
RC_WORD(Format.batch_len);
|
|
RC_STR($1, Format.str_len);
|
|
}
|
|
|
|
/* print DATE or TIME */
|
|
| DATE
|
|
= {
|
|
RC_BYTE((int) $1);
|
|
}
|
|
|
|
/* print NEWLINE */
|
|
| NEWLINE value
|
|
= {
|
|
RC_BYTE(prNEWLINE);
|
|
RC_WORD((int) $2);
|
|
}
|
|
| NEW LINE value
|
|
= {
|
|
RC_BYTE(prNEWLINE);
|
|
RC_WORD((int) $3);
|
|
}
|
|
| NEWLINE
|
|
= {
|
|
goto new_line;
|
|
}
|
|
| NEW LINE
|
|
= {
|
|
new_line:
|
|
RC_BYTE(prNEWLINE);
|
|
RC_WORD(A_NEWLINE);
|
|
}
|
|
|
|
/* print NEWPAGE */
|
|
| NEWPAGE
|
|
= {
|
|
goto new_page;
|
|
}
|
|
| NEW PAGE
|
|
= {
|
|
new_page:
|
|
RC_BYTE(prNEWPAGE);
|
|
}
|
|
|
|
/* set COLUMN pointer */
|
|
| COL value
|
|
= {
|
|
RC_BYTE(prNEWCOL);
|
|
RC_WORD((int) $2);
|
|
}
|
|
|
|
/* print SPACES */
|
|
| SPACE value
|
|
= {
|
|
RC_BYTE(prSPACE);
|
|
RC_WORD((int) $2);
|
|
}
|
|
|
|
/* print constant STRING */
|
|
| string
|
|
= {
|
|
RC_BYTE(prSTRING);
|
|
RC_WORD(Format.str_len);
|
|
RC_WORD(Format.batch_len);
|
|
RC_STR(Format.str_adr, Format.str_len);
|
|
if (Format.fr_to[1])
|
|
{
|
|
RC_BYTE(rcREPEAT);
|
|
RC_WORD((int) Format.fr_to[1]);
|
|
RC_JUMP(Format.fr_to[0]);
|
|
}
|
|
}
|
|
|
|
/* formatted OUTPUT statement */
|
|
| format
|
|
|
|
/* ERROR */
|
|
| error
|
|
;
|
|
/* ASSIGMENT */
|
|
assign : CLEAR b_var
|
|
= {
|
|
$1 = RC_INIT_JUMP(setSWITCH);
|
|
RC_BYTE(pushSWITCH);
|
|
RC_WORD((int) $2);
|
|
RC_BYTE(pushFALSE);
|
|
goto expr_end;
|
|
}
|
|
| COMPLEMENT b_var
|
|
= {
|
|
$1 = RC_INIT_JUMP(setSWITCH);
|
|
RC_BYTE(pushSWITCH);
|
|
RC_WORD((int) $2);
|
|
RC_BYTE(pushSWITCH);
|
|
RC_WORD((int) $2);
|
|
RC_BYTE(rcNOT);
|
|
goto expr_end;
|
|
}
|
|
| b_assign IS b_expr
|
|
= {
|
|
goto expr_end;
|
|
}
|
|
| b_assign
|
|
= {
|
|
RC_BYTE(pushTRUE);
|
|
goto expr_end;
|
|
}
|
|
| c_assign expr
|
|
= {
|
|
RC_BYTE(Format.data);
|
|
goto expr_end;
|
|
}
|
|
| n_assign expr
|
|
= {
|
|
expr_end:
|
|
RC_BYTE(rcEND_SET);
|
|
RC_UPDATE($1);
|
|
}
|
|
;
|
|
b_assign: SET b_var
|
|
= {
|
|
$$ = RC_INIT_JUMP(setSWITCH);
|
|
RC_BYTE(pushSWITCH);
|
|
RC_WORD((int) $2);
|
|
}
|
|
;
|
|
c_assign: SET sys_var ABIS
|
|
= {
|
|
$$ = RC_INIT_JUMP(setVAR);
|
|
RC_SYS_VAR((int) $2, FALSE);
|
|
RC_SYS_VAR((int) $2, FALSE);
|
|
Format.data = (int) $3;
|
|
}
|
|
;
|
|
n_assign: SET sys_var IS
|
|
= {
|
|
$$ = RC_INIT_JUMP(setVAR);
|
|
RC_SYS_VAR((int) $2, FALSE);
|
|
}
|
|
;
|
|
/* PROCEDURE declaration */
|
|
proc_hd : PROC proc_nam
|
|
= {
|
|
if (Proc[((int) $2) - 1])
|
|
rc_error(2, $2);
|
|
else
|
|
{
|
|
/* initialze jump over proc */
|
|
$$ = RC_INIT_JUMP(rcJUMP);
|
|
/* now get the address of procedure */
|
|
Proc[((int) $2) - 1] = R_rc;
|
|
}
|
|
}
|
|
;
|
|
/* procedure CALL statement */
|
|
call : CALL PROC proc_nam
|
|
= {
|
|
$$ = $3;
|
|
}
|
|
| CALL proc_nam
|
|
= {
|
|
$$ = $2;
|
|
}
|
|
;
|
|
proc_nam: ICONST
|
|
= {
|
|
if (((int) $1) <= 0 || ((int) $1) > MAX_PROCS)
|
|
rc_error(1, $1);
|
|
}
|
|
;
|
|
/* IF statement */
|
|
if_cond : if_kwd b_expr
|
|
= {
|
|
RC_UPDATE($1);
|
|
}
|
|
;
|
|
if_kwd : IF
|
|
= {
|
|
if_code:
|
|
/* initialize jump to THEN */
|
|
$$ = RC_INIT_JUMP(rcIF);
|
|
}
|
|
;
|
|
if_then : th_kwd stmt_s
|
|
= {
|
|
/* initialize jump to END IF */
|
|
$$ = RC_INIT_JUMP(rcJUMP);
|
|
/* update jump to THEN */
|
|
RC_UPDATE($1);
|
|
}
|
|
;
|
|
th_kwd : THEN
|
|
= {
|
|
then_code:
|
|
/* initialize jump to ELSE */
|
|
$$ = RC_INIT_JUMP(rcTHEN);
|
|
}
|
|
;
|
|
if_else : ELSE stmt_s
|
|
| /* empty */
|
|
;
|
|
/* WHILE statement */
|
|
wh_cond : wh_kwd b_expr
|
|
= {
|
|
RC_UPDATE($1);
|
|
}
|
|
;
|
|
wh_kwd : WHILE
|
|
= {
|
|
goto if_code;
|
|
}
|
|
;
|
|
wh_do : do stmt_s
|
|
;
|
|
do : DO
|
|
= {
|
|
goto then_code;
|
|
}
|
|
;
|
|
/* REPEAT statement */
|
|
repeat : REPEAT
|
|
= {
|
|
$$ = R_rc;
|
|
}
|
|
;
|
|
/* CASE statement */
|
|
case_hd : CASE var in_kwd
|
|
= {
|
|
if (Case[0])
|
|
rc_error(19);
|
|
else
|
|
{
|
|
RC_BYTE(prVAR);
|
|
RC_WORD((int) $2);
|
|
/* initialize case# and addr(jump_table) */
|
|
$$ = RC_INIT_JUMP(rcCASE);
|
|
RC_WORD(0); /* case# */
|
|
Case_no = 0;
|
|
Case[0] = R_rc;
|
|
}
|
|
}
|
|
;
|
|
in_kwd : IN
|
|
| /* empty */
|
|
;
|
|
case_s : one_case
|
|
| case_s one_case
|
|
;
|
|
one_case: DO stmt_s
|
|
= {
|
|
RC_BYTE(rcRETURN);
|
|
if (++Case_no == MAX_CASES)
|
|
rc_error(23);
|
|
else
|
|
Case[Case_no] = R_rc;
|
|
}
|
|
;
|
|
out : OUT stmt_s
|
|
= {
|
|
out_code:
|
|
RC_BYTE(rcRETURN);
|
|
}
|
|
| /* empty */
|
|
= {
|
|
goto out_code;
|
|
}
|
|
;
|
|
/* ON statement */
|
|
on_hd : ON EXCEPTION do_kwd
|
|
= {
|
|
/* initialize jump over exception */
|
|
$$ = RC_INIT_JUMP((int) $2);
|
|
}
|
|
;
|
|
/* TERMINAL statement */
|
|
console : TERMINAL SCONST BATCH value
|
|
= {
|
|
Format.batch_len = (int) $4;
|
|
$$ = $2;
|
|
}
|
|
| TERMINAL SCONST
|
|
= {
|
|
Format.batch_len = A_BATCH;
|
|
$$ = $2;
|
|
}
|
|
;
|
|
/* print constant STRING */
|
|
string : str_kwd batch
|
|
| str_kwd value
|
|
= {
|
|
Format.fr_to[1] = $2;
|
|
}
|
|
| str_kwd
|
|
;
|
|
str_kwd : sconst
|
|
= {
|
|
/* initialize string output */
|
|
Format.batch_len = A_BATCH;
|
|
Format.fr_to[0] = R_rc;
|
|
Format.fr_to[1] = (char *) 0; /* used as repeat info */
|
|
}
|
|
;
|
|
sconst : SCONST
|
|
= {
|
|
Format.str_len = AAlength($1);
|
|
Format.str_adr = $1;
|
|
}
|
|
;
|
|
batch : BATCH value
|
|
= {
|
|
Format.batch_len = (int) $2;
|
|
}
|
|
;
|
|
/* formatted OUTPUT statement */
|
|
format : int_stm int_fmt
|
|
= {
|
|
if (!Format.data)
|
|
rc_error(21);
|
|
RC_BYTE(fmtINT);
|
|
RC_WORD(Format.length);
|
|
RC_STR(&Format.scale, sizeof (double));
|
|
|
|
/* picture string */
|
|
RC_WORD(Format.str_len);
|
|
RC_STR(Format.str_adr, Format.str_len);
|
|
}
|
|
| dbl_stm dbl_fmt
|
|
= {
|
|
if (!Format.data)
|
|
rc_error(21);
|
|
RC_BYTE(fmtREAL);
|
|
RC_WORD(Format.length);
|
|
RC_STR(&Format.scale, sizeof (double));
|
|
RC_WORD(Format.before);
|
|
RC_WORD(Format.point);
|
|
RC_WORD(Format.ignore);
|
|
RC_WORD(Format.norm);
|
|
|
|
/* exponent string */
|
|
RC_WORD(Format.str_len);
|
|
RC_STR(Format.str_adr, Format.str_len);
|
|
}
|
|
| chr_stm chr_fmt
|
|
= {
|
|
if (!Format.data)
|
|
rc_error(21);
|
|
RC_BYTE(fmtCHAR);
|
|
RC_WORD(Format.length);
|
|
RC_WORD((int) Format.fr_to[0]);
|
|
RC_WORD((int) Format.fr_to[1]);
|
|
RC_WORD(Format.batch_len);
|
|
}
|
|
| gra_stm gra_fmt
|
|
= {
|
|
if (!Format.data)
|
|
rc_error(21);
|
|
RC_BYTE(fmtGRAPH);
|
|
RC_WORD(Format.length);
|
|
|
|
/* from */
|
|
RC_WORD((int) Format.fr_to_v[0]);
|
|
if (!Format.fr_to_v[0])
|
|
RC_STR(&Format.fr_to_8[0], sizeof (double));
|
|
|
|
/* to */
|
|
RC_WORD(Format.fr_to_v[1]);
|
|
if (!Format.fr_to_v[1])
|
|
RC_STR(&Format.fr_to_8[1], sizeof (double));
|
|
|
|
/* with char */
|
|
RC_STR(Format.str_adr, sizeof (char));
|
|
}
|
|
/* BIT/OCT/DEC/HEX */
|
|
| byte_kwd length data
|
|
= {
|
|
RC_BYTE((int) $1);
|
|
RC_WORD((int) $2);
|
|
}
|
|
| byte_kwd data
|
|
= {
|
|
RC_BYTE((int) $1);
|
|
RC_WORD(0);
|
|
}
|
|
;
|
|
/* INTEGER format */
|
|
int_stm : INTEGER
|
|
= {
|
|
/* initialize Format structure */
|
|
Format.data = FALSE;
|
|
Format.length = 0;
|
|
Format.scale = A_SCALE;
|
|
Format.str_len = 0;
|
|
Format.str_adr = 0;
|
|
}
|
|
;
|
|
int_fmt : i_fmt
|
|
| int_fmt i_fmt
|
|
;
|
|
i_fmt : length
|
|
| scale
|
|
| pic
|
|
| object
|
|
;
|
|
length : LENGTH value
|
|
= {
|
|
Format.length = (int) ($$ = $2);
|
|
}
|
|
;
|
|
scale : SCALE RCONST
|
|
= {
|
|
Format.scale = *((double *) $2);
|
|
}
|
|
| SCALE LCONST
|
|
= {
|
|
Format.scale = *((long *) $2);
|
|
}
|
|
| SCALE ICONST
|
|
= {
|
|
Format.scale = ((int) $2);
|
|
}
|
|
;
|
|
pic : PIC sconst
|
|
;
|
|
/* REAL format */
|
|
dbl_stm : REAL
|
|
= {
|
|
/* initialize Format structure */
|
|
Format.data = FALSE;
|
|
Format.length = 0;
|
|
Format.scale = A_SCALE;
|
|
Format.before = A_BEFORE;
|
|
Format.point = A_POINT;
|
|
Format.str_len = 0;
|
|
Format.str_adr = 0;
|
|
Format.ignore = FALSE;
|
|
Format.norm = A_NORM;
|
|
}
|
|
;
|
|
dbl_fmt : d_fmt
|
|
| dbl_fmt d_fmt
|
|
;
|
|
d_fmt : length
|
|
| scale
|
|
| BEFORE value
|
|
= {
|
|
if (((int) $2) > MAX_I1)
|
|
rc_error(22, 0, MAX_I1);
|
|
else
|
|
Format.before = ((int) $2);
|
|
}
|
|
| POINT value
|
|
= {
|
|
if (((int) $2) > MAX_I1)
|
|
rc_error(22, 0, MAX_I1);
|
|
else
|
|
Format.point = ((int) $2);
|
|
}
|
|
| EXP sconst
|
|
| IGNORE
|
|
= {
|
|
Format.ignore |= B_IGNORE;
|
|
}
|
|
| NORM norm
|
|
= {
|
|
Format.norm = ((int) $2);
|
|
}
|
|
| object
|
|
;
|
|
norm : ICONST
|
|
= {
|
|
if (((int) $1) < L_NORM || ((int) $1) > H_NORM)
|
|
rc_error(22, L_NORM, H_NORM);
|
|
else if (((int) $1) < 0)
|
|
{
|
|
Format.ignore |= B_NORM;
|
|
$$ = (char *) (- ((int) $1));
|
|
}
|
|
}
|
|
| var
|
|
;
|
|
/* CHAR format */
|
|
chr_stm : F_CHAR
|
|
= {
|
|
/* initialze Format structure */
|
|
Format.data = FALSE;
|
|
Format.length = 0;
|
|
Format.fr_to[0] = (char *) A_FROM;
|
|
Format.fr_to[1] = (char *) 0;
|
|
Format.batch_len = A_BATCH;
|
|
}
|
|
;
|
|
chr_fmt : c_fmt
|
|
| chr_fmt c_fmt
|
|
;
|
|
c_fmt : length
|
|
| fr_to
|
|
| batch
|
|
| object
|
|
;
|
|
fr_to : FROM_TO value
|
|
= {
|
|
Format.fr_to[(int) $1] = $2;
|
|
}
|
|
;
|
|
/* GRAPHIC format */
|
|
gra_stm : GRAPHIC
|
|
= {
|
|
/* initialize Format structure */
|
|
Format.data = FALSE;
|
|
Format.length = 0;
|
|
Format.fr_to_v[0] = 0;
|
|
Format.fr_to_v[1] = 0;
|
|
Format.fr_to_8[0] = 0;
|
|
Format.fr_to_8[1] = 0;
|
|
Format.str_len = sizeof (char);
|
|
Format.str_adr = "*";
|
|
}
|
|
;
|
|
gra_fmt : g_fmt
|
|
| gra_fmt g_fmt
|
|
;
|
|
g_fmt : length
|
|
| FROM_TO var
|
|
= {
|
|
Format.fr_to_v[(int) $1] = (int) $2;
|
|
}
|
|
| FROM_TO ICONST
|
|
= {
|
|
Format.fr_to_8[(int) $1] = (int) $2;
|
|
}
|
|
| FROM_TO LCONST
|
|
= {
|
|
Format.fr_to_8[(int) $1] = *((long *) $2);
|
|
}
|
|
| FROM_TO RCONST
|
|
= {
|
|
Format.fr_to_8[(int) $1] = *((double *) $2);
|
|
}
|
|
| WITH sconst
|
|
= {
|
|
if (!Format.str_len)
|
|
Format.str_adr = " ";
|
|
}
|
|
| object
|
|
;
|
|
object : data
|
|
= {
|
|
if (Format.data++)
|
|
rc_error(20);
|
|
}
|
|
;
|
|
data : SYS_CONST
|
|
= {
|
|
RC_BYTE(prCONST);
|
|
RC_WORD((int) $1);
|
|
}
|
|
| sys_var
|
|
= {
|
|
RC_SYS_VAR((int) $1, TRUE);
|
|
}
|
|
| tup_kwd
|
|
;
|
|
tup_kwd : DOMAIN value
|
|
= {
|
|
switch ((int) $1)
|
|
{
|
|
case pushLAST:
|
|
RC_BYTE(prLAST);
|
|
break;
|
|
|
|
case pushVALUE:
|
|
RC_BYTE(prVALUE);
|
|
break;
|
|
|
|
case pushNEXT:
|
|
RC_BYTE(prNEXT);
|
|
}
|
|
RC_WORD((int) $2);
|
|
}
|
|
;
|
|
|
|
|
|
/* expressions */
|
|
|
|
b_expr : LPAREN b_expr RPAREN
|
|
| LUOP b_expr
|
|
= {
|
|
RC_BYTE((int) $1);
|
|
}
|
|
| b_expr LBOP b_expr
|
|
= {
|
|
RC_BYTE((int) $2);
|
|
}
|
|
| expr relop expr
|
|
= {
|
|
RC_BYTE((int) $2);
|
|
}
|
|
| BCONST
|
|
= {
|
|
RC_BYTE((int) $1);
|
|
}
|
|
| b_var
|
|
= {
|
|
RC_BYTE(pushSWITCH);
|
|
RC_WORD((int) $1);
|
|
}
|
|
| GROUPBEGIN value
|
|
= {
|
|
RC_BYTE(pushLAST);
|
|
RC_WORD((int) $2);
|
|
RC_WORD(0); /* from */
|
|
RC_WORD(0); /* to */
|
|
RC_BYTE(pushVALUE);
|
|
RC_WORD((int) $2);
|
|
RC_WORD(0); /* from */
|
|
RC_WORD(0); /* to */
|
|
RC_BYTE(bdNE);
|
|
}
|
|
| GROUPEND value
|
|
= {
|
|
RC_BYTE(pushVALUE);
|
|
RC_WORD((int) $2);
|
|
RC_WORD(0); /* from */
|
|
RC_WORD(0); /* to */
|
|
RC_BYTE(pushNEXT);
|
|
RC_WORD((int) $2);
|
|
RC_WORD(0); /* from */
|
|
RC_WORD(0); /* to */
|
|
RC_BYTE(bdNE);
|
|
}
|
|
;
|
|
expr : LPAREN expr RPAREN
|
|
| auop expr %prec unaryop
|
|
= {
|
|
/* skip positive sign */
|
|
if (((int) $1) == ((int) rcMIN))
|
|
RC_BYTE(rcMIN);
|
|
}
|
|
| expr ABOP expr
|
|
= {
|
|
RC_BYTE((int) $2);
|
|
}
|
|
| expr AUOP expr /* binary '+' and '-' */
|
|
= {
|
|
if (((int) $2) == ((int) rcMIN))
|
|
RC_BYTE(rcSUB);
|
|
else
|
|
RC_BYTE((int) $2);
|
|
}
|
|
| ICONST
|
|
= {
|
|
if (!((int) $1))
|
|
RC_BYTE(pushNULL);
|
|
else if (((int) $1) <= MAX_I1 && ((int) $1) >= MIN_I1)
|
|
{
|
|
RC_BYTE(push1INT);
|
|
RC_BYTE((int) $1);
|
|
}
|
|
else
|
|
{
|
|
RC_BYTE(push2INT);
|
|
RC_WORD((int) $1);
|
|
}
|
|
}
|
|
| LCONST
|
|
= {
|
|
RC_BYTE(push4INT);
|
|
RC_STR($1, sizeof (long));
|
|
}
|
|
| RCONST
|
|
= {
|
|
RC_BYTE(pushREAL);
|
|
RC_STR($1, sizeof (double));
|
|
}
|
|
| sconst
|
|
= {
|
|
RC_BYTE(pushSTRING);
|
|
RC_WORD(Format.str_len);
|
|
RC_STR($1, Format.str_len);
|
|
}
|
|
| SYS_CONST
|
|
= {
|
|
RC_BYTE(pushCONST);
|
|
RC_BYTE((int) $1);
|
|
}
|
|
| sys_var
|
|
= {
|
|
RC_SYS_VAR((int) $1, FALSE);
|
|
}
|
|
| domain
|
|
= {
|
|
RC_WORD((int) Format.fr_to[0]);
|
|
RC_WORD((int) Format.fr_to[1]);
|
|
}
|
|
;
|
|
relop : EOP
|
|
| IS
|
|
| BDOP
|
|
;
|
|
auop : AUOP %prec unaryop
|
|
;
|
|
domain : dom_kwd fr_to fr_to
|
|
| dom_kwd fr_to
|
|
| dom_kwd
|
|
;
|
|
dom_kwd : DOMAIN value
|
|
= {
|
|
RC_BYTE((int) $1);
|
|
RC_WORD((int) $2);
|
|
/* initialize Format structure */
|
|
Format.fr_to[0] = (char *) 0;
|
|
Format.fr_to[1] = (char *) 0;
|
|
}
|
|
;
|
|
|
|
|
|
/* (SYSTEM) values and variables */
|
|
|
|
sys_var : var
|
|
| PAGE
|
|
= {
|
|
$$ = (char *) SYS_PAGE;
|
|
}
|
|
| LINE
|
|
= {
|
|
$$ = (char *) SYS_LINE;
|
|
}
|
|
| ALL LINE
|
|
= {
|
|
$$ = (char *) SYS_ALL_LINE;
|
|
}
|
|
| COLUMN
|
|
= {
|
|
$$ = (char *) SYS_COL;
|
|
}
|
|
| TUPLE
|
|
= {
|
|
$$ = (char *) SYS_TUPL;
|
|
}
|
|
;
|
|
var : NVAR NVAR ICONST
|
|
= {
|
|
if (((int) $3) < 0 || ((int) $3) >= MAX_VAR)
|
|
rc_error(6, $3);
|
|
else
|
|
$$ = (char *) (((int) $3) | VAR_VAR_MASK);
|
|
}
|
|
| NVAR ICONST
|
|
= {
|
|
if (((int) $2) < 0 || ((int) $2) >= MAX_VAR)
|
|
rc_error(6, $2);
|
|
else
|
|
$$ = (char *) (((int) $2)| VAR_MASK);
|
|
}
|
|
;
|
|
b_var : SWITCH value
|
|
= {
|
|
if (((int) $2) >= MAX_BVAR)
|
|
rc_error(7, $2);
|
|
else
|
|
$$ = $2;
|
|
}
|
|
;
|
|
value : ICONST
|
|
= {
|
|
if (((int) $1) < 0)
|
|
{
|
|
rc_error(8, $1);
|
|
$$ = 0;
|
|
}
|
|
}
|
|
| var
|
|
;
|
|
|
|
|
|
/* KEY WORDS */
|
|
|
|
byte_kwd: FORMAT BYTE
|
|
| FORMAT WORD
|
|
= {
|
|
$$ = $1 + 1;
|
|
}
|
|
| FORMAT
|
|
;
|
|
do_kwd : DO
|
|
| /* empty */
|
|
;
|
|
end1_kwd: ENDO
|
|
| END one_kwd
|
|
;
|
|
enda_kwd: ENDA
|
|
| END ALL
|
|
;
|
|
endc_kwd: ENDC
|
|
| END CASE
|
|
;
|
|
endi_kwd: ENDI
|
|
| END IF
|
|
;
|
|
endo_kwd: ENDO
|
|
| END
|
|
;
|
|
endr_kwd: ENDR
|
|
| END REPEAT
|
|
;
|
|
endw_kwd: ENDW
|
|
| END WHILE
|
|
;
|
|
for1_kwd: FOR one_kwd do_kwd
|
|
= {
|
|
RC_BYTE(rcONE);
|
|
}
|
|
;
|
|
fora_kwd: FOR ALL do_kwd
|
|
= {
|
|
RC_BYTE(rcALL);
|
|
$$ = R_rc;
|
|
}
|
|
;
|
|
one_kwd : ONE
|
|
| /* empty */
|
|
;
|
|
|
|
|
|
%%
|
|
|
|
|
|
# include "rc_tab.y"
|