diff --git a/src/main/java/parser/ArrayValue.java b/src/main/java/parser/ArrayValue.java new file mode 100644 index 0000000..a958863 --- /dev/null +++ b/src/main/java/parser/ArrayValue.java @@ -0,0 +1,20 @@ +package parser; + +import java.util.*; + +public class ArrayValue extends Value { + List values = new ArrayList<>(); + + public void addValue(Value value) { + values.add(value); + } + + public List getValues() { + return values; + } + + @Override + public String toString() { + return values.toString(); + } +} diff --git a/src/main/java/parser/IntegerValue.java b/src/main/java/parser/IntegerValue.java new file mode 100644 index 0000000..ad239d7 --- /dev/null +++ b/src/main/java/parser/IntegerValue.java @@ -0,0 +1,18 @@ +package parser; + +public class IntegerValue extends Value { + Integer intValue; + + public void setIntValue(Integer intValue) { + this.intValue = intValue; + } + + public Integer getIntValue() { + return intValue; + } + + @Override + public String toString() { + return String.valueOf(intValue); + } +} diff --git a/src/main/java/parser/JsonValue.java b/src/main/java/parser/JsonValue.java new file mode 100644 index 0000000..428c30d --- /dev/null +++ b/src/main/java/parser/JsonValue.java @@ -0,0 +1,34 @@ +package parser; + +import java.util.*; + +public class JsonValue extends Value { + Map json = new HashMap<>(); + + public Map getJson() { + return json; + } + + public Value getValue(StringValue key) { + return json.get(key); + } + + public void setJsonValue(StringValue key, Value value) { + json.put(key, value); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{"); + for (StringValue key : json.keySet()) { + stringBuilder.append(key).append(" : "); + stringBuilder.append(json.get(key)).append(" ,"); + } + if (stringBuilder.length() >= 2 && stringBuilder.substring(stringBuilder.length() - 2, stringBuilder.length()).equals(" ,")) { + stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length()); + } + stringBuilder.append(" }"); + return stringBuilder.toString(); + } +} diff --git a/src/main/java/parser/Parser.java b/src/main/java/parser/Parser.java new file mode 100644 index 0000000..85ee56c --- /dev/null +++ b/src/main/java/parser/Parser.java @@ -0,0 +1,324 @@ +package parser; + +import models.objectOrientedTransfer.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.*; + +public class Parser { + public TokenStream tokenStream; + + public static final String LEFT_CURLY_BRACKET = "{"; + public static final String RIGHT_CURLY_BRACKET = "}"; + public static final String LEFT_CURLY_BRACKET_REGX = "\\{"; + public static final String RIGHT_CURLY_BRACKET_REGX = "\\}"; + public static final String LEFT_SQUARE_BRACKET = "["; + public static final String RIGHT_SQUARE_BRACKET = "]"; + public static final String LEFT_SQUARE_BRACKET_REGX = "\\["; + public static final String RIGHT_SQUARE_BRACKET_REGX = "\\]"; + public static final String COMMA = ","; + public static final String COLON = ":"; + public static final String DOUBLE_QUOT = "\""; + + protected static List srcEdges = new ArrayList<>(); + protected static List dstEdges = new ArrayList<>(); + protected static Map objectNodeMap = new HashMap<>(); + protected static PushPullValue transferStyle; + protected static MultiplicityValue multiplicityValue; + + public Parser() { + Scanner sc = new Scanner(System.in); + StringBuilder s = new StringBuilder(); + System.out.println("Jsonをはりつけてください"); + while (true) { + String S = sc.nextLine(); + if (S.equals("")) { + break; + } + s.append(S); + } + tokenStream = new TokenStream(); + tokenStream.addLine(s.toString()); + } + + public Parser(final BufferedReader reader) { + this.tokenStream = new TokenStream(); + try { + String line; + while ((line = reader.readLine()) != null) { + tokenStream.addLine(line); + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Value getValue() { + return parseValue(tokenStream); + } + + public Value parseValue(TokenStream tokenStream) { + if (tokenStream.checkNext().equals(LEFT_CURLY_BRACKET)) { + tokenStream.next(); + JsonValue jsonValue = parseJsonValue(tokenStream); + if (tokenStream.checkNext().equals(RIGHT_CURLY_BRACKET)) { + tokenStream.next(); + return jsonValue; + } else { + throw new RuntimeException(String.valueOf(tokenStream.getLine())); + } + } else if (tokenStream.checkNext().equals(LEFT_SQUARE_BRACKET)) { + tokenStream.next(); + ArrayValue arrayValue = parseArrayValue(tokenStream); + if (tokenStream.checkNext().equals(RIGHT_SQUARE_BRACKET)) { + tokenStream.next(); + return arrayValue; + } else { + throw new RuntimeException(String.valueOf(tokenStream.getLine())); + } + } else if (tokenStream.checkNext().equals(DOUBLE_QUOT)) { + tokenStream.next(); + StringValue stringValue = parseStringValue(tokenStream); + if (tokenStream.checkNext().equals(DOUBLE_QUOT)) { + tokenStream.next(); + return stringValue; + } else { + throw new RuntimeException(String.valueOf(tokenStream.getLine())); + } + } else if (Character.isDigit(tokenStream.checkNext().charAt(0))) { + return parseIntegerValue(tokenStream); + } + throw new RuntimeException(String.valueOf(tokenStream.getLine())); + } + + public JsonValue parseJsonValue(TokenStream tokenStream) { + JsonValue jsonValue = new JsonValue(); + //要素が0 + if (tokenStream.checkNext().equals(RIGHT_CURLY_BRACKET)) { + return jsonValue; + } + while (true) { + //key + Value keyValue = parseValue(tokenStream); + if (!(keyValue instanceof StringValue)) { + throw new RuntimeException(String.valueOf(tokenStream.getLine())); + } + expect(tokenStream, COLON); + tokenStream.next();//COLON + //value + Value value = parseValue(tokenStream); + jsonValue.setJsonValue((StringValue) keyValue, value); + if (!tokenStream.checkNext().equals(COMMA)) { + break; + } + tokenStream.next(); + } + return jsonValue; + } + + public ArrayValue parseArrayValue(TokenStream tokenStream) { + ArrayValue arrayValue = new ArrayValue(); + //要素が0 + if (tokenStream.checkNext().equals(RIGHT_SQUARE_BRACKET)) { + return arrayValue; + } + while (true) { + Value value = parseValue(tokenStream); + arrayValue.addValue(value); + if (!tokenStream.checkNext().equals(COMMA)) { + + break; + } + tokenStream.next();//COMMA + } + return arrayValue; + } + + public IntegerValue parseIntegerValue(TokenStream tokenStream) { + IntegerValue integerValue = new IntegerValue(); + StringBuilder stringBuilder = new StringBuilder(); + while (Character.isDigit(tokenStream.checkNext().charAt(0))) { + stringBuilder.append(tokenStream.next()); + } + integerValue.setIntValue(Integer.valueOf(stringBuilder.toString())); + return integerValue; + } + + public StringValue parseStringValue(TokenStream tokenStream) { + StringValue stringValue = new StringValue(); + StringBuilder stringBuilder = new StringBuilder(); + while (!tokenStream.checkNext().equals(DOUBLE_QUOT)) { + stringBuilder.append(tokenStream.next()); + } + stringValue.setStringValue(stringBuilder.toString()); + return stringValue; + } + + public void expect(TokenStream tokenStream, String expect) { + if (!tokenStream.checkNext().equals(expect)) { + throw new RuntimeException("expect" + expect + "but" + tokenStream.checkNext() + " line" + tokenStream.getLine()); + } + } + + public static class TokenStream { + private ArrayList> tokens = new ArrayList<>(); + private ArrayList lines = new ArrayList<>(); + private int line = 0; + private int n = 0; + + public TokenStream() { + line = 0; + n = 0; + } + + public void addLine(String line) { + lines.add(line); + line = line.trim(); + ArrayList tokenList = splitByDoubleQuotation(line); + tokenList = splitBy(tokenList, COMMA, COMMA); + tokenList = splitBy(tokenList, COLON, COLON); + tokenList = splitBy(tokenList, LEFT_CURLY_BRACKET, LEFT_CURLY_BRACKET_REGX); + tokenList = splitBy(tokenList, RIGHT_CURLY_BRACKET, RIGHT_CURLY_BRACKET_REGX); + tokenList = splitBy(tokenList, LEFT_SQUARE_BRACKET, LEFT_SQUARE_BRACKET_REGX); + tokenList = splitBy(tokenList, RIGHT_SQUARE_BRACKET, RIGHT_SQUARE_BRACKET_REGX); + tokens.add(tokenList); + } + + private ArrayList splitBy(final List tokens, final String delimiter, final String delimiterRegx) { + ArrayList newTokens = new ArrayList<>(); + for (Token token : tokens) { + if (token.isAtomic()) { + newTokens.add(token); + } else { + String[] splitTokens = token.split(delimiterRegx); + boolean fFirstToken = true; + for (String t : splitTokens) { + if (!fFirstToken) { + newTokens.add(new Token(delimiter, true)); + } + if (t.length() > 0) { + newTokens.add(new Token(t)); + } + fFirstToken = false; + } + while (token.endsWith(delimiter)) { + newTokens.add(new Token(delimiter, true)); + token = token.substring(0, token.length() - 1); + } + } + } + return newTokens; + } + + private ArrayList splitByDoubleQuotation(String line) { + ArrayList newTokens = new ArrayList<>(); + String[] tokens = line.split(DOUBLE_QUOT); + boolean fFirstToken = true; + for (int i = 0; i < tokens.length; i++) { + String token = tokens[i]; + if (!fFirstToken) { + newTokens.add(new Token(DOUBLE_QUOT, true)); + } + if (!fFirstToken || token.length() > 0) { + if (i % 2 == 0) { + for (String t : token.split("[ \t]")) { + newTokens.add(new Token(t)); + } + } else { + // string literal + newTokens.add(new Token(token, true)); + } + } + fFirstToken = false; + } + if (line.endsWith(DOUBLE_QUOT)) { + newTokens.add(new Token(DOUBLE_QUOT, true)); + } + return newTokens; + } + + public String next() { + if (line >= tokens.size()) return null; + while (n >= tokens.get(line).size()) { + line++; + n = 0; + if (line >= tokens.size()) return null; + } + String token = tokens.get(line).get(n).getTokenStr(); + n++; + return token; + } + + public String checkNext() { + if (line >= tokens.size()) return null; + while (n >= tokens.get(line).size()) { + line++; + n = 0; + if (line >= tokens.size()) return null; + } + return tokens.get(line).get(n).getTokenStr(); + } + + public boolean hasNext() { + if (line >= tokens.size()) return false; + while (n >= tokens.get(line).size()) { + line++; + n = 0; + if (line >= tokens.size()) return false; + } + return true; + } + + public int getLine() { + return line; + } + + public String getSourceText(int from, int to) { + String text = ""; + for (int l = from; l <= to; l++) { + text += lines.get(l) + "\n"; + } + return text; + } + } + + public static class Token { + String token; + boolean isAtomic = false; + + public Token(String token) { + this.token = token; + } + + public Token(String token, boolean isAtomic) { + this.token = token; + this.isAtomic = isAtomic; + } + + public String getTokenStr() { + return token; + } + + public boolean isAtomic() { + return isAtomic; + } + + public String[] split(String delimiterRegx) { + return token.split(delimiterRegx); + } + + public boolean endsWith(String delimiter) { + return token.endsWith(delimiter); + } + + public int length() { + return token.length(); + } + + public Token substring(int beginIdx, int endIdx) { + return new Token(token.substring(beginIdx, endIdx)); + } + } +} diff --git a/src/main/java/parser/StringValue.java b/src/main/java/parser/StringValue.java new file mode 100644 index 0000000..d3f0021 --- /dev/null +++ b/src/main/java/parser/StringValue.java @@ -0,0 +1,18 @@ +package parser; + +public class StringValue extends Value { + String stringValue; + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + public String getStringValue() { + return stringValue; + } + + @Override + public String toString() { + return stringValue; + } +} diff --git a/src/main/java/parser/Value.java b/src/main/java/parser/Value.java new file mode 100644 index 0000000..8a4bf2b --- /dev/null +++ b/src/main/java/parser/Value.java @@ -0,0 +1,6 @@ +package parser; + +public abstract class Value { + + public abstract String toString(); +}