From 74d8b3d55da53be410ddf1c275cc83025c067577 Mon Sep 17 00:00:00 2001
From: dgelessus <dgelessus@users.noreply.github.com>
Date: Mon, 25 Apr 2022 14:51:30 +0200
Subject: [PATCH] Improve exception handling and resource management in
 non-generated code

---
 .../org/sablecc/sablecc/ConstructNFA.java     |   4 +-
 .../org/sablecc/sablecc/DisplayLicense.java   |   4 +-
 .../java/org/sablecc/sablecc/GenAlts.java     |  26 +---
 .../java/org/sablecc/sablecc/GenAnalyses.java |  98 ++------------
 .../java/org/sablecc/sablecc/GenLexer.java    |  50 +------
 .../java/org/sablecc/sablecc/GenParser.java   | 114 ++--------------
 .../java/org/sablecc/sablecc/GenProds.java    |  50 +------
 .../java/org/sablecc/sablecc/GenTokens.java   |  27 +---
 .../java/org/sablecc/sablecc/GenUtils.java    | 122 ++----------------
 .../GenerateAlternativeCodeForParser.java     |  22 ++--
 .../java/org/sablecc/sablecc/Grammar.java     |   2 +-
 .../java/org/sablecc/sablecc/SableCC.java     |  12 +-
 12 files changed, 71 insertions(+), 460 deletions(-)

diff --git a/src/main/java/org/sablecc/sablecc/ConstructNFA.java b/src/main/java/org/sablecc/sablecc/ConstructNFA.java
index ade311e..284d5e6 100644
--- a/src/main/java/org/sablecc/sablecc/ConstructNFA.java
+++ b/src/main/java/org/sablecc/sablecc/ConstructNFA.java
@@ -305,9 +305,9 @@ public class ConstructNFA extends DepthFirstAdapter
         this.nodeValues.put(node, cs1.diff(cs2));
       }
     }
-    catch(Exception e)
+    catch(RuntimeException e)
     {
-      throw new RuntimeException(node + " is invalid.");
+      throw new RuntimeException(node + " is invalid.", e);
     }
 
     // free memory
diff --git a/src/main/java/org/sablecc/sablecc/DisplayLicense.java b/src/main/java/org/sablecc/sablecc/DisplayLicense.java
index 7fae95d..88c1f78 100644
--- a/src/main/java/org/sablecc/sablecc/DisplayLicense.java
+++ b/src/main/java/org/sablecc/sablecc/DisplayLicense.java
@@ -59,9 +59,9 @@ class DisplayLicense
       in.close();
       System.out.println("---- END OF FILE: COPYING-LESSER ----");
     }
-    catch(Exception e)
+    catch(IOException | RuntimeException e)
     {
-      System.out.println(e);
+      e.printStackTrace();
       System.exit(1);
     }
   }
diff --git a/src/main/java/org/sablecc/sablecc/GenAlts.java b/src/main/java/org/sablecc/sablecc/GenAlts.java
index 8d92b5f..26e5f2c 100644
--- a/src/main/java/org/sablecc/sablecc/GenAlts.java
+++ b/src/main/java/org/sablecc/sablecc/GenAlts.java
@@ -35,7 +35,7 @@ public class GenAlts extends DepthFirstAdapter
     }
     catch(IOException e)
     {
-      throw new RuntimeException("unable to open alternatives.txt.");
+      throw new RuntimeException("unable to open alternatives.txt.", e);
     }
 
     pkgDir = new File(ast_ids.astIds.pkgDir, "node");
@@ -107,20 +107,7 @@ public class GenAlts extends DepthFirstAdapter
   {
     String name = ast_ids.ast_names.get(node);
 
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, name + ".java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, name + ".java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
     {
         boolean hasOperator = false;
         boolean hasList = false;
@@ -363,16 +350,9 @@ public class GenAlts extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, name + ".java").getAbsolutePath());
+                                 new File(pkgDir, name + ".java").getAbsolutePath(), e);
     }
 
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
-
     elemList = null;
   }
 
diff --git a/src/main/java/org/sablecc/sablecc/GenAnalyses.java b/src/main/java/org/sablecc/sablecc/GenAnalyses.java
index 624dfca..f5c0288 100644
--- a/src/main/java/org/sablecc/sablecc/GenAnalyses.java
+++ b/src/main/java/org/sablecc/sablecc/GenAnalyses.java
@@ -37,7 +37,7 @@ public class GenAnalyses extends DepthFirstAdapter
     }
     catch(IOException e)
     {
-      throw new RuntimeException("unable to open analyses.txt.");
+      throw new RuntimeException("unable to open analyses.txt.", e);
     }
 
     pkgDir = new File(ast_ids.astIds.pkgDir, "analysis");
@@ -143,20 +143,7 @@ public class GenAnalyses extends DepthFirstAdapter
 
   public void createAnalysis()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "Analysis.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "Analysis.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Analysis.java"))))
     {
       macros.apply(file, "AnalysisHeader", new String[] {pkgName,
                    ast_ids.astIds.pkgName.equals("") ? "node" : ast_ids.astIds.pkgName + ".node"});
@@ -185,33 +172,13 @@ public class GenAnalyses extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Analysis.java").getAbsolutePath());
+                                 new File(pkgDir, "Analysis.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   public void createAnalysisAdapter()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "AnalysisAdapter.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "AnalysisAdapter.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "AnalysisAdapter.java"))))
     {
       macros.apply(file, "AnalysisAdapterHeader", new String[] {pkgName,
                    ast_ids.astIds.pkgName.equals("") ? "node" : ast_ids.astIds.pkgName + ".node"});
@@ -238,33 +205,13 @@ public class GenAnalyses extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "AnalysisAdapter.java").getAbsolutePath());
+                                 new File(pkgDir, "AnalysisAdapter.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   public void createDepthFirstAdapter()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "DepthFirstAdapter.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "DepthFirstAdapter.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "DepthFirstAdapter.java"))))
     {
       macros.apply(file, "DepthFirstAdapterHeader", new String[] {pkgName,
                    ast_ids.astIds.pkgName.equals("") ? "node" : ast_ids.astIds.pkgName + ".node",
@@ -309,33 +256,13 @@ public class GenAnalyses extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "DepthFirstAdapter.java").getAbsolutePath());
+                                 new File(pkgDir, "DepthFirstAdapter.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   public void createReversedDepthFirstAdapter()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "ReversedDepthFirstAdapter.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "ReversedDepthFirstAdapter.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "ReversedDepthFirstAdapter.java"))))
     {
       macros.apply(file, "ReversedDepthFirstAdapterHeader", new String[] {pkgName,
                    ast_ids.astIds.pkgName.equals("") ? "node" : ast_ids.astIds.pkgName + ".node",
@@ -382,15 +309,8 @@ public class GenAnalyses extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "ReversedDepthFirstAdapter.java").getAbsolutePath());
+                                 new File(pkgDir, "ReversedDepthFirstAdapter.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   private static class ElemInfo
diff --git a/src/main/java/org/sablecc/sablecc/GenLexer.java b/src/main/java/org/sablecc/sablecc/GenLexer.java
index 7c776d7..e3f4963 100644
--- a/src/main/java/org/sablecc/sablecc/GenLexer.java
+++ b/src/main/java/org/sablecc/sablecc/GenLexer.java
@@ -35,7 +35,7 @@ public class GenLexer extends AnalysisAdapter
     }
     catch(IOException e)
     {
-      throw new RuntimeException("unable to open lexer.txt.");
+      throw new RuntimeException("unable to open lexer.txt.", e);
     }
 
     pkgDir = new File(ids.pkgDir, "lexer");
@@ -102,53 +102,20 @@ public class GenLexer extends AnalysisAdapter
 
   private void createLexerException()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "LexerException.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "LexerException.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "LexerException.java"))))
     {
       macros.apply(file, "LexerException", new String[] {pkgName});
     }
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "LexerException.java").getAbsolutePath());
+                                 new File(pkgDir, "LexerException.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   private void createLexer()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "Lexer.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "Lexer.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Lexer.java"))))
     {
       String startState = "INITIAL";
       if(ids.stateList.size() > 0)
@@ -332,14 +299,7 @@ public class GenLexer extends AnalysisAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Lexer.java").getAbsolutePath());
+                                 new File(pkgDir, "Lexer.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 }
diff --git a/src/main/java/org/sablecc/sablecc/GenParser.java b/src/main/java/org/sablecc/sablecc/GenParser.java
index bcb654d..7be893d 100644
--- a/src/main/java/org/sablecc/sablecc/GenParser.java
+++ b/src/main/java/org/sablecc/sablecc/GenParser.java
@@ -101,7 +101,7 @@ public class GenParser extends DepthFirstAdapter
     }
     catch(IOException e)
     {
-      throw new RuntimeException("unable to open parser.txt.");
+      throw new RuntimeException("unable to open parser.txt.", e);
     }
 
     pkgDir = new File(ids.pkgDir, "parser");
@@ -237,7 +237,7 @@ public class GenParser extends DepthFirstAdapter
           {
             System.out.println("\nA previous conflict that we've tried to solve by inline some productions inside the grammars cannot be solved that way. The transformed grammar is : ");
             tree.apply(new PrettyPrinter());
-            throw new RuntimeException(ce.getMessage());
+            throw new RuntimeException(ce.getMessage(), ce);
           }
 
           System.out.println();
@@ -245,7 +245,7 @@ public class GenParser extends DepthFirstAdapter
         }
         else
         {
-          throw new RuntimeException(ce.getMessage());
+          throw new RuntimeException(ce.getMessage(), ce);
         }
       }
     }
@@ -357,20 +357,7 @@ public class GenParser extends DepthFirstAdapter
   //Parser.java Generation
   private void createParser()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "Parser.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "Parser.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Parser.java"))))
     {
       Symbol[] terminals = Symbol.terminals();
       Symbol[] nonterminals = Symbol.nonterminals();
@@ -443,17 +430,9 @@ public class GenParser extends DepthFirstAdapter
                    }
                   );
 
-        try
+        for(Element e : stack)
         {
-          for(Element e : stack)
-          {
-            macros.apply(file, e.macro, e.arguments);
-          }
-        }
-        catch(IOException e)
-        {
-          throw new RuntimeException("An error occured while writing to " +
-                                     new File(pkgDir, "Parser.java").getAbsolutePath());
+          macros.apply(file, e.macro, e.arguments);
         }
 
         String nodeName = ids.names.get(node);
@@ -710,33 +689,13 @@ public class GenParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
-    }
-
-    try
-    {
-      file.close();
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
-    catch(IOException e)
-    {}
   }
 
   private void createTokenIndex()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "TokenIndex.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "TokenIndex.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "TokenIndex.java"))))
     {
       Symbol[] terminals = Symbol.terminals();
 
@@ -754,33 +713,13 @@ public class GenParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "TokenIndex.java").getAbsolutePath());
-    }
-
-    try
-    {
-      file.close();
+                                 new File(pkgDir, "TokenIndex.java").getAbsolutePath(), e);
     }
-    catch(IOException e)
-    {}
   }
 
   private void createParserException()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "ParserException.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "ParserException.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "ParserException.java"))))
     {
       macros.apply(file, "ParserException", new String[] {pkgName,
                    ids.pkgName.equals("") ? "node" : ids.pkgName + ".node"});
@@ -788,48 +727,21 @@ public class GenParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "ParserException.java").getAbsolutePath());
-    }
-
-    try
-    {
-      file.close();
+                                 new File(pkgDir, "ParserException.java").getAbsolutePath(), e);
     }
-    catch(IOException e)
-    {}
   }
 
   private void createState()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "State.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "State.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "State.java"))))
     {
       macros.apply(file, "State", new String[] {pkgName});
     }
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "State.java").getAbsolutePath());
+                                 new File(pkgDir, "State.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   private int count(String name)
diff --git a/src/main/java/org/sablecc/sablecc/GenProds.java b/src/main/java/org/sablecc/sablecc/GenProds.java
index 6e223d9..140e579 100644
--- a/src/main/java/org/sablecc/sablecc/GenProds.java
+++ b/src/main/java/org/sablecc/sablecc/GenProds.java
@@ -31,7 +31,7 @@ public class GenProds extends DepthFirstAdapter
     }
     catch(IOException e)
     {
-      throw new RuntimeException("unable to open productions.txt.");
+      throw new RuntimeException("unable to open productions.txt.", e);
     }
 
     pkgDir = new File(ast_ids.astIds.pkgDir, "node");
@@ -56,67 +56,27 @@ public class GenProds extends DepthFirstAdapter
 
   private void createProduction(String name)
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, name + ".java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, name + ".java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
     {
       macros.apply(file, "Production", new String[] {pkgName, name});
     }
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, name + ".java").getAbsolutePath());
+                                 new File(pkgDir, name + ".java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   private void createAlternative(String name, String macro, String[] arg)
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, name + ".java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, name + ".java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
     {
       macros.apply(file, macro, arg);
     }
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, name + ".java").getAbsolutePath());
+                                 new File(pkgDir, name + ".java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 }
diff --git a/src/main/java/org/sablecc/sablecc/GenTokens.java b/src/main/java/org/sablecc/sablecc/GenTokens.java
index 861e9c4..513aa6a 100644
--- a/src/main/java/org/sablecc/sablecc/GenTokens.java
+++ b/src/main/java/org/sablecc/sablecc/GenTokens.java
@@ -34,7 +34,7 @@ public class GenTokens extends DepthFirstAdapter
     }
     catch(IOException e)
     {
-      throw new RuntimeException("unable to open tokens.txt.");
+      throw new RuntimeException("unable to open tokens.txt.", e);
     }
 
     pkgDir = new File(ids.pkgDir, "node");
@@ -53,20 +53,6 @@ public class GenTokens extends DepthFirstAdapter
   public void inATokenDef(ATokenDef node)
   {
     String name = ids.names.get(node);
-
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, name + ".java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, name + ".java").getAbsolutePath());
-    }
-
     text = null;
 
     ARegExp regExp = (ARegExp) node.getRegExp();
@@ -104,7 +90,7 @@ public class GenTokens extends DepthFirstAdapter
       }
     }
 
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
     {
       if(text == null)
       {
@@ -128,15 +114,8 @@ public class GenTokens extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, name + ".java").getAbsolutePath());
+                                 new File(pkgDir, name + ".java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   private String processText(String s)
diff --git a/src/main/java/org/sablecc/sablecc/GenUtils.java b/src/main/java/org/sablecc/sablecc/GenUtils.java
index 2361af9..6310ed2 100644
--- a/src/main/java/org/sablecc/sablecc/GenUtils.java
+++ b/src/main/java/org/sablecc/sablecc/GenUtils.java
@@ -32,7 +32,7 @@ public class GenUtils extends DepthFirstAdapter
     }
     catch(IOException e)
     {
-      throw new RuntimeException("unable to open utils.txt.");
+      throw new RuntimeException("unable to open utils.txt.", e);
     }
 
     pkgDir = new File(ast_ids.astIds.pkgDir, "node");
@@ -85,20 +85,7 @@ public class GenUtils extends DepthFirstAdapter
 
   public void createStart()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "Start.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "Start.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Start.java"))))
     {
       macros.apply(file, "Start", new String[] {pkgName,
                    ast_ids.astIds.pkgName.equals("") ? "analysis" : ast_ids.astIds.pkgName + ".analysis",
@@ -107,33 +94,13 @@ public class GenUtils extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Start.java").getAbsolutePath());
+                                 new File(pkgDir, "Start.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   public void createEOF()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "EOF.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "EOF.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "EOF.java"))))
     {
       macros.apply(file, "EOF", new String[] {pkgName,
                                               ast_ids.astIds.pkgName.equals("") ? "analysis" : ast_ids.astIds.pkgName + ".analysis"});
@@ -141,33 +108,13 @@ public class GenUtils extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "EOF.java").getAbsolutePath());
-    }
-
-    try
-    {
-      file.close();
+                                 new File(pkgDir, "EOF.java").getAbsolutePath(), e);
     }
-    catch(IOException e)
-    {}
   }
 
   public void createNode()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "Node.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "Node.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Node.java"))))
     {
       macros.apply(file, "Node", new String[] {pkgName,
                    ast_ids.astIds.pkgName.equals("") ? "analysis" : ast_ids.astIds.pkgName + ".analysis"});
@@ -175,80 +122,33 @@ public class GenUtils extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Node.java").getAbsolutePath());
+                                 new File(pkgDir, "Node.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   public void createToken()
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, "Token.java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, "Token.java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Token.java"))))
     {
       macros.apply(file, "Token", new String[] {pkgName});
     }
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Token.java").getAbsolutePath());
+                                 new File(pkgDir, "Token.java").getAbsolutePath(), e);
     }
-
-    try
-    {
-      file.close();
-    }
-    catch(IOException e)
-    {}
   }
 
   public void create(String cls)
   {
-    BufferedWriter file;
-
-    try
-    {
-      file = new BufferedWriter(
-               new FileWriter(
-                 new File(pkgDir, cls + ".java")));
-    }
-    catch(IOException e)
-    {
-      throw new RuntimeException("Unable to create " + new File(pkgDir, cls + ".java").getAbsolutePath());
-    }
-
-    try
+    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, cls + ".java"))))
     {
       macros.apply(file, cls, new String[] {pkgName});
     }
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, cls + ".java").getAbsolutePath());
-    }
-
-    try
-    {
-      file.close();
+                                 new File(pkgDir, cls + ".java").getAbsolutePath(), e);
     }
-    catch(IOException e)
-    {}
   }
 }
diff --git a/src/main/java/org/sablecc/sablecc/GenerateAlternativeCodeForParser.java b/src/main/java/org/sablecc/sablecc/GenerateAlternativeCodeForParser.java
index 24682f1..0774d36 100644
--- a/src/main/java/org/sablecc/sablecc/GenerateAlternativeCodeForParser.java
+++ b/src/main/java/org/sablecc/sablecc/GenerateAlternativeCodeForParser.java
@@ -100,7 +100,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
       catch(IOException e)
       {
         throw new RuntimeException("An error occured while writing to " +
-                                   new File(pkgDir, "Parser.java").getAbsolutePath());
+                                   new File(pkgDir, "Parser.java").getAbsolutePath(), e);
       }
     }
   }
@@ -150,7 +150,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
   }
 
@@ -189,7 +189,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
       catch(IOException e)
       {
         throw new RuntimeException("An error occured while writing to " +
-                                   new File(pkgDir, "Parser.java").getAbsolutePath());
+                                   new File(pkgDir, "Parser.java").getAbsolutePath(), e);
       }
     }
   }
@@ -263,7 +263,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
   }
 
@@ -339,7 +339,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
   }
 
@@ -353,7 +353,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
     inAParams(node.getParams());
   }
@@ -368,7 +368,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
     inAParams(node.getParams());
   }
@@ -409,7 +409,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
   }
 
@@ -450,7 +450,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "Parser.java").getAbsolutePath());
+                                 new File(pkgDir, "Parser.java").getAbsolutePath(), e);
     }
   }
 
@@ -523,7 +523,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "TokenIndex.java").getAbsolutePath());
+                                 new File(pkgDir, "TokenIndex.java").getAbsolutePath(), e);
     }
   }
 
@@ -595,7 +595,7 @@ public class GenerateAlternativeCodeForParser extends DepthFirstAdapter
     catch(IOException e)
     {
       throw new RuntimeException("An error occured while writing to " +
-                                 new File(pkgDir, "TokenIndex.java").getAbsolutePath());
+                                 new File(pkgDir, "TokenIndex.java").getAbsolutePath(), e);
     }
   }
 
diff --git a/src/main/java/org/sablecc/sablecc/Grammar.java b/src/main/java/org/sablecc/sablecc/Grammar.java
index 6250141..ad8b406 100644
--- a/src/main/java/org/sablecc/sablecc/Grammar.java
+++ b/src/main/java/org/sablecc/sablecc/Grammar.java
@@ -144,7 +144,7 @@ public final class Grammar
           {
             production.rightside(items[k].lr0Item.position);
           }
-          catch(Exception e)
+          catch(RuntimeException e)
           {
             if(production.leftside != startSymbol)
             {
diff --git a/src/main/java/org/sablecc/sablecc/SableCC.java b/src/main/java/org/sablecc/sablecc/SableCC.java
index 5d7ba93..3df008e 100644
--- a/src/main/java/org/sablecc/sablecc/SableCC.java
+++ b/src/main/java/org/sablecc/sablecc/SableCC.java
@@ -90,7 +90,7 @@ public class SableCC {
         else if (arguments[arg].equals(OPT_INLINE_MAX_ALTS)) {
           try {
             inliningMaxAlts = Integer.parseInt(arguments[++arg]);
-          } catch (Exception e) {
+          } catch (RuntimeException e) {
             displayUsage();
             System.exit(1);
           }
@@ -117,7 +117,7 @@ public class SableCC {
       for (int i = 0; i < filename.size(); i++) {
         processGrammar(filename.elementAt(i), d_option);
       }
-    } catch (Exception e) {
+    } catch (IOException | LexerException | ParserException | RuntimeException e) {
       e.printStackTrace();
       System.exit(1);
     }
@@ -134,7 +134,7 @@ public class SableCC {
    *            output directory name
    */
   public static void processGrammar(String grammar, String destDir)
-      throws Exception {
+      throws IOException, LexerException, ParserException {
     File in;
     File dir;
 
@@ -160,7 +160,7 @@ public class SableCC {
    * @param dir
    *            output directory
    */
-  public static void processGrammar(File in, File dir) throws Exception {
+  public static void processGrammar(File in, File dir) throws IOException, LexerException, ParserException {
     if (!in.exists()) {
       System.out.println("ERROR: grammar file " + in.getName()
           + " does not exist.");
@@ -253,7 +253,7 @@ public class SableCC {
     try {
       System.out.println("Generating the lexer.");
       tree.apply(new GenLexer(ids));
-    } catch (Exception e) {
+    } catch (RuntimeException e) {
       System.out.println(e.getMessage());
       throw e;
     }
@@ -263,7 +263,7 @@ public class SableCC {
       tree.apply(new GenParser(ids, alt_ids, transform_ids, ast_ids
           .getFirstAstProduction(), processInlining, prettyPrinting,
           hasTransformations));
-    } catch (Exception e) {
+    } catch (RuntimeException e) {
       System.out.println(e.getMessage());
       throw e;
     }
-- 
GitLab