Skip to content
This repository was archived by the owner on Oct 11, 2025. It is now read-only.
Pieter Svenson edited this page Nov 25, 2022 · 3 revisions

Mantle allows you to create an ANTLR grammar file and generate most of the code that will parser users' commands. Your job will to be to write the grammar file and then to implement the specific "visitor" class that defines all the different commands that a user can actually type.

Getting Started

Add Mantle to Your Project

You may use Maven Central to include Mantle in your project. Your final JAR must include Mantle, which you can do using your build tool's shading technology.

Mantle separates platform-agnostic (common) functionality from platform-specific functionality. If you have a one-platform plugin, just include both common and the platform-specific package in your build file. If you have a multi-platform plugin, include common in your corresponding "common" project and include the platform-specific package in your platform-specific packages.

The examples below are written assuming a single-platform project.

For [platform], current options are:

  • common: For all core Mantle functionality. For multi-platform projects, this should be in your "common" equivalent project. For single-platform project, include this in your build file along with the platform-specific dependency.
  • bukkit: For bukkit/spigot/paper projects.
  • sponge8: For sponge projects using API 8

Latest version: 0.0.0

Gradle

build.gradle

plugins {
  id 'antlr'
  id 'com.github.johnrengelman.shadow' version '7.0.0'
}

repositories {
  mavenCentral()
}

dependencies {
  antlr 'org.antlr:antlr4:4.9.3'
  implementation 'me.pietelite.mantle:common:[version]'
  implementation 'me.pietelite.mantle:[platform]:[version]'
}

generateGrammarSource {
  arguments += ["-visitor", "-lib", "src/main/antlr/path/to/antlr/file/", "-package", "your.project.package"]
}

shadowJar {
  relocate 'me.pietelite.mantle', 'your.project.package.libs.mantle'
  relocate 'org.antlr', 'your.project.package.libs.antlr'
  relocate 'com.vmware.antlr4c3', 'your.project.package.libs.c3'  // used for command completion
}

Maven

pom.xml: UNTESTED, Gradle is recommended.

<project ...>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml
                    </dependencyReducedPomLocation>
                    <relocations>
                        <relocation>
                            <pattern>me.pietelite.mantle</pattern>
                            <shadedPattern>com.yourplugin.libs.mantle</shadedPattern>
                        </relocation>
                        <relocation>
                            <pattern>org.antlr</pattern>
                            <shadedPattern>com.yourplugin.libs.antlr</shadedPattern>
                        </relocation>
                        <relocation>
                            <pattern>com.vmware.antlr4c3</pattern>
                            <shadedPattern>com.yourplugin.libs.c3</shadedPattern>
                        </relocation>
                    </relocations>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <minimizeJar>true</minimizeJar>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.antlr</groupId>
                <artifactId>antlr4-maven-plugin</artifactId>
                <version>4.3</version>
                <executions>
                    <execution>
                        <configuration>
                            <goals>
                                <goal>antlr4</goal>
                            </goals>
                            <visitor>true</visitor>
                            <sourceDirectory>src/main/antlr/path/to/antlr/file/</libDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <repositories>
        ...
        <repository>
            <id>sonatype</id>
            <url>https://oss.sonatype.org/content/groups/public/</url>
        </repository>
    </repositories>

    <dependencies>
        ...
        <dependency>
            <groupId>me.pietelite.mantle</groupId>
            <artifactId>[platform]</artifactId>
            <version>[version]</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4</artifactId>
            <version>4.9.3</version>
        </dependency>
    </dependencies>
</project>

Create Grammar File

Look here to get a detailed education on ANTLR4; this tutorial will only touch on a few relevant topics.

Start by creating your grammar file in your project at yourproject/src/main/antlr/com/your/artifict/id/PluginName.g4. If your artifact id was net.minecraft, and your project was called Creeper, you may put the file at creeper/src/main/antlr/net/minecraft/Creeper.g4.

The actual file will contain a series of definitions of rules. Each rule basically defines what kind of other rules or "tokens" can come after it, where tokens are just text.

Unless you already know how to use ANTLR, put this at the end of your file:

// MANTLE NODES
identifier: ID | SINGLE_QUOTE ID+ SINGLE_QUOTE | DOUBLE_QUOTE ID+ DOUBLE_QUOTE;
ID: [a-zA-Z0-9\-_]+;
ID_SET: ID (COMMA ID)+;
COMMA: ',';
SINGLE_QUOTE: '\'';
DOUBLE_QUOTE: '"';
WS : [ \t\r\n]+ -> channel(HIDDEN); // skip spaces, tabs, newlines
// END MANTLE NODES

These are good rules and tokens to have for your custom rules and will also setup the ANTLR parsing appropriately. Use the identifier rule wherever there is a custom parameter.

Look at the test module of the project to see what a possible ANTLR file may look like.

Generate Command Code

Double check that you have included arguments to this task: -visitor -lib src/main/antlr/path/to/antlr/file/ -package your.project.package.

Use the ANTLR build process to "Generate Grammar Source". The generated code should appear in build/generated-src/. Some of the files should be a ...Visitor classes. One is an abstract class and the other is an interface. You may use either.

Implement command connector

Implement a Mantle CommandConnector. You can use CommandConnector.builder(). Use the generated lexer and parser to populate those fields in the command connector. Implement your grammar's generated ...Visitor class to return from the executor.

Register your command connector

Use the platform-specific command registrar to register your command connector. Then you are done!

Example

Here are examples of projects that use Mantle. The links may become stale.