|
|
@@ -1,10 +1,14 @@
|
|
|
package net.ranides.assira.lexer;
|
|
|
|
|
|
import net.ranides.assira.functional.CharPredicate;
|
|
|
+import net.ranides.assira.text.StringUtils;
|
|
|
+
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
|
|
public class SimpleStreamer {
|
|
|
|
|
|
- private final char content[];
|
|
|
+ private final char[] content;
|
|
|
|
|
|
private int position;
|
|
|
|
|
|
@@ -14,14 +18,16 @@ public class SimpleStreamer {
|
|
|
}
|
|
|
|
|
|
public boolean end() {
|
|
|
- return content.length == position;
|
|
|
+ return position >= content.length;
|
|
|
}
|
|
|
|
|
|
public char peek() {
|
|
|
+ check();
|
|
|
return content[position];
|
|
|
}
|
|
|
|
|
|
public String peek(CharPredicate pred) {
|
|
|
+ check();
|
|
|
int begin = position;
|
|
|
int current = position;
|
|
|
while (content.length != current && pred.test(content[current])) {
|
|
|
@@ -30,17 +36,51 @@ public class SimpleStreamer {
|
|
|
return new String(content, begin, current - begin);
|
|
|
}
|
|
|
|
|
|
+ public String peek(int n) {
|
|
|
+ check(n);
|
|
|
+ return new String(content, position, n);
|
|
|
+ }
|
|
|
+
|
|
|
+ public String peek(Pattern regex) {
|
|
|
+ check();
|
|
|
+ Matcher matcher = matcher(regex);
|
|
|
+ if(!matcher.find()) {
|
|
|
+ return "";
|
|
|
+ } else {
|
|
|
+ return matcher.group();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public void skip() {
|
|
|
+ check();
|
|
|
position++;
|
|
|
}
|
|
|
|
|
|
- public void skip(CharPredicate pred) {
|
|
|
+ public void skip(int n) {
|
|
|
+ check(n);
|
|
|
+ position += n;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int skip(CharPredicate pred) {
|
|
|
+ int c = position;
|
|
|
while (!end() && pred.test(peek())) {
|
|
|
- next();
|
|
|
+ position++;
|
|
|
+ }
|
|
|
+ return position - c;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int skip(Pattern regex) {
|
|
|
+ Matcher matcher = matcher(regex);
|
|
|
+ if(!matcher.find()) {
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ position += matcher.end();
|
|
|
+ return matcher.end();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public char next() {
|
|
|
+ check();
|
|
|
return content[position++];
|
|
|
}
|
|
|
|
|
|
@@ -50,4 +90,32 @@ public class SimpleStreamer {
|
|
|
return new String(content, begin, position - begin);
|
|
|
}
|
|
|
|
|
|
+ public String next(int n) {
|
|
|
+ check(n);
|
|
|
+ position += n;
|
|
|
+ return new String(content, position-n, n);
|
|
|
+ }
|
|
|
+
|
|
|
+ public String next(Pattern regex) {
|
|
|
+ int begin = position;
|
|
|
+ skip(regex);
|
|
|
+ return new String(content, begin, position - begin);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Matcher matcher(Pattern regex) {
|
|
|
+ return regex.matcher(StringUtils.wrap(content, position, content.length));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void check() {
|
|
|
+ if(position >= content.length) {
|
|
|
+ throw new IllegalStateException("Steamer: EOS");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void check(int n) {
|
|
|
+ if(position+n > content.length) {
|
|
|
+ throw new IllegalStateException("Steamer: EOS (remained " + (content.length - position) + " instead of " + n +")");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|