diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 1716c7ce3d20db6da234cb65590a29dea53e8e95..6a143087ad27413bfc717f56e9b0995500ba625b 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -9827,91 +9827,6 @@ keyword_str( int token ) { * All function names are rejected here; the lexer uses typed_name to check * REPOSITORY names. */ -#if 0 -int -keyword_tok( const char * text, bool include_intrinsics ) { - class cmp { - char *name; - public: - cmp( const char *name ) : name(strdup(name)) { - std::replace(this->name, this->name + strlen(this->name), '-', '_'); - static struct kw_t { const char *lexeme, *name; } kws[] = { - { "CODE_SET", "CODESET" }, - { "DATA", "DATA_DIV" }, - { "ENVIRONMENT", "ENVIRONMENT_DIV" }, - { "FALSE", "FALSE_kw" }, - { "FILE", "FILE_KW" }, - { "FILLER", "FILLER_kw" }, - { "IDENTIFICATION", "IDENTIFICATION_DIV" }, - { "I_O", "IO" }, - { "INITIAL", "INITIAL_kw" }, - { "PIC", "PICTURE" }, - { "PROCEDURE", "PROCEDURE_DIV" }, - { "PROGRAM", "PROGRAM_kw" }, - { "QUOTE", "QUOTES" }, - { "STRING", "STRING_kw" }, - { "THROUGH", "THRU" }, - { "TRUE", "TRUE_kw" }, - }; - for( size_t i=0; i < COUNT_OF(kws); i++ ) { - if( 0 == strcasecmp(this->name, kws[i].lexeme) ) { - this->name = const_cast<char*>(kws[i].name); - break; - } - } - } - - bool operator()( const char *candidate ) { - static const cbl_name_t cdf_names[] = { - "CHECKING", "LOCATION" - }, * const eonames = cdf_names + COUNT_OF(cdf_names); - - if( eonames != std::find_if(cdf_names, eonames, - [candidate](const cbl_name_t name) { - return 0 == strcasecmp(name, candidate) - && strlen(name) == strlen(candidate); - } ) ) { - return false; // CDF names are never ordinary tokens - } - - return 0 == strcasecmp(name, candidate) - && strlen(name) == strlen(candidate); - } - }; - - class tokenset_t { - std::map <std::string, size_t> tokens; - public: - tokenset_t() { - size_t i=0; - for( auto name = yytname + 3; name < last, name++ ) { - static cbl_name_t lname; - std::transform(name, name + strlen(name) + 1, lname, tolower); - tokens[lname] = i++; - } - } - size_t find_token( const cbl_name_t name ) { - cbl_name_t lname; - std::transform(name, name + strlen(name) + 1, lname, tolower); - auto p = tokens.find(lname); - return p != tokens.end()? p->second : 0; - } - }; - - static auto last = std::find_if(yytname, yytname + COUNT_OF(yytname), - [] ( const char *name ) { - return 0 == strcmp(name, "$accept"); }); - auto p = std::find_if( yytname + 3, last, cmp(text) ); - - if( p == last ) return 0; - - int token = 255 + (p - yytname); - - if( include_intrinsics ) return token; - - return intrinsic_cname(token)? 0 : token; -} -#else static struct kw_t { const char *lexeme, *name; } kws[] = { { "CODE_SET", "CODESET" }, { "DATA", "DATA_DIV" }, @@ -9944,6 +9859,8 @@ class tokenset_t { static cbl_name_t lname; strcpy(lname, *name); + // Correct for names in parse.c::yytname that do not match the string + // provided in the COBOL text. auto p = std::find_if( kws, eokws, [](kw_t kw) { return 0 == strcasecmp(lname, kw.name); @@ -9958,8 +9875,25 @@ class tokenset_t { std::transform(lname, lname + strlen(lname) + 1, lname, tolower); tokens[lname] = i++; } + + // Insert token aliases into the token map. + static struct kw_t aliases[] = { + { "space", "spaces" }, + { "through", "thru" }, + { "zeroes", "zero" }, + { "zeros", "zero" }, + }, *eoaliases = aliases + COUNT_OF(aliases); + + std::transform( aliases, eoaliases, std::inserter(tokens, tokens.begin()), + [this]( const kw_t& kw ) { + auto p = tokens.find(kw.name); + assert(p != tokens.end()); + int token = p->second; + return std::make_pair(kw.lexeme, token); + } ); } - + + // Look up the lowercase form of a keyword, excluding some CDF names. int find( const cbl_name_t name, bool include_intrinsics ) { static const cbl_name_t cdf_names[] = { "CHECKING", "LOCATION" @@ -9970,7 +9904,7 @@ class tokenset_t { return 0 == strcasecmp(cdf_name, candidate) && strlen(cdf_name) == strlen(candidate); } ) ) { - return false; // CDF names are never ordinary tokens + return 0; // CDF names are never ordinary tokens } cbl_name_t lname; @@ -9986,7 +9920,7 @@ class tokenset_t { }; int -keyword_tok( const char * text, bool include_intrinsics ) { + keyword_tok( const char * text, bool include_intrinsics ) { static auto last = std::find_if(yytname + 3, yytname + COUNT_OF(yytname), [] ( const char *name ) { return 0 == strcmp(name, "$accept"); }); @@ -9994,7 +9928,6 @@ keyword_tok( const char * text, bool include_intrinsics ) { return tokens.find(text, include_intrinsics); } -#endif static inline size_t verify_figconst( enum cbl_figconst_t figconst , size_t pos ) { diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index 6d0bd183829a7a2f4240dee6b6ce939e771364ca..ecbf2525242311cdf79fd685abb12ac6a10255fd 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -59,20 +59,20 @@ yyerror( char const *s, int error_level = LOG_ERR) { fflush(stdout); if( yychar == 0 ) { // strictly YYEOF, but not defined here fprintf( stderr, "%s:%d: %s detected at end of file\n", - basename(strdup(cobol_filename())), yylineno, s); + cobol_filename(), yylineno, s); return; } if( !yytext || yytext[0] == '.') { fprintf( stderr, "%s:%d: %s\n", - basename(strdup(cobol_filename())), yylineno, s); + cobol_filename(), yylineno, s); return; } auto len = yytext[yyleng-1] == '\n'? yyleng - 1 : yyleng; fprintf( stderr, "%s:%d: %s at '%.*s'\n", - basename(strdup(cobol_filename())), yylineno, s, len, yytext); + cobol_filename(), yylineno, s, len, yytext); } inline void yywarn( char const *msg ) { yyerror( msg, LOG_WARNING ); }