1 /* 2 * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.*; 25 import java.util.*; 26 27 /* 28 * assignment : key = value; 29 * key : string 30 * value : string | array | dict 31 * nValue : , value 32 * array : ( value nValue ) 33 * nAssignment: , assignment|value 34 * dict : { assignment* } 35 * string : "*" or anything but a ,(){}= 36 * 37 * special characters: ,(){}= 38 */ 39 40 public class PParser { 41 protected static final int OPEN_PAIR = 1; 42 protected static final int CLOSE_PAIR = 2; 43 protected static final int OPEN_ARRAY = 3; 44 protected static final int CLOSE_ARRAY = 4; 45 protected static final int MORE = 5; 46 protected static final int EQUAL = 6; 47 protected static final int STRING = 7; 48 protected static final int WS = 8; 49 50 protected Reader reader; 51 protected boolean bufferedToken; 52 protected StringBuffer stringBuffer = new StringBuffer(); 53 protected int lastChar; 54 protected int lastToken; 55 protected int lineNumber; 56 protected int column; 57 58 public PParser() { 59 } 60 61 public Hashtable parse(Reader r) throws IOException { 62 this.reader = r; 63 bufferedToken = false; 64 lineNumber = 0; 65 column = 0; 66 if (getToken() != OPEN_PAIR) { 67 error("No initial open"); 68 } 69 return parsePair(); 70 } 71 72 protected Object parseValue(int lookAhead) throws IOException { 73 int token; 74 75 if (lookAhead == -1) { 76 token = getToken(); 77 } else { 78 token = lookAhead; 79 } 80 switch (token) { 81 case STRING: 82 return stringBuffer.toString(); 83 case OPEN_ARRAY: 84 return parseArray(); 85 case OPEN_PAIR: 86 return parsePair(); 87 default: 88 error("Expecting value"); 89 } 90 return null; 91 } 92 93 protected Object parseArray() throws IOException { 94 Vector array = new Vector(); 95 int token; 96 97 while ((token = getToken()) != CLOSE_ARRAY) { 98 if (token == MORE) { 99 token = getToken(); 100 } 101 if (token != CLOSE_ARRAY) { 102 array.addElement(parseValue(token)); 103 } 104 } 105 return array; 106 } 107 108 protected Hashtable parsePair() throws IOException { 109 Hashtable ht = new Hashtable(11); 110 int token; 111 112 while ((token = getToken()) != CLOSE_PAIR) { 113 if (token != STRING) { 114 error("Pair expecting string got"); 115 } 116 String key = stringBuffer.toString(); 117 118 if (getToken() != EQUAL) { 119 error("Expecting = "); 120 } 121 122 Object value = parseValue(-1); 123 ht.put(key, value); 124 } 125 return ht; 126 } 127 128 protected void ungetToken() { 129 if (bufferedToken) { 130 error("Can not buffer more than one token"); 131 } 132 bufferedToken = true; 133 } 134 135 protected int getToken() throws IOException { 136 int token = getToken(false, false); 137 138 return token; 139 } 140 141 protected int getToken(boolean wantsWS, boolean inString) 142 throws IOException { 143 if (bufferedToken) { 144 bufferedToken = false; 145 if (lastToken != WS || wantsWS) { 146 return lastToken; 147 } 148 } 149 while ((lastChar = reader.read()) != -1) { 150 // If a line starts with '#', skip the line. 151 if (column == 0 && lastChar == '#') { 152 while ((lastChar = reader.read()) != -1 153 && lastChar != '\n') { 154 } 155 if (lastChar == -1) { 156 break; 157 } 158 } 159 160 column++; 161 switch(lastChar) { 162 case '\n': 163 lineNumber++; 164 column = 0; 165 case ' ': 166 case '\r': 167 case '\t': 168 if (wantsWS) { 169 lastToken = WS; 170 return WS; 171 } 172 break; 173 case ',': 174 lastToken = MORE; 175 return MORE; 176 case '(': 177 lastToken = OPEN_ARRAY; 178 return OPEN_ARRAY; 179 case ')': 180 lastToken = CLOSE_ARRAY; 181 return CLOSE_ARRAY; 182 case '{': 183 lastToken = OPEN_PAIR; 184 return OPEN_PAIR; 185 case '}': 186 lastToken = CLOSE_PAIR; 187 return CLOSE_PAIR; 188 case '=': 189 lastToken = EQUAL; 190 return EQUAL; 191 case '"': 192 lastToken = STRING; 193 if (!inString) { 194 stringBuffer.setLength(0); 195 while (true) { 196 getToken(true, true); 197 if (lastChar == '"') { 198 lastToken = STRING; 199 return STRING; 200 } 201 stringBuffer.append((char)lastChar); 202 } 203 } 204 return STRING; 205 default: 206 lastToken = STRING; 207 if (!inString) { 208 stringBuffer.setLength(0); 209 stringBuffer.append((char)lastChar); 210 while (getToken(true, true) == STRING) { 211 if (lastChar == '"') { 212 error("Unexpected quote"); 213 } 214 stringBuffer.append((char)lastChar); 215 } 216 ungetToken(); 217 } 218 return STRING; 219 } 220 } 221 return -1; 222 } 223 224 protected void error(String errorString) { 225 throw new RuntimeException(errorString + " at line " + lineNumber + " column " + column); 226 } 227 228 public static void dump(Object o) { 229 if (o instanceof String) { 230 System.out.print(o); 231 } else if(o instanceof Vector) { 232 Enumeration e = ((Vector)o).elements(); 233 234 dump(" ("); 235 while (e.hasMoreElements()) { 236 dump(e.nextElement()); 237 dump(" -- "); 238 } 239 dump(" )"); 240 } else { 241 Hashtable ht = (Hashtable)o; 242 Enumeration e = ht.keys(); 243 244 dump(" {"); 245 while (e.hasMoreElements()) { 246 Object key = e.nextElement(); 247 248 dump(key); 249 dump(" = "); 250 dump(ht.get(key)); 251 dump(";"); 252 } 253 dump(" }"); 254 } 255 } 256 257 public static void main(String[] args) { 258 if (args.length == 0) { 259 System.out.println("need filename"); 260 } else { 261 try { 262 FileReader fr = new FileReader(args[0]); 263 PParser parser = new PParser(); 264 Hashtable ht = parser.parse(fr); 265 266 dump(ht); 267 System.out.println(); 268 } 269 catch (IOException ioe) { 270 System.out.println("Couldn't parse: " + ioe); 271 } 272 } 273 } 274 }