From bcaee645462812b4d855d041434e933944db9888 Mon Sep 17 00:00:00 2001 From: "James K. Lowden" <jklowden@symas.com> Date: Wed, 15 Jan 2025 13:58:37 -0500 Subject: [PATCH] WIP: converting messages in parse.y --- gcc/cobol/UAT/testsuite.src/run_functions.at | 86 ++-- gcc/cobol/UAT/testsuite.src/syn_definition.at | 4 +- gcc/cobol/parse.y | 454 +++++++++--------- gcc/cobol/parse_ante.h | 3 +- gcc/cobol/scan.l | 347 ++++++++++++- gcc/cobol/scan_ante.h | 43 +- gcc/cobol/util.cc | 9 +- 7 files changed, 642 insertions(+), 304 deletions(-) diff --git a/gcc/cobol/UAT/testsuite.src/run_functions.at b/gcc/cobol/UAT/testsuite.src/run_functions.at index a5de5daeeb37..afb0f3bca8b5 100644 --- a/gcc/cobol/UAT/testsuite.src/run_functions.at +++ b/gcc/cobol/UAT/testsuite.src/run_functions.at @@ -5266,43 +5266,43 @@ AT_DATA([prog.cob], [ ]) AT_CHECK([$COMPILE prog.cob], [1], [], -[prog.cob:12:29: error: syntax error, unexpected NAME, expecting DATETIME_FMT +[prog.cob:12:29: error: syntax error, unexpected NAME, expecting datetime format 12 | (invalid-date-format) <> SPACES | ^ prog.cob:16:12: error: syntax error, unexpected END_IF 16 | END-IF | ^ -prog.cob:18:40: error: syntax error, unexpected NAME, expecting DATE_FMT +prog.cob:18:40: error: syntax error, unexpected NAME, expecting date format 18 | IF FUNCTION FORMATTED-DATE (invalid-date-format, 1) <> SPACES | ^ prog.cob:22:12: error: syntax error, unexpected END_IF 22 | END-IF | ^ -prog.cob:25:29: error: syntax error, unexpected NAME, expecting DATETIME_FMT +prog.cob:25:29: error: syntax error, unexpected NAME, expecting datetime format 25 | (invalid-datetime-format, 1, 1) <> SPACES | ^ prog.cob:29:12: error: syntax error, unexpected END_IF 29 | END-IF | ^ -prog.cob:31:40: error: syntax error, unexpected NAME, expecting TIME_FMT +prog.cob:31:40: error: syntax error, unexpected NAME, expecting time format 31 | IF FUNCTION FORMATTED-TIME (invalid-time-format, 1) <> SPACES | ^ prog.cob:35:12: error: syntax error, unexpected END_IF 35 | END-IF | ^ -prog.cob:38:29: error: syntax error, unexpected NAME, expecting DATE_FMT or DATETIME_FMT +prog.cob:38:29: error: syntax error, unexpected NAME, expecting date format or datetime format 38 | (invalid-date-format, 1) <> ZERO | ^ prog.cob:42:12: error: syntax error, unexpected END_IF 42 | END-IF | ^ -prog.cob:45:29: error: syntax error, unexpected NAME, expecting TIME_FMT or DATETIME_FMT +prog.cob:45:29: error: syntax error, unexpected NAME, expecting time format or datetime format 45 | (invalid-time-format, 1) <> ZERO | ^ prog.cob:49:12: error: syntax error, unexpected END_IF 49 | END-IF | ^ -prog.cob:52:29: error: syntax error, unexpected NAME, expecting DATE_FMT or TIME_FMT or DATETIME_FMT +prog.cob:52:29: error: syntax error, unexpected NAME, expecting date format or time format or datetime format 52 | (invalid-datetime-format, 1) <> ZERO | ^ prog.cob:56:12: error: syntax error, unexpected END_IF @@ -5450,112 +5450,112 @@ AT_DATA([prog.cob], [ END PROGRAM datetime. ]) AT_CHECK([$COMPILE prog.cob], [1], [], -[prog.cob:7:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +[prog.cob:7:46: error: syntax error, unexpected LITERAL, expecting datetime format 7 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss" 128623 45296.987654321 -300). | ^ -prog.cob:8:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:8:46: error: syntax error, unexpected LITERAL, expecting datetime format 8 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss+hhmm" 128623 45296.987654321 -300). | ^ -prog.cob:9:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:9:46: error: syntax error, unexpected LITERAL, expecting datetime format 9 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss.ssss" 128623 45296.987654321 -300). | ^ -prog.cob:10:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:10:46: error: syntax error, unexpected LITERAL, expecting datetime format 10 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss.ssss+hhmm" 128623 45296.987654321 -300). | ^ -prog.cob:11:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:11:46: error: syntax error, unexpected LITERAL, expecting datetime format 11 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss.ssssZ" 128623 45296.987654321 -300). | ^ -prog.cob:12:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:12:46: error: syntax error, unexpected LITERAL, expecting datetime format 12 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmssZ" 128623 45296.987654321 -300). | ^ -prog.cob:13:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:13:46: error: syntax error, unexpected LITERAL, expecting datetime format 13 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss" 128623 45296.987654321 -300). | ^ -prog.cob:14:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:14:46: error: syntax error, unexpected LITERAL, expecting datetime format 14 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss+hhmm" 128623 45296.987654321 -300). | ^ -prog.cob:15:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:15:46: error: syntax error, unexpected LITERAL, expecting datetime format 15 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss.ssss" 128623 45296.987654321 -300). | ^ -prog.cob:16:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:16:46: error: syntax error, unexpected LITERAL, expecting datetime format 16 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss.ssss+hhmm" 128623 45296.987654321 -300). | ^ -prog.cob:17:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:17:46: error: syntax error, unexpected LITERAL, expecting datetime format 17 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss.ssssZ" 128623 45296.987654321 -300). | ^ -prog.cob:18:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:18:46: error: syntax error, unexpected LITERAL, expecting datetime format 18 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmssZ" 128623 45296.987654321 -300). | ^ -prog.cob:19:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:19:46: error: syntax error, unexpected LITERAL, expecting datetime format 19 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss" 128623 45296.987654321 -300). | ^ -prog.cob:20:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:20:46: error: syntax error, unexpected LITERAL, expecting datetime format 20 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss+hhmm" 128623 45296.987654321 -300). | ^ -prog.cob:21:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:21:46: error: syntax error, unexpected LITERAL, expecting datetime format 21 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss.ssss" 128623 45296.987654321 -300). | ^ -prog.cob:22:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:22:46: error: syntax error, unexpected LITERAL, expecting datetime format 22 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss.ssss+hhmm" 128623 45296.987654321 -300). | ^ -prog.cob:23:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:23:46: error: syntax error, unexpected LITERAL, expecting datetime format 23 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss.ssssZ" 128623 45296.987654321 -300). | ^ -prog.cob:24:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:24:46: error: syntax error, unexpected LITERAL, expecting datetime format 24 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmssZ" 128623 45296.987654321 -300). | ^ -prog.cob:25:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:25:46: error: syntax error, unexpected LITERAL, expecting datetime format 25 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss" 128623 45296.987654321 -300). | ^ -prog.cob:26:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:26:46: error: syntax error, unexpected LITERAL, expecting datetime format 26 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss+hh:mm" 128623 45296.987654321 -300). | ^ -prog.cob:27:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:27:46: error: syntax error, unexpected LITERAL, expecting datetime format 27 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss.ssss" 128623 45296.987654321 -300). | ^ -prog.cob:28:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:28:46: error: syntax error, unexpected LITERAL, expecting datetime format 28 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss.ssss+hh:mm" 128623 45296.987654321 -300). | ^ -prog.cob:29:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:29:46: error: syntax error, unexpected LITERAL, expecting datetime format 29 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss.ssssZ" 128623 45296.987654321 -300). | ^ -prog.cob:30:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:30:46: error: syntax error, unexpected LITERAL, expecting datetime format 30 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ssZ" 128623 45296.987654321 -300). | ^ -prog.cob:31:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:31:46: error: syntax error, unexpected LITERAL, expecting datetime format 31 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss" 128623 45296.987654321 -300). | ^ -prog.cob:32:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:32:46: error: syntax error, unexpected LITERAL, expecting datetime format 32 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss+hh:mm" 128623 45296.987654321 -300). | ^ -prog.cob:33:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:33:46: error: syntax error, unexpected LITERAL, expecting datetime format 33 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss.ssss" 128623 45296.987654321 -300). | ^ -prog.cob:34:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:34:46: error: syntax error, unexpected LITERAL, expecting datetime format 34 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss.ssss+hh:mm" 128623 45296.987654321 -300). | ^ -prog.cob:35:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:35:46: error: syntax error, unexpected LITERAL, expecting datetime format 35 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss.ssssZ" 128623 45296.987654321 -300). | ^ -prog.cob:36:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:36:46: error: syntax error, unexpected LITERAL, expecting datetime format 36 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ssZ" 128623 45296.987654321 -300). | ^ -prog.cob:37:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:37:46: error: syntax error, unexpected LITERAL, expecting datetime format 37 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss" 128623 45296.987654321 -300). | ^ -prog.cob:38:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:38:46: error: syntax error, unexpected LITERAL, expecting datetime format 38 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss+hh:mm" 128623 45296.987654321 -300). | ^ -prog.cob:39:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:39:46: error: syntax error, unexpected LITERAL, expecting datetime format 39 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss.ssss" 128623 45296.987654321 -300). | ^ -prog.cob:40:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:40:46: error: syntax error, unexpected LITERAL, expecting datetime format 40 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss.ssss+hh:mm" 128623 45296.987654321 -300). | ^ -prog.cob:41:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:41:46: error: syntax error, unexpected LITERAL, expecting datetime format 41 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss.ssssZ" 128623 45296.987654321 -300). | ^ -prog.cob:42:46: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT +prog.cob:42:46: error: syntax error, unexpected LITERAL, expecting datetime format 42 | DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ssZ" 128623 45296.987654321 -300). | ^ cobol1: error: failed compiling prog.cob diff --git a/gcc/cobol/UAT/testsuite.src/syn_definition.at b/gcc/cobol/UAT/testsuite.src/syn_definition.at index 4a4329903e90..e42d7a3f370f 100644 --- a/gcc/cobol/UAT/testsuite.src/syn_definition.at +++ b/gcc/cobol/UAT/testsuite.src/syn_definition.at @@ -345,7 +345,9 @@ AT_DATA([prog.cob], [ END PROGRAM prog. ]) AT_CHECK([$COMPILE_ONLY prog.cob], [1], [], -[prog.cob:13: syntax error at 'END' +[prog.cob:13:8: error: syntax error, unexpected END, expecting end of file or END PROGRAM <contained program> + 13 | END PROGRAM prog. + | ^ cobol1: error: failed compiling prog.cob ]) AT_CLEANUP diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 2fb7efffe10a..3ecf1187bec8 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -285,21 +285,39 @@ #include "parse_ante.h" %} -%token IDENTIFICATION_DIV ENVIRONMENT_DIV PROCEDURE_DIV - DATA_DIV FILE_SECT INPUT_OUTPUT_SECT LINKAGE_SECT - LOCAL_STORAGE_SECT WORKING_STORAGE_SECT - -%token OBJECT_COMPUTER - -%token DISPLAY_OF - END_FUNCTION END_PROGRAM END_SUBPROGRAM - JUSTIFIED RETURNING +%token IDENTIFICATION_DIV _("IDENTIFICATION DIVISION") + ENVIRONMENT_DIV _("ENVIRONMENT DIVISION") + PROCEDURE_DIV _("PROCEDURE DIVISION") + DATA_DIV _("DATA DIVISION") + FILE_SECT _("FILE SECTION") + INPUT_OUTPUT_SECT _("INPUT-OUTPUT SECTION") + LINKAGE_SECT _("LINKAGE SECTION") + LOCAL_STORAGE_SECT _("LOCAL-STORAGE SECTION") + WORKING_STORAGE_SECT _("WORKING-STORAGE SECTION") + +%token OBJECT_COMPUTER _("OBJECT COMPUTER") + +%token DISPLAY_OF _("DISPLAY OF") + END_FUNCTION _("END FUNCTION") + END_PROGRAM _("END PROGRAM") + END_SUBPROGRAM _("END PROGRAM <contained program>") + +%token HIGH_ORDER_LEFT _("HIGH-ORDER-LEFT") + HIGH_ORDER_RIGHT _("HIGH-ORDER-RIGHT") + +%token JUSTIFIED RETURNING NO_CONDITION _("invalid token") %token <string> ALNUM ALPHED %token <number> ERROR EXCEPTION SIZE_ERROR %token <ec_type> EXCEPTION_NAME %token <number> LEVEL LEVEL66 LEVEL78 LEVEL88 -%token <string> CLASS_NAME NAME NAME88 NUME NUMED NUMED_CR NUMED_DB +%token <string> CLASS_NAME _("class name") + NAME + NAME88 _("Level 88 NAME") + NUME _("NAME") + NUMED _("NUMERIC-EDITED picture") + NUMED_CR _("NUMERIC-EDITED CR picture") + NUMED_DB _("NUMERIC-EDITED DB picture") %token <number> NINEDOT NINES NINEV PIC_P %token <string> SPACES %token <literal> LITERAL @@ -315,7 +333,7 @@ %token <number> POSITIVE %token <field_attr> POINTER %token <string> SECTION -%token <number> STANDARD_ALPHABET +%token <number> STANDARD_ALPHABET _("STANDARD ALPHABET") %token <string> SWITCH %token <string> UPSI %token <number> ZERO @@ -323,14 +341,18 @@ /* environment names */ %token <number> SYSIN SYSIPT SYSOUT SYSLIST SYSLST SYSPUNCH SYSPCH CONSOLE %token <number> C01 C02 C03 C04 C05 C06 C07 C08 C09 C10 C11 C12 CSP -%token <number> S01 S02 S03 S04 S05 AFP_5A +%token <number> S01 S02 S03 S04 S05 AFP_5A _("AFP 5A") %token <number> STDIN STDOUT STDERR /* intrinsics */ %token <string> LIST MAP NOLIST NOMAP NOSOURCE -%token <number> MIGHT_BE FUNCTION_UDF FUNCTION_UDF_0 +%token <number> MIGHT_BE _("IS or IS NOT") + FUNCTION_UDF _("UDF name") + FUNCTION_UDF_0 _("UDF") -%token <string> DATE_FMT TIME_FMT DATETIME_FMT +%token <string> DATE_FMT _("date format") + TIME_FMT _("time format") + DATETIME_FMT _("datetime format") // YYEOF added for compatibility with Bison 3.5 // https://savannah.gnu.org/forum/forum.php?forum_id=9735 @@ -754,8 +776,8 @@ NAMED NAT NATIONAL NATIONAL_EDITED NATIONAL_OF NATIVE NEGATIVE NESTED NEXT - NINEDOT NINES NINEV NO NOTE - NO_CONDITION NULLS NULLPTR NUMBER + NINEDOT NINES NINEV NO NOTE NO_CONDITION + NULLS NULLPTR NUMBER NUME NUMED NUMED_CR NUMED_DB NUMERIC NUMERIC_EDITED NUMSTR NUMVAL NUMVAL_C NUMVAL_F @@ -1088,7 +1110,7 @@ opt_clause: opt_arith opt_arith: ARITHMETIC is opt_arith_type { if( ! current.option($opt_arith_type) ) { - yyerror("unable to set ARITHMETIC option"); + error_msg(@3, "unable to set ARITHMETIC option"); } } ; @@ -1109,46 +1131,46 @@ opt_binary: FLOAT_BINARY default_kw is HIGH_ORDER_LEFT { cbl_unimplementedw("HIGH-ORDER-LEFT was ignored"); if( ! current.option_binary(cbl_options_t::high_order_left_e) ) { - yyerror("unable to set HIGH_ORDER_LEFT"); + error_msg(@3, "unable to set HIGH_ORDER_LEFT"); } } - | FLOAT_BINARY default_kw is HIGH_ORDER_RIGHT + | FLOAT_BINARY default_kw is HIGH_ORDER_RIGHT[opt] { cbl_unimplementedw("HIGH-ORDER-RIGHT was ignored"); if( ! current.option_binary(cbl_options_t::high_order_right_e) ) { - yyerror("unable to set HIGH_ORDER_RIGHT"); + error_msg(@opt, "unable to set HIGH-ORDER-RIGHT"); } } ; default_kw: %empty | DEFAULT ; -opt_decimal: FLOAT_DECIMAL default_kw is HIGH_ORDER_LEFT +opt_decimal: FLOAT_DECIMAL default_kw is HIGH_ORDER_LEFT[opt] { cbl_unimplementedw("HIGH-ORDER-LEFT was ignored"); if( ! current.option_decimal(cbl_options_t::high_order_left_e) ) { - yyerror("unable to set HIGH_ORDER_LEFT"); + error_msg(@opt, "unable to set HIGH-ORDER-LEFT"); } } - | FLOAT_DECIMAL default_kw is HIGH_ORDER_RIGHT + | FLOAT_DECIMAL default_kw is HIGH_ORDER_RIGHT[opt] { cbl_unimplementedw("HIGH-ORDER-RIGHT was ignored"); if( ! current.option_decimal(cbl_options_t::high_order_right_e) ) { - yyerror("unable to set HIGH_ORDER_RIGHT"); + error_msg(@opt, "unable to set HIGH-ORDER-RIGHT"); } } - | FLOAT_DECIMAL default_kw is BINARY_ENCODING + | FLOAT_DECIMAL default_kw is BINARY_ENCODING[opt] { cbl_unimplementedw("BINARY-ENCODING was ignored"); if( ! current.option(cbl_options_t::binary_encoding_e) ) { - yyerror("unable to set BINARY-ENCODING option"); + error_msg(@opt, "unable to set BINARY-ENCODING option"); } } - | FLOAT_DECIMAL default_kw is DECIMAL_ENCODING + | FLOAT_DECIMAL default_kw is DECIMAL_ENCODING[opt] { cbl_unimplementedw("DECIMAL-ENCODING was ignored"); if( ! current.option(cbl_options_t::decimal_encoding_e) ) { - yyerror("unable to set DECIMAL-ENCODING option"); + error_msg(@opt, "unable to set DECIMAL-ENCODING option"); } } ; @@ -1208,10 +1230,10 @@ opt_init_value: BINARY ZERO { $$ = constant_index(NULLS); } | LITERAL { if( $1.prefix[0] != 'X' ) { - yyerror("hexadecimal literal required"); + error_msg(@1, "hexadecimal literal required"); } if( $1.len != 1 ) { - yyerror("1-byte hexadecimal literal required"); + error_msg(@1, "1-byte hexadecimal literal required"); } char ach[16]; sprintf(ach, "%d", (int)($1.data[0])); @@ -1251,24 +1273,25 @@ comminits: comminit | comminits comminit { if( ($1.initial && $2.recursive) || ($2.initial && $1.recursive) ) { - yyerror("INITIAL cannot be used with RECURSIVE"); + auto loc = $1.initial? @1 : @2; + error_msg(loc, "INITIAL cannot be used with RECURSIVE"); } $$ = $1; if( $2.common ) { if( $1.common ) { - yyerror("COMMON repeated"); + error_msg(@2, "COMMON repeated"); } $$.common = $2.common; } if( $2.initial ) { if( $1.initial ) { - yyerror("INITIAL repeated"); + error_msg(@2, "INITIAL repeated"); } $$.initial = $2.initial; } if( $2.recursive ) { if( $1.recursive ) { - yyerror("RECURSIVE repeated"); + error_msg(@2, "RECURSIVE repeated"); } $$.recursive = $2.recursive; } @@ -1276,7 +1299,7 @@ comminits: comminit ; comminit: COMMON { if( program_level() == 0 ) { // PROGRAM-ID being parsed not added yet. - yyerror("COMMON may be used only in a contained program"); + error_msg(@1, "COMMON may be used only in a contained program"); } $$.common = true; $$.initial = $$.recursive = false; @@ -1355,7 +1378,7 @@ select: SELECT optional NAME[name] select_clauses[clauses] '.' if( !namcpy(file->name, $name) ) YYERROR; if( ! ($clauses.clauses & assign_clause_e) ) { - yyerror("ASSIGN clause missing for %s", file->name); + error_msg(@name, "ASSIGN clause missing for %s", file->name); } // key check @@ -1367,13 +1390,13 @@ select: SELECT optional NAME[name] select_clauses[clauses] '.' auto ikey = file->nkey - 1; assert(file->keys[ikey].fields); auto f = cbl_field_of(symbol_at(file->keys[ikey].fields[0])); - yyerror("INDEXED file %s cannot have RELATIVE key %s", - file->name, f->name); + error_msg(@name, "INDEXED file %s cannot have RELATIVE key %s", + file->name, f->name); break; // because next message would be redundant } if( ($clauses.clauses & record_key_clause_e) == 0 ) { - yyerror("INDEXED file %s has no RECORD KEY", - file->name); + error_msg(@name, "INDEXED file %s has no RECORD KEY", + file->name); } break; case file_disorganized_e: @@ -1385,8 +1408,8 @@ select: SELECT optional NAME[name] select_clauses[clauses] '.' auto ikey = file->nkey - 1; assert(file->keys[ikey].fields); auto f = cbl_field_of(symbol_at(file->keys[ikey].fields[0])); - yyerror("%s file %s cannot have RECORD key %s", - file_org_str(file->org), file->name, f->name); + error_msg(@name, "%s file %s cannot have RECORD key %s", + file_org_str(file->org), file->name, f->name); } break; } @@ -1396,9 +1419,9 @@ select: SELECT optional NAME[name] select_clauses[clauses] '.' case file_access_rnd_e: case file_access_dyn_e: if( is_sequential(file) ) { - yyerror("%s file %s cannot have ACCESS %s", - file_org_str(file->org), file->name, - file_access_str(file->access)); + error_msg(@name, "%s file %s cannot have ACCESS %s", + file_org_str(file->org), file->name, + file_access_str(file->access)); } break; default: @@ -1435,7 +1458,7 @@ selected_name: external scalar { $$ = $2; } { const char *name = string_of($name); if( ! name ) { - yyerror("'%s' has embedded NUL", $name.data); + error_msg(@name, "'%s' has embedded NUL", $name.data); YYERROR; } uint32_t len = $name.len; @@ -1486,27 +1509,27 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } break; case assign_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } $$.file->filename = $part.file->filename; break; case collating_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } break; case lock_mode_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } $$.file->lock = $part.file->lock; break; case organization_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } $$.file->org = $part.file->org; @@ -1516,36 +1539,36 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } case sharing_clause_e: case record_delim_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } break; case access_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } $$.file->access = $part.file->access; break; case relative_key_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } if( $$.clauses & record_key_clause_e ) { - yyerror("FILE %s is INDEXED, has no RELATIVE key", + error_msg(@part, "FILE %s is INDEXED, has no RELATIVE key", $$.file->name); YYERROR; } // fall thru case record_key_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } if( ($$.clauses & relative_key_clause_e) && $part.clause == record_key_clause_e ) { - yyerror("FILE %s is RELATIVE, has no RECORD key", + error_msg(@part, "FILE %s is RELATIVE, has no RECORD key", $$.file->name); YYERROR; } @@ -1559,7 +1582,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } /* case password_clause_e: */ case file_status_clause_e: if( exists ) { - yyerror("clause is repeated"); + error_msg(@part, "clause is repeated"); YYERROR; } $$.file->user_status = $part.file->user_status; @@ -1569,7 +1592,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } if( $$.file->lock.locked() ) { if( $$.file->org == file_sequential_e && $$.file->lock.multiple ) { - yyerror("SEQUENTIAL file cannot lock MULTIPLE records"); + error_msg(@part, "SEQUENTIAL file cannot lock MULTIPLE records"); } } @@ -1807,8 +1830,8 @@ config_paragraph: { if( $name ) { if( !current.collating_sequence($name) ) { - yyerror( "collating sequence already defined as '%s'", - current.collating_sequence() ); + error_msg(@name, "collating sequence already defined as '%s'", + current.collating_sequence()); YYERROR; } } @@ -1863,8 +1886,8 @@ repo_func_name: NAME { if( ! current.repository_add($NAME) ) { // add intrinsic by name auto token = current.udf_in($NAME); if( !token ) { - yyerror("%s is not defined here as a user-defined function", - $NAME); + error_msg(@NAME, "%s is not defined here as a user-defined function", + $NAME); current.udf_dump(); YYERROR; } @@ -1881,14 +1904,14 @@ repo_program: PROGRAM_kw NAME repo_as auto program = symbol_label( PROGRAM, LblProgram, 0, $NAME ); if( ! program ) { if( $repo_as.empty() ) { - yyerror("'%s' does not name an earlier program", $NAME); + error_msg(@repo_as, "'%s' does not name an earlier program", $NAME); YYERROR; } program = symbol_label( PROGRAM, LblProgram, 0, "", $repo_as.data ); } if( ! program ) { - yyerror("'%s' does not name an earlier program", + error_msg(@repo_as, "'%s' does not name an earlier program", $repo_as.data); YYERROR; } @@ -1914,7 +1937,7 @@ repo_property: PROPERTY NAME repo_as with_debug: %empty | with DEBUGGING MODE { if( ! set_debug(true) ) { - yyerror("DEBUGGING MODE valid only in fixed format"); + error_msg(@2, "DEBUGGING MODE valid only in fixed format"); } } ; @@ -1970,7 +1993,7 @@ special_name: dev_mnemonic // character in the PICTURE string, and 'sign' is the substitution // that gets made in memory. if( ! string_of($lit) ) { - yyerror("'%s' has embedded NUL", $lit.data); + error_msg(@lit, "'%s' has embedded NUL", $lit.data); YYERROR; } symbol_currency_add( $picture_sym, $lit.data ); @@ -2046,7 +2069,7 @@ dev_mnemonic: device_name is NAME device, toupper); auto p = fujitsus.find(device); if( p == fujitsus.end() ) { - yyerror("%s is not a device name"); + error_msg(@device, "%s is not a device name"); } cbl_special_name_t special = { .id = p->second }; @@ -2097,8 +2120,8 @@ alphabet_name: STANDARD_ALPHABET { $$ = alphabet_add(ASCII_e); } } | error { - yyerror("code-name-1 may be STANDARD-1, STANDARD-2, " - "NATIVE, OR EBCDIC"); + error_msg(@1, "code-name-1 may be STANDARD-1, STANDARD-2, " + "NATIVE, OR EBCDIC"); $$ = NULL; } ; @@ -2113,7 +2136,7 @@ alphabet_seqs: alphabet_seq[seq] $$ = new cbl_alphabet_t(custom_encoding_e); if( !$seq.low || $seq.also ) { - yyerror( "syntax error at ALSO"); + error_msg(@1, "syntax error at ALSO"); YYERROR; } $$->add_sequence($seq.low); @@ -2170,7 +2193,7 @@ alphabet_seq: alphabet_lit[low] alphabet_etc: alphabet_lit { if( $1.len > 1 ) { - yyerror("'%c' can be only a single letter", $1.data); + error_msg(@1, "'%c' can be only a single letter", $1.data); YYERROR; } $$ = (unsigned char)$1.data[0]; @@ -2240,14 +2263,6 @@ upsi: UPSI is NAME off->data.upsi_mask = new cbl_upsi_mask_t(false, value); } } - /* | error */ - /* { */ - /* yyerror("Switch names are UPSI-0 through UPSI-7"); */ - /* if( max_errors_exceeded(nparse_error) ) { */ - /* yyerror("max errors %d reached", nparse_error); */ - /* YYABORT; */ - /* } */ - /* } */ ; upsi_entry: ON status is NAME { @@ -2274,7 +2289,7 @@ upsi_entry: ON status is NAME picture_sym: %empty { $$ = NULL; } | PICTURE SYMBOL LITERAL[lit] { if( ! string_of($lit) ) { - yyerror("'%s' has embedded NUL", $lit.data); + error_msg(@lit, "'%s' has embedded NUL", $lit.data); YYERROR; } $$ = string_of($lit); @@ -2437,7 +2452,7 @@ fd_clause: record_desc f->varying_size.explicitly = f->varies(); if( f->varying_size.max != 0 ) { if( !(f->varying_size.min <= f->varying_size.max) ) { - yyerror("%zu must be <= %zu", + error_msg(@1, "%zu must be <= %zu", f->varying_size.min, f->varying_size.max); YYERROR; } @@ -2455,11 +2470,10 @@ fd_clause: record_desc case 'S': break; default: - yyerror( "syntax error: invalid RECORDING MODE '%s'", - $NAME); + error_msg(@NAME, "invalid RECORDING MODE '%s'", $NAME); YYERROR; } - yywarn("RECORDING MODE was ignored, not defined by ISO 2023"); + cbl_unimplementedw("RECORDING MODE was ignored, not defined by ISO 2023"); } | VALUE OF fd_values | CODESET is NAME @@ -2491,7 +2505,7 @@ block_desc: BLOCK contains rec_contains chars_recs rec_contains: NUMSTR[min] { ssize_t n; if( (n = numstr2i($min.string, $min.radix)) < 0 ) { - yyerror("size %s cannot be negative", $min.string); + error_msg(@min, "size %s cannot be negative", $min.string); YYERROR; } $$.min = $$.max = n; // fixed length @@ -2499,18 +2513,18 @@ rec_contains: NUMSTR[min] { | NUMSTR[min] TO NUMSTR[max] { ssize_t n; if( (n = numstr2i($min.string, $min.radix)) < 0 ) { - yyerror("size %s cannot be negative", $min.string); + error_msg(@min, "size %s cannot be negative", $min.string); YYERROR; } $$.min = n; if( (n = numstr2i($max.string, $max.radix)) < 0 ) { - yyerror("size %s cannot be negative", $max.string); + error_msg(@max, "size %s cannot be negative", $max.string); YYERROR; } $$.max = n; if( !($$.min < $$.max) ) { - yyerror("FROM (%xz) must be less than TO (%zu)", + error_msg(@max, "FROM (%xz) must be less than TO (%zu)", $$.min, $$.max); YYERROR; } @@ -2565,12 +2579,12 @@ in_size: IN SIZE from_to: FROM NUMSTR[min] TO NUMSTR[max] characters { ssize_t n; if( (n = numstr2i($min.string, $min.radix)) < 0 ) { - yyerror("size %s cannot be negative", $min.string); + error_msg(@min, "size %s cannot be negative", $min.string); YYERROR; } $$.min = n; if( (n = numstr2i($max.string, $max.radix)) < 0 ) { - yyerror("size %s cannot be negative", $max.string); + error_msg(@min, "size %s cannot be negative", $max.string); YYERROR; } $$.max = n; @@ -2578,12 +2592,12 @@ from_to: FROM NUMSTR[min] TO NUMSTR[max] characters { | NUMSTR[min] TO NUMSTR[max] characters { ssize_t n; if( (n = numstr2i($min.string, $min.radix)) < 0 ) { - yyerror("size %s cannot be negative", $min.string); + error_msg(@min, "size %s cannot be negative", $min.string); YYERROR; } $$.min = n; if( (n = numstr2i($max.string, $max.radix)) < 0 ) { - yyerror("size %s cannot be negative", $max.string); + error_msg(@max, "size %s cannot be negative", $max.string); YYERROR; } $$.max = n; @@ -2592,7 +2606,7 @@ from_to: FROM NUMSTR[min] TO NUMSTR[max] characters { | TO NUMSTR[max] characters { ssize_t n; if( (n = numstr2i($max.string, $max.radix)) < 0 ) { - yyerror("size %s cannot be negative", $max.string); + error_msg(@max, "size %s cannot be negative", $max.string); YYERROR; } $$.min = 0; @@ -2602,7 +2616,7 @@ from_to: FROM NUMSTR[min] TO NUMSTR[max] characters { | FROM NUMSTR[min] characters { ssize_t n; if( (n = numstr2i($min.string, $min.radix)) < 0 ) { - yyerror("size %s cannot be negative", $min.string); + error_msg(@min, "size %s cannot be negative", $min.string); YYERROR; } $$.min = n; @@ -2611,7 +2625,7 @@ from_to: FROM NUMSTR[min] TO NUMSTR[max] characters { | NUMSTR[min] characters { ssize_t n; if( (n = numstr2i($min.string, $min.radix)) < 0 ) { - yyerror("size %s cannot be negative", $min.string); + error_msg(@min, "size %s cannot be negative", $min.string); YYERROR; } $$.min = n; @@ -2693,8 +2707,8 @@ field: cdf prior.type == FldInvalid && prior.level == field.level ) { - yyerror("%s %s requires PICTURE", - prior.level_str(), prior.name); + error_msg(@1, "%s %s requires PICTURE", + prior.level_str(), prior.name); dbgmsg(field_str($data_descr)); YYERROR; } @@ -2719,7 +2733,7 @@ field: cdf } initial = string_of(field.data.value); if( !initial ) { - yyerror(xstrerror(errno)); + error_msg(@1, xstrerror(errno)); YYERROR; } char decimal = symbol_decimal_point(); @@ -2729,11 +2743,11 @@ field: cdf if( yydebug ) { const char *value_str = string_of(field.data.value); dbgmsg("%s::data.initial is (%%%d.%d) %s ==> '%s'", - field.name, - field.data.digits, - rdigits, - value_str? value_str : "", - field.data.initial); + field.name, + field.data.digits, + rdigits, + value_str? value_str : "", + field.data.initial); } } } @@ -2747,7 +2761,7 @@ occurs_clause: OCCURS cardinal_lb indexed | OCCURS name indexed { if( ! (is_constant($name) && $name->type == FldLiteralN) ) { - yyerror("%s is not CONSTANT", $name->name); + error_msg(@name, "%s is not CONSTANT", $name->name); YYERROR; } cbl_occurs_t *occurs = ¤t_field()->occurs; @@ -2826,7 +2840,7 @@ index_field1: ctx_name[name] auto symbol = symbol_field(PROGRAM, 0, $name); if( symbol ) { auto field( cbl_field_of(symbol) ); - yyerror( "'%s' already defined on line %d", + error_msg(@name, "'%s' already defined on line %d", field->name, field->line ); YYERROR; } @@ -2849,7 +2863,7 @@ level_name: LEVEL ctx_name case 88: break; default: - yyerror("LEVEL %d not supported", $LEVEL); + error_msg(@LEVEL, "LEVEL %d not supported", $LEVEL); YYERROR; } struct cbl_field_t field = { 0, @@ -2874,7 +2888,7 @@ level_name: LEVEL ctx_name case 88: break; default: - yyerror("LEVEL %d not supported", $LEVEL); + error_msg(@LEVEL, "LEVEL %d not supported", $LEVEL); YYERROR; } struct cbl_field_t field = { 0, @@ -2941,7 +2955,7 @@ data_descr1: level_name { cbl_field_t& field = *$1; if( field.level != 1 ) { - yyerror("%s must be an 01-level data item", field.name); + error_msg(@1, "%s must be an 01-level data item", field.name); YYERROR; } @@ -2952,7 +2966,7 @@ data_descr1: level_name field.data.initial = string_of($const_value); if( !cdf_value(field.name, static_cast<int64_t>($const_value)) ) { - yywarn("%s was defined by CDF", field.name); + error_msg(@1, "%s was defined by CDF", field.name); } } | level_name CONSTANT is_global as literalism[lit] @@ -2965,7 +2979,7 @@ data_descr1: level_name field.data.initial = $lit.data; field.attr |= literal_attr($lit.prefix); if( field.level != 1 ) { - yyerror("%s must be an 01-level data item", field.name); + error_msg(@1, "%s must be an 01-level data item", field.name); YYERROR; } if( !cdf_value(field.name, $lit.data) ) { @@ -2978,7 +2992,7 @@ data_descr1: level_name assert($1 == current_field()); const cdfval_t *cdfval = cdf_value($NAME); if( !cdfval ) { - yyerror("%s is not was defined by CDF", $NAME); + error_msg(@1, "%s was defined by CDF", $NAME); YYERROR; } cbl_field_t& field = *$1; @@ -2988,7 +3002,7 @@ data_descr1: level_name field.data.initial = cdfval->string; field.data.value = cdfval->number; if( !cdf_value(field.name, *cdfval) ) { - yywarn("%s was defined by CDF", field.name); + error_msg(@1, "%s was defined by CDF", field.name); } } @@ -3016,7 +3030,7 @@ data_descr1: level_name } } if( ($$ = field_add(&field)) == NULL ) { - yyerror("failed level 78"); + error_msg(@name, "failed level 78"); YYERROR; } } @@ -3037,12 +3051,12 @@ data_descr1: level_name field.data.domain = domain; if( ($$ = field_add(&field)) == NULL ) { - yyerror("failed level 88"); + error_msg(@NAME, "failed level 88"); YYERROR; } auto parent = cbl_field_of(symbol_at($$->parent)); if( parent->type != FldPointer ) { - yyerror("LEVEL 88 %s VALUE NULLS invalid for " + error_msg(@NAME, "LEVEL 88 %s VALUE NULLS invalid for " "%s %s, which is not a POINTER", $$->name, parent->level_str(), parent->name); } @@ -3065,7 +3079,7 @@ data_descr1: level_name domains.clear(); if( ($$ = field_add(&field)) == NULL ) { - yyerror("failed level 88"); + error_msg(@NAME, "failed level 88"); YYERROR; } } @@ -3074,27 +3088,27 @@ data_descr1: level_name { symbol_field_alias_end(); if( is_literal($orig) ) { - yyerror("cannot RENAME '%s'", name_of($orig)); + error_msg(@orig, "cannot RENAME '%s'", name_of($orig)); YYERROR; } if( !immediately_follows($orig) ) { - yyerror("%s must immediately follow %s to RENAME it", + error_msg(@orig, "%s must immediately follow %s to RENAME it", $alias, name_of($orig)); YYERROR; } if( $orig->occurs.ntimes() ) { - yyerror("cannot RENAME table %02u %s", + error_msg(@orig, "cannot RENAME table %02u %s", $orig->level, name_of($orig)); YYERROR; } auto table = occurs_in($orig); if( table ) { - yyerror("cannot RENAME '%s' OF %s", + error_msg(@orig, "cannot RENAME '%s' OF %s", name_of($orig), table->name); YYERROR; } if( ! $orig->rename_level_ok() ) { - yyerror("cannot RENAME %02u %s", + error_msg(@orig, "cannot RENAME %02u %s", $orig->level, name_of($orig)); YYERROR; } @@ -3106,37 +3120,37 @@ data_descr1: level_name { symbol_field_alias_end(); if( !immediately_follows($orig) ) { - yyerror("RENAMES: %s must immediately follow %s", + error_msg(@orig, "RENAMES: %s must immediately follow %s", $alias, name_of($orig)); YYERROR; } if( is_literal($orig) ) { - yyerror("cannot RENAME '%s'", name_of($orig)); + error_msg(@orig, "cannot RENAME '%s'", name_of($orig)); YYERROR; } if( is_literal($thru) ) { - yyerror("cannot RENAME '%s'", name_of($thru)); + error_msg(@thru, "cannot RENAME '%s'", name_of($thru)); YYERROR; } auto table = occurs_in($orig); if( table ) { - yyerror("cannot RENAME '%s' OF %s", + error_msg(@orig, "cannot RENAME '%s' OF %s", name_of($orig), table->name); YYERROR; } table = occurs_in($thru); if( table ) { - yyerror("cannot RENAME '%s' OF %s", + error_msg(@thru, "cannot RENAME '%s' OF %s", name_of($thru), table->name); YYERROR; } if( ! $orig->rename_level_ok() ) { - yyerror("cannot RENAME %02u %s", + error_msg(@orig, "cannot RENAME %02u %s", $orig->level, name_of($orig)); YYERROR; } if( $orig->has_subordinate($thru) ) { - yyerror("cannot RENAME %02u %s THRU %02u %s " + error_msg(@orig, "cannot RENAME %02u %s THRU %02u %s " "because %s is subordinate to %s", $orig->level, name_of($orig), $thru->level, name_of($thru), @@ -3145,7 +3159,7 @@ data_descr1: level_name } auto not_ok = rename_not_ok($orig, $thru); if( not_ok ) { - yyerror("cannot RENAME %02u %s THRU %02u %s " + error_msg(@orig, "cannot RENAME %02u %s THRU %02u %s " "because %02u %s cannot be renamed", $orig->level, name_of($orig), $thru->level, name_of($thru), @@ -3153,7 +3167,7 @@ data_descr1: level_name YYERROR; } if( field_index($thru) <= field_index($orig) ) { - yyerror("cannot RENAME %02u %s THRU %02u %s " + error_msg(@orig, "cannot RENAME %02u %s THRU %02u %s " "because they're in the wrong order", $orig->level, name_of($orig), $thru->level, name_of($thru)); @@ -3176,7 +3190,7 @@ data_descr1: level_name ! $field->has_attr(quoted_e) && normal_value_e == cbl_figconst_of($field->data.initial) ) { - yyerror("%s numeric VALUE %s requires PICTURE", + error_msg(@field, "%s numeric VALUE %s requires PICTURE", $field->name, $field->data.initial); } if( null_value_e == cbl_figconst_of($field->data.initial) ) { @@ -3197,12 +3211,12 @@ data_descr1: level_name switch($field->type) { case FldNumericEdited: if( $field->has_attr(signable_e) ) { - yyerror( "%s has 'S' in PICTURE, cannot be BLANK WHEN ZERO", + error_msg(@2, "%s has 'S' in PICTURE, cannot be BLANK WHEN ZERO", $field->name, cbl_field_type_str($field->type) ); } break; default: - yyerror( "%s must be " + error_msg(@2, "%s must be " "NUMERIC DISPLAY or NUMERIC-EDITED, not %s", $field->name, cbl_field_type_str($field->type) ); } @@ -3221,7 +3235,7 @@ data_descr1: level_name if( $field->attr & sign_attrs ) { dbgmsg("%s:%d: %s", __func__, __LINE__, field_str($field)); - yyerror("%s must be signed for SIGN IS", + error_msg(@field, "%s must be signed for SIGN IS", $field->name ); YYERROR; } @@ -3263,7 +3277,7 @@ data_descr1: level_name switch( $field->data.initial[0] ) { case '-': if( !$field->has_attr(signable_e) ) { - yyerror("%s is unsigned but has signed VALUE '%s'", + error_msg(@field, "%s is unsigned but has signed VALUE '%s'", $field->name, $field->data.initial); } } @@ -3304,7 +3318,7 @@ name66: LEVEL66 NAME[alias] { build_symbol_map(); if( ! symbol_field_alias_begin() ) { - yyerror("no Level 01 record exists " + error_msg(@alias, "no Level 01 record exists " "for %s to redefine", $alias); } $$ = $alias; @@ -3316,12 +3330,12 @@ data_clauses: data_clause if( $data_clause == redefines_clause_e ) { auto parent = parent_of(current_field()); if( !parent ) { - yyerror("%s invalid REDEFINES", + error_msg(@1, "%s invalid REDEFINES", current_field()->name); YYERROR; } if( parent->occurs.ntimes() > 0 ) { - yyerror("%s cannot REDEFINE table %s", + error_msg(@1, "%s cannot REDEFINE table %s", current_field()->name, parent->name); YYERROR; @@ -3349,19 +3363,19 @@ data_clauses: data_clause case typedef_clause_e: clause = "TYPEDEF"; break; } if( ($$ & $2) == $2 ) { - yyerror("%s clause repeated", clause); + error_msg(@2, "%s clause repeated", clause); YYERROR; } if( $data_clause == redefines_clause_e ) { - yyerror("REDEFINES must appear " + error_msg(@2, "REDEFINES must appear " "immediately after LEVEL and NAME"); YYERROR; } cbl_field_t *field = current_field(); const int globex = (global_e | external_e); if( (($$ | $2) & globex) == globex ) { - yyerror("GLOBAL and EXTERNAL specified"); + error_msg(@2, "GLOBAL and EXTERNAL specified"); YYERROR; } @@ -3376,18 +3390,18 @@ data_clauses: data_clause if( type_clause_e < ($$ & (type_clause_e | type_implies)) ) { if( $2 == type_clause_e ) { - yyerror("TYPE TO incompatible with ALIGNED, " + error_msg(@2, "TYPE TO incompatible with ALIGNED, " "BLANK WHEN ZERO, JUSTIFIED, PICTURE, SIGN, " "SYNCHRONIZED, and USAGE"); } else { - yyerror("%s incompatible with TYPE TO", clause); + error_msg(@2, "%s incompatible with TYPE TO", clause); } YYERROR; } if( ($$ & same_clause_e) == same_clause_e ) { if( 0 < ($$ & ~same_clause_e) ) { - yyerror("%s %s SAME AS " + error_msg(@2, "%s %s SAME AS " "precludes other DATA DIVISION clauses", field->level_str(), field->name); YYERROR; @@ -3396,7 +3410,7 @@ data_clauses: data_clause if( is_numeric(field->type) && field->type != FldNumericDisplay ) { if( $$ & sign_clause_e ) { - yyerror("%s is binary NUMERIC type, " + error_msg(@2, "%s is binary NUMERIC type, " "incompatible with SIGN IS", field->name); } } @@ -3419,7 +3433,7 @@ data_clauses: data_clause switch( field->type ) { case FldFloat: if( ($$ & picture_clause_e) == picture_clause_e ) { - yyerror("%s: FLOAT types do not allow PICTURE", + error_msg(@2, "%s: FLOAT types do not allow PICTURE", field->name); } break; @@ -3428,7 +3442,7 @@ data_clauses: data_clause } if( ! field->is_justifiable() ) { - yyerror("%s: %s is incompatible with JUSTIFIED", + error_msg(@2, "%s: %s is incompatible with JUSTIFIED", field->name, 3 + cbl_field_type_str(field->type)); } } @@ -3481,8 +3495,8 @@ data_clause: any_length { $$ = any_length_e; } } const cbl_field_t *parent; if( (parent = parent_has_value(field)) != NULL ) { - yyerror("VALUE invalid because group %s has VALUE clause", - parent->name); + error_msg(@1, "VALUE invalid because group %s has VALUE clause", + parent->name); } } | volatile_clause { $$ = volatile_clause_e; } @@ -3499,13 +3513,13 @@ picture_clause: PIC signed nps[fore] nines nps[aft] field->data.capacity = type_capacity(field->type, $4); field->data.digits = $4; if( long(field->data.digits) != $4 ) { - yyerror("indicated size would be %ld bytes, " + error_msg(@2, "indicated size would be %ld bytes, " "maximum data item size is %u", $4, UINT32_MAX); } if( $fore && $aft ) { // leading and trailing P's - yyerror("PIC cannot have both leading and trailing P"); + error_msg(@2, "PIC cannot have both leading and trailing P"); YYERROR; } if( $fore || $aft ) { @@ -3513,7 +3527,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] field->data.rdigits = $fore? $fore : -$aft; } if( ! field->reasonable_capacity() ) { - yyerror("%s limited to capacity of %d (would need %u)", + error_msg(@2, "%s limited to capacity of %d (would need %u)", field->name, MAX_FIXED_POINT_DIGITS, field->data.capacity); } } @@ -3536,7 +3550,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] field->data.rdigits = $rdigits; } if( ! field->reasonable_capacity() ) { - yyerror("%s limited to capacity of %d (would need %u)", + error_msg(@2, "%s limited to capacity of %d (would need %u)", field->name, MAX_FIXED_POINT_DIGITS, field->data.capacity); } } @@ -3555,7 +3569,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] field->data.rdigits = $rdigits; if( ! field->reasonable_capacity() ) { - yyerror("%s limited to capacity of %d (would need %u)", + error_msg(@2, "%s limited to capacity of %d (would need %u)", field->name, MAX_FIXED_POINT_DIGITS, field->data.capacity); } } @@ -3569,7 +3583,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] dialect_mf() ) { // PIC X COMP-X or COMP-9 if( ! field->has_attr(all_x_e) ) { - yyerror("COMP PICTURE requires all X's or all 9's"); + error_msg(@2, "COMP PICTURE requires all X's or all 9's"); YYERROR; } } else { @@ -3603,7 +3617,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] } ERROR_IF_CAPACITY(field); if( !is_numeric_edited($picture) ) { - yyerror(numed_message); + error_msg(@picture, numed_message); YYERROR; } field->data.picture = $picture; @@ -3637,7 +3651,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] break; case FldAlphaEdited: if( !is_alpha_edited(field->data.picture) ) { - yyerror("invalid picture for Alphanumeric-edited"); + error_msg(@picture, "invalid picture for Alphanumeric-edited"); YYERROR; } break; @@ -3654,19 +3668,16 @@ alphanum_pic: alphanum_part { | alphanum_pic alphanum_part { auto field = current_field(); - if( yydebug ) - yywarn("%s has %s against %s", - field->name, field_attr_str(field), - cbl_field_attr_str($2.attr)); + dbgmsg("%s has %s against %s", + field->name, field_attr_str(field), + cbl_field_attr_str($2.attr)); if( ! field->has_attr($2.attr) ) { field->clear_attr(all_ax_e); // clears 2 bits } $$ += $2.nbyte; - if( yydebug ) - yywarn("%s attrs: %s", - field->name, field_attr_str(field)); + dbgmsg("%s attrs: %s", field->name, field_attr_str(field)); } ; alphanum_part: ALNUM[picture] count @@ -3679,7 +3690,7 @@ alphanum_part: ALNUM[picture] count $$.nbyte += count; // AX9(3) has count 5 } if( count < 0 ) { - yyerror("PICTURE count '(%d)' is negative", count ); + error_msg(@2, "PICTURE count '(%d)' is negative", count ); YYERROR; } } @@ -3698,7 +3709,7 @@ nine: %empty { $$ = 0; } { $$ = $1; if( $$ == 0 ) { - yyerror("'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); + error_msg(@1, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); } } ; @@ -3711,28 +3722,30 @@ count: %empty { $$ = 0; } { $$ = numstr2i( $NUMSTR.string, $NUMSTR.radix ); if( $$ == 0 ) { - yyerror("'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); + error_msg(@2, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); } } | '(' NAME ')' { auto value = cdf_value($NAME); if( ! (value && value->is_numeric()) ) { - yyerror("PICTURE '(%s)' requires a CONSTANT value", $NAME ); + error_msg(@NAME, "PICTURE '(%s)' requires a CONSTANT value", $NAME ); YYERROR; } + int nmsg = 0; auto e = symbol_field(PROGRAM, 0, $NAME); if( e ) { // verify not floating point with nonzero fraction auto field = cbl_field_of(e); assert(is_literal(field)); if( field->data.value != size_t(field->data.value) ) { - yyerror("invalid PICTURE count '(%s)'", - field->data.initial ); + nmsg++; + error_msg(@NAME, "invalid PICTURE count '(%s)'", + field->data.initial ); } } $$ = value->as_number(); - if( $$ <= 0 ) { - yyerror("invalid PICTURE count '(%s)'", $NAME ); + if( $$ <= 0 && !nmsg) { + error_msg(@NAME, "invalid PICTURE count '(%s)'", $NAME ); } } ; @@ -3775,7 +3788,7 @@ usage_clause1: usage COMPUTATIONAL[comp] native field->type = $comp.type; field->clear_attr(signable_e); } else { - yyerror("numeric USAGE invalid " + error_msg(@comp, "numeric USAGE invalid " "with Alpnanumeric PICTURE"); YYERROR; } @@ -3816,7 +3829,7 @@ usage_clause1: usage COMPUTATIONAL[comp] native if( infer ) { if( $comp.capacity > 0 ) { if( field->data.capacity > 0 ) { - yyerror("%s is BINARY type, incompatible with PICTURE", + error_msg(@comp, "%s is BINARY type, incompatible with PICTURE", field->name); YYERROR; } @@ -3836,7 +3849,7 @@ usage_clause1: usage COMPUTATIONAL[comp] native cbl_field_t *field = current_field(); if( field->data.capacity > 0 && field->type != FldNumericDisplay) { - yyerror("%s PICTURE is incompatible with USAGE PACKED DECIMAL", + error_msg(@2, "%s PICTURE is incompatible with USAGE PACKED DECIMAL", field->name); YYERROR; } @@ -3877,7 +3890,7 @@ usage_clause1: usage COMPUTATIONAL[comp] native if( redefined->data.initial ) { char *s = new char[1 + redefined->data.capacity]; if( !s ) { - yyerror("could not expand initial value of %s", field->name); + error_msg(@2, "could not expand initial value of %s", field->name); YYERROR; } (void)! snprintf(s, 1 + redefined->data.capacity, @@ -3906,10 +3919,7 @@ value_clause: VALUE all LITERAL[lit] { field->data.capacity = $lit.len; } else { if( $all ) { - if( ! field_value_all(field) ) { - yyerror("could not allocate field %s", field->name); - YYERROR; - } + field_value_all(field); } else { if( $lit.len < field->data.capacity ) { auto p = blank_pad_initial( $lit.data, $lit.len, @@ -3932,10 +3942,7 @@ value_clause: VALUE all LITERAL[lit] { pristine_values.insert(initial); } else { initial = string_of($value); - if( !initial ) { - yyerror("could not allocate field %s", field->name); - YYERROR; - } + gcc_assert(initial); } char decimal = symbol_decimal_point(); @@ -3944,10 +3951,7 @@ value_clause: VALUE all LITERAL[lit] { field->data.initial = initial; field->data.value = $value; - if( $all && ! field_value_all(field) ) { - yyerror("could not allocate ALL field %s", field->name); - YYERROR; - } + if( $all ) field_value_all(field); } | VALUE all reserved_value[value] { @@ -3963,7 +3967,7 @@ value_clause: VALUE all LITERAL[lit] { } | VALUE error { - yyerror("no valid VALUE supplied"); + error_msg(@2, "no valid VALUE supplied"); } ; @@ -3991,23 +3995,23 @@ redefines_clause: REDEFINES NAME[orig] { struct symbol_elem_t *e = field_of($orig); if( !e ) { - yyerror("REDEFINES target not defined"); + error_msg(@2, "REDEFINES target not defined"); YYERROR; } cbl_field_t *field = current_field(); cbl_field_t *orig = cbl_field_of(e); if( orig->has_attr(filler_e) ) { - yyerror("%s may not REDEFINE %s", + error_msg(@2, "%s may not REDEFINE %s", field->name, orig->name); } cbl_field_t *super = symbol_redefines(orig); if( super ) { - yyerror("%s may not REDEFINE %s, " + error_msg(@2, "%s may not REDEFINE %s, " "which redefines %s", field->name, orig->name, super->name); } if( field->level != orig->level ) { - yyerror("cannot redefine %s %s as %s %s " + error_msg(@2, "cannot redefine %s %s as %s %s " "because they have different levels", orig->level_str(), name_of(orig), field->level_str(), name_of(field)); @@ -4027,7 +4031,7 @@ redefines_clause: REDEFINES NAME[orig] } ); if( p != symbol_elem_of(field) ) { auto mid( cbl_field_of(p) ); - yyerror("cannot redefine %s %s as %s %s " + error_msg(@2, "cannot redefine %s %s as %s %s " "because %s %s intervenes", orig->level_str(), name_of(orig), field->level_str(), name_of(field), @@ -4047,13 +4051,13 @@ redefines_clause: REDEFINES NAME[orig] any_length: ANY LENGTH { cbl_field_t *field = current_field(); if( field->attr & any_length_e ) { - yyerror("ANY LENGTH already set"); + error_msg(@1, "ANY LENGTH already set"); } if( ! (field->level == 1 && current_data_section == linkage_datasect_e && (1 < current.program_level() || current.program()->is_function())) ) { - yyerror("ANY LENGTH valid only for 01 " + error_msg(@1, "ANY LENGTH valid only for 01 " "in LINKAGE SECTION of a function or contained program"); YYERROR; } @@ -4064,7 +4068,7 @@ any_length: ANY LENGTH based_clause: BASED { cbl_field_t *field = current_field(); if( field->attr & based_e ) { - yyerror("BASED already set"); + error_msg(@1, "BASED already set"); } field->attr |= based_e; } @@ -4093,34 +4097,34 @@ same_clause: SAME AS name { cbl_field_t *field = current_field(), *other = $name; if( other->occurs.ntimes() > 0 ) { - yyerror("SAME AS %s: cannot have OCCURS", + error_msg(@name, "SAME AS %s: cannot have OCCURS", other->name); // 13.18.49.2,P5 YYERROR; } if( field->level == 77 and !is_elementary(other->type) ) { // ISO 2023 13.18.49.2,P8 - yyerror("%s %s SAME AS %s: must be elementary", + error_msg(@name, "%s %s SAME AS %s: must be elementary", field->level_str(), field->name, other->name); YYERROR; } if( (other->attr & (sign_clause_e | usage_clause_e)) > 0 ) { - yyerror("%s: source of SAME AS cannot have " + error_msg(@name, "%s: source of SAME AS cannot have " "SIGN or USAGE clause", other->name); YYERROR; } if( other->usage == FldGroup ) { - yyerror("%s: source of SAME AS cannot have " + error_msg(@name, "%s: source of SAME AS cannot have " "GROUP-USAGE clause", other->name); YYERROR; } if( other->has_attr(constant_e ) ) { - yyerror("%s: source of SAME AS cannot " + error_msg(@name, "%s: source of SAME AS cannot " "be constant", other->name); YYERROR; } if( field->parent == field_index(other) ) { - yyerror("%s: SAME AS uses " + error_msg(@name, "%s: SAME AS uses " "its own parent %s", field->name, other->name); YYERROR; } @@ -4195,7 +4199,7 @@ typedef_clause: is TYPEDEF strong switch( field->level ) { case 1: case 77: break; default: - yyerror("%s %s IS TYPEDEF must be level 01", + error_msg(@2, "%s %s IS TYPEDEF must be level 01", field->level_str(), field->name); } field->attr |= typedef_e; @@ -4203,7 +4207,7 @@ typedef_clause: is TYPEDEF strong if( ! current.typedef_add(field) ) { auto prior = current.has_typedef(field); assert(prior); - yyerror("%s %s IS TYPEDEF is not unique " + error_msg(@2, "%s %s IS TYPEDEF is not unique " "(see %s, line %d)", field->level_str(), field->name, prior->name, prior->line); @@ -4240,14 +4244,16 @@ procedure_args: USING procedure_uses[args] { if( !procedure_division_ready($ret, $args) ) YYABORT; if( ! $ret->has_attr(linkage_e) ) { - yyerror("RETURNING %s is not defined in LINKAGE SECTION", $ret->name); + error_msg(@ret, "RETURNING %s is not defined in LINKAGE SECTION", + $ret->name); } } | RETURNING name[ret] { if( !procedure_division_ready($ret, NULL) ) YYABORT; if( ! $ret->has_attr(linkage_e) ) { - yyerror("RETURNING %s is not defined in LINKAGE SECTION", $ret->name); + error_msg(@ret, "RETURNING %s is not defined in LINKAGE SECTION", + $ret->name); } } ; @@ -4367,7 +4373,7 @@ sentence: statements '.' assert(prog); const char *name = string_of($name); if( !name || 0 != strcasecmp(prog->name, name) ) { - yyerror( "END PROGRAM '%s' does not match PROGRAM-ID '%s'", + error_msg(@name, "END PROGRAM '%s' does not match PROGRAM-ID '%s'", name? name : $name.data, prog->name); YYERROR; } @@ -4399,11 +4405,11 @@ statements: statement { $$ = $1; } statement: error { if( current.declarative_section_name() ) { - yyerror("missing END DECLARATIVES or SECTION name", nparse_error); + error_msg(@1, "missing END DECLARATIVES or SECTION name", nparse_error); YYABORT; } if( max_errors_exceeded(nparse_error) ) { - yyerror("max errors %d reached", nparse_error); + error_msg(@1, "max errors %d reached", nparse_error); YYABORT; } } @@ -4488,7 +4494,7 @@ accept: accept_body end_accept { cbl_field_t *argi = register_find("_ARGI"); switch( $accept_body.func ) { case accept_done_e: - yyerror("ON EXCEPTION valid only " + error_msg(@ec, "ON EXCEPTION valid only " "with ENVIRONMENT or COMAMND-LINE(n)"); break; case accept_command_line_e: @@ -4500,7 +4506,7 @@ accept: accept_body end_accept { } else if( $1.from->field == argi ) { parser_move(*$1.into, *$1.from); if( $ec.on_error || $ec.not_error ) { - yyerror("ON EXCEPTION valid only " + error_msg(@ec, "ON EXCEPTION valid only " "with ENVIRONMENT or COMAMND-LINE(n)"); } } else { @@ -4528,7 +4534,7 @@ accept_body: accept_refer { $$.func = accept_done_e; if( $1->is_reference() ) { - yyerror("subscripts are unsupported here"); + error_msg(@1, "subscripts are unsupported here"); YYERROR; } parser_accept_date_yymmdd($1->field); @@ -4537,7 +4543,7 @@ accept_body: accept_refer { $$.func = accept_done_e; if( $1->is_reference() ) { - yyerror("subscripts are unsupported here"); + error_msg(@1, "subscripts are unsupported here"); YYERROR; } parser_accept_date_yyyymmdd($1->field); @@ -4546,7 +4552,7 @@ accept_body: accept_refer { $$.func = accept_done_e; if( $1->is_reference() ) { - yyerror("subscripts are unsupported here"); + error_msg(@1, "subscripts are unsupported here"); YYERROR; } parser_accept_date_yyddd($1->field); @@ -4555,7 +4561,7 @@ accept_body: accept_refer { $$.func = accept_done_e; if( $1->is_reference() ) { - yyerror("subscripts are unsupported here"); + error_msg(@1, "subscripts are unsupported here"); YYERROR; } parser_accept_date_yyyyddd($1->field); @@ -4564,7 +4570,7 @@ accept_body: accept_refer { $$.func = accept_done_e; if( $1->is_reference() ) { - yyerror("subscripts are unsupported here"); + error_msg(@1, "subscripts are unsupported here"); YYERROR; } parser_accept_date_dow($1->field); @@ -4574,7 +4580,7 @@ accept_body: accept_refer { $$.func = accept_done_e; if( $1->is_reference() ) { - yyerror("subscripts are unsupported here"); + error_msg(@1, "subscripts are unsupported here"); YYERROR; } parser_accept_date_hhmmssff($1->field); @@ -4629,16 +4635,16 @@ accept_refer: ACCEPT scalar { statement_begin(@1, ACCEPT); $$ = $2; } accept_excepts: accept_excepts[a] accept_except[b] statements %prec ACCEPT { if( $a.on_error && $a.not_error ) { - yyerror("too many ON EXCEPTION clauses"); + error_msg(@b, "too many ON EXCEPTION clauses"); YYERROR; } // "ON" and "NOT ON" could be reversed, but not duplicated. if( $a.on_error && $b.on_error ) { - yyerror("duplicate ON EXCEPTION clauses"); + error_msg(@b, "duplicate ON EXCEPTION clauses"); YYERROR; } if( $a.not_error && $b.not_error ) { - yyerror("duplicate NOT ON EXCEPTION clauses"); + error_msg(@b, "duplicate NOT ON EXCEPTION clauses"); YYERROR; } $$ = $a; @@ -5948,7 +5954,7 @@ typename: NAME { auto e = symbol_typedef(PROGRAM, $NAME); if( ! e ) { - error_msg(@1, "symbol '%s' not found", $NAME ); + error_msg(@1, "DATA-ITEM '%s' not found", $NAME ); YYERROR; } $$ = cbl_field_of(e); @@ -5962,7 +5968,7 @@ name: qname if( ($$ = field_find(names)) == NULL ) { if( procedure_div_e == current_division ) { - error_msg(@1, "symbol '%s' not found", names.back() ); + error_msg(@1, "DATA-ITEM '%s' not found", names.back() ); YYERROR; } /* @@ -8636,7 +8642,7 @@ nume: qnume { for( ; !names.empty(); names.pop_front() ) { if( (e = symbol_field(PROGRAM, index, names.front())) == NULL ) { - yyerror("symbol '%s' not found", names.front() ); + error_msg(@1, "DATA-ITEM '%s' not found", names.front() ); YYERROR; } $$ = cbl_field_of(e); diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index 65fe4fc2675c..0f55fdcec326 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -2747,7 +2747,7 @@ valid_redefine( const cbl_field_t *field, const cbl_field_t *orig ) { return true; } -static struct cbl_field_t * +static void field_value_all(struct cbl_field_t * field ) { // Expand initial by repeating its contents until it is of length capacity: assert(field->data.initial != NULL); @@ -2761,7 +2761,6 @@ field_value_all(struct cbl_field_t * field ) { new_initial[field->data.capacity] = '\0'; free(const_cast<char *>(field->data.initial)); field->data.initial = new_initial; - return field; } static cbl_field_t * diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index 6b3103eddd9b..c936894bc153 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -252,7 +252,7 @@ PROGRAM-ID/{DOTEOL} { yy_push_state(ident_state); PROCEDURE{SPC}DIVISION { yy_push_state(procedure_div); return PROCEDURE_DIV; } <comment_entries>{ - (ENVIRONMENT|DATA|PROCEDURE){SPC}DIVISION { yyless(0); yy_pop_state(); } + (ENVIRONMENT|DATA|PROCEDURE){SPC}DIVISION { myless(0); yy_pop_state(); } {BLANK_EOL} [^[:space:]]{1,512}{BLANK_OEOL} // about 1/2 KB at a time } @@ -262,9 +262,9 @@ PROCEDURE{SPC}DIVISION { yy_push_state(procedure_div); AS{SPC}[''] { yy_push_state(quoted1); return AS; } IS { pop_return IS; } - OPTIONS { yy_pop_state(); yyless(0); } + OPTIONS { yy_pop_state(); myless(0); } [[:blank:]]*(ENVIRONMENT|DATA|PROCEDURE)[[:blank:]]+DIVISION/.+\n { - yy_pop_state(); yyless(0); } + yy_pop_state(); myless(0); } [[:blank:]]*AUTHOR[[:blank:].]+{EOL}? { // Might not have an EOL, but stop on one. yy_push_state(author_state); } @@ -291,7 +291,7 @@ PROCEDURE{SPC}DIVISION { yy_push_state(procedure_div); ^[[:blank:]]*0?1/[[:space:]] { /* If in File Section parse record */ yy_push_state(field_state); yy_set_bol(1); - yyless(0); } + myless(0); } } <INITIAL,procedure_div,cdf_state>{ @@ -427,7 +427,7 @@ CONTINUE { return CONTINUE; } COPY { yy_push_state(copy_state); - yyless(0); + myless(0); } EXTEND { return EXTEND;} @@ -571,7 +571,7 @@ RELATIVE{SPC}(KEY{SPC})?(IS{SPC})?{NAME} { assert(ISALNUM(name[0])); assert(ISSPACE(name[-1])); int token = keyword_tok(name)? RELATIVE : KEY; - yyless( name - yytext ); + myless( name - yytext ); return token; } RELATIVE { return RELATIVE; } @@ -937,7 +937,7 @@ USE({SPC}FOR)? { return USE; } assert(len); if( s[--len] == '.' ) { s[len] = '\0'; - yyless(len); + myless(len); } numstr_of(s); free(s); return NUMSTR; @@ -1049,7 +1049,7 @@ USE({SPC}FOR)? { return USE; } dialect_error("EJECT is not ISO syntax,", "ibm"); } auto len = yyleng - 1; - if( yytext[len] == '\f' ) yyless(--len); + if( yytext[len] == '\f' ) myless(--len); } EXTERNAL { return EXTERNAL; } FALSE { return FALSE_kw; } @@ -1098,7 +1098,7 @@ USE({SPC}FOR)? { return USE; } COPY { yy_push_state(copy_state); - yyless(0); + myless(0); } FD/[[:blank:]]+ { parsing.need_level(false); return FD; } @@ -1344,7 +1344,7 @@ USE({SPC}FOR)? { return USE; } return FEATURE; } [[:blank:]]+ {BLANK_EOL} - . { yyless(0); yy_pop_state(); } // not a CDF token + . { myless(0); yy_pop_state(); } // not a CDF token } <program_id_state>{ @@ -1361,7 +1361,7 @@ USE({SPC}FOR)? { return USE; } COMMON { pop_return COMMON; } PROGRAM { pop_return PROGRAM; } - AS/{SPC} { yyless(0); yy_pop_state(); } /* => ident_state */ + AS/{SPC} { myless(0); yy_pop_state(); } /* => ident_state */ [[:blank:]]*{DOTSEP}[[:blank:].]+{EOL} { pop_return '.'; } {DOTEOL} { pop_return '.'; } } @@ -1382,8 +1382,8 @@ USE({SPC}FOR)? { return USE; } [.]/[[:blank:]]+. { return *yytext; } [[:blank:]]*{DOTSEP}[[:blank:].]+{EOL} { - yy_pop_state(); yyless(0); } - {DOTEOL} { yy_pop_state(); yyless(0); } + yy_pop_state(); myless(0); } + {DOTEOL} { yy_pop_state(); myless(0); } } <dot_state>{ [[:blank:]]*[.][[:blank:].]+{EOL} { pop_return '.'; } @@ -1431,7 +1431,7 @@ USE({SPC}FOR)? { return USE; } [+-]?({dfc}|{dseq})([.,][[:digit:]])* { auto eotext = yytext + yyleng - 1; if( *eotext == '.' ) { - yyless(yyleng - 1); + myless(yyleng - 1); *eotext = '\0'; } return numstr_of(yytext); } @@ -1455,7 +1455,7 @@ USE({SPC}FOR)? { return USE; } char *p = strchr(s, '.'); if( p && strlen(p) == 1 ) { *p = '\0'; - yyless(p - s); + myless(p - s); } numstr_of(s); free(s); pop_return NUMSTR; @@ -1494,7 +1494,7 @@ USE({SPC}FOR)? { return USE; } <procedure_div>{ (ID|IDENTIFICATION|ENVIRONMENT|DATA|PROCEDURE){SPC}DIVISION { - yyless(0); yy_pop_state(); } + myless(0); yy_pop_state(); } EXIT{SPC}/(PROGRAM|SECTION|PARAGRAPH|PERFORM) { return EXIT; } @@ -1572,12 +1572,12 @@ USE({SPC}FOR)? { return USE; } {ISNT}{SPC}{VARTYPE} { yylval.number = NOT; yy_push_state(classify); - yyless(0); + myless(0); return MIGHT_BE; } IS{SPC}{VARTYPE} { yylval.number = IS; yy_push_state(classify); - yyless(0); + myless(0); return MIGHT_BE; } @@ -1619,7 +1619,7 @@ USE({SPC}FOR)? { return USE; } int token = keyword_tok(yytext); if( token ) return token; if( is_integer_token() ) return numstr_of(yytext); - yyless(0); + myless(0); yy_push_state(partial_name); tee_up_empty(); } @@ -1659,7 +1659,7 @@ USE({SPC}FOR)? { return USE; } return NAME; } } - yyless(0); + myless(0); yy_push_state(partial_name); tee_up_empty(); } @@ -1766,7 +1766,7 @@ USE({SPC}FOR)? { return USE; } pop_return token; } - . { yyless(0); yy_pop_state(); } + . { myless(0); yy_pop_state(); } } <function>{ @@ -2019,10 +2019,10 @@ BASIS { yy_push_state(basis); return BASIS; } <*>{ ^[ ]{6}D.*\n { if( !is_fixed_format() ) { - yyless(6); + myless(6); } else { // If WITH DEBUGGING MODE, drop the D, else drop the line. - if( include_debug() ) yyless(7); + if( include_debug() ) myless(7); } } ^[ ]*>>{OSPC}IF { yy_push_state(cdf_state); return CDF_IF; } @@ -2124,6 +2124,301 @@ BASIS { yy_push_state(basis); return BASIS; } ^{TITLE} } +<*>{ + ACCEPT { return ACCEPT; } + ACCESS { return ACCESS; } + ADD { return ADD; } + ADDRESS { return ADDRESS; } + ADVANCING { return ADVANCING; } + AFTER { return AFTER; } + ALL { return ALL; } + ALLOCATE { return ALLOCATE; } + ALPHABET { return ALPHABET; } + ALPHABETIC { return ALPHABETIC; } + ALPHABETIC-LOWER { return ALPHABETIC_LOWER; } + ALPHABETIC-UPPER { return ALPHABETIC_UPPER; } + ALPHANUMERIC { return ALPHANUMERIC; } + ALPHANUMERIC-EDITED { return ALPHANUMERIC_EDITED; } + ALSO { return ALSO; } + ALTERNATE { return ALTERNATE; } + AND { return AND; } + ANY { return ANY; } + ANYCASE { return ANYCASE; } + ARE { return ARE; } + AREA { return AREA; } + AREAS { return AREAS; } + AS { return AS; } + ASCENDING { return ASCENDING; } + ASSIGN { return ASSIGN; } + AT { return AT; } + BASED { return BASED; } + BEFORE { return BEFORE; } + BINARY { return BINARY; } + BIT { return BIT; } + BLANK { return BLANK; } + BLOCK { return BLOCK; } + BOTTOM { return BOTTOM; } + BY { return BY; } + CALL { return CALL; } + CANCEL { return CANCEL; } + CF { return CF; } + CH { return CH; } + CHARACTER { return CHARACTER; } + CHARACTERS { return CHARACTERS; } + CLASS { return CLASS; } + CLOSE { return CLOSE; } + CODE { return CODE; } + COMMA { return COMMA; } + COMMIT { return COMMIT; } + COMMON { return COMMON; } + CONDITION { return CONDITION; } + CONSTANT { return CONSTANT; } + CONTAINS { return CONTAINS; } + CONTENT { return CONTENT; } + CONTINUE { return CONTINUE; } + CONTROL { return CONTROL; } + CONTROLS { return CONTROLS; } + CONVERTING { return CONVERTING; } + COPY { return COPY; } + COUNT { return COUNT; } + CURRENCY { return CURRENCY; } + DATA { return DATA; } + DATE { return DATE; } + DAY { return DAY; } + DAY-OF-WEEK { return DAY_OF_WEEK; } + DE { return DE; } + DECIMAL-POINT { return DECIMAL_POINT; } + DECLARATIVES { return DECLARATIVES; } + DEFAULT { return DEFAULT; } + DELETE { return DELETE; } + DELIMITED { return DELIMITED; } + DELIMITER { return DELIMITER; } + DEPENDING { return DEPENDING; } + DESCENDING { return DESCENDING; } + DETAIL { return DETAIL; } + DISPLAY { return DISPLAY; } + DIVIDE { return DIVIDE; } + DOWN { return DOWN; } + DUPLICATES { return DUPLICATES; } + DYNAMIC { return DYNAMIC; } + EC { return EC; } + ELSE { return ELSE; } + END { return END; } + END-ACCEPT { return END_ACCEPT; } + END-ADD { return END_ADD; } + END-CALL { return END_CALL; } + END-DELETE { return END_DELETE; } + END-DISPLAY { return END_DISPLAY; } + END-DIVIDE { return END_DIVIDE; } + END-EVALUATE { return END_EVALUATE; } + END-IF { return END_IF; } + END-MULTIPLY { return END_MULTIPLY; } + END-PERFORM { return END_PERFORM; } + END-READ { return END_READ; } + END-RETURN { return END_RETURN; } + END-REWRITE { return END_REWRITE; } + END-SEARCH { return END_SEARCH; } + END-SUBTRACT { return END_SUBTRACT; } + END-WRITE { return END_WRITE; } + ENVIRONMENT { return ENVIRONMENT; } + EQUAL { return EQUAL; } + ERROR { return ERROR; } + EVALUATE { return EVALUATE; } + EXCEPTION { return EXCEPTION; } + EXIT { return EXIT; } + EXTEND { return EXTEND; } + EXTERNAL { return EXTERNAL; } + FALSE { return FALSE; } + FD { return FD; } + FINAL { return FINAL; } + FINALLY { return FINALLY; } + FIRST { return FIRST; } + FOOTING { return FOOTING; } + FOR { return FOR; } + FREE { return FREE; } + FROM { return FROM; } + FUNCTION { return FUNCTION; } + GENERATE { return GENERATE; } + GIVING { return GIVING; } + GLOBAL { return GLOBAL; } + GO { return GO; } + GOBACK { return GOBACK; } + GROUP { return GROUP; } + HEADING { return HEADING; } + IDENTIFICATION { return IDENTIFICATION_DIV; } + IF { return IF; } + IN { return IN; } + INDEX { return INDEX; } + INDEXED { return INDEXED; } + INDICATE { return INDICATE; } + INITIAL { return INITIAL; } + INITIALIZE { return INITIALIZE; } + INITIATE { return INITIATE; } + INPUT { return INPUT; } + INSPECT { return INSPECT; } + INTERFACE { return INTERFACE; } + INTO { return INTO; } + INVOKE { return INVOKE; } + IS { return IS; } + KEY { return KEY; } + LAST { return LAST; } + LEADING { return LEADING; } + LEFT { return LEFT; } + LENGTH { return LENGTH; } + LIMIT { return LIMIT; } + LIMITS { return LIMITS; } + LINAGE { return LINAGE; } + LINE { return LINE; } + LINE-COUNTER { return LINE_COUNTER; } + LINES { return LINES; } + LINKAGE { return LINKAGE; } + LOCAL-STORAGE { return LOCAL_STORAGE; } + LOCALE { return LOCALE; } + LOCATION { return LOCATION; } + LOCK { return LOCK; } + MERGE { return MERGE; } + MODE { return MODE; } + MOVE { return MOVE; } + MULTIPLY { return MULTIPLY; } + NATIONAL { return NATIONAL; } + NATIONAL-EDITED { return NATIONAL_EDITED; } + NATIVE { return NATIVE; } + NEGATIVE { return NEGATIVE; } + NESTED { return NESTED; } + NEXT { return NEXT; } + NO { return NO; } + NOT { return NOT; } + NUMBER { return NUMBER; } + NUMERIC { return NUMERIC; } + NUMERIC-EDITED { return NUMERIC_EDITED; } + OCCURS { return OCCURS; } + OF { return OF; } + OFF { return OFF; } + OMITTED { return OMITTED; } + ON { return ON; } + OPEN { return OPEN; } + OPTIONAL { return OPTIONAL; } + OPTIONS { return OPTIONS; } + OR { return OR; } + ORDER { return ORDER; } + ORGANIZATION { return ORGANIZATION; } + OTHER { return OTHER; } + OUTPUT { return OUTPUT; } + OVERFLOW { return OVERFLOW; } + OVERRIDE { return OVERRIDE; } + PACKED-DECIMAL { return PACKED_DECIMAL; } + PAGE { return PAGE; } + PAGE-COUNTER { return PAGE_COUNTER; } + PERFORM { return PERFORM; } + PF { return PF; } + PH { return PH; } + PIC { return PIC; } + PICTURE { return PICTURE; } + PLUS { return PLUS; } + POINTER { return POINTER; } + POSITIVE { return POSITIVE; } + PROCEDURE { return PROCEDURE; } + PROGRAM { return PROGRAM; } + PROGRAM-ID { return PROGRAM_ID; } + PROPERTY { return PROPERTY; } + PROTOTYPE { return PROTOTYPE; } + QUOTE { return QUOTE; } + QUOTES { return QUOTES; } + RAISE { return RAISE; } + RAISING { return RAISING; } + RANDOM { return RANDOM; } + RD { return RD; } + READ { return READ; } + RECORD { return RECORD; } + RECORDS { return RECORDS; } + REDEFINES { return REDEFINES; } + REEL { return REEL; } + REFERENCE { return REFERENCE; } + RELATIVE { return RELATIVE; } + RELEASE { return RELEASE; } + REMAINDER { return REMAINDER; } + REMOVAL { return REMOVAL; } + RENAMES { return RENAMES; } + REPLACE { return REPLACE; } + REPLACING { return REPLACING; } + REPORT { return REPORT; } + REPORTING { return REPORTING; } + REPORTS { return REPORTS; } + REPOSITORY { return REPOSITORY; } + RESERVE { return RESERVE; } + RESET { return RESET; } + RESUME { return RESUME; } + RETURN { return RETURN; } + RETURNING { return RETURNING; } + REWIND { return REWIND; } + REWRITE { return REWRITE; } + RF { return RF; } + RH { return RH; } + RIGHT { return RIGHT; } + ROUNDED { return ROUNDED; } + RUN { return RUN; } + SAME { return SAME; } + SCREEN { return SCREEN; } + SD { return SD; } + SEARCH { return SEARCH; } + SECTION { return SECTION; } + SELECT { return SELECT; } + SENTENCE { return SENTENCE; } + SEPARATE { return SEPARATE; } + SEQUENCE { return SEQUENCE; } + SEQUENTIAL { return SEQUENTIAL; } + SET { return SET; } + SHARING { return SHARING; } + SIGN { return SIGN; } + SIZE { return SIZE; } + SORT { return SORT; } + SORT-MERGE { return SORT_MERGE; } + SOURCE { return SOURCE; } + SPACE { return SPACE; } + SPACES { return SPACES; } + SPECIAL-NAMES { return SPECIAL_NAMES; } + STANDARD { return STANDARD; } + STANDARD-1 { return STANDARD_1; } + START { return START; } + STATUS { return STATUS; } + STOP { return STOP; } + SUBTRACT { return SUBTRACT; } + SUM { return SUM; } + SUPPRESS { return SUPPRESS; } + SYMBOLIC { return SYMBOLIC; } + TALLYING { return TALLYING; } + TERMINATE { return TERMINATE; } + TEST { return TEST; } + THAN { return THAN; } + THEN { return THEN; } + THRU { return THRU; } + TIME { return TIME; } + TIMES { return TIMES; } + TO { return TO; } + TOP { return TOP; } + TRAILING { return TRAILING; } + TRUE { return TRUE; } + TYPE { return TYPE; } + TYPEDEF { return TYPEDEF; } + UNIT { return UNIT; } + UNTIL { return UNTIL; } + UP { return UP; } + UPON { return UPON; } + USAGE { return USAGE; } + USE { return USE; } + USING { return USING; } + VALUE { return VALUE; } + VARYING { return VARYING; } + WHEN { return WHEN; } + WITH { return WITH; } + WORKING-STORAGE { return WORKING_STORAGE; } + WRITE { return WRITE; } + + ZERO | + ZEROES | + ZEROS { return ZERO; } +} + <*>{ %EBCDIC-MODE { ydflval.number = feature_internal_ebcdic_e; return FEATURE; } @@ -2135,9 +2430,9 @@ BASIS { yy_push_state(basis); return BASIS; } {NAME} { int token = keyword_tok(yytext); if( token ) { - if(yydebug && YY_START) { - yywarn("missed token %s in start condition %d", - yytext, YY_START); + if(yy_flex_debug && YY_START) { + dbgmsg("missed token %s in start condition %d", + yytext, YY_START); } // Do not return "token" because it may have been excluded // by a start condition. For example, REM might be a name, diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index eeaf78129040..15f95813ce9d 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -357,6 +357,13 @@ static void level_found() { if( scanner_normal() ) parsing.need_level(false); } +#define myless(N) \ + do { \ + auto n(N); \ + trim_location(n); \ + yyless(n); \ + } while(0) + static void update_location() { auto nline = std::count(yytext, yytext + yyleng, '\n'); @@ -380,6 +387,38 @@ update_location() { } } +static void +trim_location( int nkeep) { + gcc_assert( 0 <= nkeep && nkeep <= yyleng ); + struct { char *p, *pend; + size_t size() const { return pend - p; } + } rescan = { yytext + nkeep, yytext + yyleng }; + + auto nline = std::count(rescan.p, rescan.pend, '\n'); + dbgmsg("%s:%d: yyless(%d), rescan '%.*s' (%zu lines, %d bytes)", + __func__, __LINE__, + nkeep, + int(rescan.size()), rescan.p, + nline, rescan.size()); + if( nline ) { + gcc_assert( yylloc.first_line + nline <= yylloc.last_line ); + yylloc.last_line =- int(nline); + char *p = static_cast<char*>(memrchr(rescan.p, '\n', rescan.size())); + yylloc.last_column = rescan.pend - ++p; + return; + } + + gcc_assert( int(rescan.size()) < yylloc.last_column ); + yylloc.last_column -= rescan.size(); + if( yylloc.last_column < yylloc.first_column ) { + yylloc.first_column = 1; + } + + if( getenv("update_location") ) { + location_dump(__func__, __LINE__, "yylloc", yylloc); + } +} + static void update_location_col( const char str[], int correction = 0) { auto col = yylloc.last_column - strlen(str) + correction; @@ -456,7 +495,7 @@ picset( int token ) { char *p = orig_picture + strlen(orig_picture); if( eop < p + yyleng ) { - yyerror("PICTURE exceeds maximum size of %zu bytes", + error_msg(yylloc, "PICTURE exceeds maximum size of %zu bytes", sizeof(orig_picture) - 1); } snprintf( p, eop - p, "%s", yytext ); @@ -472,7 +511,7 @@ is_integer_token( int *pvalue = NULL ) { static bool need_nume = false; bool need_nume_set( bool tf ) { - if( yydebug ) yywarn( "need_nume now %s", tf? "true" : "false" ); + dbgmsg( "need_nume now %s", tf? "true" : "false" ); return need_nume = tf; } diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index 984f74e9e235..edd2eb4cd374 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -239,7 +239,6 @@ is_alpha_edited( const char picture[] ) { bool is_numeric_edited( const char picture[] ) { static const char valid[] = "BbPpVvZz90/(),.+-*"; // and CR DB - char *s; const char *p; assert(picture); @@ -295,10 +294,9 @@ is_numeric_edited( const char picture[] ) { numed_message = "expected DB in PICTURE"; break; default: - asprintf(&s, "invalid PICTURE character " - "'%c' at offset %zu in '%s'", - *p, p - picture, picture); - numed_message = s; + numed_message = xasprintf("invalid PICTURE character " + "'%c' at offset %zu in '%s'", + *p, p - picture, picture); break; } @@ -2417,7 +2415,6 @@ cbl_unimplemented(const char *gmsgid, ...) { va_list ap; va_start(ap, gmsgid); emit_diagnostic_valist( DK_SORRY, token_location, option_id, gmsgid, &ap ); - yyerror("Program requires unimplemented syntax."); va_end(ap); } -- GitLab