From 381f0aaf0835c28dd0c30f84f978a45bdb57f605 Mon Sep 17 00:00:00 2001
From: dgelessus <dgelessus@users.noreply.github.com>
Date: Fri, 19 May 2023 21:47:56 +0200
Subject: [PATCH] Consistently use UTF-8 instead of platform default charset

Fixes platform-dependent behavior when using non-ASCII characters in
grammar source files.
---
 .../org/sablecc/sablecc/DisplayLicense.java     |  7 ++++---
 src/main/java/org/sablecc/sablecc/GenAlts.java  |  7 ++++---
 .../java/org/sablecc/sablecc/GenAnalyses.java   | 13 +++++++------
 src/main/java/org/sablecc/sablecc/GenLexer.java |  9 +++++----
 .../java/org/sablecc/sablecc/GenParser.java     | 13 +++++++------
 src/main/java/org/sablecc/sablecc/GenProds.java |  9 +++++----
 .../java/org/sablecc/sablecc/GenTokens.java     |  7 ++++---
 src/main/java/org/sablecc/sablecc/GenUtils.java | 15 ++++++++-------
 src/main/java/org/sablecc/sablecc/SableCC.java  | 17 ++++++++++-------
 9 files changed, 54 insertions(+), 43 deletions(-)

diff --git a/src/main/java/org/sablecc/sablecc/DisplayLicense.java b/src/main/java/org/sablecc/sablecc/DisplayLicense.java
index 75452da..cc212c4 100644
--- a/src/main/java/org/sablecc/sablecc/DisplayLicense.java
+++ b/src/main/java/org/sablecc/sablecc/DisplayLicense.java
@@ -10,6 +10,7 @@ package org.sablecc.sablecc;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
 
 class DisplayLicense
 {
@@ -20,7 +21,7 @@ class DisplayLicense
       BufferedReader in =
         new BufferedReader(
           new InputStreamReader(
-            getClass().getResourceAsStream("LICENSE")));
+            getClass().getResourceAsStream("LICENSE"), StandardCharsets.UTF_8));
       System.out.println("---- FILE: LICENSE ----");
 
       String s;
@@ -37,7 +38,7 @@ class DisplayLicense
       in =
         new BufferedReader(
           new InputStreamReader(
-            getClass().getResourceAsStream("AUTHORS")));
+            getClass().getResourceAsStream("AUTHORS"), StandardCharsets.UTF_8));
 
       while((s = in.readLine()) != null)
       {
@@ -52,7 +53,7 @@ class DisplayLicense
       in =
         new BufferedReader(
           new InputStreamReader(
-            getClass().getResourceAsStream("COPYING-LESSER")));
+            getClass().getResourceAsStream("COPYING-LESSER"), StandardCharsets.UTF_8));
 
       while((s = in.readLine()) != null)
       {
diff --git a/src/main/java/org/sablecc/sablecc/GenAlts.java b/src/main/java/org/sablecc/sablecc/GenAlts.java
index 0809c35..08864ef 100644
--- a/src/main/java/org/sablecc/sablecc/GenAlts.java
+++ b/src/main/java/org/sablecc/sablecc/GenAlts.java
@@ -9,9 +9,10 @@ package org.sablecc.sablecc;
 
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -37,7 +38,7 @@ public class GenAlts extends DepthFirstAdapter
     {
       macros = new MacroExpander(
                  new InputStreamReader(
-                   getClass().getResourceAsStream("alternatives.txt")));
+                   getClass().getResourceAsStream("alternatives.txt"), StandardCharsets.UTF_8));
     }
     catch(IOException e)
     {
@@ -112,7 +113,7 @@ public class GenAlts extends DepthFirstAdapter
   {
     String name = ast_ids.ast_names.get(node);
 
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, name + ".java").toPath(), StandardCharsets.UTF_8))
     {
         boolean hasOperator = false;
         boolean hasList = false;
diff --git a/src/main/java/org/sablecc/sablecc/GenAnalyses.java b/src/main/java/org/sablecc/sablecc/GenAnalyses.java
index 45682f1..f56b61e 100644
--- a/src/main/java/org/sablecc/sablecc/GenAnalyses.java
+++ b/src/main/java/org/sablecc/sablecc/GenAnalyses.java
@@ -9,9 +9,10 @@ package org.sablecc.sablecc;
 
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
@@ -39,7 +40,7 @@ public class GenAnalyses extends DepthFirstAdapter
     {
       macros = new MacroExpander(
                  new InputStreamReader(
-                   getClass().getResourceAsStream("analyses.txt")));
+                   getClass().getResourceAsStream("analyses.txt"), StandardCharsets.UTF_8));
     }
     catch(IOException e)
     {
@@ -148,7 +149,7 @@ public class GenAnalyses extends DepthFirstAdapter
 
   public void createAnalysis()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Analysis.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "Analysis.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "AnalysisHeader", new String[] {ast_ids.astIds.pkgNameDot});
 
@@ -182,7 +183,7 @@ public class GenAnalyses extends DepthFirstAdapter
 
   public void createAnalysisAdapter()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "AnalysisAdapter.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "AnalysisAdapter.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "AnalysisAdapterHeader", new String[] {ast_ids.astIds.pkgNameDot});
 
@@ -214,7 +215,7 @@ public class GenAnalyses extends DepthFirstAdapter
 
   public void createDepthFirstAdapter()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "DepthFirstAdapter.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "DepthFirstAdapter.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "DepthFirstAdapterHeader", new String[] {ast_ids.astIds.pkgNameDot, mainProduction});
 
@@ -263,7 +264,7 @@ public class GenAnalyses extends DepthFirstAdapter
 
   public void createReversedDepthFirstAdapter()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "ReversedDepthFirstAdapter.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "ReversedDepthFirstAdapter.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "ReversedDepthFirstAdapterHeader", new String[] {ast_ids.astIds.pkgNameDot, mainProduction});
 
diff --git a/src/main/java/org/sablecc/sablecc/GenLexer.java b/src/main/java/org/sablecc/sablecc/GenLexer.java
index 8e9105b..d4b8e53 100644
--- a/src/main/java/org/sablecc/sablecc/GenLexer.java
+++ b/src/main/java/org/sablecc/sablecc/GenLexer.java
@@ -12,9 +12,10 @@ import java.io.BufferedWriter;
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -41,7 +42,7 @@ public class GenLexer extends AnalysisAdapter
     {
       macros = new MacroExpander(
                  new InputStreamReader(
-                   getClass().getResourceAsStream("lexer.txt")));
+                   getClass().getResourceAsStream("lexer.txt"), StandardCharsets.UTF_8));
     }
     catch(IOException e)
     {
@@ -111,7 +112,7 @@ public class GenLexer extends AnalysisAdapter
 
   private void createLexerException()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "LexerException.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "LexerException.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "LexerException", new String[] {ids.pkgNameDot});
     }
@@ -124,7 +125,7 @@ public class GenLexer extends AnalysisAdapter
 
   private void createLexer()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Lexer.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "Lexer.java").toPath(), StandardCharsets.UTF_8))
     {
       String startState = "INITIAL";
       if(ids.stateList.size() > 0)
diff --git a/src/main/java/org/sablecc/sablecc/GenParser.java b/src/main/java/org/sablecc/sablecc/GenParser.java
index b29b93b..20592f2 100644
--- a/src/main/java/org/sablecc/sablecc/GenParser.java
+++ b/src/main/java/org/sablecc/sablecc/GenParser.java
@@ -12,9 +12,10 @@ import java.io.BufferedWriter;
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Deque;
 import java.util.HashMap;
@@ -107,7 +108,7 @@ public class GenParser extends DepthFirstAdapter
     {
       macros = new MacroExpander(
                  new InputStreamReader(
-                   getClass().getResourceAsStream("parser.txt")));
+                   getClass().getResourceAsStream("parser.txt"), StandardCharsets.UTF_8));
     }
     catch(IOException e)
     {
@@ -366,7 +367,7 @@ public class GenParser extends DepthFirstAdapter
   //Parser.java Generation
   private void createParser()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Parser.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "Parser.java").toPath(), StandardCharsets.UTF_8))
     {
       Symbol[] terminals = Symbol.terminals();
       Symbol[] nonterminals = Symbol.nonterminals();
@@ -726,7 +727,7 @@ public class GenParser extends DepthFirstAdapter
 
   private void createTokenIndex()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "TokenIndex.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "TokenIndex.java").toPath(), StandardCharsets.UTF_8))
     {
       Symbol[] terminals = Symbol.terminals();
 
@@ -748,7 +749,7 @@ public class GenParser extends DepthFirstAdapter
 
   private void createParserException()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "ParserException.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "ParserException.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "ParserException", new String[] {ids.pkgNameDot});
     }
@@ -761,7 +762,7 @@ public class GenParser extends DepthFirstAdapter
 
   private void createState()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "State.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "State.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "State", new String[] {ids.pkgNameDot});
     }
diff --git a/src/main/java/org/sablecc/sablecc/GenProds.java b/src/main/java/org/sablecc/sablecc/GenProds.java
index a5da4d6..aea041b 100644
--- a/src/main/java/org/sablecc/sablecc/GenProds.java
+++ b/src/main/java/org/sablecc/sablecc/GenProds.java
@@ -9,9 +9,10 @@ package org.sablecc.sablecc;
 
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 
 import org.sablecc.sablecc.analysis.DepthFirstAdapter;
 import org.sablecc.sablecc.node.AAstProd;
@@ -30,7 +31,7 @@ public class GenProds extends DepthFirstAdapter
     {
       macros = new MacroExpander(
                  new InputStreamReader(
-                   getClass().getResourceAsStream("productions.txt")));
+                   getClass().getResourceAsStream("productions.txt"), StandardCharsets.UTF_8));
     }
     catch(IOException e)
     {
@@ -58,7 +59,7 @@ public class GenProds extends DepthFirstAdapter
 
   private void createProduction(String name)
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, name + ".java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "Production", new String[] {ast_ids.astIds.pkgNameDot, name});
     }
@@ -71,7 +72,7 @@ public class GenProds extends DepthFirstAdapter
 
   private void createAlternative(String name, String macro, String[] arg)
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, name + ".java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, macro, arg);
     }
diff --git a/src/main/java/org/sablecc/sablecc/GenTokens.java b/src/main/java/org/sablecc/sablecc/GenTokens.java
index 28e1eaf..eac6020 100644
--- a/src/main/java/org/sablecc/sablecc/GenTokens.java
+++ b/src/main/java/org/sablecc/sablecc/GenTokens.java
@@ -9,9 +9,10 @@ package org.sablecc.sablecc;
 
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.List;
 
 import org.sablecc.sablecc.analysis.DepthFirstAdapter;
@@ -34,7 +35,7 @@ public class GenTokens extends DepthFirstAdapter
     {
       macros = new MacroExpander(
                  new InputStreamReader(
-                   getClass().getResourceAsStream("tokens.txt")));
+                   getClass().getResourceAsStream("tokens.txt"), StandardCharsets.UTF_8));
     }
     catch(IOException e)
     {
@@ -93,7 +94,7 @@ public class GenTokens extends DepthFirstAdapter
       }
     }
 
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, name + ".java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, name + ".java").toPath(), StandardCharsets.UTF_8))
     {
       if(text == null)
       {
diff --git a/src/main/java/org/sablecc/sablecc/GenUtils.java b/src/main/java/org/sablecc/sablecc/GenUtils.java
index 4931081..10eed45 100644
--- a/src/main/java/org/sablecc/sablecc/GenUtils.java
+++ b/src/main/java/org/sablecc/sablecc/GenUtils.java
@@ -9,9 +9,10 @@ package org.sablecc.sablecc;
 
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 
 import org.sablecc.sablecc.analysis.DepthFirstAdapter;
 import org.sablecc.sablecc.node.AAstProd;
@@ -32,7 +33,7 @@ public class GenUtils extends DepthFirstAdapter
     {
       macros = new MacroExpander(
                  new InputStreamReader(
-                   getClass().getResourceAsStream("utils.txt")));
+                   getClass().getResourceAsStream("utils.txt"), StandardCharsets.UTF_8));
     }
     catch(IOException e)
     {
@@ -88,7 +89,7 @@ public class GenUtils extends DepthFirstAdapter
 
   public void createStart()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Start.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "Start.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "Start", new String[] {ast_ids.astIds.pkgNameDot, mainProduction, GenAlts.nodeName(mainProduction)});
     }
@@ -101,7 +102,7 @@ public class GenUtils extends DepthFirstAdapter
 
   public void createEOF()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "EOF.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "EOF.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "EOF", new String[] {ast_ids.astIds.pkgNameDot});
     }
@@ -114,7 +115,7 @@ public class GenUtils extends DepthFirstAdapter
 
   public void createNode()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Node.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "Node.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "Node", new String[] {ast_ids.astIds.pkgNameDot});
     }
@@ -127,7 +128,7 @@ public class GenUtils extends DepthFirstAdapter
 
   public void createToken()
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, "Token.java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, "Token.java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, "Token", new String[] {ast_ids.astIds.pkgNameDot});
     }
@@ -140,7 +141,7 @@ public class GenUtils extends DepthFirstAdapter
 
   public void create(String cls)
   {
-    try(BufferedWriter file = new BufferedWriter(new FileWriter(new File(pkgDir, cls + ".java"))))
+    try(BufferedWriter file = Files.newBufferedWriter(new File(pkgDir, cls + ".java").toPath(), StandardCharsets.UTF_8))
     {
       macros.apply(file, cls, new String[] {ast_ids.astIds.pkgNameDot});
     }
diff --git a/src/main/java/org/sablecc/sablecc/SableCC.java b/src/main/java/org/sablecc/sablecc/SableCC.java
index 2ed2bb3..be66d89 100644
--- a/src/main/java/org/sablecc/sablecc/SableCC.java
+++ b/src/main/java/org/sablecc/sablecc/SableCC.java
@@ -7,10 +7,12 @@
 
 package org.sablecc.sablecc;
 
+import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.PushbackReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -186,13 +188,14 @@ public class SableCC {
     System.out.println("\n -- Generating parser for " + in.getName()
         + " in " + dir.getPath());
 
-    FileReader temp = new FileReader(in);
-
     // Build the AST
-    Start tree = new Parser(new Lexer(new PushbackReader(
-        temp = new FileReader(in), 1000))).parse();
-
-    temp.close();
+    Start tree;
+    try (
+      BufferedReader temp = Files.newBufferedReader(in.toPath(), StandardCharsets.UTF_8);
+      PushbackReader reader = new PushbackReader(temp, 1000);
+    ) {
+      tree = new Parser(new Lexer(reader)).parse();
+    }
 
     boolean hasTransformations = false;
 
-- 
GitLab