mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Вывод информации о позиции в исходнике, где произошла ошибка
This commit is contained in:
parent
ef175a71af
commit
0883845872
@ -59,12 +59,14 @@ public final class Lexer {
|
||||
private final List<Token> tokens;
|
||||
|
||||
private int pos;
|
||||
private int row, col;
|
||||
|
||||
public Lexer(String input) {
|
||||
this.input = input;
|
||||
length = input.length();
|
||||
|
||||
tokens = new ArrayList<>();
|
||||
row = col = 1;
|
||||
}
|
||||
|
||||
public List<Token> tokenize() {
|
||||
@ -92,7 +94,7 @@ public final class Lexer {
|
||||
char current = peek(0);
|
||||
while (true) {
|
||||
if (current == '.') {
|
||||
if (buffer.indexOf(".") != -1) throw new RuntimeException("Invalid float number");
|
||||
if (buffer.indexOf(".") != -1) throw error("Invalid float number");
|
||||
} else if (!Character.isDigit(current)) {
|
||||
break;
|
||||
}
|
||||
@ -178,6 +180,7 @@ public final class Lexer {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
char current = peek(0);
|
||||
while (true) {
|
||||
if (current == '\0') throw error("Reached end of file while parsing text string.");
|
||||
if (current == '\\') {
|
||||
current = next();
|
||||
switch (current) {
|
||||
@ -207,7 +210,7 @@ public final class Lexer {
|
||||
private void tokenizeMultilineComment() {
|
||||
char current = peek(0);
|
||||
while (true) {
|
||||
if (current == '\0') throw new RuntimeException("Missing close tag");
|
||||
if (current == '\0') throw error("Reached end of file while parsing multiline comment");
|
||||
if (current == '*' && peek(1) == '/') break;
|
||||
current = next();
|
||||
}
|
||||
@ -217,7 +220,12 @@ public final class Lexer {
|
||||
|
||||
private char next() {
|
||||
pos++;
|
||||
return peek(0);
|
||||
final char result = peek(0);
|
||||
if (result == '\n') {
|
||||
row++;
|
||||
col = 1;
|
||||
} else col++;
|
||||
return result;
|
||||
}
|
||||
|
||||
private char peek(int relativePosition) {
|
||||
@ -231,6 +239,10 @@ public final class Lexer {
|
||||
}
|
||||
|
||||
private void addToken(TokenType type, String text) {
|
||||
tokens.add(new Token(type, text));
|
||||
tokens.add(new Token(type, text, row, col));
|
||||
}
|
||||
|
||||
private LexerException error(String text) {
|
||||
return new LexerException(row, col, text);
|
||||
}
|
||||
}
|
||||
|
16
src/com/annimon/ownlang/parser/LexerException.java
Normal file
16
src/com/annimon/ownlang/parser/LexerException.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.annimon.ownlang.parser;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class LexerException extends RuntimeException {
|
||||
|
||||
public LexerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public LexerException(int row, int col, String message) {
|
||||
super("["+row+":"+col+"] " + message);
|
||||
}
|
||||
}
|
16
src/com/annimon/ownlang/parser/ParseException.java
Normal file
16
src/com/annimon/ownlang/parser/ParseException.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.annimon.ownlang.parser;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class ParseException extends RuntimeException {
|
||||
|
||||
public ParseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ParseException(String string) {
|
||||
super(string);
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ import java.util.List;
|
||||
*/
|
||||
public final class Parser {
|
||||
|
||||
private static final Token EOF = new Token(TokenType.EOF, "");
|
||||
private static final Token EOF = new Token(TokenType.EOF, "", -1, -1);
|
||||
|
||||
private final List<Token> tokens;
|
||||
private final int size;
|
||||
@ -82,7 +82,6 @@ public final class Parser {
|
||||
}
|
||||
|
||||
private Statement assignmentStatement() {
|
||||
// WORD EQ
|
||||
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.EQ)) {
|
||||
final String variable = consume(TokenType.WORD).getText();
|
||||
consume(TokenType.EQ);
|
||||
@ -93,7 +92,7 @@ public final class Parser {
|
||||
consume(TokenType.EQ);
|
||||
return new ArrayAssignmentStatement(array, expression());
|
||||
}
|
||||
throw new RuntimeException("Unknown statement");
|
||||
throw new ParseException("Unknown statement: " + get(0));
|
||||
}
|
||||
|
||||
private Statement ifElse() {
|
||||
@ -128,7 +127,7 @@ public final class Parser {
|
||||
final Expression termination = expression();
|
||||
consume(TokenType.COMMA);
|
||||
final Statement increment = assignmentStatement();
|
||||
match(TokenType.RPAREN);
|
||||
match(TokenType.RPAREN); // необязательные скобки
|
||||
final Statement statement = statementOrBlock();
|
||||
return new ForStatement(initialization, termination, increment, statement);
|
||||
}
|
||||
@ -409,12 +408,12 @@ public final class Parser {
|
||||
match(TokenType.RPAREN);
|
||||
return result;
|
||||
}
|
||||
throw new RuntimeException("Unknown expression");
|
||||
throw new ParseException("Unknown expression: " + current);
|
||||
}
|
||||
|
||||
private Token consume(TokenType type) {
|
||||
final Token current = get(0);
|
||||
if (type != current.getType()) throw new RuntimeException("Token " + current + " doesn't match " + type);
|
||||
if (type != current.getType()) throw new ParseException("Token " + current + " doesn't match " + type);
|
||||
pos++;
|
||||
return current;
|
||||
}
|
||||
|
@ -6,35 +6,39 @@ package com.annimon.ownlang.parser;
|
||||
*/
|
||||
public final class Token {
|
||||
|
||||
private TokenType type;
|
||||
private String text;
|
||||
private final TokenType type;
|
||||
private final String text;
|
||||
private final int row, col;
|
||||
|
||||
public Token() {
|
||||
}
|
||||
|
||||
public Token(TokenType type, String text) {
|
||||
public Token(TokenType type, String text, int row, int col) {
|
||||
this.type = type;
|
||||
this.text = text;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
}
|
||||
|
||||
public TokenType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(TokenType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
public int getCol() {
|
||||
return col;
|
||||
}
|
||||
|
||||
public String position() {
|
||||
return "[" + row + " " + col + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type + " " + text;
|
||||
return type.name() + " " + position() + " " + text;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user