diff --git a/src/jsil/jsil_parser.cpp b/src/jsil/jsil_parser.cpp
index 234f6510212..e84b4a662c9 100644
--- a/src/jsil/jsil_parser.cpp
+++ b/src/jsil/jsil_parser.cpp
@@ -10,3 +10,5 @@ Author: Michael Tautschnig, tautschn@amazon.com
 /// Jsil Language
 
 #include "jsil_parser.h"
+
+int jsil_parsert::instance_count = 0;
diff --git a/src/jsil/jsil_parser.h b/src/jsil/jsil_parser.h
index c77e492259b..84cbc65bea0 100644
--- a/src/jsil/jsil_parser.h
+++ b/src/jsil/jsil_parser.h
@@ -26,17 +26,27 @@ class jsil_parsert:public parsert
   explicit jsil_parsert(message_handlert &message_handler)
     : parsert(message_handler)
   {
+    // Simplistic check that we don't attempt to do reentrant parsing as the
+    // Bison-generated parser has global state.
+    PRECONDITION(++instance_count == 1);
+  }
+
+  jsil_parsert(const jsil_parsert &) = delete;
+
+  ~jsil_parsert() override
+  {
+    --instance_count;
   }
 
   jsil_parse_treet parse_tree;
 
-  virtual bool parse() override
+  bool parse() override
   {
     jsil_scanner_init(*this);
     return yyjsilparse(*this) != 0;
   }
 
-  virtual void clear() override
+  void clear() override
   {
     parsert::clear();
     parse_tree.clear();
@@ -47,6 +57,9 @@ class jsil_parsert:public parsert
 
   // internal state of the scanner
   std::string string_literal;
+
+protected:
+  static int instance_count;
 };
 
 #endif // CPROVER_JSIL_JSIL_PARSER_H