Skip to content

Commit 367151b

Browse files
Copilothzhangxyz
andcommitted
Implement error handling for ANTLR4 JS binding
Co-authored-by: hzhangxyz <11623447+hzhangxyz@users.noreply.github.com>
1 parent 77bfa8f commit 367151b

3 files changed

Lines changed: 45 additions & 36 deletions

File tree

bnf/atsds_bnf/index.mjs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
import { InputStream, CommonTokenStream } from "antlr4";
1+
import { InputStream, CommonTokenStream, ErrorListener } from "antlr4";
22
import DspLexer from "./DspLexer.js";
33
import DspParser from "./DspParser.js";
44
import DspVisitor from "./DspVisitor.js";
55
import DsLexer from "./DsLexer.js";
66
import DsParser from "./DsParser.js";
77
import DsVisitor from "./DsVisitor.js";
88

9+
class ThrowingErrorListener extends ErrorListener {
10+
syntaxError(recognizer, offendingSymbol, line, column, msg, e) {
11+
throw new Error(`line ${line}:${column} ${msg}`);
12+
}
13+
}
14+
915
class ParseVisitor extends DspVisitor {
1016
visitRule_pool(ctx) {
1117
return ctx
@@ -104,8 +110,12 @@ class UnparseVisitor extends DsVisitor {
104110
export function parse(input) {
105111
const chars = new InputStream(input);
106112
const lexer = new DspLexer(chars);
113+
lexer.removeErrorListeners();
114+
lexer.addErrorListener(new ThrowingErrorListener());
107115
const tokens = new CommonTokenStream(lexer);
108116
const parser = new DspParser(tokens);
117+
parser.removeErrorListeners();
118+
parser.addErrorListener(new ThrowingErrorListener());
109119
const tree = parser.rule_pool();
110120
const visitor = new ParseVisitor();
111121
return visitor.visit(tree);
@@ -114,8 +124,12 @@ export function parse(input) {
114124
export function unparse(input) {
115125
const chars = new InputStream(input);
116126
const lexer = new DsLexer(chars);
127+
lexer.removeErrorListeners();
128+
lexer.addErrorListener(new ThrowingErrorListener());
117129
const tokens = new CommonTokenStream(lexer);
118130
const parser = new DsParser(tokens);
131+
parser.removeErrorListeners();
132+
parser.addErrorListener(new ThrowingErrorListener());
119133
const tree = parser.rule_pool();
120134
const visitor = new UnparseVisitor();
121135
return visitor.visit(tree);

bnf/test_error_listener.mjs

Lines changed: 0 additions & 35 deletions
This file was deleted.

bnf/tests/test_parse_unparse.mjs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,33 @@ test("roundtrip_unparse_parse", () => {
143143
const ds_result = parse(dsp_intermediate);
144144
expect(ds_result).toBe(ds_original);
145145
});
146+
147+
test("parse_error_missing_closing_parenthesis", () => {
148+
// Test that parse throws error on missing closing parenthesis
149+
const dsp_input = "(a + b -> c";
150+
expect(() => parse(dsp_input)).toThrow(/line 1:7 no viable alternative/);
151+
});
152+
153+
test("parse_error_bad_syntax", () => {
154+
// Test that parse throws error on bad syntax
155+
const dsp_input = "a b c -> -> d";
156+
expect(() => parse(dsp_input)).toThrow(/line 1:2 mismatched input/);
157+
});
158+
159+
test("parse_error_malformed_parentheses", () => {
160+
// Test that parse throws error on malformed parentheses
161+
const dsp_input = "()()()";
162+
expect(() => parse(dsp_input)).toThrow(/line 1:1 no viable alternative/);
163+
});
164+
165+
test("unparse_error_incomplete_binary", () => {
166+
// Test that unparse throws error on incomplete binary expression
167+
const ds_input = "(binary";
168+
expect(() => unparse(ds_input)).toThrow(/line 1:7 mismatched input/);
169+
});
170+
171+
test("unparse_error_malformed_function", () => {
172+
// Test that unparse throws error on malformed function
173+
const ds_input = "(function";
174+
expect(() => unparse(ds_input)).toThrow(/line 1:9 mismatched input/);
175+
});

0 commit comments

Comments
 (0)