blob: 6ada76b1059a1d629a3102fc74cd13eeeaba11eb [file] [log] [blame]
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.*;
import java.util.*;
/*
* assignment : key = value;
* key : string
* value : string | array | dict
* nValue : , value
* array : ( value nValue )
* nAssignment: , assignment|value
* dict : { assignment* }
* string : "*" or anything but a ,(){}=
*
* special characters: ,(){}=
*/
public class PParser {
protected static final int OPEN_PAIR = 1;
protected static final int CLOSE_PAIR = 2;
protected static final int OPEN_ARRAY = 3;
protected static final int CLOSE_ARRAY = 4;
protected static final int MORE = 5;
protected static final int EQUAL = 6;
protected static final int STRING = 7;
protected static final int WS = 8;
protected Reader reader;
protected boolean bufferedToken;
protected StringBuffer stringBuffer = new StringBuffer();
protected int lastChar;
protected int lastToken;
protected int lineNumber;
protected int column;
public PParser() {
}
public Hashtable parse(Reader r) throws IOException {
this.reader = r;
bufferedToken = false;
lineNumber = 0;
column = 0;
if (getToken() != OPEN_PAIR) {
error("No initial open");
}
return parsePair();
}
protected Object parseValue(int lookAhead) throws IOException {
int token;
if (lookAhead == -1) {
token = getToken();
} else {
token = lookAhead;
}
switch (token) {
case STRING:
return stringBuffer.toString();
case OPEN_ARRAY:
return parseArray();
case OPEN_PAIR:
return parsePair();
default:
error("Expecting value");
}
return null;
}
protected Object parseArray() throws IOException {
Vector array = new Vector();
int token;
while ((token = getToken()) != CLOSE_ARRAY) {
if (token == MORE) {
token = getToken();
}
if (token != CLOSE_ARRAY) {
array.addElement(parseValue(token));
}
}
return array;
}
protected Hashtable parsePair() throws IOException {
Hashtable ht = new Hashtable(11);
int token;
while ((token = getToken()) != CLOSE_PAIR) {
if (token != STRING) {
error("Pair expecting string got");
}
String key = stringBuffer.toString();
if (getToken() != EQUAL) {
error("Expecting = ");
}
Object value = parseValue(-1);
ht.put(key, value);
}
return ht;
}
protected void ungetToken() {
if (bufferedToken) {
error("Can not buffer more than one token");
}
bufferedToken = true;
}
protected int getToken() throws IOException {
int token = getToken(false, false);
return token;
}
protected int getToken(boolean wantsWS, boolean inString)
throws IOException {
if (bufferedToken) {
bufferedToken = false;
if (lastToken != WS || wantsWS) {
return lastToken;
}
}
while ((lastChar = reader.read()) != -1) {
// If a line starts with '#', skip the line.
if (column == 0 && lastChar == '#') {
while ((lastChar = reader.read()) != -1
&& lastChar != '\n') {
}
if (lastChar == -1) {
break;
}
}
column++;
switch(lastChar) {
case '\n':
lineNumber++;
column = 0;
case ' ':
case '\r':
case '\t':
if (wantsWS) {
lastToken = WS;
return WS;
}
break;
case ',':
lastToken = MORE;
return MORE;
case '(':
lastToken = OPEN_ARRAY;
return OPEN_ARRAY;
case ')':
lastToken = CLOSE_ARRAY;
return CLOSE_ARRAY;
case '{':
lastToken = OPEN_PAIR;
return OPEN_PAIR;
case '}':
lastToken = CLOSE_PAIR;
return CLOSE_PAIR;
case '=':
lastToken = EQUAL;
return EQUAL;
case '"':
lastToken = STRING;
if (!inString) {
stringBuffer.setLength(0);
while (true) {
getToken(true, true);
if (lastChar == '"') {
lastToken = STRING;
return STRING;
}
stringBuffer.append((char)lastChar);
}
}
return STRING;
default:
lastToken = STRING;
if (!inString) {
stringBuffer.setLength(0);
stringBuffer.append((char)lastChar);
while (getToken(true, true) == STRING) {
if (lastChar == '"') {
error("Unexpected quote");
}
stringBuffer.append((char)lastChar);
}
ungetToken();
}
return STRING;
}
}
return -1;
}
protected void error(String errorString) {
throw new RuntimeException(errorString + " at line " + lineNumber + " column " + column);
}
public static void dump(Object o) {
if (o instanceof String) {
System.out.print(o);
} else if(o instanceof Vector) {
Enumeration e = ((Vector)o).elements();
dump(" (");
while (e.hasMoreElements()) {
dump(e.nextElement());
dump(" -- ");
}
dump(" )");
} else {
Hashtable ht = (Hashtable)o;
Enumeration e = ht.keys();
dump(" {");
while (e.hasMoreElements()) {
Object key = e.nextElement();
dump(key);
dump(" = ");
dump(ht.get(key));
dump(";");
}
dump(" }");
}
}
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("need filename");
} else {
try {
FileReader fr = new FileReader(args[0]);
PParser parser = new PParser();
Hashtable ht = parser.parse(fr);
dump(ht);
System.out.println();
}
catch (IOException ioe) {
System.out.println("Couldn't parse: " + ioe);
}
}
}
}