--- antlr3-3.5.3/tool/src/main/antlr3/org/antlr/grammar/v3/CodeGenTreeWalker.g 2023-09-15 20:06:39.620275234 +0200 +++ antlr3-3.5.3/tool/src/main/antlr3/org/antlr/grammar/v3/CodeGenTreeWalker.g 2023-09-15 20:07:19.236138007 +0200 @@ -56,6 +56,7 @@ import java.util.HashSet; import java.util.Set; import java.util.Collection; +import java.util.Collections; import org.antlr.runtime.BitSet; import org.antlr.runtime.DFA; import org.stringtemplate.v4.ST; @@ -284,6 +285,7 @@ } labels.add( label ); } + Collections.sort(labels); // ensure reproducible order return labels; } --- antlr3-3.5.3/tool/src/main/java/org/antlr/codegen/ACyclicDFACodeGenerator.java 2023-09-15 20:06:39.623608500 +0200 +++ antlr3-3.5.3/tool/src/main/java/org/antlr/codegen/ACyclicDFACodeGenerator.java 2023-09-16 06:04:09.530338104 +0200 @@ -33,6 +33,7 @@ import org.stringtemplate.v4.ST; import org.stringtemplate.v4.STGroup; +import java.util.Collections; import java.util.List; public class ACyclicDFACodeGenerator { @@ -114,6 +115,7 @@ // If the template wants all the label values delineated, do that if ( edgeST.impl.formalArguments.get("labels")!=null ) { List labels = edge.label.getSet().toList(); + Collections.sort(labels); List targetLabels = new ArrayList(labels.size()); for (int j = 0; j < labels.size(); j++) { Integer vI = labels.get(j); --- antlr3-3.5.3/tool/src/main/java/org/antlr/codegen/CodeGenerator.java 2023-09-15 20:06:39.623608500 +0200 +++ antlr3-3.5.3/tool/src/main/java/org/antlr/codegen/CodeGenerator.java 2023-09-16 06:02:44.522033399 +0200 @@ -587,6 +588,7 @@ BitSet bits = BitSet.of(follow.tokenTypeSet); words = bits.toPackedArray(); tokenTypeList = follow.tokenTypeSet.toList(); + Collections.sort(tokenTypeList); } // use the target to convert to hex strings (typically) String[] wordStrings = new String[words.length];