diff --git a/runtime/Java/src/org/antlr/v4/runtime/Vocabulary.java b/runtime/Java/src/org/antlr/v4/runtime/Vocabulary.java
index 0b6386c8e..46c4af1f7 100644
--- a/runtime/Java/src/org/antlr/v4/runtime/Vocabulary.java
+++ b/runtime/Java/src/org/antlr/v4/runtime/Vocabulary.java
@@ -37,6 +37,14 @@ package org.antlr.v4.runtime;
* @author Sam Harwell
*/
public interface Vocabulary {
+
+ /**
+ * Returns the highest token type value. It can be used to iterate from
+ * zero to that number, thus querying all stored entries.
+ * @return the highest token type value
+ */
+ int getMaxTokenType();
+
/**
* Gets the string literal associated with a token type. The string returned
* by this method, when not {@code null}, can be used unaltered in a parser
@@ -85,7 +93,7 @@ public interface Vocabulary {
*
*
* - Tokens created by lexer rules.
- * - Tokens defined in a {@code tokens{}} block in a lexer or parser
+ *
- Tokens defined in a
tokens{}
block in a lexer or parser
* grammar.
* - The implicitly defined {@code EOF} token, which has the token type
* {@link Token#EOF}.
diff --git a/runtime/Java/src/org/antlr/v4/runtime/VocabularyImpl.java b/runtime/Java/src/org/antlr/v4/runtime/VocabularyImpl.java
index ff5beefe2..75833ec2c 100644
--- a/runtime/Java/src/org/antlr/v4/runtime/VocabularyImpl.java
+++ b/runtime/Java/src/org/antlr/v4/runtime/VocabularyImpl.java
@@ -57,6 +57,8 @@ public class VocabularyImpl implements Vocabulary {
private final String[] displayNames;
+ private final int maxTokenType;
+
/**
* Constructs a new instance of {@link VocabularyImpl} from the specified
* literal and symbolic token names.
@@ -94,6 +96,8 @@ public class VocabularyImpl implements Vocabulary {
this.literalNames = literalNames != null ? literalNames : EMPTY_NAMES;
this.symbolicNames = symbolicNames != null ? symbolicNames : EMPTY_NAMES;
this.displayNames = displayNames != null ? displayNames : EMPTY_NAMES;
+ this.maxTokenType = Math.max(this.displayNames.length,
+ Math.max(this.literalNames.length, this.symbolicNames.length));
}
/**
@@ -143,6 +147,11 @@ public class VocabularyImpl implements Vocabulary {
return new VocabularyImpl(literalNames, symbolicNames, tokenNames);
}
+ @Override
+ public int getMaxTokenType() {
+ return maxTokenType;
+ }
+
@Override
public String getLiteralName(int tokenType) {
if (tokenType >= 0 && tokenType < literalNames.length) {