/** do some pre-computation parsing to a formula */ public static String preParse(String f, FormulaManager fm) { // remove spaces StringTokenizer t = new StringTokenizer(f, " ", false); String s = ""; while (t.hasMoreTokens()) s = s + t.nextToken(); if (s.equals("")) return s; // multi-pass pre-parse sequence String os; do { os = s; s = preParseOnce(os, fm); } while (!s.equals(os)); return s; }
/** * convert an array of strings of the form "package.Class.method(Class, Class, ...)" to * an array of Method objects */ public static Method[] stringsToMethods(String[] strings) { int len = strings.length; Method[] methods = new Method[len]; for (int j = 0; j < len; j++) { // remove spaces StringTokenizer t = new StringTokenizer(strings[j], " ", false); String s = ""; while (t.hasMoreTokens()) s = s + t.nextToken(); // separate into two strings t = new StringTokenizer(s, "(", false); String pre = t.nextToken(); String post = t.nextToken(); // separate first string into class and method strings t = new StringTokenizer(pre, ".", false); String c = t.nextToken(); int count = t.countTokens(); for (int i = 0; i < count - 1; i++) c = c + "." + t.nextToken(); String m = t.nextToken(); // get argument array of strings t = new StringTokenizer(post, ",)", false); count = t.countTokens(); String[] a; if (count == 0) a = null; else a = new String[count]; int x = 0; while (t.hasMoreTokens()) a[x++] = t.nextToken(); // convert result to Method object Class clas = null; try { clas = Class.forName(c); } catch (ClassNotFoundException exc) { if (FormulaVar.DEBUG) { System.out.println("ERROR: Class " + c + " does not exist!"); } methods[j] = null; continue; } Class[] param; if (a == null) param = null; else param = new Class[a.length]; for (int i = 0; i < count; i++) { // hack to convert array arguments to correct form if (a[i].endsWith("[]")) { a[i] = "[L" + a[i].substring(0, a[i].length() - 2); while (a[i].endsWith("[]")) { a[i] = "[" + a[i].substring(0, a[i].length() - 2); } a[i] = a[i] + ";"; } try { param[i] = Class.forName(a[i]); } catch (ClassNotFoundException exc) { if (FormulaVar.DEBUG) { System.out.println("ERROR: Class " + a[i] + " (" + i + ") does not exist!"); } methods[j] = null; continue; } } Method method = null; try { method = clas.getMethod(m, param); } catch (NoSuchMethodException exc) { if (FormulaVar.DEBUG) { System.out.println("ERROR: Method " + m + " does not exist!"); } methods[j] = null; continue; } methods[j] = method; } return methods; }
/** used by preParse */ private static String preParseOnce(String s, FormulaManager fm) { // convert to lower case String l = s.toLowerCase(); // scan entire string int len = l.length(); boolean letter = false; String ns = ""; for (int i = 0; i < len; i++) { if (!letter && i < len - 1 && l.substring(i, i + 2).equals("d(")) { // convert d(x)/d(y) notation to standard derive(x, y) notation i += 2; int s1 = i; for (int paren = 1; paren > 0; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e1 = i - 1; // check for correct syntax if (i > len - 3 || !l.substring(i, i + 3).equals("/d(")) return s; i += 3; int s2 = i; for (int paren = 1; paren > 0; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e2 = i - 1; ns = ns + "derive(" + s.substring(s1, e1) + "," + s.substring(s2, e2) + ")"; i--; } else if (!letter && i < len - 4 && l.substring(i, i + 5).equals("link(")) { // evaluate link(code) notation and replace with link variable i += 5; int s1 = i; try { while (l.charAt(i) != '(') i++; } catch (ArrayIndexOutOfBoundsException exc) { // incorrect syntax return s; } i++; int e1 = i - 1; int s2 = i; for (int paren = 2; paren > 1; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e2 = i - 1; // check for correct syntax if (i >= len || l.charAt(i) != ')') return s; String prestr = s.substring(s1, e1) + "("; String str = prestr; // parse method's arguments; determine if they are Data or RealType String sub = s.substring(s2, e2); StringTokenizer st = new StringTokenizer(sub, ",", false); boolean first = true; Vector v = new Vector(); while (st.hasMoreTokens()) { String token = st.nextToken(); if (first) first = false; else str = str + ","; RealType rt = RealType.getRealTypeByName(token); String sv = (rt == null ? "visad.Data" : "visad.RealType"); v.add(sv); str = str + sv; } str = str + ")"; // obtain Method object Method[] meths = FormulaUtil.stringsToMethods(new String[] {str}); if (meths[0] == null) { // attempt to identify any matching methods by compressing // some or all of the arguments into array form int vlen = v.size(); Vector vstrs = new Vector(); for (int iv = 0; iv < vlen; iv++) { String si = (String) v.elementAt(iv); int lv = iv; String sl; while (lv < vlen) { sl = (String) v.elementAt(lv++); if (!sl.equals(si)) { break; } str = prestr; first = true; for (int j = 0; j < vlen; j++) { if (first) first = false; else str = str + ","; String sj = (String) v.elementAt(j); str = str + sj; if (iv == j) { str = str + "[]"; j = lv - 1; } } str = str + ")"; vstrs.add(str); } } String[] strlist = new String[vstrs.size()]; vstrs.toArray(strlist); meths = FormulaUtil.stringsToMethods(strlist); int found = -1; for (int j = 0; j < meths.length && found < 0; j++) { if (meths[j] != null) found = j; } if (found >= 0) meths[0] = meths[found]; else { // could not find a matching method return s; } } // store method object in a link variable String link = "link" + (++linkNum); try { fm.setThing(link, new VMethod(meths[0])); } // catch any errors setting the link variable catch (FormulaException exc) { return s; } catch (VisADException exc) { return s; } catch (RemoteException exc) { return s; } ns = ns + "linkx(" + link + "," + s.substring(s2, e2) + ")"; } else if (!letter) { int j = i; char c = l.charAt(j++); while (j < len && ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))) { c = l.charAt(j++); } // check for end-of-string if (j == len) return ns + s.substring(i, len); if (c == '[') { // convert x[y] notation to standard getSample(x, y) notation int k = j; for (int paren = 1; paren > 0; k++) { // check for correct syntax if (k >= len) return s; c = l.charAt(k); if (c == '[') paren++; if (c == ']') paren--; } ns = ns + "getSample(" + s.substring(i, j - 1) + "," + s.substring(j, k - 1) + ")"; i = k - 1; } else ns = ns + s.charAt(i); } else { // append character to new string ns = ns + s.charAt(i); } char c = (i < len) ? l.charAt(i) : '\0'; letter = (c >= 'a' && c <= 'z'); } return ns; }