Tôi có ngữ pháp ANLTR đơn giản và Khách truy cập đi kèm. Mọi thứ hoạt động tốt, trừ khi đầu vào không hợp lệ. Nếu đầu vào không hợp lệ, lỗi sẽ bị nuốt và máy tính của tôi xuất hiện với đầu ra sai.Có thể ném ngoại lệ nếu đầu vào không hợp lệ không?
Tôi đã thử triển khai trình nghe lỗi, qua phương pháp Recover
của từ khóa, và ... cũng ... nửa tá những thứ khác hiện nay. Ai đó có thể chỉ cho tôi cách chỉ đơn giản là ném một lỗi thay vì nuốt "thẻ" xấu? (. Tôi sử dụng dấu ngoặc kép bởi vì họ đang không tokens ở tất cả các ký tự được định nghĩa trong ngữ pháp của tôi.)
trị Input:
1 + 2 * 3 - 4
Invalid Input:
1 + 2 + 3 (4)
Tôi muốn ném ArgumentException
nếu trình phân tích cú pháp/lexer xuất hiện trên dấu ngoặc đơn (hoặc bất kỳ ký tự không xác định nào khác). Hiện tại, các ký tự không hợp lệ dường như chỉ biến mất thành ête và trình phân tích cú pháp chỉ đơn giản như không có gì sai.
Nếu tôi chạy nó trong bảng điều khiển với lệnh grun
, tôi nhận được kết quả sau, do đó, nó nhận ra các mã thông báo không hợp lệ ở một mức nào đó.
dòng 1: 9 lỗi thẻ nhận tại địa chỉ: '('
dòng 1:11 thẻ lỗi công nhận tại địa chỉ: ')'
và kết quả là cây phân tích cú pháp này.
BasicMath.g4
grammar BasicMath;
/*
* Parser Rules
*/
compileUnit : expression+ EOF;
expression :
expression MULTIPLY expression #Multiplication
| expression DIVIDE expression #Division
| expression ADD expression #Addition
| expression SUBTRACT expression #Subtraction
| NUMBER #Number
;
/*
* Lexer Rules
*/
NUMBER : INT; //Leave room to extend what kind of math we can do.
INT : ('0'..'9')+;
MULTIPLY : '*';
DIVIDE : '/';
SUBTRACT : '-';
ADD : '+';
WS : [ \t\r\n] -> channel(HIDDEN);
Calculator:
public static class Calculator
{
public static int Evaluate(string expression)
{
var lexer = new BasicMathLexer(new AntlrInputStream(expression));
var tokens = new CommonTokenStream(lexer);
var parser = new BasicMathParser(tokens);
var tree = parser.compileUnit();
var visitor = new IntegerMathVisitor();
return visitor.Visit(tree);
}
}
Hãy xem câu trả lời này từ tác giả Antlr4cs: http://stackoverflow.com/a/18486405/2573395 – Alex
Yup. Đã thử rằng @Alex. Tôi được kế thừa từ 'BaseErrorListener' và đính kèm nó vào trình phân tích cú pháp của tôi, nhưng không có phương thức nào được gọi. – RubberDuck
Lưu ý về bản thân, khi cưỡi một thứ gì đó ở đây có thể hữu ích. Có vẻ như độ dài lớn đã biến mất để đảm bảo phân tích cú pháp hoàn thành khi tôi cần nó dừng lại. https://github.com/antlr/antlr4/blob/master/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java – RubberDuck