diff --git a/src/main/java/org/ntlab/rdlcanvas/Main.java b/src/main/java/org/ntlab/rdlcanvas/Main.java index a5bddc1..0330b5b 100644 --- a/src/main/java/org/ntlab/rdlcanvas/Main.java +++ b/src/main/java/org/ntlab/rdlcanvas/Main.java @@ -13,7 +13,7 @@ Value value = parser.getValue(); System.out.println(value.toString()); -// Map map = ((JsonValue)value).getJson(); +// Map map = ((JsonValue)value).getKeyToValue(); // for (StringValue key : map.keySet()){ // String keyName = key.getStringValue(); // System.out.println(keyName); diff --git a/src/main/java/org/ntlab/rdlcanvas/parser/ArrayValue.java b/src/main/java/org/ntlab/rdlcanvas/parser/ArrayValue.java index 66f1029..84a9346 100644 --- a/src/main/java/org/ntlab/rdlcanvas/parser/ArrayValue.java +++ b/src/main/java/org/ntlab/rdlcanvas/parser/ArrayValue.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class ArrayValue extends Value { List values = new ArrayList<>(); @@ -21,4 +22,17 @@ public String toString() { return values.toString(); } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ArrayValue)) { + return false; + } + return getValues().equals(((ArrayValue) obj).getValues()); + } + + @Override + public int hashCode() { + return Objects.hashCode(values); + } } diff --git a/src/main/java/org/ntlab/rdlcanvas/parser/IntegerValue.java b/src/main/java/org/ntlab/rdlcanvas/parser/IntegerValue.java index feb5bc4..7a989ec 100644 --- a/src/main/java/org/ntlab/rdlcanvas/parser/IntegerValue.java +++ b/src/main/java/org/ntlab/rdlcanvas/parser/IntegerValue.java @@ -1,8 +1,14 @@ package org.ntlab.rdlcanvas.parser; +import java.util.Objects; + public class IntegerValue extends Value { Integer intValue; + public IntegerValue(Integer intValue) { + this.intValue = intValue; + } + // 与えられた整数を代入するコンストラクタ public void setIntValue(Integer intValue) { this.intValue = intValue; @@ -18,4 +24,17 @@ public String toString() { return String.valueOf(intValue); } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof IntegerValue)) { + return false; + } + return Objects.equals(((IntegerValue) obj).getIntValue(), getIntValue()); + } + + @Override + public int hashCode() { + return Objects.hashCode(intValue); + } } diff --git a/src/main/java/org/ntlab/rdlcanvas/parser/JsonValue.java b/src/main/java/org/ntlab/rdlcanvas/parser/JsonValue.java index ae29b55..90ac48d 100644 --- a/src/main/java/org/ntlab/rdlcanvas/parser/JsonValue.java +++ b/src/main/java/org/ntlab/rdlcanvas/parser/JsonValue.java @@ -2,24 +2,25 @@ import java.util.HashMap; import java.util.Map; +import java.util.Objects; public class JsonValue extends Value { //JsonのKeyとValueの対応を保持するMap(Keyは文字列、ValueはValueクラスのインスタンス) - Map json = new HashMap<>(); + Map keyToValue = new HashMap<>(); //KeyとValueの対応(Map丸ごと)を返す - public Map getJson() { - return json; + public Map getKeyToValue() { + return keyToValue; } // 与えられたKeyに対応するValueを返す public Value getValue(StringValue key) { - return json.get(key); + return keyToValue.get(key); } // 与えられたKeyとValueの対応をMapに追加 public void setJsonValue(StringValue key, Value value) { - json.put(key, value); + keyToValue.put(key, value); } // MapからJson文字列を生成する。形式は{key1 : value1 , key2 : value2 , ...} @@ -27,9 +28,9 @@ public String toString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("{"); - for (StringValue key : json.keySet()) { + for (StringValue key : keyToValue.keySet()) { stringBuilder.append(key).append(" : "); - stringBuilder.append(json.get(key)).append(" ,"); + stringBuilder.append(keyToValue.get(key)).append(" ,"); } if (stringBuilder.length() >= 2 && stringBuilder.substring(stringBuilder.length() - 2, stringBuilder.length()).equals(" ,")) { stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length()); @@ -37,4 +38,17 @@ stringBuilder.append(" }"); return stringBuilder.toString(); } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof JsonValue)) { + return false; + } + return keyToValue.equals(((JsonValue) obj).getKeyToValue()); + } + + @Override + public int hashCode() { + return Objects.hashCode(keyToValue); + } } diff --git a/src/main/java/org/ntlab/rdlcanvas/parser/Parser.java b/src/main/java/org/ntlab/rdlcanvas/parser/Parser.java index f9e7895..dceac65 100644 --- a/src/main/java/org/ntlab/rdlcanvas/parser/Parser.java +++ b/src/main/java/org/ntlab/rdlcanvas/parser/Parser.java @@ -60,37 +60,20 @@ return parseValue(tokenStream); } + public JsonValue parseJsonValue() { + return parseJsonValue(tokenStream); + } + // 値のパース(構文解析) public Value parseValue(TokenStream tokenStream) throws ExpectedJsonValue, ExpectedArrayValue, ExpectedStringValue { // 次のトークンを見て、どの型の値をパースするかを決定する // "{"のとき、JsonValue, "["のとき、ArrayValue, "\""のとき、StringValueとしてパースへ流す 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 ExpectedJsonValue(String.valueOf(tokenStream.getLine())); - } + return parseJsonValue(tokenStream); } 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 ExpectedArrayValue(String.valueOf(tokenStream.getLine())); - } + return parseArrayValue(tokenStream); } 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 ExpectedStringValue(String.valueOf(tokenStream.getLine())); - } + return parseStringValue(tokenStream); } else if (Character.isDigit(tokenStream.checkNext().charAt(0))) { return parseIntegerValue(tokenStream); } @@ -99,8 +82,14 @@ public JsonValue parseJsonValue(TokenStream tokenStream) throws ExpectedStringValue { JsonValue jsonValue = new JsonValue(); + if (tokenStream.checkNext().equals(LEFT_CURLY_BRACKET)) { + tokenStream.next(); + } else { + throw new ExpectedJsonValue(String.valueOf(tokenStream.getLine())); + } //要素が0 if (tokenStream.checkNext().equals(RIGHT_CURLY_BRACKET)) { + tokenStream.next(); return jsonValue; } while (true) { @@ -119,13 +108,26 @@ } tokenStream.next(); } + + if (tokenStream.checkNext().equals(RIGHT_CURLY_BRACKET)) { + tokenStream.next(); + } else { + throw new ExpectedJsonValue(String.valueOf(tokenStream.getLine())); + } return jsonValue; } public ArrayValue parseArrayValue(TokenStream tokenStream) { ArrayValue arrayValue = new ArrayValue(); + if (tokenStream.checkNext().equals(LEFT_SQUARE_BRACKET)) { + tokenStream.next(); + } else { + throw new ExpectedArrayValue(String.valueOf(tokenStream.getLine())); + } + //要素が0 if (tokenStream.checkNext().equals(RIGHT_SQUARE_BRACKET)) { + tokenStream.next(); return arrayValue; } while (true) { @@ -136,26 +138,44 @@ } tokenStream.next();//COMMA } + + if (tokenStream.checkNext().equals(RIGHT_SQUARE_BRACKET)) { + tokenStream.next(); + } else { + throw new ExpectedArrayValue(String.valueOf(tokenStream.getLine())); + } return arrayValue; } public IntegerValue parseIntegerValue(TokenStream tokenStream) { - IntegerValue integerValue = new IntegerValue(); + IntegerValue integerValue; StringBuilder stringBuilder = new StringBuilder(); while (Character.isDigit(tokenStream.checkNext().charAt(0))) { stringBuilder.append(tokenStream.next()); } - integerValue.setIntValue(Integer.valueOf(stringBuilder.toString())); + integerValue = new IntegerValue(Integer.valueOf(stringBuilder.toString())); return integerValue; } public StringValue parseStringValue(TokenStream tokenStream) { - StringValue stringValue = new StringValue(); + if (tokenStream.checkNext().equals(DOUBLE_QUOT)) { + tokenStream.next(); + } else { + throw new ExpectedStringValue(String.valueOf(tokenStream.getLine())); + } + + StringValue stringValue; StringBuilder stringBuilder = new StringBuilder(); while (!tokenStream.checkNext().equals(DOUBLE_QUOT)) { stringBuilder.append(tokenStream.next()); } - stringValue.setStringValue(stringBuilder.toString()); + stringValue = new StringValue(stringBuilder.toString()); + + if (tokenStream.checkNext().equals(DOUBLE_QUOT)) { + tokenStream.next(); + } else { + throw new ExpectedStringValue(String.valueOf(tokenStream.getLine())); + } return stringValue; } diff --git a/src/main/java/org/ntlab/rdlcanvas/parser/StringValue.java b/src/main/java/org/ntlab/rdlcanvas/parser/StringValue.java index 649b82c..f04ea6f 100644 --- a/src/main/java/org/ntlab/rdlcanvas/parser/StringValue.java +++ b/src/main/java/org/ntlab/rdlcanvas/parser/StringValue.java @@ -1,8 +1,14 @@ package org.ntlab.rdlcanvas.parser; +import java.util.Objects; + public class StringValue extends Value { String stringValue; + public StringValue(String stringValue) { + this.stringValue = stringValue; + } + // 与えられた文字列を保持するコンストラクタ public void setStringValue(String stringValue) { this.stringValue = stringValue; @@ -18,4 +24,17 @@ public String toString() { return stringValue; } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof StringValue)) { + return false; + } + return ((StringValue) obj).getStringValue().equals(getStringValue()); + } + + @Override + public int hashCode() { + return Objects.hashCode(stringValue); + } } diff --git a/src/main/java/org/ntlab/rdlcanvas/parser/Value.java b/src/main/java/org/ntlab/rdlcanvas/parser/Value.java index a59c891..cc2ffc0 100644 --- a/src/main/java/org/ntlab/rdlcanvas/parser/Value.java +++ b/src/main/java/org/ntlab/rdlcanvas/parser/Value.java @@ -4,4 +4,14 @@ public abstract class Value { public abstract String toString(); + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } }