From 142c6907347d932b84c9740f8ed48facd2590cac Mon Sep 17 00:00:00 2001
From: "James K. Lowden" <jklowden@symas.com>
Date: Fri, 17 May 2024 11:12:47 -0400
Subject: [PATCH] better parser state encapsulation

---
 gcc/cobol/scan_ante.h | 19 +++++++++----------
 gcc/cobol/scan_post.h |  5 ++---
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index d446552412c0..34290b14fa9e 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -262,15 +262,14 @@ struct cdf_status_t {
 static bool run_cdf( int token );
 
 static class parsing_status_t : public std::stack<cdf_status_t> {
+  typedef int (parser_t)(void);
   struct parsing_state_t {
     bool expect_field_level;
-    parsing_state_t() : expect_field_level(true) {}
+    parser_t *parser;
+    parsing_state_t() : expect_field_level(true), parser(yyparse) {}
   } state, shadow;
   
-  int (*parser)(void) = yyparse;
-
  public:
-
   bool on() const { // true only if all true
     bool parsing = std::all_of( c.begin(), c.end(),
 			       []( const auto& status ) { return status.parsing; } );
@@ -278,21 +277,22 @@ static class parsing_status_t : public std::stack<cdf_status_t> {
   }
 
   bool feed_a_parser() const {
-    return on() || parser == ydfparse;
+    return on() || state.parser == ydfparse;
   }
 
   void need_level( bool tf ) {     state.expect_field_level = tf; }
   bool need_level() const { return state.expect_field_level; }
 
-  void state_save() {
+  void parser_save( parser_t * new_parser ) {
     shadow = state;
+    state.parser = new_parser;
   }
-  void state_restore() {
+  void parser_restore() {
     state = shadow;
   }
 
-  bool in_cdf() const { return parser == ydfparse; }
-  bool normal() const { return on() && parser == yyparse; }
+  bool in_cdf() const { return state.parser == ydfparse; }
+  bool normal() const { return on() && state.parser == yyparse; }
 
   void splat() const {
     int i=0;
@@ -300,7 +300,6 @@ static class parsing_status_t : public std::stack<cdf_status_t> {
       warnx( "%4d\t%s", ++i, status.str() );
     }
   }
-  friend bool run_cdf( int token );
 } parsing;
 
 // Used only by parser, so scanner_normal() obviously true. 
diff --git a/gcc/cobol/scan_post.h b/gcc/cobol/scan_post.h
index 7ecd07aa217e..fa56f1a1a5a1 100644
--- a/gcc/cobol/scan_post.h
+++ b/gcc/cobol/scan_post.h
@@ -202,12 +202,11 @@ run_cdf( int token ) {
 
   // Parse the CDF directive.
 
-  int (*parser)(void) = ydfparse;
-  std::swap(parser, parsing.parser);
+  parsing.parser_save(ydfparse);
 
   int erc = ydfparse();
 
-  std::swap(parser, parsing.parser);
+  parsing.parser_restore();
 
   if( YY_START == cdf_state ) yy_pop_state(); 
 
-- 
GitLab