/*
* 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 Map<String,Object> 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 {
List<Object> array = new ArrayList<>();
int token;
while ((token = getToken()) != CLOSE_ARRAY) {
if (token == MORE) {
token = getToken();
}
if (token != CLOSE_ARRAY) {
array.add(parseValue(token));
}
}
return array;
}
protected Map<String,Object> parsePair() throws IOException {
Map<String,Object> ht = new HashMap<>(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;
}
@SuppressWarnings("fallthrough" )
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);
}
@SuppressWarnings("unchecked" )
public static void dump(Object o) {
if (o instanceof String) {
System.out.print(o);
} else if (o instanceof List) {
dump(" (" );
((List)o).forEach((l) -> {
dump(l);
dump(" -- " );
});
dump(" )" );
} else {
Map<String,Object> ht = (Map<String,Object>)o;
dump(" {" );
ht.keySet().forEach(l -> {
dump(l);
dump(" = " );
dump(ht.get(l));
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();
Map<String,Object> ht = parser.parse(fr);
dump(ht);
System.out.println();
}
catch (IOException ioe) {
System.out.println("Couldn't parse: " + ioe);
}
}
}
}
Messung V0.5 in Prozent C=96 H=78 G=87
¤ Dauer der Verarbeitung: 0.4 Sekunden
¤
*© Formatika GbR, Deutschland