diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 31ab8e475fec034c8e84ab3f8f1e0fb0dc44aae4..c0d0fc2aa5326c944ca7f90664d2e18198a51fe5 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -733,22 +733,9 @@ location_set( const YYLTYPE& loc ) { top: programs { - const cbl_label_t *prog = current.program(); - assert(prog); - current.end_paragraph(); - current.end_section(); - std::set<std::string> externals = current.end_program(); - // Jim? I don't think accumulate() does what you think it is doing - if( !externals.empty() || - std::accumulate(externals.begin(), externals.end(), 0, - external_message(prog->name)) ) - { - YYERROR; - } - - // pointer still valid because name is in symbol table - ast_end_program(prog->name); - + if( ! goodnight_gracie() ) { + YYABORT; + } if( nparse_error > 0 ) YYABORT; } | programs end_program @@ -3166,6 +3153,14 @@ sentences: sentence ; sentence: statements '.' + | statements YYEOF + { + if( ! goodnight_gracie() ) { + YYERROR; + } + if( nparse_error > 0 ) YYABORT; + YYACCEPT; + } | program END_SUBPROGRAM namestr[name] '.' { const cbl_label_t *prog = current.program(); diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index f3e1a0cc3a3c5fd75bde555cf1eb33ed366f6723..22930b36b6579afec2b1efe213ab22d1d6584022 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -85,7 +85,6 @@ class external_message { external_message( const char *program ) : program(program) {} int operator()( int nerr, const std::string& name ) { - ////if( name[0] == ':' ) return ++nerr; // ambiguity message already printed warnx("%s calls external symbol '%s'", program, name.c_str()); return nerr; } @@ -2141,3 +2140,26 @@ ast_end_program(const char name[] ) { } parser_end_program(name); } + +static bool +goodnight_gracie() { + const cbl_label_t *prog = current.program(); + assert(prog); + current.end_paragraph(); + current.end_section(); + std::set<std::string> externals = current.end_program(); + if( !externals.empty() || + std::count_if(externals.begin(), externals.end(), + [program = prog->name]( const std::string& name ) { + warnx("%s calls external symbol '%s'", + program, name.c_str()); + return true; + } ) ) + { + return false; + } + + // pointer still valid because name is in symbol table + ast_end_program(prog->name); + return true; +} diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index 38f4c461016c8f185655f5863978a680a063411b..baf8dffe5e56bb47aa882a66ecf4edfa39d7642d 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -1690,12 +1690,7 @@ COPY { yypop_buffer_state(); if ( !YY_CURRENT_BUFFER ) { - if( final_token != '.' ) { - warnx("warning: adding a dot to %s", cobol_filename()); - yyrestart(yyin); - return final_token = '.'; - } - yyterminate(); + return 0; } if( ! wait_for_the_child() ) {