From 4e23f49a2859cf8e2eb184c6a869dfc3c1e00bbc Mon Sep 17 00:00:00 2001 From: "James K. Lowden" <jklowden@symas.com> Date: Fri, 22 Dec 2023 11:58:24 -0500 Subject: [PATCH] WIP: re-parsing CALL and UDF --- gcc/cobol/cdf.y | 26 +++++++++---------- gcc/cobol/parse.y | 58 +++++++++++++++--------------------------- gcc/cobol/parse_ante.h | 15 +++++++---- gcc/cobol/scan.l | 2 +- gcc/cobol/symbols.h | 2 +- 5 files changed, 46 insertions(+), 57 deletions(-) diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index 77ea416303e7..9136afb0f1bd 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -262,12 +262,12 @@ apply_cdf_turn( exception_turns_t& turns ) { %token BY 470 %token COPY 358 %token CDF_DISPLAY 380 -%token IN 583 +%token IN 584 %token NAME 286 %token NUMSTR 304 -%token OF 661 -%token PSEUDOTEXT 697 -%token REPLACING 719 +%token OF 662 +%token PSEUDOTEXT 698 +%token REPLACING 720 %token LITERAL 297 %token SUPPRESS 375 @@ -279,19 +279,19 @@ apply_cdf_turn( exception_turns_t& turns ) { %token AS 454 CONSTANT 357 DEFINED 359 %type <boolean> DEFINED -%token OTHER 673 PARAMETER_kw 364 OFF 662 OVERRIDE 365 -%token THRU 909 -%token TRUE_kw 784 +%token OTHER 674 PARAMETER_kw 364 OFF 663 OVERRIDE 365 +%token THRU 910 +%token TRUE_kw 785 -%token TURN 786 CHECKING 478 LOCATION 625 ON 664 WITH 810 +%token TURN 787 CHECKING 479 LOCATION 626 ON 665 WITH 811 -%left OR 910 -%left AND 911 -%right NOT 912 -%left '<' '>' '=' NE 913 LE 914 GE 915 +%left OR 911 +%left AND 912 +%right NOT 913 +%left '<' '>' '=' NE 914 LE 915 GE 916 %left '-' '+' %left '*' '/' -%right NEG 916 +%right NEG 917 %define api.prefix {ydf} %define api.token.prefix{YDF_} diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 776c265454b0..99c55295b906 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -420,9 +420,8 @@ %type <number> /* addr_len_of */ alphanum_pic %type <pic_part> alphanum_part -%type <ffi_arg> ffi_by_ref ffi_by_con ffi_by_val -%type <ffi_args> ffi_by_refs ffi_by_cons ffi_by_vals -%type <ffi_args> parameter parameters +%type <ffi_arg> parameter ffi_by_ref ffi_by_con ffi_by_val +%type <ffi_args> parameters %type <ffi_impl> call_body call_impl %type <ffi_arg> procedure_use @@ -636,7 +635,7 @@ ASCENDING ASIN ASSIGN AT ATAN AUTHOR BASED BEFORE BINARY BIT BIT_OF BIT_TO_CHAR BLANK BLOCK - BOTTOM BY BYTE_LENGTH + BOTTOM BY BYTE_LENGTH BYTE_LENGTH_OF C01 C02 C03 C04 C05 C06 C07 C08 C09 C10 C11 C12 CF CH CHANGED CHAR CHARACTER CHARACTERS CHECKING CLASS @@ -955,6 +954,7 @@ program_id: PROGRAM_ID dot namestr[name] program_as program_attrs[attr] dot if(false && yydebug) { warnx("current program is now %s", name); } + if( nparse_error > 0 ) YYABORT; } ; dot: %empty @@ -978,6 +978,7 @@ function_id: FUNCTION '.' NAME program_as program_attrs[attr] '.' if(false && yydebug) { warnx("current program is now %s", $NAME); } + if( nparse_error > 0 ) YYABORT; } | FUNCTION '.' NAME program_as is PROTOTYPE '.' { @@ -2700,8 +2701,8 @@ data_descr: data_descr1 ; const_value: cce_expr - | BYTE_LENGTH of name { $$ = $name->data.capacity; } - | LENGTH of name { $$ = $name->data.capacity; } + | BYTE_LENGTH_OF of name { $$ = $name->data.capacity; } + | LENGTH of name { $$ = $name->data.capacity; } ; value78: literalism @@ -6150,16 +6151,16 @@ varg: varg1 | ALL varg1 { $$ = $2; $$->all = true; } ; -varg1: literal +varg1: scalar + | intrinsic_call + | literal { $$ = new_reference($1); } - | scalar | reserved_value { $$ = new_reference(constant_of(constant_index($1))); } - | intrinsic_call ; literal: LITERAL @@ -7786,23 +7787,17 @@ ffi_name: name | LITERAL { $$ = new_reference(new_literal($1, quoted_e)); } ; -parameters: parameter +parameters: parameter { $$ = new ffi_args_t($1); } | parameters parameter { - $1->elems.splice($1->elems.end(), $2->elems); + $1->push_back($2); $$ = $1; } ; -parameter: ffi_by_ref { $$ = new ffi_args_t($1); } - | by REFERENCE ffi_by_refs { $$ = $3; } - | by CONTENT ffi_by_cons { $$ = $3; } - | by VALUE ffi_by_vals { $$ = $3; } - ; -ffi_by_refs: ffi_by_ref { $$ = new ffi_args_t($1); } - | ffi_by_refs ffi_by_ref[ref] - { - $$ = $1->push_back($ref); - } +parameter: ffi_by_ref { $$ = $1; $$->crv = cbl_ffi_crv_t(0); } + | by REFERENCE ffi_by_ref { $$ = $3; } + | by CONTENT ffi_by_con { $$ = $3; } + | by VALUE ffi_by_val { $$ = $3; } ; ffi_by_ref: scalar_arg[refer] { @@ -7819,20 +7814,12 @@ ffi_by_ref: scalar_arg[refer] } ; -ffi_by_cons: ffi_by_con { $$ = new ffi_args_t($1); } - | ffi_by_cons ffi_by_con { $$ = $1->push_back($2); } - ; -ffi_by_con: scalar_arg - { - $$ = new cbl_ffi_arg_t(by_content_e, $1); - } - | ADDRESS OF scalar_arg[arg] +ffi_by_con: expr { - $$ = new cbl_ffi_arg_t(by_content_e, $arg, address_of_e); - } - | LENGTH OF scalar_arg[arg] - { - $$ = new cbl_ffi_arg_t(by_content_e, $arg, length_of_e); + cbl_refer_t *r = new cbl_refer_t(*$1); + r->field = new_temporary_clone($1->field); + parser_move(r->field, $1->field); + $$ = new cbl_ffi_arg_t(by_content_e, r); } | LITERAL { @@ -7846,9 +7833,6 @@ ffi_by_con: scalar_arg } ; -ffi_by_vals: ffi_by_val { $$ = new ffi_args_t($1); } - | ffi_by_vals ffi_by_val { $$ = $1->push_back($2); } - ; ffi_by_val: by_value_arg { $$ = new cbl_ffi_arg_t(by_value_e, $1); diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index 88d54ba58dd6..7de44a83a6ae 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -1143,20 +1143,24 @@ struct ffi_args_t { list<cbl_ffi_arg_t> elems; ffi_args_t( cbl_ffi_arg_t *arg ) { - elems.push_back(*arg); - delete arg; + this->push_back(arg); } + // set explicitly, or assume ffi_args_t * push_back( cbl_ffi_arg_t *arg ) { + if( arg->crv < by_reference_e ) { + arg->crv = elems.empty()? by_reference_e : elems.back().crv; + } elems.push_back(*arg); delete arg; return this; } + // infer reference/content/value from previous ffi_args_t * push_back( cbl_refer_t* refer, cbl_ffi_arg_attr_t attr = none_of_e ) { - assert(!elems.empty()); - cbl_ffi_arg_t arg( elems.back().crv, refer, attr ); + cbl_ffi_crv_t crv = elems.empty()? by_reference_e : elems.back().crv; + cbl_ffi_arg_t arg( crv, refer, attr ); elems.push_back(arg); return this; } @@ -1826,7 +1830,8 @@ new_tempnumeric_float(void) { return new_temporary(FldFloat); } static inline cbl_field_t * new_temporary_clone( const cbl_field_t *orig) { - auto f = new_temporary_imply(orig->type); + cbl_field_type_t type = is_literal(orig)? FldAlphanumeric : orig->type; + auto f = new_temporary_imply(type); f->data = orig->data; parser_symbol_add(f); return f; diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index a7ee009a4a48..3e4b7dee2f0e 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -980,7 +980,7 @@ USE([[:space:]]+FOR)? { return USE; } BLANK { return BLANK; } BLOCK { return BLOCK; } BY { return BY; } - BYTE-LENGTH { return BYTE_LENGTH; } + BYTE-LENGTH { return BYTE_LENGTH_OF; } CHARACTER { return CHARACTER; } CHARACTERS { return CHARACTERS; } CODE-SET { return CODESET; } diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index d0b215db02c9..7fa780255391 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -888,7 +888,7 @@ struct cbl_num_result_t { * CALL */ enum cbl_ffi_arg_attr_t { none_of_e, address_of_e, length_of_e }; -enum cbl_ffi_crv_t { by_reference_e, by_content_e, by_value_e }; +enum cbl_ffi_crv_t { by_reference_e = 'R', by_content_e = 'C', by_value_e = 'E' }; void parser_symbol_add( struct cbl_field_t *new_var ); void parser_local_add( struct cbl_field_t *new_var ); -- GitLab