package com.kreative.paint.material.shape; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; public class ExpressionLexer { private final List<String> reservedTokens; private final String s; private final int n; private int i; public ExpressionLexer(String s) { this.reservedTokens = new ArrayList<String>(); this.reservedTokens.addAll(Function.functions.keySet()); for (Map<String,Operator> ops : Operator.operators.values()) { this.reservedTokens.addAll(ops.keySet()); } Collections.sort(this.reservedTokens, new Comparator<String>() { @Override public int compare(String a, String b) { int cmp = b.length() - a.length(); if (cmp != 0) return cmp; return a.compareTo(b); } }); this.s = s; this.n = s.length(); this.i = 0; } public int currentIndex() { return i; } public boolean hasNext() { while (i < n && Character.isWhitespace(s.charAt(i))) i++; return (i < n); } public String lookNext() { while (i < n && Character.isWhitespace(s.charAt(i))) i++; if (i >= n) return null; final char ch = s.charAt(i); final int i = this.i; int j = i + 1; if (isNumberPart(ch)) { while (j < n && isNumberPart(s.charAt(j))) j++; } else if (isIdentifierPart(ch)) { while (j < n && isIdentifierPart(s.charAt(j))) j++; } else { String rest = s.substring(i); for (String token : reservedTokens) { if (rest.startsWith(token)) { j = i + token.length(); break; } } } return s.substring(i, j); } public String getNext() { while (i < n && Character.isWhitespace(s.charAt(i))) i++; if (i >= n) return null; final char ch = s.charAt(i); final int i = this.i; int j = i + 1; if (isNumberPart(ch)) { while (j < n && isNumberPart(s.charAt(j))) j++; } else if (isIdentifierPart(ch)) { while (j < n && isIdentifierPart(s.charAt(j))) j++; } else { String rest = s.substring(i); for (String token : reservedTokens) { if (rest.startsWith(token)) { j = i + token.length(); break; } } } this.i = j; return s.substring(i, j); } private static boolean isNumberPart(char ch) { return ch == '.' || Character.isDigit(ch); } private static boolean isIdentifierPart(char ch) { return ch == '.' || Character.isDigit(ch) || Character.isLetter(ch); } }