Skip to content

Commit 12d6688

Browse files
committed
Migrate to antlr4ng 3
1 parent 969e526 commit 12d6688

8 files changed

+50
-48
lines changed

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
},
8484
"peerDependencies": {
8585
"@lionweb/core": "^0.6.2",
86-
"antlr4ng": "^2.0.3",
86+
"antlr4ng": "^3.0.4",
8787
"cmd-ts": "^0.11.0",
8888
"ecore": "^0.12.0"
8989
},
@@ -122,8 +122,8 @@
122122
"@types/node": "^18.19.2",
123123
"@typescript-eslint/eslint-plugin": "^6.13.2",
124124
"@typescript-eslint/parser": "^6.13.2",
125-
"antlr4ng": "^2.0.3",
126-
"antlr4ng-cli": "^1.0.6",
125+
"antlr4ng": "^3.0.4",
126+
"antlr4ng-cli": "^2.0.0",
127127
"chai": "^4.3.10",
128128
"cmd-ts": "^0.11.0",
129129
"cross-env": "^7.0.3",

src/parsing/parse-tree.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Node, Origin, Point, Position} from "../";
2-
import {Interval, ParserRuleContext, ParseTree, TerminalNode, Token} from "antlr4ng";
2+
import {ParserRuleContext, ParseTree, TerminalNode, Token} from "antlr4ng";
33

44
// Note: we cannot provide Kolasu-style extension methods on ParseTree because it's an interface.
55
// Also, Kolasu-style extension methods on Token are problematic because we use Token.EOF below.
@@ -116,6 +116,5 @@ Object.defineProperty(Node.prototype, "parseTree", {
116116
ParserRuleContext.prototype.getOriginalText = function () {
117117
const a = this.start.start;
118118
const b = this.stop.stop;
119-
const interval = new Interval(a, b);
120-
return this.start.inputStream.getText(interval);
119+
return this.start.inputStream?.getTextFromRange(a, b);
121120
}

src/parsing/tylasu-parser.ts

+5-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
CharStream,
55
CommonTokenStream,
66
ErrorNode,
7-
Interval,
87
Lexer,
98
Parser as ANTLRParser,
109
ParserRuleContext,
@@ -103,7 +102,7 @@ export abstract class TylasuANTLRLexer<T extends TylasuToken> implements TylasuL
103102
issues.push(Issue.syntactic(message, IssueSeverity.WARNING, Position.ofTokenEnd(t)))
104103
}
105104

106-
const code = inputStream.getText(Interval.of(0, inputStream.size - 1));
105+
const code = inputStream.getTextFromRange(0, inputStream.size - 1);
107106
return new LexingResult(code, tokens, issues, performance.now() - time);
108107
}
109108

@@ -183,12 +182,7 @@ export abstract class TylasuParser<
183182

184183
processDescendantsAndErrors(
185184
root,
186-
it => {
187-
if (it.exception != null) {
188-
const message = `Recognition exception: ${it.exception.message}`;
189-
issues.push(Issue.syntactic(message, IssueSeverity.ERROR, Position.ofParseTree(it)));
190-
}
191-
},
185+
() => {},
192186
it => {
193187
const message = `Error node found (token: ${it.symbol?.text})`;
194188
issues.push(Issue.syntactic(message, IssueSeverity.ERROR, Position.ofParseTree(it)));
@@ -217,7 +211,7 @@ export abstract class TylasuParser<
217211
if (root != null) {
218212
this.verifyParseTree(parser, issues, root);
219213
}
220-
const code = inputStream.getText(Interval.of(0, inputStream.size - 1));
214+
const code = inputStream.getTextFromRange(0, inputStream.size - 1);
221215
return new FirstStageParsingResult(code, root, issues, parser, performance.now() - time, lexingTime);
222216
}
223217

@@ -234,7 +228,7 @@ export abstract class TylasuParser<
234228
if (!source) {
235229
source = new StringSource(code);
236230
}
237-
code = new CharStream(code);
231+
code = CharStream.fromString(code);
238232
}
239233
const start = performance.now();
240234
const firstStage = this.parseFirstStage(code, measureLexingTime);
@@ -251,7 +245,7 @@ export abstract class TylasuParser<
251245
delete node.origin;
252246
}
253247
}
254-
const text = code.getText(Interval.of(0, code.size - 1));
248+
const text = code.getTextFromRange(0, code.size - 1);
255249
return new ParsingResult(text, ast, issues, undefined, firstStage, performance.now() - start);
256250
}
257251

tests/mapping.test.ts

+7-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {expect} from "chai";
22

33
import {ASTTransformer, Child, GenericErrorNode, GenericNode, Node, Position} from "../src";
44
import {SimpleLangLexer} from "./parser/SimpleLangLexer";
5-
import {CharStreams, CommonTokenStream, ParserRuleContext} from "antlr4ng";
5+
import {CharStream, CommonTokenStream, ParserRuleContext} from "antlr4ng";
66
import {CompilationUnitContext, DisplayStmtContext, SetStmtContext, SimpleLangParser} from "./parser/SimpleLangParser";
77
import {ParseTreeOrigin} from "../src/parsing";
88
import {ParseTreeToASTTransformer} from "../src/mapping";
@@ -56,14 +56,14 @@ describe('Mapping of Parse Trees to ASTs', function() {
5656
it("Generic node",
5757
function () {
5858
const transformer = new ParseTreeToASTTransformer();
59-
const node = transformer.transform(new ParserRuleContext());
59+
const node = transformer.transform(new ParserRuleContext(null));
6060
expect(node).not.to.be.undefined;
6161
expect(node instanceof GenericNode).to.be.true;
6262
});
6363
it("Node registered declaratively",
6464
function () {
6565
const code = "set foo = 123 + 45";
66-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
66+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
6767
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
6868
const cu = parser.compilationUnit();
6969
const setStmt = cu.statement(0) as SetStmtContext;
@@ -84,7 +84,7 @@ describe('Mapping of Parse Trees to ASTs', function() {
8484
describe('ParseTreeToASTTransformer', function () {
8585
it("Test ParseTree Transformer", function () {
8686
const code = "set foo = 123\ndisplay 456";
87-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
87+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
8888
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
8989
const pt = parser.compilationUnit();
9090

@@ -104,7 +104,7 @@ describe('ParseTreeToASTTransformer', function () {
104104
});
105105
it("Test transformation with errors", function () {
106106
const code = "set foo = \ndisplay @@@";
107-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
107+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
108108
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
109109
parser.removeErrorListeners();
110110
const pt = parser.compilationUnit();
@@ -127,7 +127,7 @@ describe('ParseTreeToASTTransformer', function () {
127127
});
128128
it("Test generic node", function () {
129129
const code = "set foo = 123\ndisplay 456";
130-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
130+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
131131
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
132132
const pt = parser.compilationUnit();
133133

@@ -136,7 +136,7 @@ describe('ParseTreeToASTTransformer', function () {
136136
});
137137
it("test generic AST transformer", function () {
138138
const code = "set foo = 123\ndisplay 456";
139-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
139+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
140140
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
141141
const pt = parser.compilationUnit();
142142

@@ -163,20 +163,12 @@ const configure = function(transformer: ASTTransformer) : void {
163163
transformer.registerNodeFactory<DisplayStmtContext, DisplayIntStatement>(
164164
DisplayStmtContext,
165165
source => {
166-
if (source.exception || source.expression().exception) {
167-
// We throw a custom error so that we can check that it's recorded in the AST
168-
throw new Error("Parse error");
169-
}
170166
return new DisplayIntStatement(parseInt(source.expression().INT_LIT()!.getText()));
171167
});
172168

173169
transformer.registerNodeFactory<SetStmtContext, SetStatement>(
174170
SetStmtContext,
175171
source => {
176-
if (source.exception || source.expression().exception) {
177-
// We throw a custom error so that we can check that it's recorded in the AST
178-
throw new Error("Parse error");
179-
}
180172
const setStatement = new SetStatement();
181173
setStatement.variable = source.ID().getText();
182174
setStatement.value = parseInt(source.expression().INT_LIT()!.getText());

tests/model/origin.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {SimpleLangLexer} from "../parser/SimpleLangLexer";
2-
import {CharStreams, CommonTokenStream} from "antlr4ng";
2+
import {CharStream, CommonTokenStream} from "antlr4ng";
33
import {SimpleLangParser} from "../parser/SimpleLangParser";
44
import {ParseTreeOrigin} from "../../src/parsing";
55
import {expect} from "chai";
@@ -11,7 +11,7 @@ describe('Origin', function () {
1111
const code = `set a = 1 + 2
1212
input c is string
1313
display 2 * 3`;
14-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
14+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
1515
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
1616
const parseTreeRoot = parser.compilationUnit();
1717
expect(parser.numberOfSyntaxErrors).to.equal(0);
@@ -31,7 +31,7 @@ display 2 * 3`;
3131
const code = `set a = 1 + 2
3232
input c is string
3333
display 2 * 3`;
34-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
34+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
3535
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
3636
const parseTreeRoot = parser.compilationUnit();
3737
expect(parser.numberOfSyntaxErrors).to.equal(0);

tests/model/position.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {expect} from "chai";
22

33
import {Point, START_POINT, Node, Position} from "../../src";
44
import {SimpleLangLexer} from "../parser/SimpleLangLexer";
5-
import {CharStreams, CommonTokenStream} from "antlr4ng";
5+
import {CharStream, CommonTokenStream} from "antlr4ng";
66
import {SetStmtContext, SimpleLangParser} from "../parser/SimpleLangParser";
77
import {positionOfParseTree} from "../../src/parsing";
88

@@ -49,7 +49,7 @@ describe('Position', function() {
4949
it("ParserRuleContext position",
5050
function () {
5151
const code = "set foo = 123";
52-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
52+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
5353
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
5454
const cu = parser.compilationUnit();
5555
const setStmt = cu.statement(0) as SetStmtContext;
@@ -60,7 +60,7 @@ describe('Position', function() {
6060
it("Position derived from parse tree node",
6161
function () {
6262
const code = "set foo = 123";
63-
const lexer = new SimpleLangLexer(CharStreams.fromString(code));
63+
const lexer = new SimpleLangLexer(CharStream.fromString(code));
6464
const parser = new SimpleLangParser(new CommonTokenStream(lexer));
6565
const cu = parser.compilationUnit();
6666
const setStmt = cu.statement(0) as SetStmtContext;

tests/strumenta-playground.test.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,33 @@ import {Issue, Source} from "../src";
44
import {registerECoreModel} from "../src/interop/ecore";
55
import {ParserTraceLoader, saveForStrumentaPlayground} from "../src/interop/strumenta-playground";
66
import {NodeSubclass} from "./nodes";
7-
import {CharStream, CommonToken, Lexer, TerminalNode, Token, TokenStream} from "antlr4ng";
7+
import {CharStream, CommonToken, Lexer, TerminalNode, Token, TokenSource, TokenStream} from "antlr4ng";
88
import * as fs from "fs";
99
import ECore from "ecore/dist/ecore";
1010
import {ANTLRTokenFactory, ParsingResult} from "../src/parsing";
1111
import {EcoreEnabledParser} from "../src/interop/ecore-enabled-parser";
1212

13+
class SyntheticToken extends CommonToken {
14+
15+
constructor(details: {
16+
source?: [TokenSource | null, CharStream | null];
17+
type: number;
18+
channel?: number;
19+
start?: number;
20+
stop?: number;
21+
text?: string;
22+
line?: number;
23+
tokenIndex?: number;
24+
column?: number
25+
}) {
26+
super({...details, source: [null, null]});
27+
}
28+
}
29+
1330
describe('Strumenta Playground', function() {
1431
it("Export round-trip", function () {
1532
// We assign a fake parse tree, to ensure that we don't attempt to serialize ANTLR parse trees into the model.
16-
const fakePT = new TerminalNode(new CommonToken([null, null], Token.EOF, Token.DEFAULT_CHANNEL, 0, 0));
33+
const fakePT = new TerminalNode(new SyntheticToken({ type: Token.EOF }));
1734
(fakePT.symbol as CommonToken).line = 1;
1835
(fakePT.symbol as CommonToken).column = 0;
1936
/* TODO not supported yet

yarn.lock

+8-8
Original file line numberDiff line numberDiff line change
@@ -973,15 +973,15 @@ ansi-styles@^5.0.0:
973973
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
974974
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
975975

976-
antlr4ng-cli@^1.0.6:
977-
version "1.0.6"
978-
resolved "https://registry.yarnpkg.com/antlr4ng-cli/-/antlr4ng-cli-1.0.6.tgz#db22d74b4a931489ef0c59f146fc90624c6871ae"
979-
integrity sha512-9ZeVmXu8v/UO4mLhSTyNSCi2fEEBzya2G04bqigwZVg5YdTlS6HhuAa2ruZy/HdV5erhL12USqPCJPMsq+OeKQ==
976+
antlr4ng-cli@^2.0.0:
977+
version "2.0.0"
978+
resolved "https://registry.yarnpkg.com/antlr4ng-cli/-/antlr4ng-cli-2.0.0.tgz#4f86f3c3818a2170aa1041d4e1633b489af00131"
979+
integrity sha512-oAt5OSSYhRQn1PgahtpAP4Vp3BApCoCqlzX7Q8ZUWWls4hX59ryYuu0t7Hwrnfk796OxP/vgIJaqxdltd/oEvQ==
980980

981-
antlr4ng@^2.0.3:
982-
version "2.0.3"
983-
resolved "https://registry.yarnpkg.com/antlr4ng/-/antlr4ng-2.0.3.tgz#2dde0c90474597395917ed48b9f4394ec5563b3b"
984-
integrity sha512-usw0hZsNbTQrJ899P6sHLlQbmKgwQ9UBYq5rh6ZFicPf5qtRJogPVTBj4fSB3OY5ZLP5TSZ7d8tR2p4I5KyiLQ==
981+
antlr4ng@^3.0.4:
982+
version "3.0.4"
983+
resolved "https://registry.yarnpkg.com/antlr4ng/-/antlr4ng-3.0.4.tgz#71a47e6148ae75f72fa5f27fbed5ef3462815c7c"
984+
integrity sha512-u1Ww6wVv9hq70E9AaYe5qW3ba8hvnjJdO3ZsKnb3iJWFV/medLEEhbyWwXCvvD2ef0ptdaiIUgmaazS/WE6uyQ==
985985

986986
anymatch@^3.0.3:
987987
version "3.1.3"

0 commit comments

Comments
 (0)