diff src/goodjava/parser/ParseException.java @ 1402:27efb1fcbcb5

move luan.lib to goodjava
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 17 Sep 2019 01:35:01 -0400
parents src/luan/lib/parser/ParseException.java@540e1940170f
children 764723436f05
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/parser/ParseException.java	Tue Sep 17 01:35:01 2019 -0400
@@ -0,0 +1,71 @@
+package goodjava.parser;
+
+
+public final class ParseException extends Exception {
+	public final String text;
+	public final int errorIndex;
+	public final int highIndex;
+
+	public ParseException(Parser parser,String msg) {
+		super(msg);
+		this.text = parser.text;
+		this.errorIndex = parser.currentIndex();
+		this.highIndex = parser.highIndex();
+	}
+
+	public ParseException(Parser parser,Exception cause) {
+		this(parser,cause.getMessage(),cause);
+	}
+
+	public ParseException(Parser parser,String msg,Exception cause) {
+		super(msg,cause);
+		this.text = parser.text;
+		this.errorIndex = parser.currentIndex();
+		this.highIndex = parser.highIndex();
+	}
+
+	private class Location {
+		final int line;
+		final int pos;
+
+		Location(int index) {
+			int line = 0;
+			int i = -1;
+			while(true) {
+				int j = text.indexOf('\n',i+1);
+				if( j == -1 || j >= index )
+					break;
+				i = j;
+				line++;
+			}
+			this.line = line;
+			this.pos = index - i - 1;
+		}
+	}
+
+	private String[] lines() {
+		return text.split("\n",-1);
+	}
+
+	@Override public String getMessage() {
+		String line;
+		int pos;
+		StringBuilder sb = new StringBuilder(super.getMessage());
+		if( text.indexOf('\n') == -1 ) {
+			line = text;
+			pos = errorIndex;
+			sb.append( " (position " + (pos+1) + ")\n" );
+		} else {
+			Location loc = new Location(errorIndex);
+			line = lines()[loc.line];
+			pos = loc.pos;
+			sb.append( " (line " + (loc.line+1) + ", pos " + (pos+1) + ")\n" );
+		}
+		sb.append( line + "\n" );
+		for( int i=0; i<pos; i++ ) {
+			sb.append( line.charAt(i)=='\t' ? '\t' : ' ' );
+		}
+		sb.append("^\n");
+		return sb.toString();
+	}
+}