This is an automated email from the ASF dual-hosted git repository.

dlmarion pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo-access.git


The following commit(s) were added to refs/heads/main by this push:
     new 5870821  Migrate to multi-module project to separate examples (#92)
5870821 is described below

commit 587082171a7658c07c0ec1254941d0a4f8797a42
Author: Dave Marion <[email protected]>
AuthorDate: Fri Dec 19 12:41:37 2025 -0500

    Migrate to multi-module project to separate examples (#92)
---
 README.md                                          |  34 +-
 .../antlr4-example => antlr4-example}/.gitignore   |   0
 .../it/antlr4-example => antlr4-example}/README.md |  15 +-
 antlr4-example/pom.xml                             | 179 ++++++
 .../src/main/antlr4/Abnf.g4                        |   0
 .../src/main/antlr4/AccessExpression.g4            |   0
 .../apache/accumulo/access/grammars/Abnf.interp    |  49 ++
 .../apache/accumulo/access/grammars/Abnf.tokens    |  21 +
 .../accumulo/access/grammars/AbnfLexer.interp      |  66 +++
 .../apache/accumulo/access/grammars/AbnfLexer.java | 244 ++++++++
 .../accumulo/access/grammars/AbnfLexer.tokens      |  21 +
 .../accumulo/access/grammars/AbnfParser.java       | 658 +++++++++++++++++++++
 .../access/grammars/AccessExpression.interp        |  30 +
 .../access/grammars/AccessExpression.tokens        |  10 +
 .../access/grammars/AccessExpressionLexer.interp   |  35 ++
 .../access/grammars/AccessExpressionLexer.java     | 149 +++++
 .../access/grammars/AccessExpressionLexer.tokens   |  10 +
 .../access/grammars/AccessExpressionParser.java    | 567 ++++++++++++++++++
 .../src}/main/java/module-info.java                |   7 +-
 .../antlr4}/AccessExpressionAntlrEvaluator.java    |   3 +-
 .../antlr4}/AccessExpressionAntlrParser.java       |   4 +-
 .../accumulo/access/antlr/TestDataLoader.java      |  22 +-
 .../accumulo/access/grammar/SpecificationTest.java |   5 +-
 .../antlr/AccessExpressionAntlrBenchmark.java      |   8 +-
 .../accumulo/access/grammar/antlr/Antlr4Tests.java |   7 +-
 core/pom.xml                                       | 125 ++++
 {src => core/src}/main/java/module-info.java       |   2 +-
 .../apache/accumulo/access/AccessEvaluator.java    |   0
 .../apache/accumulo/access/AccessExpression.java   |   0
 .../org/apache/accumulo/access/Authorizations.java |   0
 .../access/InvalidAccessExpressionException.java   |   0
 .../accumulo/access/ParsedAccessExpression.java    |   0
 .../accumulo/access/impl/AccessEvaluatorImpl.java  |   0
 .../accumulo/access/impl/AccessExpressionImpl.java |   0
 .../org/apache/accumulo/access/impl/ByteUtils.java |   0
 .../apache/accumulo/access/impl/BytesWrapper.java  |   0
 .../access/impl/MultiAccessEvaluatorImpl.java      |   0
 .../access/impl/ParsedAccessExpressionImpl.java    |   0
 .../accumulo/access/impl/ParserEvaluator.java      |   0
 .../org/apache/accumulo/access/impl/Tokenizer.java |   0
 .../access/specification/AccessExpression.abnf     |   0
 .../accumulo/access/tests/AccessEvaluatorTest.java |   0
 .../access/tests/AccessExpressionBenchmark.java    |   0
 .../access/tests/AccessExpressionTest.java         |  14 +-
 .../accumulo/access/tests/AuthorizationTest.java   |   0
 .../access/tests/ParsedAccessExpressionTest.java   |   0
 src/it/settings.xml => examples/pom.xml            |  56 +-
 {src => examples/src}/main/java/module-info.java   |   5 +-
 .../accumulo/access/examples}/AccessExample.java   |  27 +-
 .../accumulo/access/examples}/ParseExamples.java   |   4 +-
 .../access/examples/test}/AccessExampleTest.java   |   7 +-
 .../access/examples/test}/ParseExamplesTest.java   |   5 +-
 pom.xml                                            | 204 +++----
 src/it/antlr4-example/invoker.properties           |  23 -
 src/it/antlr4-example/pom.xml                      | 102 ----
 55 files changed, 2339 insertions(+), 379 deletions(-)

diff --git a/README.md b/README.md
index 702fad9..34e2295 100644
--- a/README.md
+++ b/README.md
@@ -35,12 +35,12 @@ section](#getting-started) for an example of how to use 
this java library.
 The following types constitute the public API of this library. All other types
 are package private and are not part of the public API.
 
-  * 
[InvalidAccessExpressionException](src/main/java/org/apache/accumulo/access/InvalidAccessExpressionException.java).
-  * 
[AccessEvaluator](src/main/java/org/apache/accumulo/access/AccessEvaluator.java).
-  * 
[AccessExpression](src/main/java/org/apache/accumulo/access/AccessExpression.java).
-  * 
[ParsedAccessExpression](src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java).
-  * 
[ExpressionType](src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java).
-  * 
[Authorizations](src/main/java/org/apache/accumulo/access/Authorizations.java).
+  * 
[InvalidAccessExpressionException](core/src/main/java/org/apache/accumulo/access/InvalidAccessExpressionException.java).
+  * 
[AccessEvaluator](core/src/main/java/org/apache/accumulo/access/AccessEvaluator.java).
+  * 
[AccessExpression](core/src/main/java/org/apache/accumulo/access/AccessExpression.java).
+  * 
[ParsedAccessExpression](core/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java).
+  * 
[ExpressionType](core/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java).
+  * 
[Authorizations](core/src/main/java/org/apache/accumulo/access/Authorizations.java).
 
 ## Getting Started
 
@@ -56,39 +56,37 @@ Add the library to your CLASSPATH. For Maven, use:
 </dependencies>
 ```
 
-## Running the [Examples](src/test/java/example)
+## Running the [Examples](examples/src/main/java)
 
-To run [AccessExample](src/test/java/example/AccessExample.java)
+To run 
[AccessExample](examples/src/main/java/org/apache/accumulo/access/examples/AccessExample.java)
 
 ```
 mvn clean package
 
-java --module-path=$(ls target/accumulo-access-*.jar) 
--add-modules=accumulo.access src/test/java/example/AccessExample.java
-java --module-path=$(ls target/accumulo-access-*.jar) 
--add-modules=accumulo.access src/test/java/example/AccessExample.java RED BLUE
+java 
--module-path=core/target/accumulo-access-core-1.0.0-SNAPSHOT.jar:examples/target/accumulo-access-examples-1.0.0-SNAPSHOT.jar
  
--module=accumulo.access.examples/org.apache.accumulo.access.examples.AccessExample
+java 
--module-path=core/target/accumulo-access-core-1.0.0-SNAPSHOT.jar:examples/target/accumulo-access-examples-1.0.0-SNAPSHOT.jar
  
--module=accumulo.access.examples/org.apache.accumulo.access.examples.AccessExample
 RED BLUE
 ```
 
 Note that `data6` is always returned, because it has no access expression. And
 remember, authorizations are case-sensitive.
 
-To run [ParseExamples](src/test/java/example/ParseExamples.java)
+To run 
[ParseExamples](examples/src/main/java/org/apache/accumulo/access/examples/ParseExamples.java)
 
 ```
 mvn clean package
-java --module-path=$(ls target/accumulo-access-*.jar) 
--add-modules=accumulo.access src/test/java/example/ParseExamples.java
+java 
--module-path=core/target/accumulo-access-core-1.0.0-SNAPSHOT.jar:examples/target/accumulo-access-examples-1.0.0-SNAPSHOT.jar
 
--module=accumulo.access.examples/org.apache.accumulo.access.examples.ParseExamples
 ```
 
-
-For an ANTLRv4 example, see antlr-example integration test's
-[README](src/it/antlr4-example/README.md).
+For an ANTLRv4 example, see its [README](antlr4-example/README.md).
 
 ## Running the Benchmark
 
 This project includes a JMH Benchmark. To run it:
 
 ```
-mvn clean verify -Pbenchmark
+mvn clean verify -pl core -Pbenchmark
 ```
 
 
-[1]: 
https://github.com/apache/accumulo/blob/rel/2.1.2/core/src/main/java/org/apache/accumulo/core/security/ColumnVisibility.java
-[2]: 
https://github.com/apache/accumulo/blob/rel/2.1.2/core/src/main/java/org/apache/accumulo/core/security/VisibilityEvaluator.java
+[1]: 
https://github.com/apache/accumulo/blob/rel/2.1.4/core/src/main/java/org/apache/accumulo/core/security/ColumnVisibility.java
+[2]: 
https://github.com/apache/accumulo/blob/rel/2.1.4/core/src/main/java/org/apache/accumulo/core/security/VisibilityEvaluator.java
diff --git a/src/it/antlr4-example/.gitignore b/antlr4-example/.gitignore
similarity index 100%
rename from src/it/antlr4-example/.gitignore
rename to antlr4-example/.gitignore
diff --git a/src/it/antlr4-example/README.md b/antlr4-example/README.md
similarity index 75%
rename from src/it/antlr4-example/README.md
rename to antlr4-example/README.md
index 1c0d971..1da42d1 100644
--- a/src/it/antlr4-example/README.md
+++ b/antlr4-example/README.md
@@ -33,21 +33,16 @@ it doesn't parse as fast as the custom implementation. You 
can view the
 performance differences by running the JMH benchmark in this antlr4-example 
project
 and the one in the main project.
 
-To run the benchmark in this project, first build the main project using:
+To run the benchmark in this project execute the following commands at the top 
level
+of the project:
 
 ```
 mvn clean install
-```
-
-Then, switch to the cloned directory for this example, and run the benchmark
-command:
+mvn clean verify -pl antlr4-example -Pbenchmark
 
-```
-cd target/its/antlr4-example/
-mvn exec:exec -Dexec.executable="java" -Dexec.classpathScope=test 
-Dexec.args="-classpath %classpath 
org.apache.accumulo.access.grammar.antlr.AccessExpressionAntlrBenchmark"
 ```
 
 [1]: https://www.antlr.org
 [2]: src/main/antlr4/AccessExpression.g4
-[3]: 
src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrParser.java
-[4]: 
src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
+[3]: 
src/main/java/org/apache/accumulo/access/grammar/antlr4/AccessExpressionAntlrParser.java
+[4]: 
src/main/java/org/apache/accumulo/access/grammar/antlr4/AccessExpressionAntlrEvaluator.java
diff --git a/antlr4-example/pom.xml b/antlr4-example/pom.xml
new file mode 100644
index 0000000..daa2966
--- /dev/null
+++ b/antlr4-example/pom.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      https://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.accumulo</groupId>
+    <artifactId>accumulo-access</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>accumulo-access-antlr4-example</artifactId>
+  <packaging>jar</packaging>
+  <properties>  
+    <checkstyle.skip>true</checkstyle.skip>
+    <formatter.skip>true</formatter.skip>
+    <impsort.skip>true</impsort.skip>
+    <modernizer.skip>true</modernizer.skip>
+    <sort.skip>true</sort.skip>
+    <spotbugs.skip>true</spotbugs.skip>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.antlr</groupId>
+      <artifactId>antlr4-runtime</artifactId>
+      <version>4.13.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-access-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.openjdk.jmh</groupId>
+      <artifactId>jmh-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.openjdk.jmh</groupId>
+      <artifactId>jmh-generator-annprocess</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.antlr</groupId>
+        <artifactId>antlr4-maven-plugin</artifactId>
+        <version>4.13.1</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>antlr4</goal>
+            </goals>
+            <phase>generate-sources</phase>
+            <configuration>
+              <arguments>
+                <arg>-o</arg>
+                
<arg>${project.basedir}/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars</arg>
+                <arg>-package</arg>
+                <arg>org.apache.accumulo.access.grammars</arg>
+              </arguments>
+              <listener>false</listener>
+              <visitor>false</visitor>
+              
<outputDirectory>${project.basedir}/src/main/generated-antlr4-sources</outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-abnf-test-resources</id>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <phase>process-test-resources</phase>
+            <configuration>
+              
<outputDirectory>${project.basedir}/target/test-classes</outputDirectory>
+              <resources>
+                <resource>
+                  
<directory>${maven.multiModuleProjectDirectory}/core/src/main/resources/org/apache/accumulo/access/specification</directory>
+                  <filtering>false</filtering>
+                  <includes>
+                    <include>AccessExpression.abnf</include>
+                  </includes>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>3.5.0</version>
+        <executions>
+          <execution>
+            <id>add-antlr4-sources</id>
+            <goals>
+              <goal>add-source</goal>
+            </goals>
+            <phase>process-sources</phase>
+            <configuration>
+              <sources>
+                
<source>${project.basedir}/src/main/antlr4/generated-antlr4-sources</source>
+              </sources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>benchmark</id>
+      <activation>
+        <property>
+          <name>benchmark</name>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>exec-maven-plugin</artifactId>
+            <version>3.3.0</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <phase>verify</phase>
+                <configuration>
+                  <classpathScope>test</classpathScope>
+                  <executable>java</executable>
+                  <arguments>
+                    <argument>-classpath</argument>
+                    <classpath />
+                    
<argument>org.apache.accumulo.access.grammar.antlr.AccessExpressionAntlrBenchmark</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles> 
+</project>
diff --git a/src/it/antlr4-example/src/main/antlr4/Abnf.g4 
b/antlr4-example/src/main/antlr4/Abnf.g4
similarity index 100%
rename from src/it/antlr4-example/src/main/antlr4/Abnf.g4
rename to antlr4-example/src/main/antlr4/Abnf.g4
diff --git a/src/it/antlr4-example/src/main/antlr4/AccessExpression.g4 
b/antlr4-example/src/main/antlr4/AccessExpression.g4
similarity index 100%
rename from src/it/antlr4-example/src/main/antlr4/AccessExpression.g4
rename to antlr4-example/src/main/antlr4/AccessExpression.g4
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/Abnf.interp
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/Abnf.interp
new file mode 100644
index 0000000..3a5e404
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/Abnf.interp
@@ -0,0 +1,49 @@
+token literal names:
+null
+'='
+'/'
+'*'
+'('
+')'
+'['
+']'
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+NumberValue
+ProseValue
+ID
+INT
+COMMENT
+WS
+STRING
+
+rule names:
+rulelist
+rule_
+elements
+alternation
+concatenation
+repetition
+repeat_
+element
+group
+option
+
+
+atn:
+[4, 1, 14, 82, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 
5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 1, 0, 5, 0, 22, 8, 0, 
10, 0, 12, 0, 25, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 32, 8, 1, 1, 1, 1, 
1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 5, 3, 41, 8, 3, 10, 3, 12, 3, 44, 9, 3, 1, 4, 
4, 4, 47, 8, 4, 11, 4, 12, 4, 48, 1, 5, 3, 5, 52, 8, 5, 1, 5, 1, 5, 1, 6, 1, 6, 
3, 6, 58, 8, 6, 1, 6, 1, 6, 3, 6, 62, 8, 6, 3, 6, 64, 8, 6, 1, 7, 1, 7, 1, 7, 
1, 7, 1, 7, 1, 7, 3 [...]
\ No newline at end of file
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/Abnf.tokens
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/Abnf.tokens
new file mode 100644
index 0000000..db19df3
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/Abnf.tokens
@@ -0,0 +1,21 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+NumberValue=8
+ProseValue=9
+ID=10
+INT=11
+COMMENT=12
+WS=13
+STRING=14
+'='=1
+'/'=2
+'*'=3
+'('=4
+')'=5
+'['=6
+']'=7
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.interp
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.interp
new file mode 100644
index 0000000..55a9821
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.interp
@@ -0,0 +1,66 @@
+token literal names:
+null
+'='
+'/'
+'*'
+'('
+')'
+'['
+']'
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+NumberValue
+ProseValue
+ID
+INT
+COMMENT
+WS
+STRING
+
+rule names:
+T__0
+T__1
+T__2
+T__3
+T__4
+T__5
+T__6
+NumberValue
+BinaryValue
+DecimalValue
+HexValue
+ProseValue
+ID
+INT
+COMMENT
+WS
+STRING
+LETTER
+BIT
+DIGIT
+HEX_DIGIT
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 14, 199, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 
7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 
2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 
16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 1, 0, 1, 0, 1, 1, 
1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 
1, 7, 1, 7, 3, 7, 62, 8, 7, 1, 8, 1, 8, 4, 8, 66, 8, 8, 11, 8, 12, 8, 67, 1, 8, 
1, 8, 4, 8, 72, 8,  [...]
\ No newline at end of file
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.java
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.java
new file mode 100644
index 0000000..97bf4bc
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.java
@@ -0,0 +1,244 @@
+// Generated from Abnf.g4 by ANTLR 4.13.1
+package org.apache.accumulo.access.grammars;
+import org.antlr.v4.runtime.Lexer;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.misc.*;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", 
"CheckReturnValue", "this-escape"})
+public class AbnfLexer extends Lexer {
+       static { RuntimeMetaData.checkVersion("4.13.1", 
RuntimeMetaData.VERSION); }
+
+       protected static final DFA[] _decisionToDFA;
+       protected static final PredictionContextCache _sharedContextCache =
+               new PredictionContextCache();
+       public static final int
+               T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, 
NumberValue=8, 
+               ProseValue=9, ID=10, INT=11, COMMENT=12, WS=13, STRING=14;
+       public static String[] channelNames = {
+               "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
+       };
+
+       public static String[] modeNames = {
+               "DEFAULT_MODE"
+       };
+
+       private static String[] makeRuleNames() {
+               return new String[] {
+                       "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", 
"NumberValue", 
+                       "BinaryValue", "DecimalValue", "HexValue", 
"ProseValue", "ID", "INT", 
+                       "COMMENT", "WS", "STRING", "LETTER", "BIT", "DIGIT", 
"HEX_DIGIT"
+               };
+       }
+       public static final String[] ruleNames = makeRuleNames();
+
+       private static String[] makeLiteralNames() {
+               return new String[] {
+                       null, "'='", "'/'", "'*'", "'('", "')'", "'['", "']'"
+               };
+       }
+       private static final String[] _LITERAL_NAMES = makeLiteralNames();
+       private static String[] makeSymbolicNames() {
+               return new String[] {
+                       null, null, null, null, null, null, null, null, 
"NumberValue", "ProseValue", 
+                       "ID", "INT", "COMMENT", "WS", "STRING"
+               };
+       }
+       private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
+       public static final Vocabulary VOCABULARY = new 
VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+       /**
+        * @deprecated Use {@link #VOCABULARY} instead.
+        */
+       @Deprecated
+       public static final String[] tokenNames;
+       static {
+               tokenNames = new String[_SYMBOLIC_NAMES.length];
+               for (int i = 0; i < tokenNames.length; i++) {
+                       tokenNames[i] = VOCABULARY.getLiteralName(i);
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = VOCABULARY.getSymbolicName(i);
+                       }
+
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = "<INVALID>";
+                       }
+               }
+       }
+
+       @Override
+       @Deprecated
+       public String[] getTokenNames() {
+               return tokenNames;
+       }
+
+       @Override
+
+       public Vocabulary getVocabulary() {
+               return VOCABULARY;
+       }
+
+
+       public AbnfLexer(CharStream input) {
+               super(input);
+               _interp = new 
LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+       }
+
+       @Override
+       public String getGrammarFileName() { return "Abnf.g4"; }
+
+       @Override
+       public String[] getRuleNames() { return ruleNames; }
+
+       @Override
+       public String getSerializedATN() { return _serializedATN; }
+
+       @Override
+       public String[] getChannelNames() { return channelNames; }
+
+       @Override
+       public String[] getModeNames() { return modeNames; }
+
+       @Override
+       public ATN getATN() { return _ATN; }
+
+       public static final String _serializedATN =
+               
"\u0004\u0000\u000e\u00c7\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+
+               
"\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+
+               
"\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+
+               
"\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+
+               
"\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+
+               
"\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+
+               
"\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+
+               
"\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002"+
+               
"\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005"+
+               
"\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
+               
"\u0003\u0007>\b\u0007\u0001\b\u0001\b\u0004\bB\b\b\u000b\b\f\bC\u0001"+
+               
"\b\u0001\b\u0004\bH\b\b\u000b\b\f\bI\u0004\bL\b\b\u000b\b\f\bM\u0001\b"+
+               
"\u0001\b\u0004\bR\b\b\u000b\b\f\bS\u0003\bV\b\b\u0001\t\u0001\t\u0004"+
+               
"\tZ\b\t\u000b\t\f\t[\u0001\t\u0001\t\u0004\t`\b\t\u000b\t\f\ta\u0004\t"+
+               
"d\b\t\u000b\t\f\te\u0001\t\u0001\t\u0004\tj\b\t\u000b\t\f\tk\u0003\tn"+
+               
"\b\t\u0001\n\u0001\n\u0004\nr\b\n\u000b\n\f\ns\u0001\n\u0001\n\u0004\n"+
+               
"x\b\n\u000b\n\f\ny\u0004\n|\b\n\u000b\n\f\n}\u0001\n\u0001\n\u0004\n\u0082"+
+               
"\b\n\u000b\n\f\n\u0083\u0003\n\u0086\b\n\u0001\u000b\u0001\u000b\u0005"+
+               
"\u000b\u008a\b\u000b\n\u000b\f\u000b\u008d\t\u000b\u0001\u000b\u0001\u000b"+
+               
"\u0001\f\u0001\f\u0001\f\u0001\f\u0005\f\u0095\b\f\n\f\f\f\u0098\t\f\u0001"+
+               
"\r\u0004\r\u009b\b\r\u000b\r\f\r\u009c\u0001\u000e\u0001\u000e\u0005\u000e"+
+               
"\u00a1\b\u000e\n\u000e\f\u000e\u00a4\t\u000e\u0001\u000e\u0003\u000e\u00a7"+
+               
"\b\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001"+
+               
"\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001"+
+               
"\u0010\u0003\u0010\u00b5\b\u0010\u0001\u0010\u0001\u0010\u0005\u0010\u00b9"+
+               
"\b\u0010\n\u0010\f\u0010\u00bc\t\u0010\u0001\u0010\u0001\u0010\u0001\u0011"+
+               
"\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0014"+
+               
"\u0001\u0014\u0000\u0000\u0015\u0001\u0001\u0003\u0002\u0005\u0003\u0007"+
+               
"\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\u0000\u0013\u0000\u0015"+
+               
"\u0000\u0017\t\u0019\n\u001b\u000b\u001d\f\u001f\r!\u000e#\u0000%\u0000"+
+               
"\'\u0000)\u0000\u0001\u0000\u0006\u0001\u0000>>\u0002\u0000\n\n\r\r\u0003"+
+               "\u0000\t\n\r\r  
\u0001\u0000\"\"\u0002\u0000AZaz\u0003\u000009AFaf\u00dd"+
+               
"\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000"+
+               
"\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000"+
+               
"\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000"+
+               
"\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0017"+
+               
"\u0001\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b"+
+               
"\u0001\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f"+
+               
"\u0001\u0000\u0000\u0000\u0000!\u0001\u0000\u0000\u0000\u0001+\u0001\u0000"+
+               
"\u0000\u0000\u0003-\u0001\u0000\u0000\u0000\u0005/\u0001\u0000\u0000\u0000"+
+               
"\u00071\u0001\u0000\u0000\u0000\t3\u0001\u0000\u0000\u0000\u000b5\u0001"+
+               
"\u0000\u0000\u0000\r7\u0001\u0000\u0000\u0000\u000f9\u0001\u0000\u0000"+
+               
"\u0000\u0011?\u0001\u0000\u0000\u0000\u0013W\u0001\u0000\u0000\u0000\u0015"+
+               
"o\u0001\u0000\u0000\u0000\u0017\u0087\u0001\u0000\u0000\u0000\u0019\u0090"+
+               
"\u0001\u0000\u0000\u0000\u001b\u009a\u0001\u0000\u0000\u0000\u001d\u009e"+
+               
"\u0001\u0000\u0000\u0000\u001f\u00ac\u0001\u0000\u0000\u0000!\u00b4\u0001"+
+               
"\u0000\u0000\u0000#\u00bf\u0001\u0000\u0000\u0000%\u00c1\u0001\u0000\u0000"+
+               
"\u0000\'\u00c3\u0001\u0000\u0000\u0000)\u00c5\u0001\u0000\u0000\u0000"+
+               
"+,\u0005=\u0000\u0000,\u0002\u0001\u0000\u0000\u0000-.\u0005/\u0000\u0000"+
+               
".\u0004\u0001\u0000\u0000\u0000/0\u0005*\u0000\u00000\u0006\u0001\u0000"+
+               
"\u0000\u000012\u0005(\u0000\u00002\b\u0001\u0000\u0000\u000034\u0005)"+
+               
"\u0000\u00004\n\u0001\u0000\u0000\u000056\u0005[\u0000\u00006\f\u0001"+
+               
"\u0000\u0000\u000078\u0005]\u0000\u00008\u000e\u0001\u0000\u0000\u0000"+
+               
"9=\u0005%\u0000\u0000:>\u0003\u0011\b\u0000;>\u0003\u0013\t\u0000<>\u0003"+
+               
"\u0015\n\u0000=:\u0001\u0000\u0000\u0000=;\u0001\u0000\u0000\u0000=<\u0001"+
+               
"\u0000\u0000\u0000>\u0010\u0001\u0000\u0000\u0000?A\u0005b\u0000\u0000"+
+               
"@B\u0003%\u0012\u0000A@\u0001\u0000\u0000\u0000BC\u0001\u0000\u0000\u0000"+
+               
"CA\u0001\u0000\u0000\u0000CD\u0001\u0000\u0000\u0000DU\u0001\u0000\u0000"+
+               
"\u0000EG\u0005.\u0000\u0000FH\u0003%\u0012\u0000GF\u0001\u0000\u0000\u0000"+
+               
"HI\u0001\u0000\u0000\u0000IG\u0001\u0000\u0000\u0000IJ\u0001\u0000\u0000"+
+               
"\u0000JL\u0001\u0000\u0000\u0000KE\u0001\u0000\u0000\u0000LM\u0001\u0000"+
+               
"\u0000\u0000MK\u0001\u0000\u0000\u0000MN\u0001\u0000\u0000\u0000NV\u0001"+
+               
"\u0000\u0000\u0000OQ\u0005-\u0000\u0000PR\u0003%\u0012\u0000QP\u0001\u0000"+
+               
"\u0000\u0000RS\u0001\u0000\u0000\u0000SQ\u0001\u0000\u0000\u0000ST\u0001"+
+               
"\u0000\u0000\u0000TV\u0001\u0000\u0000\u0000UK\u0001\u0000\u0000\u0000"+
+               
"UO\u0001\u0000\u0000\u0000UV\u0001\u0000\u0000\u0000V\u0012\u0001\u0000"+
+               
"\u0000\u0000WY\u0005d\u0000\u0000XZ\u0003\'\u0013\u0000YX\u0001\u0000"+
+               
"\u0000\u0000Z[\u0001\u0000\u0000\u0000[Y\u0001\u0000\u0000\u0000[\\\u0001"+
+               
"\u0000\u0000\u0000\\m\u0001\u0000\u0000\u0000]_\u0005.\u0000\u0000^`\u0003"+
+               
"\'\u0013\u0000_^\u0001\u0000\u0000\u0000`a\u0001\u0000\u0000\u0000a_\u0001"+
+               
"\u0000\u0000\u0000ab\u0001\u0000\u0000\u0000bd\u0001\u0000\u0000\u0000"+
+               
"c]\u0001\u0000\u0000\u0000de\u0001\u0000\u0000\u0000ec\u0001\u0000\u0000"+
+               
"\u0000ef\u0001\u0000\u0000\u0000fn\u0001\u0000\u0000\u0000gi\u0005-\u0000"+
+               
"\u0000hj\u0003\'\u0013\u0000ih\u0001\u0000\u0000\u0000jk\u0001\u0000\u0000"+
+               
"\u0000ki\u0001\u0000\u0000\u0000kl\u0001\u0000\u0000\u0000ln\u0001\u0000"+
+               
"\u0000\u0000mc\u0001\u0000\u0000\u0000mg\u0001\u0000\u0000\u0000mn\u0001"+
+               
"\u0000\u0000\u0000n\u0014\u0001\u0000\u0000\u0000oq\u0005x\u0000\u0000"+
+               
"pr\u0003)\u0014\u0000qp\u0001\u0000\u0000\u0000rs\u0001\u0000\u0000\u0000"+
+               
"sq\u0001\u0000\u0000\u0000st\u0001\u0000\u0000\u0000t\u0085\u0001\u0000"+
+               
"\u0000\u0000uw\u0005.\u0000\u0000vx\u0003)\u0014\u0000wv\u0001\u0000\u0000"+
+               
"\u0000xy\u0001\u0000\u0000\u0000yw\u0001\u0000\u0000\u0000yz\u0001\u0000"+
+               
"\u0000\u0000z|\u0001\u0000\u0000\u0000{u\u0001\u0000\u0000\u0000|}\u0001"+
+               
"\u0000\u0000\u0000}{\u0001\u0000\u0000\u0000}~\u0001\u0000\u0000\u0000"+
+               
"~\u0086\u0001\u0000\u0000\u0000\u007f\u0081\u0005-\u0000\u0000\u0080\u0082"+
+               
"\u0003)\u0014\u0000\u0081\u0080\u0001\u0000\u0000\u0000\u0082\u0083\u0001"+
+               
"\u0000\u0000\u0000\u0083\u0081\u0001\u0000\u0000\u0000\u0083\u0084\u0001"+
+               
"\u0000\u0000\u0000\u0084\u0086\u0001\u0000\u0000\u0000\u0085{\u0001\u0000"+
+               
"\u0000\u0000\u0085\u007f\u0001\u0000\u0000\u0000\u0085\u0086\u0001\u0000"+
+               
"\u0000\u0000\u0086\u0016\u0001\u0000\u0000\u0000\u0087\u008b\u0005<\u0000"+
+               
"\u0000\u0088\u008a\b\u0000\u0000\u0000\u0089\u0088\u0001\u0000\u0000\u0000"+
+               
"\u008a\u008d\u0001\u0000\u0000\u0000\u008b\u0089\u0001\u0000\u0000\u0000"+
+               
"\u008b\u008c\u0001\u0000\u0000\u0000\u008c\u008e\u0001\u0000\u0000\u0000"+
+               
"\u008d\u008b\u0001\u0000\u0000\u0000\u008e\u008f\u0005>\u0000\u0000\u008f"+
+               
"\u0018\u0001\u0000\u0000\u0000\u0090\u0096\u0003#\u0011\u0000\u0091\u0095"+
+               
"\u0003#\u0011\u0000\u0092\u0095\u0003\'\u0013\u0000\u0093\u0095\u0005"+
+               
"-\u0000\u0000\u0094\u0091\u0001\u0000\u0000\u0000\u0094\u0092\u0001\u0000"+
+               
"\u0000\u0000\u0094\u0093\u0001\u0000\u0000\u0000\u0095\u0098\u0001\u0000"+
+               
"\u0000\u0000\u0096\u0094\u0001\u0000\u0000\u0000\u0096\u0097\u0001\u0000"+
+               
"\u0000\u0000\u0097\u001a\u0001\u0000\u0000\u0000\u0098\u0096\u0001\u0000"+
+               
"\u0000\u0000\u0099\u009b\u000209\u0000\u009a\u0099\u0001\u0000\u0000\u0000"+
+               
"\u009b\u009c\u0001\u0000\u0000\u0000\u009c\u009a\u0001\u0000\u0000\u0000"+
+               
"\u009c\u009d\u0001\u0000\u0000\u0000\u009d\u001c\u0001\u0000\u0000\u0000"+
+               
"\u009e\u00a2\u0005;\u0000\u0000\u009f\u00a1\b\u0001\u0000\u0000\u00a0"+
+               
"\u009f\u0001\u0000\u0000\u0000\u00a1\u00a4\u0001\u0000\u0000\u0000\u00a2"+
+               
"\u00a0\u0001\u0000\u0000\u0000\u00a2\u00a3\u0001\u0000\u0000\u0000\u00a3"+
+               
"\u00a6\u0001\u0000\u0000\u0000\u00a4\u00a2\u0001\u0000\u0000\u0000\u00a5"+
+               
"\u00a7\u0005\r\u0000\u0000\u00a6\u00a5\u0001\u0000\u0000\u0000\u00a6\u00a7"+
+               
"\u0001\u0000\u0000\u0000\u00a7\u00a8\u0001\u0000\u0000\u0000\u00a8\u00a9"+
+               
"\u0005\n\u0000\u0000\u00a9\u00aa\u0001\u0000\u0000\u0000\u00aa\u00ab\u0006"+
+               
"\u000e\u0000\u0000\u00ab\u001e\u0001\u0000\u0000\u0000\u00ac\u00ad\u0007"+
+               
"\u0002\u0000\u0000\u00ad\u00ae\u0001\u0000\u0000\u0000\u00ae\u00af\u0006"+
+               "\u000f\u0000\u0000\u00af 
\u0001\u0000\u0000\u0000\u00b0\u00b1\u0005%\u0000"+
+               
"\u0000\u00b1\u00b5\u0005s\u0000\u0000\u00b2\u00b3\u0005%\u0000\u0000\u00b3"+
+               
"\u00b5\u0005i\u0000\u0000\u00b4\u00b0\u0001\u0000\u0000\u0000\u00b4\u00b2"+
+               
"\u0001\u0000\u0000\u0000\u00b4\u00b5\u0001\u0000\u0000\u0000\u00b5\u00b6"+
+               
"\u0001\u0000\u0000\u0000\u00b6\u00ba\u0005\"\u0000\u0000\u00b7\u00b9\b"+
+               
"\u0003\u0000\u0000\u00b8\u00b7\u0001\u0000\u0000\u0000\u00b9\u00bc\u0001"+
+               
"\u0000\u0000\u0000\u00ba\u00b8\u0001\u0000\u0000\u0000\u00ba\u00bb\u0001"+
+               
"\u0000\u0000\u0000\u00bb\u00bd\u0001\u0000\u0000\u0000\u00bc\u00ba\u0001"+
+               
"\u0000\u0000\u0000\u00bd\u00be\u0005\"\u0000\u0000\u00be\"\u0001\u0000"+
+               
"\u0000\u0000\u00bf\u00c0\u0007\u0004\u0000\u0000\u00c0$\u0001\u0000\u0000"+
+               
"\u0000\u00c1\u00c2\u000201\u0000\u00c2&\u0001\u0000\u0000\u0000\u00c3"+
+               
"\u00c4\u000209\u0000\u00c4(\u0001\u0000\u0000\u0000\u00c5\u00c6\u0007"+
+               
"\u0005\u0000\u0000\u00c6*\u0001\u0000\u0000\u0000\u0019\u0000=CIMSU[a"+
+               
"ekmsy}\u0083\u0085\u008b\u0094\u0096\u009c\u00a2\u00a6\u00b4\u00ba\u0001"+
+               "\u0000\u0001\u0000";
+       public static final ATN _ATN =
+               new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+       static {
+               _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+               for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+                       _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), 
i);
+               }
+       }
+}
\ No newline at end of file
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.tokens
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.tokens
new file mode 100644
index 0000000..db19df3
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfLexer.tokens
@@ -0,0 +1,21 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+NumberValue=8
+ProseValue=9
+ID=10
+INT=11
+COMMENT=12
+WS=13
+STRING=14
+'='=1
+'/'=2
+'*'=3
+'('=4
+')'=5
+'['=6
+']'=7
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfParser.java
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfParser.java
new file mode 100644
index 0000000..a83afff
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AbnfParser.java
@@ -0,0 +1,658 @@
+// Generated from Abnf.g4 by ANTLR 4.13.1
+package org.apache.accumulo.access.grammars;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.misc.*;
+import org.antlr.v4.runtime.tree.*;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", 
"CheckReturnValue"})
+public class AbnfParser extends Parser {
+       static { RuntimeMetaData.checkVersion("4.13.1", 
RuntimeMetaData.VERSION); }
+
+       protected static final DFA[] _decisionToDFA;
+       protected static final PredictionContextCache _sharedContextCache =
+               new PredictionContextCache();
+       public static final int
+               T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, 
NumberValue=8, 
+               ProseValue=9, ID=10, INT=11, COMMENT=12, WS=13, STRING=14;
+       public static final int
+               RULE_rulelist = 0, RULE_rule_ = 1, RULE_elements = 2, 
RULE_alternation = 3, 
+               RULE_concatenation = 4, RULE_repetition = 5, RULE_repeat_ = 6, 
RULE_element = 7, 
+               RULE_group = 8, RULE_option = 9;
+       private static String[] makeRuleNames() {
+               return new String[] {
+                       "rulelist", "rule_", "elements", "alternation", 
"concatenation", "repetition", 
+                       "repeat_", "element", "group", "option"
+               };
+       }
+       public static final String[] ruleNames = makeRuleNames();
+
+       private static String[] makeLiteralNames() {
+               return new String[] {
+                       null, "'='", "'/'", "'*'", "'('", "')'", "'['", "']'"
+               };
+       }
+       private static final String[] _LITERAL_NAMES = makeLiteralNames();
+       private static String[] makeSymbolicNames() {
+               return new String[] {
+                       null, null, null, null, null, null, null, null, 
"NumberValue", "ProseValue", 
+                       "ID", "INT", "COMMENT", "WS", "STRING"
+               };
+       }
+       private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
+       public static final Vocabulary VOCABULARY = new 
VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+       /**
+        * @deprecated Use {@link #VOCABULARY} instead.
+        */
+       @Deprecated
+       public static final String[] tokenNames;
+       static {
+               tokenNames = new String[_SYMBOLIC_NAMES.length];
+               for (int i = 0; i < tokenNames.length; i++) {
+                       tokenNames[i] = VOCABULARY.getLiteralName(i);
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = VOCABULARY.getSymbolicName(i);
+                       }
+
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = "<INVALID>";
+                       }
+               }
+       }
+
+       @Override
+       @Deprecated
+       public String[] getTokenNames() {
+               return tokenNames;
+       }
+
+       @Override
+
+       public Vocabulary getVocabulary() {
+               return VOCABULARY;
+       }
+
+       @Override
+       public String getGrammarFileName() { return "Abnf.g4"; }
+
+       @Override
+       public String[] getRuleNames() { return ruleNames; }
+
+       @Override
+       public String getSerializedATN() { return _serializedATN; }
+
+       @Override
+       public ATN getATN() { return _ATN; }
+
+       public AbnfParser(TokenStream input) {
+               super(input);
+               _interp = new 
ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class RulelistContext extends ParserRuleContext {
+               public TerminalNode EOF() { return getToken(AbnfParser.EOF, 0); 
}
+               public List<Rule_Context> rule_() {
+                       return getRuleContexts(Rule_Context.class);
+               }
+               public Rule_Context rule_(int i) {
+                       return getRuleContext(Rule_Context.class,i);
+               }
+               public RulelistContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_rulelist; }
+       }
+
+       public final RulelistContext rulelist() throws RecognitionException {
+               RulelistContext _localctx = new RulelistContext(_ctx, 
getState());
+               enterRule(_localctx, 0, RULE_rulelist);
+               int _la;
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(23);
+                       _errHandler.sync(this);
+                       _la = _input.LA(1);
+                       while (_la==ID) {
+                               {
+                               {
+                               setState(20);
+                               rule_();
+                               }
+                               }
+                               setState(25);
+                               _errHandler.sync(this);
+                               _la = _input.LA(1);
+                       }
+                       setState(26);
+                       match(EOF);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class Rule_Context extends ParserRuleContext {
+               public TerminalNode ID() { return getToken(AbnfParser.ID, 0); }
+               public ElementsContext elements() {
+                       return getRuleContext(ElementsContext.class,0);
+               }
+               public Rule_Context(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_rule_; }
+       }
+
+       public final Rule_Context rule_() throws RecognitionException {
+               Rule_Context _localctx = new Rule_Context(_ctx, getState());
+               enterRule(_localctx, 2, RULE_rule_);
+               int _la;
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(28);
+                       match(ID);
+                       setState(29);
+                       match(T__0);
+                       setState(31);
+                       _errHandler.sync(this);
+                       _la = _input.LA(1);
+                       if (_la==T__1) {
+                               {
+                               setState(30);
+                               match(T__1);
+                               }
+                       }
+
+                       setState(33);
+                       elements();
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class ElementsContext extends ParserRuleContext {
+               public AlternationContext alternation() {
+                       return getRuleContext(AlternationContext.class,0);
+               }
+               public ElementsContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_elements; }
+       }
+
+       public final ElementsContext elements() throws RecognitionException {
+               ElementsContext _localctx = new ElementsContext(_ctx, 
getState());
+               enterRule(_localctx, 4, RULE_elements);
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(35);
+                       alternation();
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class AlternationContext extends ParserRuleContext {
+               public List<ConcatenationContext> concatenation() {
+                       return getRuleContexts(ConcatenationContext.class);
+               }
+               public ConcatenationContext concatenation(int i) {
+                       return getRuleContext(ConcatenationContext.class,i);
+               }
+               public AlternationContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_alternation; }
+       }
+
+       public final AlternationContext alternation() throws 
RecognitionException {
+               AlternationContext _localctx = new AlternationContext(_ctx, 
getState());
+               enterRule(_localctx, 6, RULE_alternation);
+               int _la;
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(37);
+                       concatenation();
+                       setState(42);
+                       _errHandler.sync(this);
+                       _la = _input.LA(1);
+                       while (_la==T__1) {
+                               {
+                               {
+                               setState(38);
+                               match(T__1);
+                               setState(39);
+                               concatenation();
+                               }
+                               }
+                               setState(44);
+                               _errHandler.sync(this);
+                               _la = _input.LA(1);
+                       }
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class ConcatenationContext extends ParserRuleContext {
+               public List<RepetitionContext> repetition() {
+                       return getRuleContexts(RepetitionContext.class);
+               }
+               public RepetitionContext repetition(int i) {
+                       return getRuleContext(RepetitionContext.class,i);
+               }
+               public ConcatenationContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return 
RULE_concatenation; }
+       }
+
+       public final ConcatenationContext concatenation() throws 
RecognitionException {
+               ConcatenationContext _localctx = new ConcatenationContext(_ctx, 
getState());
+               enterRule(_localctx, 8, RULE_concatenation);
+               try {
+                       int _alt;
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(46); 
+                       _errHandler.sync(this);
+                       _alt = 1;
+                       do {
+                               switch (_alt) {
+                               case 1:
+                                       {
+                                       {
+                                       setState(45);
+                                       repetition();
+                                       }
+                                       }
+                                       break;
+                               default:
+                                       throw new NoViableAltException(this);
+                               }
+                               setState(48); 
+                               _errHandler.sync(this);
+                               _alt = 
getInterpreter().adaptivePredict(_input,3,_ctx);
+                       } while ( _alt!=2 && 
_alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class RepetitionContext extends ParserRuleContext {
+               public ElementContext element() {
+                       return getRuleContext(ElementContext.class,0);
+               }
+               public Repeat_Context repeat_() {
+                       return getRuleContext(Repeat_Context.class,0);
+               }
+               public RepetitionContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_repetition; }
+       }
+
+       public final RepetitionContext repetition() throws RecognitionException 
{
+               RepetitionContext _localctx = new RepetitionContext(_ctx, 
getState());
+               enterRule(_localctx, 10, RULE_repetition);
+               int _la;
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(51);
+                       _errHandler.sync(this);
+                       _la = _input.LA(1);
+                       if (_la==T__2 || _la==INT) {
+                               {
+                               setState(50);
+                               repeat_();
+                               }
+                       }
+
+                       setState(53);
+                       element();
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class Repeat_Context extends ParserRuleContext {
+               public List<TerminalNode> INT() { return 
getTokens(AbnfParser.INT); }
+               public TerminalNode INT(int i) {
+                       return getToken(AbnfParser.INT, i);
+               }
+               public Repeat_Context(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_repeat_; }
+       }
+
+       public final Repeat_Context repeat_() throws RecognitionException {
+               Repeat_Context _localctx = new Repeat_Context(_ctx, getState());
+               enterRule(_localctx, 12, RULE_repeat_);
+               int _la;
+               try {
+                       setState(63);
+                       _errHandler.sync(this);
+                       switch ( 
getInterpreter().adaptivePredict(_input,7,_ctx) ) {
+                       case 1:
+                               enterOuterAlt(_localctx, 1);
+                               {
+                               setState(55);
+                               match(INT);
+                               }
+                               break;
+                       case 2:
+                               enterOuterAlt(_localctx, 2);
+                               {
+                               setState(57);
+                               _errHandler.sync(this);
+                               _la = _input.LA(1);
+                               if (_la==INT) {
+                                       {
+                                       setState(56);
+                                       match(INT);
+                                       }
+                               }
+
+                               setState(59);
+                               match(T__2);
+                               setState(61);
+                               _errHandler.sync(this);
+                               _la = _input.LA(1);
+                               if (_la==INT) {
+                                       {
+                                       setState(60);
+                                       match(INT);
+                                       }
+                               }
+
+                               }
+                               break;
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class ElementContext extends ParserRuleContext {
+               public TerminalNode ID() { return getToken(AbnfParser.ID, 0); }
+               public GroupContext group() {
+                       return getRuleContext(GroupContext.class,0);
+               }
+               public OptionContext option() {
+                       return getRuleContext(OptionContext.class,0);
+               }
+               public TerminalNode STRING() { return 
getToken(AbnfParser.STRING, 0); }
+               public TerminalNode NumberValue() { return 
getToken(AbnfParser.NumberValue, 0); }
+               public TerminalNode ProseValue() { return 
getToken(AbnfParser.ProseValue, 0); }
+               public ElementContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_element; }
+       }
+
+       public final ElementContext element() throws RecognitionException {
+               ElementContext _localctx = new ElementContext(_ctx, getState());
+               enterRule(_localctx, 14, RULE_element);
+               try {
+                       setState(71);
+                       _errHandler.sync(this);
+                       switch (_input.LA(1)) {
+                       case ID:
+                               enterOuterAlt(_localctx, 1);
+                               {
+                               setState(65);
+                               match(ID);
+                               }
+                               break;
+                       case T__3:
+                               enterOuterAlt(_localctx, 2);
+                               {
+                               setState(66);
+                               group();
+                               }
+                               break;
+                       case T__5:
+                               enterOuterAlt(_localctx, 3);
+                               {
+                               setState(67);
+                               option();
+                               }
+                               break;
+                       case STRING:
+                               enterOuterAlt(_localctx, 4);
+                               {
+                               setState(68);
+                               match(STRING);
+                               }
+                               break;
+                       case NumberValue:
+                               enterOuterAlt(_localctx, 5);
+                               {
+                               setState(69);
+                               match(NumberValue);
+                               }
+                               break;
+                       case ProseValue:
+                               enterOuterAlt(_localctx, 6);
+                               {
+                               setState(70);
+                               match(ProseValue);
+                               }
+                               break;
+                       default:
+                               throw new NoViableAltException(this);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class GroupContext extends ParserRuleContext {
+               public AlternationContext alternation() {
+                       return getRuleContext(AlternationContext.class,0);
+               }
+               public GroupContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_group; }
+       }
+
+       public final GroupContext group() throws RecognitionException {
+               GroupContext _localctx = new GroupContext(_ctx, getState());
+               enterRule(_localctx, 16, RULE_group);
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(73);
+                       match(T__3);
+                       setState(74);
+                       alternation();
+                       setState(75);
+                       match(T__4);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class OptionContext extends ParserRuleContext {
+               public AlternationContext alternation() {
+                       return getRuleContext(AlternationContext.class,0);
+               }
+               public OptionContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_option; }
+       }
+
+       public final OptionContext option() throws RecognitionException {
+               OptionContext _localctx = new OptionContext(_ctx, getState());
+               enterRule(_localctx, 18, RULE_option);
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(77);
+                       match(T__5);
+                       setState(78);
+                       alternation();
+                       setState(79);
+                       match(T__6);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       public static final String _serializedATN =
+               
"\u0004\u0001\u000eR\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
+               
"\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+
+               
"\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+
+               
"\b\u0007\b\u0002\t\u0007\t\u0001\u0000\u0005\u0000\u0016\b\u0000\n\u0000"+
+               
"\f\u0000\u0019\t\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"+
+               "\u0001\u0001\u0003\u0001 
\b\u0001\u0001\u0001\u0001\u0001\u0001\u0002"+
+               
"\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0005\u0003)\b\u0003"+
+               
"\n\u0003\f\u0003,\t\u0003\u0001\u0004\u0004\u0004/\b\u0004\u000b\u0004"+
+               
"\f\u00040\u0001\u0005\u0003\u00054\b\u0005\u0001\u0005\u0001\u0005\u0001"+
+               
"\u0006\u0001\u0006\u0003\u0006:\b\u0006\u0001\u0006\u0001\u0006\u0003"+
+               
"\u0006>\b\u0006\u0003\u0006@\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+
+               
"\u0001\u0007\u0001\u0007\u0001\u0007\u0003\u0007H\b\u0007\u0001\b\u0001"+
+               
"\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0000\u0000"+
+               
"\n\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0000\u0000T\u0000"+
+               
"\u0017\u0001\u0000\u0000\u0000\u0002\u001c\u0001\u0000\u0000\u0000\u0004"+
+               
"#\u0001\u0000\u0000\u0000\u0006%\u0001\u0000\u0000\u0000\b.\u0001\u0000"+
+               
"\u0000\u0000\n3\u0001\u0000\u0000\u0000\f?\u0001\u0000\u0000\u0000\u000e"+
+               
"G\u0001\u0000\u0000\u0000\u0010I\u0001\u0000\u0000\u0000\u0012M\u0001"+
+               
"\u0000\u0000\u0000\u0014\u0016\u0003\u0002\u0001\u0000\u0015\u0014\u0001"+
+               
"\u0000\u0000\u0000\u0016\u0019\u0001\u0000\u0000\u0000\u0017\u0015\u0001"+
+               
"\u0000\u0000\u0000\u0017\u0018\u0001\u0000\u0000\u0000\u0018\u001a\u0001"+
+               
"\u0000\u0000\u0000\u0019\u0017\u0001\u0000\u0000\u0000\u001a\u001b\u0005"+
+               
"\u0000\u0000\u0001\u001b\u0001\u0001\u0000\u0000\u0000\u001c\u001d\u0005"+
+               "\n\u0000\u0000\u001d\u001f\u0005\u0001\u0000\u0000\u001e 
\u0005\u0002"+
+               "\u0000\u0000\u001f\u001e\u0001\u0000\u0000\u0000\u001f 
\u0001\u0000\u0000"+
+               "\u0000 
!\u0001\u0000\u0000\u0000!\"\u0003\u0004\u0002\u0000\"\u0003\u0001"+
+               
"\u0000\u0000\u0000#$\u0003\u0006\u0003\u0000$\u0005\u0001\u0000\u0000"+
+               
"\u0000%*\u0003\b\u0004\u0000&\'\u0005\u0002\u0000\u0000\')\u0003\b\u0004"+
+               
"\u0000(&\u0001\u0000\u0000\u0000),\u0001\u0000\u0000\u0000*(\u0001\u0000"+
+               
"\u0000\u0000*+\u0001\u0000\u0000\u0000+\u0007\u0001\u0000\u0000\u0000"+
+               
",*\u0001\u0000\u0000\u0000-/\u0003\n\u0005\u0000.-\u0001\u0000\u0000\u0000"+
+               
"/0\u0001\u0000\u0000\u00000.\u0001\u0000\u0000\u000001\u0001\u0000\u0000"+
+               
"\u00001\t\u0001\u0000\u0000\u000024\u0003\f\u0006\u000032\u0001\u0000"+
+               
"\u0000\u000034\u0001\u0000\u0000\u000045\u0001\u0000\u0000\u000056\u0003"+
+               
"\u000e\u0007\u00006\u000b\u0001\u0000\u0000\u00007@\u0005\u000b\u0000"+
+               
"\u00008:\u0005\u000b\u0000\u000098\u0001\u0000\u0000\u00009:\u0001\u0000"+
+               
"\u0000\u0000:;\u0001\u0000\u0000\u0000;=\u0005\u0003\u0000\u0000<>\u0005"+
+               
"\u000b\u0000\u0000=<\u0001\u0000\u0000\u0000=>\u0001\u0000\u0000\u0000"+
+               
">@\u0001\u0000\u0000\u0000?7\u0001\u0000\u0000\u0000?9\u0001\u0000\u0000"+
+               
"\u0000@\r\u0001\u0000\u0000\u0000AH\u0005\n\u0000\u0000BH\u0003\u0010"+
+               
"\b\u0000CH\u0003\u0012\t\u0000DH\u0005\u000e\u0000\u0000EH\u0005\b\u0000"+
+               
"\u0000FH\u0005\t\u0000\u0000GA\u0001\u0000\u0000\u0000GB\u0001\u0000\u0000"+
+               
"\u0000GC\u0001\u0000\u0000\u0000GD\u0001\u0000\u0000\u0000GE\u0001\u0000"+
+               
"\u0000\u0000GF\u0001\u0000\u0000\u0000H\u000f\u0001\u0000\u0000\u0000"+
+               
"IJ\u0005\u0004\u0000\u0000JK\u0003\u0006\u0003\u0000KL\u0005\u0005\u0000"+
+               
"\u0000L\u0011\u0001\u0000\u0000\u0000MN\u0005\u0006\u0000\u0000NO\u0003"+
+               
"\u0006\u0003\u0000OP\u0005\u0007\u0000\u0000P\u0013\u0001\u0000\u0000"+
+               "\u0000\t\u0017\u001f*039=?G";
+       public static final ATN _ATN =
+               new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+       static {
+               _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+               for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+                       _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), 
i);
+               }
+       }
+}
\ No newline at end of file
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpression.interp
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpression.interp
new file mode 100644
index 0000000..927eb0c
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpression.interp
@@ -0,0 +1,30 @@
+token literal names:
+null
+'('
+')'
+'&'
+'|'
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+ACCESS_TOKEN
+WS
+
+rule names:
+access_expression
+expression
+and_expression
+or_expression
+access_token
+and_operator
+or_operator
+
+
+atn:
+[4, 1, 6, 74, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 
5, 7, 5, 2, 6, 7, 6, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 19, 8, 0, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 28, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 35, 
8, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 43, 8, 2, 4, 2, 45, 8, 2, 11, 
2, 12, 2, 46, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 54, 8, 3, 1, 3, 1, 3, 1, 3, 
1, 3, 1, 3, 1, 3, 3, 3, 62, 8, 3, 4, 3, 64, 8, 3, 11, 3, 12, 3, 65, 1, 4, 1, 4, 
1, 5, 1, 5, 1, 6, 1, [...]
\ No newline at end of file
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpression.tokens
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpression.tokens
new file mode 100644
index 0000000..673de68
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpression.tokens
@@ -0,0 +1,10 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+ACCESS_TOKEN=5
+WS=6
+'('=1
+')'=2
+'&'=3
+'|'=4
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.interp
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.interp
new file mode 100644
index 0000000..7331380
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.interp
@@ -0,0 +1,35 @@
+token literal names:
+null
+'('
+')'
+'&'
+'|'
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+ACCESS_TOKEN
+WS
+
+rule names:
+T__0
+T__1
+T__2
+T__3
+ACCESS_TOKEN
+WS
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 6, 48, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 
4, 2, 5, 7, 5, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 4, 4, 23, 
8, 4, 11, 4, 12, 4, 24, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 33, 8, 4, 4, 
4, 35, 8, 4, 11, 4, 12, 4, 36, 1, 4, 3, 4, 40, 8, 4, 1, 5, 4, 5, 43, 8, 5, 11, 
5, 12, 5, 44, 1, 5, 1, 5, 0, 0, 6, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 1, 0, 
3, 4, 0, 45, 58, 65, 90, 95, 95, 97, 122, 5, 0, 32, 33, 35, 91, 93, 126, 128, 
55295, 57344, 1114111 [...]
\ No newline at end of file
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.java
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.java
new file mode 100644
index 0000000..7719789
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.java
@@ -0,0 +1,149 @@
+// Generated from AccessExpression.g4 by ANTLR 4.13.1
+package org.apache.accumulo.access.grammars;
+import org.antlr.v4.runtime.Lexer;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.misc.*;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", 
"CheckReturnValue", "this-escape"})
+public class AccessExpressionLexer extends Lexer {
+       static { RuntimeMetaData.checkVersion("4.13.1", 
RuntimeMetaData.VERSION); }
+
+       protected static final DFA[] _decisionToDFA;
+       protected static final PredictionContextCache _sharedContextCache =
+               new PredictionContextCache();
+       public static final int
+               T__0=1, T__1=2, T__2=3, T__3=4, ACCESS_TOKEN=5, WS=6;
+       public static String[] channelNames = {
+               "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
+       };
+
+       public static String[] modeNames = {
+               "DEFAULT_MODE"
+       };
+
+       private static String[] makeRuleNames() {
+               return new String[] {
+                       "T__0", "T__1", "T__2", "T__3", "ACCESS_TOKEN", "WS"
+               };
+       }
+       public static final String[] ruleNames = makeRuleNames();
+
+       private static String[] makeLiteralNames() {
+               return new String[] {
+                       null, "'('", "')'", "'&'", "'|'"
+               };
+       }
+       private static final String[] _LITERAL_NAMES = makeLiteralNames();
+       private static String[] makeSymbolicNames() {
+               return new String[] {
+                       null, null, null, null, null, "ACCESS_TOKEN", "WS"
+               };
+       }
+       private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
+       public static final Vocabulary VOCABULARY = new 
VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+       /**
+        * @deprecated Use {@link #VOCABULARY} instead.
+        */
+       @Deprecated
+       public static final String[] tokenNames;
+       static {
+               tokenNames = new String[_SYMBOLIC_NAMES.length];
+               for (int i = 0; i < tokenNames.length; i++) {
+                       tokenNames[i] = VOCABULARY.getLiteralName(i);
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = VOCABULARY.getSymbolicName(i);
+                       }
+
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = "<INVALID>";
+                       }
+               }
+       }
+
+       @Override
+       @Deprecated
+       public String[] getTokenNames() {
+               return tokenNames;
+       }
+
+       @Override
+
+       public Vocabulary getVocabulary() {
+               return VOCABULARY;
+       }
+
+
+       public AccessExpressionLexer(CharStream input) {
+               super(input);
+               _interp = new 
LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+       }
+
+       @Override
+       public String getGrammarFileName() { return "AccessExpression.g4"; }
+
+       @Override
+       public String[] getRuleNames() { return ruleNames; }
+
+       @Override
+       public String getSerializedATN() { return _serializedATN; }
+
+       @Override
+       public String[] getChannelNames() { return channelNames; }
+
+       @Override
+       public String[] getModeNames() { return modeNames; }
+
+       @Override
+       public ATN getATN() { return _ATN; }
+
+       public static final String _serializedATN =
+               
"\u0004\u0000\u00060\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+
+               
"\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+
+               
"\u0007\u0004\u0002\u0005\u0007\u0005\u0001\u0000\u0001\u0000\u0001\u0001"+
+               
"\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0004"+
+               
"\u0004\u0004\u0017\b\u0004\u000b\u0004\f\u0004\u0018\u0001\u0004\u0001"+
+               
"\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004!\b"+
+               
"\u0004\u0004\u0004#\b\u0004\u000b\u0004\f\u0004$\u0001\u0004\u0003\u0004"+
+               
"(\b\u0004\u0001\u0005\u0004\u0005+\b\u0005\u000b\u0005\f\u0005,\u0001"+
+               
"\u0005\u0001\u0005\u0000\u0000\u0006\u0001\u0001\u0003\u0002\u0005\u0003"+
+               
"\u0007\u0004\t\u0005\u000b\u0006\u0001\u0000\u0003\u0004\u0000-:AZ__a"+
+               "z\u0005\u0000 
!#[]~\u0080\u8000\ud7ff\u8000\ue000\u8010\uffff\u0002\u0000"+
+               
"\b\t\f\r5\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000"+
+               
"\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000"+
+               
"\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000"+
+               
"\u0000\u0001\r\u0001\u0000\u0000\u0000\u0003\u000f\u0001\u0000\u0000\u0000"+
+               
"\u0005\u0011\u0001\u0000\u0000\u0000\u0007\u0013\u0001\u0000\u0000\u0000"+
+               
"\t\'\u0001\u0000\u0000\u0000\u000b*\u0001\u0000\u0000\u0000\r\u000e\u0005"+
+               
"(\u0000\u0000\u000e\u0002\u0001\u0000\u0000\u0000\u000f\u0010\u0005)\u0000"+
+               
"\u0000\u0010\u0004\u0001\u0000\u0000\u0000\u0011\u0012\u0005&\u0000\u0000"+
+               
"\u0012\u0006\u0001\u0000\u0000\u0000\u0013\u0014\u0005|\u0000\u0000\u0014"+
+               
"\b\u0001\u0000\u0000\u0000\u0015\u0017\u0007\u0000\u0000\u0000\u0016\u0015"+
+               
"\u0001\u0000\u0000\u0000\u0017\u0018\u0001\u0000\u0000\u0000\u0018\u0016"+
+               
"\u0001\u0000\u0000\u0000\u0018\u0019\u0001\u0000\u0000\u0000\u0019(\u0001"+
+               
"\u0000\u0000\u0000\u001a\"\u0005\"\u0000\u0000\u001b#\u0007\u0001\u0000"+
+               
"\u0000\u001c\u001d\u0005\\\u0000\u0000\u001d!\u0005\"\u0000\u0000\u001e"+
+               "\u001f\u0005\\\u0000\u0000\u001f!\u0005\\\u0000\u0000 
\u001c\u0001\u0000"+
+               "\u0000\u0000 
\u001e\u0001\u0000\u0000\u0000!#\u0001\u0000\u0000\u0000"+
+               "\"\u001b\u0001\u0000\u0000\u0000\" 
\u0001\u0000\u0000\u0000#$\u0001\u0000"+
+               
"\u0000\u0000$\"\u0001\u0000\u0000\u0000$%\u0001\u0000\u0000\u0000%&\u0001"+
+               
"\u0000\u0000\u0000&(\u0005\"\u0000\u0000\'\u0016\u0001\u0000\u0000\u0000"+
+               
"\'\u001a\u0001\u0000\u0000\u0000(\n\u0001\u0000\u0000\u0000)+\u0007\u0002"+
+               
"\u0000\u0000*)\u0001\u0000\u0000\u0000+,\u0001\u0000\u0000\u0000,*\u0001"+
+               
"\u0000\u0000\u0000,-\u0001\u0000\u0000\u0000-.\u0001\u0000\u0000\u0000"+
+               
"./\u0006\u0005\u0000\u0000/\f\u0001\u0000\u0000\u0000\b\u0000\u0016\u0018"+
+               " \"$\',\u0001\u0006\u0000\u0000";
+       public static final ATN _ATN =
+               new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+       static {
+               _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+               for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+                       _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), 
i);
+               }
+       }
+}
\ No newline at end of file
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.tokens
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.tokens
new file mode 100644
index 0000000..673de68
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionLexer.tokens
@@ -0,0 +1,10 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+ACCESS_TOKEN=5
+WS=6
+'('=1
+')'=2
+'&'=3
+'|'=4
diff --git 
a/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionParser.java
 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionParser.java
new file mode 100644
index 0000000..d51913d
--- /dev/null
+++ 
b/antlr4-example/src/main/generated-antlr4-sources/org/apache/accumulo/access/grammars/AccessExpressionParser.java
@@ -0,0 +1,567 @@
+// Generated from AccessExpression.g4 by ANTLR 4.13.1
+package org.apache.accumulo.access.grammars;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.misc.*;
+import org.antlr.v4.runtime.tree.*;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", 
"CheckReturnValue"})
+public class AccessExpressionParser extends Parser {
+       static { RuntimeMetaData.checkVersion("4.13.1", 
RuntimeMetaData.VERSION); }
+
+       protected static final DFA[] _decisionToDFA;
+       protected static final PredictionContextCache _sharedContextCache =
+               new PredictionContextCache();
+       public static final int
+               T__0=1, T__1=2, T__2=3, T__3=4, ACCESS_TOKEN=5, WS=6;
+       public static final int
+               RULE_access_expression = 0, RULE_expression = 1, 
RULE_and_expression = 2, 
+               RULE_or_expression = 3, RULE_access_token = 4, 
RULE_and_operator = 5, 
+               RULE_or_operator = 6;
+       private static String[] makeRuleNames() {
+               return new String[] {
+                       "access_expression", "expression", "and_expression", 
"or_expression", 
+                       "access_token", "and_operator", "or_operator"
+               };
+       }
+       public static final String[] ruleNames = makeRuleNames();
+
+       private static String[] makeLiteralNames() {
+               return new String[] {
+                       null, "'('", "')'", "'&'", "'|'"
+               };
+       }
+       private static final String[] _LITERAL_NAMES = makeLiteralNames();
+       private static String[] makeSymbolicNames() {
+               return new String[] {
+                       null, null, null, null, null, "ACCESS_TOKEN", "WS"
+               };
+       }
+       private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
+       public static final Vocabulary VOCABULARY = new 
VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+       /**
+        * @deprecated Use {@link #VOCABULARY} instead.
+        */
+       @Deprecated
+       public static final String[] tokenNames;
+       static {
+               tokenNames = new String[_SYMBOLIC_NAMES.length];
+               for (int i = 0; i < tokenNames.length; i++) {
+                       tokenNames[i] = VOCABULARY.getLiteralName(i);
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = VOCABULARY.getSymbolicName(i);
+                       }
+
+                       if (tokenNames[i] == null) {
+                               tokenNames[i] = "<INVALID>";
+                       }
+               }
+       }
+
+       @Override
+       @Deprecated
+       public String[] getTokenNames() {
+               return tokenNames;
+       }
+
+       @Override
+
+       public Vocabulary getVocabulary() {
+               return VOCABULARY;
+       }
+
+       @Override
+       public String getGrammarFileName() { return "AccessExpression.g4"; }
+
+       @Override
+       public String[] getRuleNames() { return ruleNames; }
+
+       @Override
+       public String getSerializedATN() { return _serializedATN; }
+
+       @Override
+       public ATN getATN() { return _ATN; }
+
+       public AccessExpressionParser(TokenStream input) {
+               super(input);
+               _interp = new 
ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class Access_expressionContext extends ParserRuleContext {
+               public TerminalNode EOF() { return 
getToken(AccessExpressionParser.EOF, 0); }
+               public ExpressionContext expression() {
+                       return getRuleContext(ExpressionContext.class,0);
+               }
+               public Access_expressionContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return 
RULE_access_expression; }
+       }
+
+       public final Access_expressionContext access_expression() throws 
RecognitionException {
+               Access_expressionContext _localctx = new 
Access_expressionContext(_ctx, getState());
+               enterRule(_localctx, 0, RULE_access_expression);
+               try {
+                       setState(18);
+                       _errHandler.sync(this);
+                       switch (_input.LA(1)) {
+                       case EOF:
+                               enterOuterAlt(_localctx, 1);
+                               {
+                               setState(14);
+                               match(EOF);
+                               }
+                               break;
+                       case T__0:
+                       case ACCESS_TOKEN:
+                               enterOuterAlt(_localctx, 2);
+                               {
+                               setState(15);
+                               expression();
+                               setState(16);
+                               match(EOF);
+                               }
+                               break;
+                       default:
+                               throw new NoViableAltException(this);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class ExpressionContext extends ParserRuleContext {
+               public And_expressionContext and_expression() {
+                       return getRuleContext(And_expressionContext.class,0);
+               }
+               public Or_expressionContext or_expression() {
+                       return getRuleContext(Or_expressionContext.class,0);
+               }
+               public ExpressionContext expression() {
+                       return getRuleContext(ExpressionContext.class,0);
+               }
+               public Access_tokenContext access_token() {
+                       return getRuleContext(Access_tokenContext.class,0);
+               }
+               public ExpressionContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_expression; }
+       }
+
+       public final ExpressionContext expression() throws RecognitionException 
{
+               ExpressionContext _localctx = new ExpressionContext(_ctx, 
getState());
+               enterRule(_localctx, 2, RULE_expression);
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(27);
+                       _errHandler.sync(this);
+                       switch ( 
getInterpreter().adaptivePredict(_input,1,_ctx) ) {
+                       case 1:
+                               {
+                               setState(20);
+                               and_expression();
+                               }
+                               break;
+                       case 2:
+                               {
+                               setState(21);
+                               or_expression();
+                               }
+                               break;
+                       case 3:
+                               {
+                               setState(22);
+                               match(T__0);
+                               setState(23);
+                               expression();
+                               setState(24);
+                               match(T__1);
+                               }
+                               break;
+                       case 4:
+                               {
+                               setState(26);
+                               access_token();
+                               }
+                               break;
+                       }
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class And_expressionContext extends ParserRuleContext {
+               public List<Access_tokenContext> access_token() {
+                       return getRuleContexts(Access_tokenContext.class);
+               }
+               public Access_tokenContext access_token(int i) {
+                       return getRuleContext(Access_tokenContext.class,i);
+               }
+               public List<ExpressionContext> expression() {
+                       return getRuleContexts(ExpressionContext.class);
+               }
+               public ExpressionContext expression(int i) {
+                       return getRuleContext(ExpressionContext.class,i);
+               }
+               public List<And_operatorContext> and_operator() {
+                       return getRuleContexts(And_operatorContext.class);
+               }
+               public And_operatorContext and_operator(int i) {
+                       return getRuleContext(And_operatorContext.class,i);
+               }
+               public And_expressionContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return 
RULE_and_expression; }
+       }
+
+       public final And_expressionContext and_expression() throws 
RecognitionException {
+               And_expressionContext _localctx = new 
And_expressionContext(_ctx, getState());
+               enterRule(_localctx, 4, RULE_and_expression);
+               int _la;
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(34);
+                       _errHandler.sync(this);
+                       switch (_input.LA(1)) {
+                       case ACCESS_TOKEN:
+                               {
+                               setState(29);
+                               access_token();
+                               }
+                               break;
+                       case T__0:
+                               {
+                               setState(30);
+                               match(T__0);
+                               setState(31);
+                               expression();
+                               setState(32);
+                               match(T__1);
+                               }
+                               break;
+                       default:
+                               throw new NoViableAltException(this);
+                       }
+                       setState(44); 
+                       _errHandler.sync(this);
+                       _la = _input.LA(1);
+                       do {
+                               {
+                               {
+                               setState(36);
+                               and_operator();
+                               setState(42);
+                               _errHandler.sync(this);
+                               switch (_input.LA(1)) {
+                               case ACCESS_TOKEN:
+                                       {
+                                       setState(37);
+                                       access_token();
+                                       }
+                                       break;
+                               case T__0:
+                                       {
+                                       setState(38);
+                                       match(T__0);
+                                       setState(39);
+                                       expression();
+                                       setState(40);
+                                       match(T__1);
+                                       }
+                                       break;
+                               default:
+                                       throw new NoViableAltException(this);
+                               }
+                               }
+                               }
+                               setState(46); 
+                               _errHandler.sync(this);
+                               _la = _input.LA(1);
+                       } while ( _la==T__2 );
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class Or_expressionContext extends ParserRuleContext {
+               public List<Access_tokenContext> access_token() {
+                       return getRuleContexts(Access_tokenContext.class);
+               }
+               public Access_tokenContext access_token(int i) {
+                       return getRuleContext(Access_tokenContext.class,i);
+               }
+               public List<ExpressionContext> expression() {
+                       return getRuleContexts(ExpressionContext.class);
+               }
+               public ExpressionContext expression(int i) {
+                       return getRuleContext(ExpressionContext.class,i);
+               }
+               public List<Or_operatorContext> or_operator() {
+                       return getRuleContexts(Or_operatorContext.class);
+               }
+               public Or_operatorContext or_operator(int i) {
+                       return getRuleContext(Or_operatorContext.class,i);
+               }
+               public Or_expressionContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return 
RULE_or_expression; }
+       }
+
+       public final Or_expressionContext or_expression() throws 
RecognitionException {
+               Or_expressionContext _localctx = new Or_expressionContext(_ctx, 
getState());
+               enterRule(_localctx, 6, RULE_or_expression);
+               int _la;
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(53);
+                       _errHandler.sync(this);
+                       switch (_input.LA(1)) {
+                       case ACCESS_TOKEN:
+                               {
+                               setState(48);
+                               access_token();
+                               }
+                               break;
+                       case T__0:
+                               {
+                               setState(49);
+                               match(T__0);
+                               setState(50);
+                               expression();
+                               setState(51);
+                               match(T__1);
+                               }
+                               break;
+                       default:
+                               throw new NoViableAltException(this);
+                       }
+                       setState(63); 
+                       _errHandler.sync(this);
+                       _la = _input.LA(1);
+                       do {
+                               {
+                               {
+                               setState(55);
+                               or_operator();
+                               setState(61);
+                               _errHandler.sync(this);
+                               switch (_input.LA(1)) {
+                               case ACCESS_TOKEN:
+                                       {
+                                       setState(56);
+                                       access_token();
+                                       }
+                                       break;
+                               case T__0:
+                                       {
+                                       setState(57);
+                                       match(T__0);
+                                       setState(58);
+                                       expression();
+                                       setState(59);
+                                       match(T__1);
+                                       }
+                                       break;
+                               default:
+                                       throw new NoViableAltException(this);
+                               }
+                               }
+                               }
+                               setState(65); 
+                               _errHandler.sync(this);
+                               _la = _input.LA(1);
+                       } while ( _la==T__3 );
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class Access_tokenContext extends ParserRuleContext {
+               public TerminalNode ACCESS_TOKEN() { return 
getToken(AccessExpressionParser.ACCESS_TOKEN, 0); }
+               public Access_tokenContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_access_token; 
}
+       }
+
+       public final Access_tokenContext access_token() throws 
RecognitionException {
+               Access_tokenContext _localctx = new Access_tokenContext(_ctx, 
getState());
+               enterRule(_localctx, 8, RULE_access_token);
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(67);
+                       match(ACCESS_TOKEN);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class And_operatorContext extends ParserRuleContext {
+               public And_operatorContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_and_operator; 
}
+       }
+
+       public final And_operatorContext and_operator() throws 
RecognitionException {
+               And_operatorContext _localctx = new And_operatorContext(_ctx, 
getState());
+               enterRule(_localctx, 10, RULE_and_operator);
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(69);
+                       match(T__2);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       @SuppressWarnings("CheckReturnValue")
+       public static class Or_operatorContext extends ParserRuleContext {
+               public Or_operatorContext(ParserRuleContext parent, int 
invokingState) {
+                       super(parent, invokingState);
+               }
+               @Override public int getRuleIndex() { return RULE_or_operator; }
+       }
+
+       public final Or_operatorContext or_operator() throws 
RecognitionException {
+               Or_operatorContext _localctx = new Or_operatorContext(_ctx, 
getState());
+               enterRule(_localctx, 12, RULE_or_operator);
+               try {
+                       enterOuterAlt(_localctx, 1);
+                       {
+                       setState(71);
+                       match(T__3);
+                       }
+               }
+               catch (RecognitionException re) {
+                       _localctx.exception = re;
+                       _errHandler.reportError(this, re);
+                       _errHandler.recover(this, re);
+               }
+               finally {
+                       exitRule();
+               }
+               return _localctx;
+       }
+
+       public static final String _serializedATN =
+               
"\u0004\u0001\u0006J\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
+               
"\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+
+               
"\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0001\u0000\u0001\u0000\u0001"+
+               
"\u0000\u0001\u0000\u0003\u0000\u0013\b\u0000\u0001\u0001\u0001\u0001\u0001"+
+               
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001\u001c"+
+               
"\b\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0003"+
+               
"\u0002#\b\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+
+               
"\u0002\u0001\u0002\u0003\u0002+\b\u0002\u0004\u0002-\b\u0002\u000b\u0002"+
+               
"\f\u0002.\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
+               
"\u0003\u00036\b\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
+               
"\u0001\u0003\u0001\u0003\u0003\u0003>\b\u0003\u0004\u0003@\b\u0003\u000b"+
+               
"\u0003\f\u0003A\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001"+
+               
"\u0006\u0001\u0006\u0001\u0006\u0000\u0000\u0007\u0000\u0002\u0004\u0006"+
+               
"\b\n\f\u0000\u0000L\u0000\u0012\u0001\u0000\u0000\u0000\u0002\u001b\u0001"+
+               
"\u0000\u0000\u0000\u0004\"\u0001\u0000\u0000\u0000\u00065\u0001\u0000"+
+               
"\u0000\u0000\bC\u0001\u0000\u0000\u0000\nE\u0001\u0000\u0000\u0000\fG"+
+               
"\u0001\u0000\u0000\u0000\u000e\u0013\u0005\u0000\u0000\u0001\u000f\u0010"+
+               
"\u0003\u0002\u0001\u0000\u0010\u0011\u0005\u0000\u0000\u0001\u0011\u0013"+
+               
"\u0001\u0000\u0000\u0000\u0012\u000e\u0001\u0000\u0000\u0000\u0012\u000f"+
+               
"\u0001\u0000\u0000\u0000\u0013\u0001\u0001\u0000\u0000\u0000\u0014\u001c"+
+               
"\u0003\u0004\u0002\u0000\u0015\u001c\u0003\u0006\u0003\u0000\u0016\u0017"+
+               
"\u0005\u0001\u0000\u0000\u0017\u0018\u0003\u0002\u0001\u0000\u0018\u0019"+
+               
"\u0005\u0002\u0000\u0000\u0019\u001c\u0001\u0000\u0000\u0000\u001a\u001c"+
+               
"\u0003\b\u0004\u0000\u001b\u0014\u0001\u0000\u0000\u0000\u001b\u0015\u0001"+
+               
"\u0000\u0000\u0000\u001b\u0016\u0001\u0000\u0000\u0000\u001b\u001a\u0001"+
+               
"\u0000\u0000\u0000\u001c\u0003\u0001\u0000\u0000\u0000\u001d#\u0003\b"+
+               "\u0004\u0000\u001e\u001f\u0005\u0001\u0000\u0000\u001f 
\u0003\u0002\u0001"+
+               "\u0000 
!\u0005\u0002\u0000\u0000!#\u0001\u0000\u0000\u0000\"\u001d\u0001"+
+               
"\u0000\u0000\u0000\"\u001e\u0001\u0000\u0000\u0000#,\u0001\u0000\u0000"+
+               
"\u0000$*\u0003\n\u0005\u0000%+\u0003\b\u0004\u0000&\'\u0005\u0001\u0000"+
+               
"\u0000\'(\u0003\u0002\u0001\u0000()\u0005\u0002\u0000\u0000)+\u0001\u0000"+
+               
"\u0000\u0000*%\u0001\u0000\u0000\u0000*&\u0001\u0000\u0000\u0000+-\u0001"+
+               
"\u0000\u0000\u0000,$\u0001\u0000\u0000\u0000-.\u0001\u0000\u0000\u0000"+
+               
".,\u0001\u0000\u0000\u0000./\u0001\u0000\u0000\u0000/\u0005\u0001\u0000"+
+               
"\u0000\u000006\u0003\b\u0004\u000012\u0005\u0001\u0000\u000023\u0003\u0002"+
+               
"\u0001\u000034\u0005\u0002\u0000\u000046\u0001\u0000\u0000\u000050\u0001"+
+               
"\u0000\u0000\u000051\u0001\u0000\u0000\u00006?\u0001\u0000\u0000\u0000"+
+               
"7=\u0003\f\u0006\u00008>\u0003\b\u0004\u00009:\u0005\u0001\u0000\u0000"+
+               
":;\u0003\u0002\u0001\u0000;<\u0005\u0002\u0000\u0000<>\u0001\u0000\u0000"+
+               
"\u0000=8\u0001\u0000\u0000\u0000=9\u0001\u0000\u0000\u0000>@\u0001\u0000"+
+               
"\u0000\u0000?7\u0001\u0000\u0000\u0000@A\u0001\u0000\u0000\u0000A?\u0001"+
+               
"\u0000\u0000\u0000AB\u0001\u0000\u0000\u0000B\u0007\u0001\u0000\u0000"+
+               
"\u0000CD\u0005\u0005\u0000\u0000D\t\u0001\u0000\u0000\u0000EF\u0005\u0003"+
+               
"\u0000\u0000F\u000b\u0001\u0000\u0000\u0000GH\u0005\u0004\u0000\u0000"+
+               "H\r\u0001\u0000\u0000\u0000\b\u0012\u001b\"*.5=A";
+       public static final ATN _ATN =
+               new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+       static {
+               _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+               for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+                       _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), 
i);
+               }
+       }
+}
\ No newline at end of file
diff --git a/src/main/java/module-info.java 
b/antlr4-example/src/main/java/module-info.java
similarity index 78%
copy from src/main/java/module-info.java
copy to antlr4-example/src/main/java/module-info.java
index 537dec8..8e8b3a3 100644
--- a/src/main/java/module-info.java
+++ b/antlr4-example/src/main/java/module-info.java
@@ -16,6 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-module accumulo.access {
-  exports org.apache.accumulo.access;
+module accumulo.access.examples.antlr {
+  exports org.apache.accumulo.access.antlr4;
+  exports org.apache.accumulo.access.grammars;
+  requires transitive accumulo.access.core;
+  requires transitive org.antlr.antlr4.runtime;
 }
\ No newline at end of file
diff --git 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
 
b/antlr4-example/src/main/java/org/apache/accumulo/access/antlr4/AccessExpressionAntlrEvaluator.java
similarity index 97%
rename from 
src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
rename to 
antlr4-example/src/main/java/org/apache/accumulo/access/antlr4/AccessExpressionAntlrEvaluator.java
index 7120150..0d1ba19 100644
--- 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
+++ 
b/antlr4-example/src/main/java/org/apache/accumulo/access/antlr4/AccessExpressionAntlrEvaluator.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.accumulo.access.grammar.antlr;
+package org.apache.accumulo.access.antlr4;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -25,7 +25,6 @@ import java.util.Set;
 
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
-import org.apache.accumulo.access.AccessEvaluator;
 import org.apache.accumulo.access.AccessExpression;
 import org.apache.accumulo.access.Authorizations;
 import org.apache.accumulo.access.InvalidAccessExpressionException;
diff --git 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrParser.java
 
b/antlr4-example/src/main/java/org/apache/accumulo/access/antlr4/AccessExpressionAntlrParser.java
similarity index 97%
rename from 
src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrParser.java
rename to 
antlr4-example/src/main/java/org/apache/accumulo/access/antlr4/AccessExpressionAntlrParser.java
index 8c2995e..289456c 100644
--- 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrParser.java
+++ 
b/antlr4-example/src/main/java/org/apache/accumulo/access/antlr4/AccessExpressionAntlrParser.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.accumulo.access.grammar.antlr;
+package org.apache.accumulo.access.antlr4;
 
 import java.nio.charset.StandardCharsets;
 
@@ -83,6 +83,8 @@ public class AccessExpressionAntlrParser {
 
   }
 
+  private AccessExpressionAntlrParser() {}
+
   public static Access_expressionContext parseAccessExpression(byte[] 
accessExpression)
       throws InvalidAccessExpressionException {
     return parseAccessExpression(new String(accessExpression, 
StandardCharsets.UTF_8));
diff --git 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/antlr/TestDataLoader.java
 
b/antlr4-example/src/test/java/org/apache/accumulo/access/antlr/TestDataLoader.java
similarity index 64%
rename from 
src/it/antlr4-example/src/test/java/org/apache/accumulo/access/antlr/TestDataLoader.java
rename to 
antlr4-example/src/test/java/org/apache/accumulo/access/antlr/TestDataLoader.java
index 173155f..a6a06bd 100644
--- 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/antlr/TestDataLoader.java
+++ 
b/antlr4-example/src/test/java/org/apache/accumulo/access/antlr/TestDataLoader.java
@@ -19,14 +19,10 @@
 package org.apache.accumulo.access.antlr;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.lang.reflect.Type;
 import java.net.URISyntaxException;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -52,20 +48,10 @@ public class TestDataLoader {
 
   public static List<TestDataSet> readTestData() throws IOException, 
URISyntaxException {
 
-    URL url = TestDataLoader.class.getClassLoader().getResource(".");
-    File testClassesDir = new File(url.toURI());
-    File accumuloAccessParentDir = 
testClassesDir.getParentFile().getParentFile().getParentFile()
-        .getParentFile().getParentFile();
-    File accumuloAccessSourceDir = new File(accumuloAccessParentDir, "src");
-    assertTrue(accumuloAccessSourceDir.exists());
-    File accumuloAccessTestDir = new File(accumuloAccessSourceDir, "test");
-    assertTrue(accumuloAccessTestDir.exists());
-    File accumuloAccessTestResourcesDir = new File(accumuloAccessTestDir, 
"resources");
-    assertTrue(accumuloAccessTestResourcesDir.exists());
-    File testDataFile = new File(accumuloAccessTestResourcesDir, 
"testdata.json");
-    assertTrue(testDataFile.exists());
-
-    try (FileInputStream input = new FileInputStream(testDataFile)) {
+    try (var input = 
TestDataLoader.class.getClassLoader().getResourceAsStream("testdata.json")) {
+      if (input == null) {
+        throw new IllegalStateException("could not find resource : 
testdata.json");
+      }
       var json = new String(input.readAllBytes(), UTF_8);
 
       Type listType = new TypeToken<ArrayList<TestDataSet>>() {}.getType();
diff --git 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/SpecificationTest.java
 
b/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/SpecificationTest.java
similarity index 91%
rename from 
src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/SpecificationTest.java
rename to 
antlr4-example/src/test/java/org/apache/accumulo/access/grammar/SpecificationTest.java
index b990775..5535f4b 100644
--- 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/SpecificationTest.java
+++ 
b/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/SpecificationTest.java
@@ -21,7 +21,6 @@ package org.apache.accumulo.access.grammar;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import java.io.InputStream;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.antlr.v4.runtime.CharStreams;
@@ -30,8 +29,6 @@ import org.antlr.v4.runtime.ConsoleErrorListener;
 import org.antlr.v4.runtime.LexerNoViableAltException;
 import org.antlr.v4.runtime.RecognitionException;
 import org.antlr.v4.runtime.Recognizer;
-import org.apache.accumulo.access.AccessExpression;
-import org.apache.accumulo.access.grammar.antlr.Antlr4Tests;
 import org.apache.accumulo.access.grammars.AbnfLexer;
 import org.apache.accumulo.access.grammars.AbnfParser;
 import org.junit.jupiter.api.Test;
@@ -44,7 +41,7 @@ public class SpecificationTest {
   @Test
   public void testAbnfSpecificationParses() throws Exception {
 
-    var is = 
AccessExpression.class.getResourceAsStream("specification/AccessExpression.abnf");
+    var is = 
SpecificationTest.class.getResourceAsStream("/AccessExpression.abnf");
     assertNotNull(is);
 
     final AtomicLong errors = new AtomicLong(0);
diff --git 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrBenchmark.java
 
b/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrBenchmark.java
similarity index 95%
rename from 
src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrBenchmark.java
rename to 
antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrBenchmark.java
index 75ec0a7..e32593a 100644
--- 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrBenchmark.java
+++ 
b/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrBenchmark.java
@@ -24,13 +24,15 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.TimeUnit;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.apache.accumulo.access.Authorizations;
 import org.apache.accumulo.access.antlr.TestDataLoader;
+import org.apache.accumulo.access.antlr4.AccessExpressionAntlrEvaluator;
+import org.apache.accumulo.access.antlr4.AccessExpressionAntlrParser;
 import 
org.apache.accumulo.access.grammars.AccessExpressionParser.Access_expressionContext;
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.Mode;
@@ -86,8 +88,8 @@ public class AccessExpressionAntlrBenchmark {
         et.parsedExpressions = new ArrayList<>();
         et.expressions = new ArrayList<>();
 
-        et.evaluator = new AccessExpressionAntlrEvaluator(
-            Stream.of(testDataSet.auths).map(a -> 
Authorizations.of(Set.of(a))).collect(Collectors.toList()));
+        et.evaluator = new 
AccessExpressionAntlrEvaluator(Stream.of(testDataSet.auths)
+            .map(a -> 
Authorizations.of(Set.of(a))).collect(Collectors.toList()));
 
         for (var tests : testDataSet.tests) {
           if (tests.expectedResult != TestDataLoader.ExpectedResult.ERROR) {
diff --git 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/Antlr4Tests.java
 
b/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/Antlr4Tests.java
similarity index 97%
rename from 
src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/Antlr4Tests.java
rename to 
antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/Antlr4Tests.java
index 4258a6b..3ed6a9e 100644
--- 
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/Antlr4Tests.java
+++ 
b/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/Antlr4Tests.java
@@ -26,8 +26,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -47,6 +47,7 @@ import org.apache.accumulo.access.antlr.TestDataLoader;
 import org.apache.accumulo.access.antlr.TestDataLoader.ExpectedResult;
 import org.apache.accumulo.access.antlr.TestDataLoader.TestDataSet;
 import org.apache.accumulo.access.antlr.TestDataLoader.TestExpressions;
+import org.apache.accumulo.access.antlr4.AccessExpressionAntlrEvaluator;
 import org.apache.accumulo.access.grammars.AccessExpressionLexer;
 import org.apache.accumulo.access.grammars.AccessExpressionParser;
 import 
org.apache.accumulo.access.grammars.AccessExpressionParser.Access_expressionContext;
@@ -141,8 +142,8 @@ public class Antlr4Tests {
     List<TestDataSet> testData = TestDataLoader.readTestData();
     for (TestDataSet testSet : testData) {
 
-      List<Authorizations> authSets =
-          Stream.of(testSet.auths).map(a -> 
Authorizations.of(Set.of(a))).collect(Collectors.toList());
+      List<Authorizations> authSets = Stream.of(testSet.auths)
+          .map(a -> Authorizations.of(Set.of(a))).collect(Collectors.toList());
       AccessEvaluator evaluator = AccessEvaluator.of(authSets);
       AccessExpressionAntlrEvaluator antlr = new 
AccessExpressionAntlrEvaluator(authSets);
 
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..ac07dfa
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      https://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.accumulo</groupId>
+    <artifactId>accumulo-access</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>accumulo-access-core</artifactId>
+  <packaging>jar</packaging>
+  <dependencies>
+    <dependency>
+      <groupId>com.github.spotbugs</groupId>
+      <artifactId>spotbugs-annotations</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.openjdk.jmh</groupId>
+      <artifactId>jmh-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.openjdk.jmh</groupId>
+      <artifactId>jmh-generator-annprocess</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>net.revelc.code</groupId>
+        <artifactId>apilyzer-maven-plugin</artifactId>
+        <version>1.3.0</version>
+        <executions>
+          <execution>
+            <id>apilyzer</id>
+            <goals>
+              <goal>analyze</goal>
+            </goals>
+            <configuration>
+              <includes>
+                
<include>org[.]apache[.]accumulo[.]access[.]InvalidAccessExpressionException</include>
+                
<include>org[.]apache[.]accumulo[.]access[.]AccessExpression</include>
+                
<include>org[.]apache[.]accumulo[.]access[.]AccessEvaluator</include>
+                
<include>org[.]apache[.]accumulo[.]access[.]Authorizations</include>
+                
<include>org[.]apache[.]accumulo[.]access[.]ParsedAccessExpression</include>
+              </includes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>benchmark</id>
+      <activation>
+        <property>
+          <name>benchmark</name>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>exec-maven-plugin</artifactId>
+            <version>3.3.0</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <phase>verify</phase>
+                <configuration>
+                  <classpathScope>test</classpathScope>
+                  <executable>java</executable>
+                  <arguments>
+                    <argument>-classpath</argument>
+                    <classpath />
+                    
<argument>org.apache.accumulo.access.tests.AccessExpressionBenchmark</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
diff --git a/src/main/java/module-info.java 
b/core/src/main/java/module-info.java
similarity index 96%
copy from src/main/java/module-info.java
copy to core/src/main/java/module-info.java
index 537dec8..37addd4 100644
--- a/src/main/java/module-info.java
+++ b/core/src/main/java/module-info.java
@@ -16,6 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-module accumulo.access {
+module accumulo.access.core {
   exports org.apache.accumulo.access;
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/accumulo/access/AccessEvaluator.java 
b/core/src/main/java/org/apache/accumulo/access/AccessEvaluator.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/AccessEvaluator.java
rename to core/src/main/java/org/apache/accumulo/access/AccessEvaluator.java
diff --git a/src/main/java/org/apache/accumulo/access/AccessExpression.java 
b/core/src/main/java/org/apache/accumulo/access/AccessExpression.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/AccessExpression.java
rename to core/src/main/java/org/apache/accumulo/access/AccessExpression.java
diff --git a/src/main/java/org/apache/accumulo/access/Authorizations.java 
b/core/src/main/java/org/apache/accumulo/access/Authorizations.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/Authorizations.java
rename to core/src/main/java/org/apache/accumulo/access/Authorizations.java
diff --git 
a/src/main/java/org/apache/accumulo/access/InvalidAccessExpressionException.java
 
b/core/src/main/java/org/apache/accumulo/access/InvalidAccessExpressionException.java
similarity index 100%
rename from 
src/main/java/org/apache/accumulo/access/InvalidAccessExpressionException.java
rename to 
core/src/main/java/org/apache/accumulo/access/InvalidAccessExpressionException.java
diff --git 
a/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java 
b/core/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java
rename to 
core/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java
diff --git 
a/src/main/java/org/apache/accumulo/access/impl/AccessEvaluatorImpl.java 
b/core/src/main/java/org/apache/accumulo/access/impl/AccessEvaluatorImpl.java
similarity index 100%
rename from 
src/main/java/org/apache/accumulo/access/impl/AccessEvaluatorImpl.java
rename to 
core/src/main/java/org/apache/accumulo/access/impl/AccessEvaluatorImpl.java
diff --git 
a/src/main/java/org/apache/accumulo/access/impl/AccessExpressionImpl.java 
b/core/src/main/java/org/apache/accumulo/access/impl/AccessExpressionImpl.java
similarity index 100%
rename from 
src/main/java/org/apache/accumulo/access/impl/AccessExpressionImpl.java
rename to 
core/src/main/java/org/apache/accumulo/access/impl/AccessExpressionImpl.java
diff --git a/src/main/java/org/apache/accumulo/access/impl/ByteUtils.java 
b/core/src/main/java/org/apache/accumulo/access/impl/ByteUtils.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/impl/ByteUtils.java
rename to core/src/main/java/org/apache/accumulo/access/impl/ByteUtils.java
diff --git a/src/main/java/org/apache/accumulo/access/impl/BytesWrapper.java 
b/core/src/main/java/org/apache/accumulo/access/impl/BytesWrapper.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/impl/BytesWrapper.java
rename to core/src/main/java/org/apache/accumulo/access/impl/BytesWrapper.java
diff --git 
a/src/main/java/org/apache/accumulo/access/impl/MultiAccessEvaluatorImpl.java 
b/core/src/main/java/org/apache/accumulo/access/impl/MultiAccessEvaluatorImpl.java
similarity index 100%
rename from 
src/main/java/org/apache/accumulo/access/impl/MultiAccessEvaluatorImpl.java
rename to 
core/src/main/java/org/apache/accumulo/access/impl/MultiAccessEvaluatorImpl.java
diff --git 
a/src/main/java/org/apache/accumulo/access/impl/ParsedAccessExpressionImpl.java 
b/core/src/main/java/org/apache/accumulo/access/impl/ParsedAccessExpressionImpl.java
similarity index 100%
rename from 
src/main/java/org/apache/accumulo/access/impl/ParsedAccessExpressionImpl.java
rename to 
core/src/main/java/org/apache/accumulo/access/impl/ParsedAccessExpressionImpl.java
diff --git a/src/main/java/org/apache/accumulo/access/impl/ParserEvaluator.java 
b/core/src/main/java/org/apache/accumulo/access/impl/ParserEvaluator.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/impl/ParserEvaluator.java
rename to 
core/src/main/java/org/apache/accumulo/access/impl/ParserEvaluator.java
diff --git a/src/main/java/org/apache/accumulo/access/impl/Tokenizer.java 
b/core/src/main/java/org/apache/accumulo/access/impl/Tokenizer.java
similarity index 100%
rename from src/main/java/org/apache/accumulo/access/impl/Tokenizer.java
rename to core/src/main/java/org/apache/accumulo/access/impl/Tokenizer.java
diff --git 
a/src/main/resources/org/apache/accumulo/access/specification/AccessExpression.abnf
 
b/core/src/main/resources/org/apache/accumulo/access/specification/AccessExpression.abnf
similarity index 100%
rename from 
src/main/resources/org/apache/accumulo/access/specification/AccessExpression.abnf
rename to 
core/src/main/resources/org/apache/accumulo/access/specification/AccessExpression.abnf
diff --git 
a/src/test/java/org/apache/accumulo/access/tests/AccessEvaluatorTest.java 
b/core/src/test/java/org/apache/accumulo/access/tests/AccessEvaluatorTest.java
similarity index 100%
rename from 
src/test/java/org/apache/accumulo/access/tests/AccessEvaluatorTest.java
rename to 
core/src/test/java/org/apache/accumulo/access/tests/AccessEvaluatorTest.java
diff --git 
a/src/test/java/org/apache/accumulo/access/tests/AccessExpressionBenchmark.java 
b/core/src/test/java/org/apache/accumulo/access/tests/AccessExpressionBenchmark.java
similarity index 100%
rename from 
src/test/java/org/apache/accumulo/access/tests/AccessExpressionBenchmark.java
rename to 
core/src/test/java/org/apache/accumulo/access/tests/AccessExpressionBenchmark.java
diff --git 
a/src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java 
b/core/src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
similarity index 95%
rename from 
src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
rename to 
core/src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
index 4bec427..c7f4c40 100644
--- a/src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
+++ 
b/core/src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
@@ -30,8 +30,6 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URISyntaxException;
-import java.nio.file.Files;
-import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -170,10 +168,14 @@ public class AccessExpressionTest {
       specLinesFromAbnfFile = 
bufferedReader.lines().dropWhile(beforeFirstLine).collect(toList());
     }
 
-    // grab from the markdown, but make sure to skip the markdown triple ticks
-    List<String> specLinesFromMarkdownFile = 
Files.readAllLines(Path.of("SPECIFICATION.md"))
-        .stream().dropWhile(line -> !line.startsWith("```ABNF")).skip(1)
-        .takeWhile(line -> !line.startsWith("```")).collect(toList());
+    List<String> specLinesFromMarkdownFile;
+    try (var specFile = 
AccessExpression.class.getResourceAsStream("/SPECIFICATION.md");
+        var specFileReader = new InputStreamReader(specFile, UTF_8);
+        var specFileBufferedReader = new BufferedReader(specFileReader)) {
+      specLinesFromMarkdownFile =
+          specFileBufferedReader.lines().dropWhile(line -> 
!line.startsWith("```ABNF")).skip(1)
+              .takeWhile(line -> !line.startsWith("```")).collect(toList());
+    }
 
     assertFalse(specLinesFromAbnfFile.isEmpty()); // make sure we didn't just 
compare nothing
     assertEquals(specLinesFromAbnfFile, specLinesFromMarkdownFile);
diff --git 
a/src/test/java/org/apache/accumulo/access/tests/AuthorizationTest.java 
b/core/src/test/java/org/apache/accumulo/access/tests/AuthorizationTest.java
similarity index 100%
rename from 
src/test/java/org/apache/accumulo/access/tests/AuthorizationTest.java
rename to 
core/src/test/java/org/apache/accumulo/access/tests/AuthorizationTest.java
diff --git 
a/src/test/java/org/apache/accumulo/access/tests/ParsedAccessExpressionTest.java
 
b/core/src/test/java/org/apache/accumulo/access/tests/ParsedAccessExpressionTest.java
similarity index 100%
rename from 
src/test/java/org/apache/accumulo/access/tests/ParsedAccessExpressionTest.java
rename to 
core/src/test/java/org/apache/accumulo/access/tests/ParsedAccessExpressionTest.java
diff --git a/src/it/settings.xml b/examples/pom.xml
similarity index 50%
rename from src/it/settings.xml
rename to examples/pom.xml
index 0b3a97b..854d318 100644
--- a/src/it/settings.xml
+++ b/examples/pom.xml
@@ -19,37 +19,25 @@
     under the License.
 
 -->
-<settings>
-  <profiles>
-    <profile>
-      <id>it-repo</id>
-      <activation>
-        <activeByDefault>true</activeByDefault>
-      </activation>
-      <repositories>
-        <repository>
-          <id>local.central</id>
-          <url>@localRepositoryUrl@</url>
-          <releases>
-            <enabled>true</enabled>
-          </releases>
-          <snapshots>
-            <enabled>true</enabled>
-          </snapshots>
-        </repository>
-      </repositories>
-      <pluginRepositories>
-        <pluginRepository>
-          <id>local.central</id>
-          <url>@localRepositoryUrl@</url>
-          <releases>
-            <enabled>true</enabled>
-          </releases>
-          <snapshots>
-            <enabled>true</enabled>
-          </snapshots>
-        </pluginRepository>
-      </pluginRepositories>
-    </profile>
-  </profiles>
-</settings>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.accumulo</groupId>
+    <artifactId>accumulo-access</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>accumulo-access-examples</artifactId>
+  <packaging>jar</packaging>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-access-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/src/main/java/module-info.java 
b/examples/src/main/java/module-info.java
similarity index 86%
rename from src/main/java/module-info.java
rename to examples/src/main/java/module-info.java
index 537dec8..1e17bb0 100644
--- a/src/main/java/module-info.java
+++ b/examples/src/main/java/module-info.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-module accumulo.access {
-  exports org.apache.accumulo.access;
+module accumulo.access.examples {
+  exports org.apache.accumulo.access.examples;
+  requires transitive accumulo.access.core;
 }
\ No newline at end of file
diff --git a/src/test/java/example/AccessExample.java 
b/examples/src/main/java/org/apache/accumulo/access/examples/AccessExample.java
similarity index 82%
rename from src/test/java/example/AccessExample.java
rename to 
examples/src/main/java/org/apache/accumulo/access/examples/AccessExample.java
index 5b4b2cc..d60bcfb 100644
--- a/src/test/java/example/AccessExample.java
+++ 
b/examples/src/main/java/org/apache/accumulo/access/examples/AccessExample.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package example;
+package org.apache.accumulo.access.examples;
 
 import java.io.PrintStream;
 import java.util.Arrays;
@@ -31,29 +31,24 @@ import org.apache.accumulo.access.Authorizations;
 public class AccessExample {
 
   public static void main(String[] args) {
-    PrintStream out = System.out;
-    var example = new AccessExample(out);
+    var example = new AccessExample();
     if (args.length == 0) {
-      out.printf("No authorizations provided. Running several examples.%n"
+      System.out.printf("No authorizations provided. Running several 
examples.%n"
           + "Specify authorizations on the command line (separated by spaces) 
to try a specific example.%n%n");
 
-      example.run("BLUE", "GREEN", "PINK", "RED");
-      example.run();
-      example.run("BLUE", "RED");
-      example.run("GREEN", "RED");
-      example.run("PINK");
+      example.run(System.out, "BLUE", "GREEN", "PINK", "RED");
+      example.run(System.out);
+      example.run(System.out, "BLUE", "RED");
+      example.run(System.out, "GREEN", "RED");
+      example.run(System.out, "PINK");
     } else {
-      example.run(args);
+      example.run(System.out, args);
     }
   }
 
-  private final PrintStream out;
+  public AccessExample() {}
 
-  AccessExample(PrintStream out) {
-    this.out = out;
-  }
-
-  void run(String... authorizations) {
+  public void run(PrintStream out, String... authorizations) {
     out.printf("Showing accessible records using authorizations: %s%n",
         Arrays.toString(authorizations));
 
diff --git a/src/test/java/example/ParseExamples.java 
b/examples/src/main/java/org/apache/accumulo/access/examples/ParseExamples.java
similarity index 99%
rename from src/test/java/example/ParseExamples.java
rename to 
examples/src/main/java/org/apache/accumulo/access/examples/ParseExamples.java
index 2c99322..d9cf134 100644
--- a/src/test/java/example/ParseExamples.java
+++ 
b/examples/src/main/java/org/apache/accumulo/access/examples/ParseExamples.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package example;
+package org.apache.accumulo.access.examples;
 
 import static org.apache.accumulo.access.AccessExpression.quote;
 import static org.apache.accumulo.access.AccessExpression.unquote;
@@ -36,6 +36,8 @@ import 
org.apache.accumulo.access.ParsedAccessExpression.ExpressionType;
  */
 public class ParseExamples {
 
+  private ParseExamples() {}
+
   /**
    * This example will replace authorizations in an access expression.
    */
diff --git a/src/test/java/example/AccessExampleTest.java 
b/examples/src/test/java/org/apache/accumulo/access/examples/test/AccessExampleTest.java
similarity index 89%
rename from src/test/java/example/AccessExampleTest.java
rename to 
examples/src/test/java/org/apache/accumulo/access/examples/test/AccessExampleTest.java
index 2bb34bb..7ec077b 100644
--- a/src/test/java/example/AccessExampleTest.java
+++ 
b/examples/src/test/java/org/apache/accumulo/access/examples/test/AccessExampleTest.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package example;
+package org.apache.accumulo.access.examples.test;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -27,6 +27,7 @@ import java.io.IOException;
 import java.io.PrintStream;
 import java.util.List;
 
+import org.apache.accumulo.access.examples.AccessExample;
 import org.junit.jupiter.api.Test;
 
 public class AccessExampleTest {
@@ -34,8 +35,8 @@ public class AccessExampleTest {
   public void testExampleCode() throws IOException {
     try (final var baos = new ByteArrayOutputStream();
         final var out = new PrintStream(baos, false, UTF_8)) {
-      final var example = new AccessExample(out);
-      example.run("RED", "BLUE");
+      final var example = new AccessExample();
+      example.run(out, "RED", "BLUE");
       var output = baos.toString(UTF_8);
       for (var expected : List.of("data3", "data5", "data6", "data9")) {
         assertTrue(output.contains(expected + " : "));
diff --git a/src/test/java/example/ParseExamplesTest.java 
b/examples/src/test/java/org/apache/accumulo/access/examples/test/ParseExamplesTest.java
similarity index 96%
rename from src/test/java/example/ParseExamplesTest.java
rename to 
examples/src/test/java/org/apache/accumulo/access/examples/test/ParseExamplesTest.java
index 81b4d6e..6800a01 100644
--- a/src/test/java/example/ParseExamplesTest.java
+++ 
b/examples/src/test/java/org/apache/accumulo/access/examples/test/ParseExamplesTest.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package example;
+package org.apache.accumulo.access.examples.test;
 
-import static example.ParseExamples.replaceAuthorizations;
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static 
org.apache.accumulo.access.examples.ParseExamples.replaceAuthorizations;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.ArrayList;
@@ -27,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.examples.ParseExamples;
 import org.junit.jupiter.api.Test;
 
 // In addition to testing the examples, these test also provide extensive 
testing of ParsedAccessExpression
diff --git a/pom.xml b/pom.xml
index 5fb4358..2e1ef63 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,7 @@
   <groupId>org.apache.accumulo</groupId>
   <artifactId>accumulo-access</artifactId>
   <version>1.0.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
   <name>Apache Accumulo Access Project</name>
   <description>Apache Accumulo Access is a library that provides the same 
functionality, semantics, and syntax
   as the Apache Accumulo ColumnVisibility and VisibilityEvaluator classes. 
This functionality is provided in a
@@ -72,6 +73,11 @@
       
<archive>https://lists.apache.org/[email protected]</archive>
     </mailingList>
   </mailingLists>
+  <modules>
+    <module>core</module>
+    <module>examples</module>
+    <module>antlr4-example</module>
+  </modules>
   <scm>
     
<connection>scm:git:https://gitbox.apache.org/repos/asf/accumulo-access.git</connection>
     
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/accumulo-access.git</developerConnection>
@@ -104,49 +110,52 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <rat.consoleOutput>true</rat.consoleOutput>
     
<sourceReleaseAssemblyDescriptor>source-release-tar</sourceReleaseAssemblyDescriptor>
+    <version.accumulo>3.0.0</version.accumulo>
     <version.errorprone>2.24.1</version.errorprone>
     <version.gson>2.10.1</version.gson>
     <version.jmh>1.37</version.jmh>
     <version.junit>5.10.2</version.junit>
   </properties>
-  <dependencies>
-    <dependency>
-      <groupId>com.github.spotbugs</groupId>
-      <artifactId>spotbugs-annotations</artifactId>
-      <version>4.9.3</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-      <version>${version.gson}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-core</artifactId>
-      <version>3.0.0</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-api</artifactId>
-      <version>${version.junit}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.openjdk.jmh</groupId>
-      <artifactId>jmh-core</artifactId>
-      <version>${version.jmh}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.openjdk.jmh</groupId>
-      <artifactId>jmh-generator-annprocess</artifactId>
-      <version>${version.jmh}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>com.github.spotbugs</groupId>
+        <artifactId>spotbugs-annotations</artifactId>
+        <version>4.9.3</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>com.google.code.gson</groupId>
+        <artifactId>gson</artifactId>
+        <version>${version.gson}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.accumulo</groupId>
+        <artifactId>accumulo-core</artifactId>
+        <version>${version.accumulo}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>${version.junit}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.openjdk.jmh</groupId>
+        <artifactId>jmh-core</artifactId>
+        <version>${version.jmh}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.openjdk.jmh</groupId>
+        <artifactId>jmh-generator-annprocess</artifactId>
+        <version>${version.jmh}</version>
+        <scope>test</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
   <build>
     <plugins>
       <plugin>
@@ -158,7 +167,8 @@
             <licenseSet>
               <header>src/build/license-header.txt</header>
               <excludes>
-                
<exclude>src/it/antlr4-example/src/main/antlr4/Abnf.g4</exclude>
+                <exclude>src/main/antlr4/Abnf.g4</exclude>
+                <exclude>src/main/generated-antlr4-sources/**</exclude>
                 <exclude>**/DEPENDENCIES</exclude>
                 <exclude>**/LICENSE</exclude>
                 <exclude>**/NOTICE</exclude>
@@ -222,7 +232,7 @@
         <artifactId>formatter-maven-plugin</artifactId>
         <version>2.23.0</version>
         <configuration>
-          <configFile>src/build/eclipse-codestyle.xml</configFile>
+          <configFile>../src/build/eclipse-codestyle.xml</configFile>
           <lineEnding>LF</lineEnding>
           <skipCssFormatting>true</skipCssFormatting>
           <skipHtmlFormatting>true</skipHtmlFormatting>
@@ -239,28 +249,6 @@
           </execution>
         </executions>
       </plugin>
-      <plugin>
-        <groupId>net.revelc.code</groupId>
-        <artifactId>apilyzer-maven-plugin</artifactId>
-        <version>1.3.0</version>
-        <executions>
-          <execution>
-            <id>apilyzer</id>
-            <goals>
-              <goal>analyze</goal>
-            </goals>
-            <configuration>
-              <includes>
-                
<include>org[.]apache[.]accumulo[.]access[.]InvalidAccessExpressionException</include>
-                
<include>org[.]apache[.]accumulo[.]access[.]AccessExpression</include>
-                
<include>org[.]apache[.]accumulo[.]access[.]AccessEvaluator</include>
-                
<include>org[.]apache[.]accumulo[.]access[.]Authorizations</include>
-                
<include>org[.]apache[.]accumulo[.]access[.]ParsedAccessExpression</include>
-              </includes>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
       <plugin>
         <groupId>org.gaul</groupId>
         <artifactId>modernizer-maven-plugin</artifactId>
@@ -291,7 +279,7 @@
         <artifactId>spotbugs-maven-plugin</artifactId>
         <version>4.9.3.0</version>
         <configuration>
-          
<excludeFilterFile>src/build/ci/spotbugs-exclude.xml</excludeFilterFile>
+          
<excludeFilterFile>../src/build/ci/spotbugs-exclude.xml</excludeFilterFile>
           <xmlOutput>true</xmlOutput>
           <effort>Max</effort>
           <failOnError>true</failOnError>
@@ -454,7 +442,6 @@
         <configuration>
           <archive>
             <manifestEntries>
-              
<Automatic-Module-Name>${accumulo.module.name}</Automatic-Module-Name>
               <Implementation-Build>${mvngit.commit.id}</Implementation-Build>
               <Sealed>true</Sealed>
             </manifestEntries>
@@ -468,27 +455,9 @@
           <quiet>true</quiet>
           <additionalJOption>-J-Xmx512m</additionalJOption>
           <doclint>all,-missing</doclint>
-          <legacyMode>true</legacyMode>
+          <legacyMode>false</legacyMode>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-invoker-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>invoked-integration-tests</id>
-            <goals>
-              <goal>install</goal>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <cloneProjectsTo>${project.build.directory}/its</cloneProjectsTo>
-              
<localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>
-              <settingsFile>src/it/settings.xml</settingsFile>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-release-plugin</artifactId>
@@ -509,9 +478,10 @@
         <artifactId>apache-rat-plugin</artifactId>
         <configuration>
           <excludes>
-            <exclude>src/it/antlr4-example/src/main/antlr4/Abnf.g4</exclude>
+            <exclude>src/main/generated-antlr4-sources/**</exclude>
+            <exclude>src/main/antlr4/Abnf.g4</exclude>
             <exclude>src/test/resources/testdata.json</exclude>
-            <exclude>.github/**</exclude>
+            <exclude>**/.github/**</exclude>
           </excludes>
         </configuration>
         <executions>
@@ -525,20 +495,32 @@
         </executions>
       </plugin>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.5.0</version>
+        <artifactId>maven-resources-plugin</artifactId>
         <executions>
           <execution>
-            <id>create-automatic-module-name</id>
+            <id>copy-test-resources</id>
             <goals>
-              <goal>regex-property</goal>
+              <goal>copy-resources</goal>
             </goals>
+            <phase>process-test-resources</phase>
             <configuration>
-              <name>accumulo.module.name</name>
-              <regex>-</regex>
-              <replacement>.</replacement>
-              <value>org-apache-${project.artifactId}</value>
+              <outputDirectory>${basedir}/target/test-classes</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>${maven.multiModuleProjectDirectory}</directory>
+                  <filtering>false</filtering>
+                  <includes>
+                    <include>SPECIFICATION.md</include>
+                  </includes>
+                </resource>
+                <resource>
+                  
<directory>${maven.multiModuleProjectDirectory}/src/test/resources</directory>
+                  <filtering>false</filtering>
+                  <includes>
+                    <include>testdata.json</include>
+                  </includes>
+                </resource>
+              </resources>
             </configuration>
           </execution>
         </executions>
@@ -753,39 +735,5 @@
         </plugins>
       </build>
     </profile>
-    <profile>
-      <id>benchmark</id>
-      <activation>
-        <property>
-          <name>benchmark</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <version>3.3.0</version>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>exec</goal>
-                </goals>
-                <phase>verify</phase>
-                <configuration>
-                  <classpathScope>test</classpathScope>
-                  <executable>java</executable>
-                  <arguments>
-                    <argument>-classpath</argument>
-                    <classpath />
-                    
<argument>org.apache.accumulo.access.tests.AccessExpressionBenchmark</argument>
-                  </arguments>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
   </profiles>
 </project>
diff --git a/src/it/antlr4-example/invoker.properties 
b/src/it/antlr4-example/invoker.properties
deleted file mode 100644
index 8b360bf..0000000
--- a/src/it/antlr4-example/invoker.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-invoker.goals = clean verify
-
-# The expected result of the build, possible values are "success" (default) 
and "failure"
-invoker.buildResult = success
diff --git a/src/it/antlr4-example/pom.xml b/src/it/antlr4-example/pom.xml
deleted file mode 100644
index c1ace65..0000000
--- a/src/it/antlr4-example/pom.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-      https://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache</groupId>
-    <artifactId>apache</artifactId>
-    <version>31</version>
-  </parent>
-  <groupId>org.apache.accumulo</groupId>
-  <artifactId>accumulo-access-antlr4-example</artifactId>
-  <version>@project.version@</version>
-  <name>Apache Accumulo Access Antlr4 Example</name>
-  <properties>
-    <maven.compiler.release>17</maven.compiler.release>
-    <maven.compiler.source>17</maven.compiler.source>
-    <maven.compiler.target>17</maven.compiler.target>
-    
<maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>org.antlr</groupId>
-      <artifactId>antlr4-runtime</artifactId>
-      <version>4.13.1</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-access</artifactId>
-      <version>@project.version@</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-      <version>@version.gson@</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-api</artifactId>
-      <version>@version.junit@</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.openjdk.jmh</groupId>
-      <artifactId>jmh-core</artifactId>
-      <version>@version.jmh@</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.openjdk.jmh</groupId>
-      <artifactId>jmh-generator-annprocess</artifactId>
-      <version>@version.jmh@</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.antlr</groupId>
-        <artifactId>antlr4-maven-plugin</artifactId>
-        <version>4.13.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>antlr4</goal>
-            </goals>
-            <phase>generate-sources</phase>
-            <configuration>
-              <arguments>
-                <arg>-package</arg>
-                <arg>org.apache.accumulo.access.grammars</arg>
-              </arguments>
-              <listener>false</listener>
-              <visitor>false</visitor>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>

Reply via email to