Skip to content

Commit bc27bd2

Browse files
committed
Merge branch 'antlr'
2 parents 725bf14 + ec6393a commit bc27bd2

File tree

14 files changed

+287
-61
lines changed

14 files changed

+287
-61
lines changed

gradle/libs.versions.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
[versions]
55
recordbuilder = "52"
6+
antlr = "4.13.1"
67

78
[libraries]
89
jspecify = { group = "org.jspecify", name = "jspecify", version = "1.0.0" }
@@ -30,6 +31,9 @@ mockito-junit-jupiter = { group = "org.mockito", name = "mockito-junit-jupiter",
3031

3132
jimfs = { group = "com.google.jimfs", name = "jimfs", version = "1.3.1" }
3233

34+
antlr-tool = { group = "org.antlr", name = "antlr4", version.ref = "antlr" }
35+
antlr-runtime = { group = "org.antlr", name = "antlr4-runtime", version.ref = "antlr" }
36+
3337
[bundles]
3438
recordbuilder = ["recordbuilder-core", "recordbuilder-processor"]
3539

@@ -38,3 +42,4 @@ versions = { id = "com.github.ben-manes.versions", version = "0.53.0" }
3842
errorprone = { id = "net.ltgt.errorprone", version = "5.1.0" }
3943
nullaway = { id = "net.ltgt.nullaway", version = "2.3.0" }
4044
spotless = { id = "com.diffplug.spotless", version = "8.4.0" }
45+
antlr = { id = "antlr" }

jst/build.gradle

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
plugins {
22
id 'buildlogic.java-library-conventions'
33
alias(libs.plugins.versions)
4-
id "org.xcommand.javacc"
4+
alias(libs.plugins.antlr)
55
alias(libs.plugins.errorprone)
66
alias(libs.plugins.spotless)
77
}
88

9-
javacc {
10-
inputFile = file("src/main/javacc/jst.jj")
11-
genDir = file("build/src/main/java/org/xcommand/template/jst/parser")
9+
// ===== ANTLR: =====
10+
sourceSets.main.java.srcDir("$buildDir/generated-src/antlr/main")
11+
tasks.named('generateGrammarSource') {
12+
// Define package folder target
13+
def pkgPath = 'org/xcommand/template/jst/parser'
14+
def pkgDir = file("$buildDir/generated-src/antlr/main/$pkgPath")
15+
pkgDir.mkdirs()
16+
17+
// ANTLR options
18+
arguments += ['-listener', '-visitor']
19+
20+
// Make ANTLR write directly into the package folder
21+
outputDirectory = pkgDir
22+
}
23+
// Make sure compileJava depends on generated sources
24+
tasks.named('compileJava') {
25+
dependsOn(tasks.named('generateGrammarSource'))
1226
}
13-
compileJava.dependsOn(jcc)
1427

28+
// ===== errorprone: =====
1529
import net.ltgt.gradle.errorprone.CheckSeverity
1630
tasks.withType(JavaCompile) {
1731
options.errorprone {
@@ -73,12 +87,16 @@ dependencies {
7387
testImplementation libs.mockito.junit.jupiter
7488

7589
testImplementation libs.assertj.core
90+
91+
antlr libs.antlr.tool
92+
implementation libs.antlr.runtime
7693
}
7794

7895
test {
7996
systemProperty 'eu.javaspecialists.books.dynamicproxies.util.MethodTurboBooster.disabled', 'true'
8097
}
8198

99+
82100
// ben-manes version-plugin:
83101
def isNonStable = { String version ->
84102
def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) }

jst/src/main/antlr/JSTLexer.g4

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
lexer grammar JSTLexer;
2+
3+
@header {
4+
package org.xcommand.template.jst.parser;
5+
}
6+
7+
// =====================
8+
// Default mode
9+
// =====================
10+
JAVA_EOL
11+
: '\r\n' | '\n' | '\r'
12+
;
13+
14+
COMMENT_START
15+
: '/*#' -> pushMode(IN_COMMENT)
16+
;
17+
18+
JAVA_TEXT
19+
: .
20+
;
21+
22+
// =====================
23+
// COMMENT mode
24+
// =====================
25+
mode IN_COMMENT;
26+
27+
COMMENT_END
28+
: '#*/' -> popMode
29+
;
30+
31+
COMMENT_EOL
32+
: '\r\n' | '\n' | '\r'
33+
;
34+
35+
COMMENT_TEXT
36+
: .
37+
;
38+
39+
JAVA_EXPR_START
40+
: '$jv{' -> pushMode(IN_JAVA_EXPR)
41+
;
42+
43+
// =====================
44+
// JAVA EXPR mode
45+
// =====================
46+
mode IN_JAVA_EXPR;
47+
48+
JAVA_EXPR_END
49+
: '}' -> popMode
50+
;
51+
52+
fragment DIGIT : [0-9A-Z];
53+
fragment LETTER : [a-zA-Z_];
54+
fragment JAVA_CHARS : '.' | '(' | ')';
55+
56+
JAVA_EXPR
57+
: (LETTER | DIGIT | JAVA_CHARS)+
58+
;

jst/src/main/antlr/JSTParser.g4

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
parser grammar JSTParser;
2+
3+
@header {
4+
package org.xcommand.template.jst.parser;
5+
}
6+
7+
options { tokenVocab = JSTLexer; }
8+
9+
// =====================
10+
// Parser rules
11+
// =====================
12+
13+
start
14+
: element* EOF
15+
;
16+
17+
element
18+
: JAVA_EOL #JavaEol
19+
| JAVA_TEXT #JavaText
20+
| COMMENT_START #CommentStart
21+
| COMMENT_END #CommentEnd
22+
| COMMENT_TEXT #CommentText
23+
| COMMENT_EOL #CommentEol
24+
| JAVA_EXPR_START #JavaVarStart
25+
| JAVA_EXPR #JavaVar
26+
| JAVA_EXPR_END #JavaVarEnd
27+
;

jst/src/main/java/org/xcommand/template/jst/DefaultJSTParserProvider.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
11
package org.xcommand.template.jst;
22

3-
import java.nio.charset.StandardCharsets;
43
import lombok.extern.slf4j.Slf4j;
54
import org.xcommand.core.DynaBeanProvider;
65
import org.xcommand.core.ICommand;
76
import org.xcommand.core.IDynaBeanProvider;
8-
import org.xcommand.template.jst.parser.JSTParser;
97
import org.xcommand.template.parser.IParserCV;
108

119
@Slf4j
1210
public class DefaultJSTParserProvider implements IJSTParserProvider {
1311
@Override
14-
public JSTParser newJSTParser() {
15-
var encoding = jstParserCV.getEncoding();
16-
if (encoding == null) {
17-
encoding = StandardCharsets.UTF_8.name();
18-
}
19-
var parser = new JSTParser(jstParserCV.getInputStream(), encoding);
20-
parser.getJavaVarNotifier().registerObserver(javaVariableObserver);
21-
parser.getJavaTextNotifier().registerObserver(javaTextObserver);
22-
parser.getCommentStartNotifier().registerObserver(commentStartObserver);
23-
parser.getCommentTextNotifier().registerObserver(commentTextObserver);
24-
parser.getCommentEndNotifier().registerObserver(commentEndObserver);
25-
parser.getEolInCommentNotifier().registerObserver(eolInCommentObserver);
26-
parser.getEolInJavaNotifier().registerObserver(eolInJavaObserver);
27-
return parser;
12+
public JSTParserWrapper newJSTParser() {
13+
var pw = new JSTParserWrapper();
14+
pw.getNotifiers().javaVarNotifier.registerObserver(javaVariableObserver);
15+
pw.getNotifiers().javaTextNotifier.registerObserver(javaTextObserver);
16+
pw.getNotifiers().commentStartNotifier.registerObserver(commentStartObserver);
17+
pw.getNotifiers().commentTextNotifier.registerObserver(commentTextObserver);
18+
pw.getNotifiers().commentEndNotifier.registerObserver(commentEndObserver);
19+
pw.getNotifiers().eolInCommentNotifier.registerObserver(eolInCommentObserver);
20+
pw.getNotifiers().eolInJavaNotifier.registerObserver(eolInJavaObserver);
21+
return pw;
2822
}
2923

3024
private final ICommand javaVariableObserver = new ICommand() {

jst/src/main/java/org/xcommand/template/jst/FileSystemBasedJSTScanner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public void execute() {
6464
});
6565

6666
jstParserCV.setGeneratedJavaCode(new StringBuffer());
67-
Sneaky.runnable(() -> parser.Start()).run();
67+
parser.parse();
6868
var newFme = cme.fme()
6969
.with()
7070
.content(jstParserCV.getGeneratedJavaCode().toString())
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.xcommand.template.jst;
22

3-
import org.xcommand.template.jst.parser.JSTParser;
4-
53
public interface IJSTParserProvider {
6-
public JSTParser newJSTParser();
4+
JSTParserWrapper newJSTParser();
75
}

jst/src/main/java/org/xcommand/template/jst/JSTJavaResourceLoader.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.util.HashMap;
55
import java.util.Map;
66
import lombok.extern.slf4j.Slf4j;
7-
import org.jooq.lambda.Sneaky;
87
import org.xcommand.core.DynaBeanProvider;
98
import org.xcommand.core.IDynaBeanProvider;
109

@@ -30,7 +29,7 @@ public void load(String resourceName) {
3029
jstParserCV.setInputStream(is);
3130
var parser = new DefaultJSTParserProvider().newJSTParser();
3231
jstParserCV.setGeneratedJavaCode(new StringBuffer());
33-
Sneaky.runnable(parser::Start).run();
32+
parser.parse();
3433
var s = jstParserCV.getGeneratedJavaCode().toString();
3534

3635
classMap = new HashMap<>();
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.xcommand.template.jst;
2+
3+
import org.antlr.v4.runtime.Token;
4+
import org.antlr.v4.runtime.tree.TerminalNode;
5+
import org.xcommand.template.jst.parser.JSTLexer;
6+
import org.xcommand.template.jst.parser.JSTParserBaseListener;
7+
8+
public class JSTListener extends JSTParserBaseListener {
9+
10+
private final JSTNotifiers notifiers;
11+
12+
public JSTListener(JSTNotifiers notifiers) {
13+
this.notifiers = notifiers;
14+
}
15+
16+
@Override
17+
public void visitTerminal(TerminalNode node) {
18+
Token token = node.getSymbol();
19+
20+
switch (token.getType()) {
21+
case JSTLexer.JAVA_TEXT -> notifiers.javaTextNotifier.execute();
22+
case JSTLexer.JAVA_EXPR_START -> notifiers.javaVarStartNotifier.execute();
23+
case JSTLexer.JAVA_EXPR -> notifiers.javaVarNotifier.execute();
24+
case JSTLexer.JAVA_EXPR_END -> notifiers.javaVarEndNotifier.execute();
25+
case JSTLexer.JAVA_EOL -> notifiers.eolInJavaNotifier.execute();
26+
case JSTLexer.COMMENT_START -> notifiers.commentStartNotifier.execute();
27+
case JSTLexer.COMMENT_TEXT -> notifiers.commentTextNotifier.execute();
28+
case JSTLexer.COMMENT_END -> notifiers.commentEndNotifier.execute();
29+
case JSTLexer.COMMENT_EOL -> notifiers.eolInCommentNotifier.execute();
30+
default -> {} // ignore other tokens
31+
}
32+
}
33+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.xcommand.template.jst;
2+
3+
import org.xcommand.pattern.observer.INotifier;
4+
import org.xcommand.pattern.observer.BasicNotifier;
5+
6+
public class JSTNotifiers {
7+
8+
public final INotifier startNotifier = new BasicNotifier();
9+
public final INotifier eolInCommentNotifier = new BasicNotifier();
10+
public final INotifier eolInJavaNotifier = new BasicNotifier();
11+
public final INotifier eofNotifier = new BasicNotifier();
12+
13+
public final INotifier commentStartNotifier = new BasicNotifier();
14+
public final INotifier commentTextNotifier = new BasicNotifier();
15+
public final INotifier commentEndNotifier = new BasicNotifier();
16+
17+
public final INotifier javaTextNotifier = new BasicNotifier();
18+
public final INotifier javaVarStartNotifier = new BasicNotifier();
19+
public final INotifier javaVarNotifier = new BasicNotifier();
20+
public final INotifier javaVarEndNotifier = new BasicNotifier();
21+
}

0 commit comments

Comments
 (0)