Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion RichRail/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,57 @@
RichRail
# ANTLR4 RichRail Starter
A starter project for the RichRail command line DSL.
This project is part of an assignment for
Patterns and Frameworks at the Hogeschool Utrecht.

# How do I set this up?
* The project uses Java 11, but you can change this in `pom.xml` if need be
* Install packages using Maven (see `pom.xml`)
* This automatically generates
the required classes through ANTLR4
* For manually updating/regenerating the required classes
based on the grammar, you can let Maven execute the
antlr4:antlr4 command

# How to start?
`Main.java` is the entry point. This sets up
all the required components.
It requests input, tokenizes it, parses it
and walks over the ParseTree using our custom
`RichRailCli`, which is a Listener that *extends*
the `RichRailBaseListener` generated by ANTLR4. The
Listener listens to `enter` and `exit` events.

To configure our own actions, we need to override
the relevant methods.

# What is going on?
ANTLR4 generates Parser, Visitor and Listener
classes based on the `RichRail.g4` grammar
found in `src/main/antlr4/parser`.
These classes contain context and methods needed
for visiting the nodes in the parse tree or
for listening to events when entering or exiting
the nodes in a parse tree.
In this example, a Visitor approach has been used.

The `RichRailCli` is a custom class that extends
the base listener generated by ANTLR4. In this custom class,
we can overwrite the steps taken when traversing each node
in a certain expression.

# Where are all the classes?
ANTLR4 generates these class files
in the target directory. You can use the
maven commands defined in the `pom.xml`.

The generated classes are output to
the `target/generated-sources/antlr4` directory
and reside in the project's `parser` package.
This is due to the standard configuration of ANTLR4,
matching the location of the grammar file (`src/antlr4/parser`).
No further configuration required.

# Author
Alex Rothuis: [@arothuis](https://twitter.com/arothuis)

[arothuis.nl](http://arothuis.nl)
55 changes: 55 additions & 0 deletions RichRail/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>

<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>

<groupId>nl.arothuis</groupId>
<artifactId>antlr4-richrail-starter</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<!-- Add the antlr-runtime -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.7.1</version>
</dependency>

<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>4.7.1</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.7.1</version>
<configuration>
<arguments>
<argument>-listener</argument>
<argument>-visitor</argument>
</arguments>
</configuration>
<executions>
<execution>
<id>antlr</id>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
17 changes: 17 additions & 0 deletions RichRail/src/main/antlr4/parser/RichRail.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
grammar RichRail;

// Rules
command : newcommand | addcommand | getcommand | delcommand | remcommand;
newcommand : newtraincommand | newwagoncommand;
newtraincommand : 'new' 'train' ID;
newwagoncommand : 'new' 'wagon' ID ('numseats' NUMBER)?;
addcommand : 'add' ID 'to' ID;
getcommand : 'getnumseats' type id=ID;
delcommand : 'delete' type ID;
remcommand : 'remove' ID 'from' ID;
type : 'train' | 'wagon';

// Tokens
ID : ('a'..'z')('a'..'z'|'0'..'9')*;
NUMBER : ('0'..'9')+;
WHITESPACE : [ \t\r\n\u000C] -> skip;
28 changes: 28 additions & 0 deletions RichRail/src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import parser.*;

public class Main {
public static void main(String[] args) {
CharStream lineStream = CharStreams.fromString("new train tr1");

// Tokenize / Lexical analysis
Lexer lexer = new RichRailLexer(lineStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);

// Create Parse Tree
RichRailParser parser = new RichRailParser(tokens);
ParseTree tree = parser.command();

// Create ParseTreeWalker and Custom Listener
ParseTreeWalker walker = new ParseTreeWalker();
RichRailListener listener = new RichRailCli();

// Walk over ParseTree using Custom Listener that listens to enter/exit events
walker.walk(listener, tree);
}
}
5 changes: 5 additions & 0 deletions RichRail/src/main/java/parser/RichRailCli.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package parser;

public class RichRailCli extends RichRailBaseListener {
// Override methods as desired...
}
Binary file added RichRail/target/classes/Main.class
Binary file not shown.
23 changes: 23 additions & 0 deletions RichRail/target/classes/RichRail.tokens
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
ID=11
NUMBER=12
WHITESPACE=13
'new'=1
'train'=2
'wagon'=3
'numseats'=4
'add'=5
'to'=6
'getnumseats'=7
'delete'=8
'remove'=9
'from'=10
23 changes: 23 additions & 0 deletions RichRail/target/classes/RichRailLexer.tokens
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
ID=11
NUMBER=12
WHITESPACE=13
'new'=1
'train'=2
'wagon'=3
'numseats'=4
'add'=5
'to'=6
'getnumseats'=7
'delete'=8
'remove'=9
'from'=10
46 changes: 46 additions & 0 deletions RichRail/target/classes/parser/RichRail.interp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
token literal names:
null
'new'
'train'
'wagon'
'numseats'
'add'
'to'
'getnumseats'
'delete'
'remove'
'from'
null
null
null

token symbolic names:
null
null
null
null
null
null
null
null
null
null
null
ID
NUMBER
WHITESPACE

rule names:
command
newcommand
newtraincommand
newwagoncommand
addcommand
getcommand
delcommand
remcommand
type


atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 15, 63, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 26, 10, 2, 3, 3, 3, 3, 5, 3, 30, 10, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 41, 10, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 2, 2, 11, 2, 4, 6, 8, 10, 12, 14, 16, 18, 2, 3, 3, 2, 4, 5, 2, 59, 2, 25, 3, 2, 2, 2, 4, 29, 3, 2, 2, 2, 6, 31, 3, 2, 2, 2, 8, 35, 3, 2, 2, 2, 10, 42, 3, 2, 2, 2, 12, 47, 3, 2, 2, 2, 14, 51, 3, 2, 2, 2, 16, 55, 3, 2, 2, 2, 18, 60, 3, 2, 2, 2, 20, 26, 5, 4, 3, 2, 21, 26, 5, 10, 6, 2, 22, 26, 5, 12, 7, 2, 23, 26, 5, 14, 8, 2, 24, 26, 5, 16, 9, 2, 25, 20, 3, 2, 2, 2, 25, 21, 3, 2, 2, 2, 25, 22, 3, 2, 2, 2, 25, 23, 3, 2, 2, 2, 25, 24, 3, 2, 2, 2, 26, 3, 3, 2, 2, 2, 27, 30, 5, 6, 4, 2, 28, 30, 5, 8, 5, 2, 29, 27, 3, 2, 2, 2, 29, 28, 3, 2, 2, 2, 30, 5, 3, 2, 2, 2, 31, 32, 7, 3, 2, 2, 32, 33, 7, 4, 2, 2, 33, 34, 7, 13, 2, 2, 34, 7, 3, 2, 2, 2, 35, 36, 7, 3, 2, 2, 36, 37, 7, 5, 2, 2, 37, 40, 7, 13, 2, 2, 38, 39, 7, 6, 2, 2, 39, 41, 7, 14, 2, 2, 40, 38, 3, 2, 2, 2, 40, 41, 3, 2, 2, 2, 41, 9, 3, 2, 2, 2, 42, 43, 7, 7, 2, 2, 43, 44, 7, 13, 2, 2, 44, 45, 7, 8, 2, 2, 45, 46, 7, 13, 2, 2, 46, 11, 3, 2, 2, 2, 47, 48, 7, 9, 2, 2, 48, 49, 5, 18, 10, 2, 49, 50, 7, 13, 2, 2, 50, 13, 3, 2, 2, 2, 51, 52, 7, 10, 2, 2, 52, 53, 5, 18, 10, 2, 53, 54, 7, 13, 2, 2, 54, 15, 3, 2, 2, 2, 55, 56, 7, 11, 2, 2, 56, 57, 7, 13, 2, 2, 57, 58, 7, 12, 2, 2, 58, 59, 7, 13, 2, 2, 59, 17, 3, 2, 2, 2, 60, 61, 9, 2, 2, 2, 61, 19, 3, 2, 2, 2, 5, 25, 29, 40]
Binary file not shown.
Binary file not shown.
Binary file added RichRail/target/classes/parser/RichRailCli.class
Binary file not shown.
Binary file not shown.
56 changes: 56 additions & 0 deletions RichRail/target/classes/parser/RichRailLexer.interp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
token literal names:
null
'new'
'train'
'wagon'
'numseats'
'add'
'to'
'getnumseats'
'delete'
'remove'
'from'
null
null
null

token symbolic names:
null
null
null
null
null
null
null
null
null
null
null
ID
NUMBER
WHITESPACE

rule names:
T__0
T__1
T__2
T__3
T__4
T__5
T__6
T__7
T__8
T__9
ID
NUMBER
WHITESPACE

channel names:
DEFAULT_TOKEN_CHANNEL
HIDDEN

mode names:
DEFAULT_MODE

atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 15, 108, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 7, 12, 95, 10, 12, 12, 12, 14, 12, 98, 11, 12, 3, 13, 6, 13, 101, 10, 13, 13, 13, 14, 13, 102, 3, 14, 3, 14, 3, 14, 3, 14, 2, 2, 15, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 3, 2, 4, 4, 2, 50, 59, 99, 124, 5, 2, 11, 12, 14, 15, 34, 34, 2, 109, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 3, 29, 3, 2, 2, 2, 5, 33, 3, 2, 2, 2, 7, 39, 3, 2, 2, 2, 9, 45, 3, 2, 2, 2, 11, 54, 3, 2, 2, 2, 13, 58, 3, 2, 2, 2, 15, 61, 3, 2, 2, 2, 17, 73, 3, 2, 2, 2, 19, 80, 3, 2, 2, 2, 21, 87, 3, 2, 2, 2, 23, 92, 3, 2, 2, 2, 25, 100, 3, 2, 2, 2, 27, 104, 3, 2, 2, 2, 29, 30, 7, 112, 2, 2, 30, 31, 7, 103, 2, 2, 31, 32, 7, 121, 2, 2, 32, 4, 3, 2, 2, 2, 33, 34, 7, 118, 2, 2, 34, 35, 7, 116, 2, 2, 35, 36, 7, 99, 2, 2, 36, 37, 7, 107, 2, 2, 37, 38, 7, 112, 2, 2, 38, 6, 3, 2, 2, 2, 39, 40, 7, 121, 2, 2, 40, 41, 7, 99, 2, 2, 41, 42, 7, 105, 2, 2, 42, 43, 7, 113, 2, 2, 43, 44, 7, 112, 2, 2, 44, 8, 3, 2, 2, 2, 45, 46, 7, 112, 2, 2, 46, 47, 7, 119, 2, 2, 47, 48, 7, 111, 2, 2, 48, 49, 7, 117, 2, 2, 49, 50, 7, 103, 2, 2, 50, 51, 7, 99, 2, 2, 51, 52, 7, 118, 2, 2, 52, 53, 7, 117, 2, 2, 53, 10, 3, 2, 2, 2, 54, 55, 7, 99, 2, 2, 55, 56, 7, 102, 2, 2, 56, 57, 7, 102, 2, 2, 57, 12, 3, 2, 2, 2, 58, 59, 7, 118, 2, 2, 59, 60, 7, 113, 2, 2, 60, 14, 3, 2, 2, 2, 61, 62, 7, 105, 2, 2, 62, 63, 7, 103, 2, 2, 63, 64, 7, 118, 2, 2, 64, 65, 7, 112, 2, 2, 65, 66, 7, 119, 2, 2, 66, 67, 7, 111, 2, 2, 67, 68, 7, 117, 2, 2, 68, 69, 7, 103, 2, 2, 69, 70, 7, 99, 2, 2, 70, 71, 7, 118, 2, 2, 71, 72, 7, 117, 2, 2, 72, 16, 3, 2, 2, 2, 73, 74, 7, 102, 2, 2, 74, 75, 7, 103, 2, 2, 75, 76, 7, 110, 2, 2, 76, 77, 7, 103, 2, 2, 77, 78, 7, 118, 2, 2, 78, 79, 7, 103, 2, 2, 79, 18, 3, 2, 2, 2, 80, 81, 7, 116, 2, 2, 81, 82, 7, 103, 2, 2, 82, 83, 7, 111, 2, 2, 83, 84, 7, 113, 2, 2, 84, 85, 7, 120, 2, 2, 85, 86, 7, 103, 2, 2, 86, 20, 3, 2, 2, 2, 87, 88, 7, 104, 2, 2, 88, 89, 7, 116, 2, 2, 89, 90, 7, 113, 2, 2, 90, 91, 7, 111, 2, 2, 91, 22, 3, 2, 2, 2, 92, 96, 4, 99, 124, 2, 93, 95, 9, 2, 2, 2, 94, 93, 3, 2, 2, 2, 95, 98, 3, 2, 2, 2, 96, 94, 3, 2, 2, 2, 96, 97, 3, 2, 2, 2, 97, 24, 3, 2, 2, 2, 98, 96, 3, 2, 2, 2, 99, 101, 4, 50, 59, 2, 100, 99, 3, 2, 2, 2, 101, 102, 3, 2, 2, 2, 102, 100, 3, 2, 2, 2, 102, 103, 3, 2, 2, 2, 103, 26, 3, 2, 2, 2, 104, 105, 9, 3, 2, 2, 105, 106, 3, 2, 2, 2, 106, 107, 8, 14, 2, 2, 107, 28, 3, 2, 2, 2, 5, 2, 96, 102, 3, 8, 2, 2]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
23 changes: 23 additions & 0 deletions RichRail/target/generated-sources/antlr4/RichRail.tokens
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
ID=11
NUMBER=12
WHITESPACE=13
'new'=1
'train'=2
'wagon'=3
'numseats'=4
'add'=5
'to'=6
'getnumseats'=7
'delete'=8
'remove'=9
'from'=10
23 changes: 23 additions & 0 deletions RichRail/target/generated-sources/antlr4/RichRailLexer.tokens
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
ID=11
NUMBER=12
WHITESPACE=13
'new'=1
'train'=2
'wagon'=3
'numseats'=4
'add'=5
'to'=6
'getnumseats'=7
'delete'=8
'remove'=9
'from'=10
Loading