| 1 2 12 package com.versant.core.jdo; 13 14 import com.versant.core.util.CharBuf; 15 16 import com.versant.core.common.BindingSupportImpl; 17 18 22 public class ParamDeclarationParser { 23 24 27 public static interface Handler { 28 29 33 public void parameterParsed(int index, String type, String name); 34 } 35 36 private static final int STATE_START = 0; 37 private static final int STATE_LOOK_FOR_TYPE = 1; 38 private static final int STATE_IN_TYPE = 2; 39 private static final int STATE_LOOK_FOR_NAME = 3; 40 private static final int STATE_IN_NAME = 4; 41 private static final int STATE_LOOK_FOR_COMMA = 5; 42 43 47 public static int parse(String params, Handler handler) { 48 if (params == null) return 0; 49 int len = params.length(); 50 if (len == 0) return 0; 51 int state = STATE_START; 52 String type = null; 53 int count = 0; 54 CharBuf buf = new CharBuf(); 55 for (int pos = 0; ; pos++) { 56 if (pos < len) { 57 char c = params.charAt(pos); 58 switch (state) { 59 case STATE_START: 60 case STATE_LOOK_FOR_TYPE: 61 if (isIdStart(c)) { 62 buf.append(c); 63 state = STATE_IN_TYPE; 64 } else if (!isWs(c)) { 65 error(pos, "parameter type", c); 66 } 67 break; 68 case STATE_IN_TYPE: 69 if (isId(c) || c == '.') { 70 buf.append(c); 71 } else if (isWs(c)) { 72 type = buf.toString(); 73 buf.clear(); 74 state = STATE_LOOK_FOR_NAME; 75 } else { 76 error(pos, "parameter type", c); 77 } 78 break; 79 case STATE_LOOK_FOR_NAME: 80 if (isIdStart(c)) { 81 buf.append(c); 82 state = STATE_IN_NAME; 83 } else if (!isWs(c)) { 84 error(pos, "parameter name", c); 85 } 86 break; 87 case STATE_IN_NAME: 88 if (isId(c)) { 89 buf.append(c); 90 } else if (c == ',' || isWs(c)) { 91 handler.parameterParsed(count++, type, buf.toString()); 92 buf.clear(); 93 type = null; 94 if (c == ',') state = STATE_LOOK_FOR_TYPE; 95 else state = STATE_LOOK_FOR_COMMA; 96 } else { 97 error(pos, "parameter name", c); 98 } 99 break; 100 case STATE_LOOK_FOR_COMMA: 101 if (c == ',') { 102 state = STATE_LOOK_FOR_TYPE; 103 } else if (!isWs(c)) { 104 error(pos, "comma", c); 105 } 106 break; 107 } 108 } else { 109 switch (state) { 110 case STATE_LOOK_FOR_TYPE: 111 error(pos, "parameter type", (char)-1); 112 case STATE_IN_TYPE: 113 case STATE_LOOK_FOR_NAME: 114 error(pos, "parameter name", (char)-1); 115 case STATE_IN_NAME: 116 handler.parameterParsed(count++, type, buf.toString()); 117 } 118 break; 119 } 120 } 121 return count; 122 } 123 124 private static boolean isWs(char c) { 125 return c == ' ' || c == '\n' || c == '\t'; 126 } 127 128 private static boolean isIdStart(char c) { 129 return c == '_' 130 || (c >= 'A' && c <= 'Z') 131 || (c >= 'a' && c <= 'z'); 132 } 133 134 private static boolean isId(char c) { 135 return c == '_' 136 || (c >= 'A' && c <= 'Z') 137 || (c >= 'a' && c <= 'z') 138 || (c >= '0' && c <= '9'); 139 } 140 141 private static void error(int pos, String msg, char c) { 142 throw BindingSupportImpl.getInstance().runtime("Invalid parameter declaration: Expected " + 143 msg + ", got '" + c + "' at position " + pos); 144 } 145 146 } 147 148 | Popular Tags |