package nl.helixsoft.graph; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import nl.helixsoft.graph.GmlTokenizer.Token; import nl.helixsoft.graph.GmlTokenizer.TokenType; public class GmlParser { private final Emitter emitter; private final GmlTokenizer tokenizer; private GmlParser (Reader fis, Emitter emitter) throws IOException { tokenizer = new GmlTokenizer(fis); this.emitter = emitter; eatList(); getExpectedToken(TokenType.EOF); } private Token getExpectedToken (TokenType type) throws IOException { Token token = tokenizer.getToken(); if (token.getType() != type) throw new IllegalStateException("Expected " + type + ", but found " + token.getType() + " in " + tokenizer.getPosition()); return token; } private void eatWhitespace() throws IOException { Token token = tokenizer.getLookAhead(); while (token.getType() == TokenType.WHITESPACE) { tokenizer.getToken(); // consume token token = tokenizer.getLookAhead(); } } private void eatValue(String key) throws IOException { Token token = tokenizer.getLookAhead(); switch (token.getType()) { case LBRACKET: emitter.startList(key); tokenizer.getToken(); eatList(); eatWhitespace(); getExpectedToken(TokenType.RBRACKET); emitter.closeList(); break; case INTEGER_LITERAL: token = tokenizer.getToken(); emitter.intLiteral (key, token.getIntValue()); break; case DOUBLE_LITERAL: tokenizer.getToken(); emitter.doubleLiteral (key, token.getDoubleValue()); break; case STRING_LITERAL: token = tokenizer.getToken(); emitter.stringLiteral (key, token.getStringValue()); break; default: throw new IllegalStateException("Expected LBRACKET, NUMBER_LITERAL or STRING_LITERAL, found " + token.getType()); } } private void eatList() throws IOException { eatWhitespace(); Token token = tokenizer.getLookAhead(); while (token.getType() == TokenType.KEYWORD) { String key = tokenizer.getToken().getStringValue(); getExpectedToken(TokenType.WHITESPACE); eatValue(key); eatWhitespace(); token = tokenizer.getLookAhead(); } } public static void parse(File f, Emitter emitter) throws IOException { new GmlParser (new FileReader(f), emitter); } public static void parse(Reader r, Emitter emitter) throws IOException { new GmlParser (r, emitter); } }