[Jiemamy-notify:1379] commit [2623] gtreeのパーサに変数の概念を追加。

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2009年 2月 6日 (金) 02:57:30 JST


Revision: 2623
          http://svn.sourceforge.jp/view?root=jiemamy&view=rev&rev=2623
Author:   ashigeru
Date:     2009-02-06 02:57:30 +0900 (Fri, 06 Feb 2009)

Log Message:
-----------
gtreeのパーサに変数の概念を追加。

Modified Paths:
--------------
    artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Parser.java
    artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/package-info.java
    artemis/trunk/generic-tree/src/main/javacc/GtreeParser.jj
    artemis/trunk/generic-tree/src/test/java/org/jiemamy/utils/gtree/text/ParserTest.java

Added Paths:
-----------
    artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Variables.java


-------------- next part --------------
Modified: artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Parser.java
===================================================================
--- artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Parser.java	2009-02-05 17:56:32 UTC (rev 2622)
+++ artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Parser.java	2009-02-05 17:57:30 UTC (rev 2623)
@@ -17,6 +17,8 @@
 
 import java.io.IOException;
 import java.io.Reader;
+import java.util.Collections;
+import java.util.Map;
 
 import org.jiemamy.utils.gtree.model.Value;
 
@@ -26,28 +28,50 @@
  * @author Suguru ARAKAWA
  */
 public class Parser {
-    
-    /**
-     * 指定のソースから{@code Generic Tree Notation}形式のテキストを読み出し、
-     * 対応する{@link Value}を構築する。
-     * @param source {@code Generic Tree Notation}のテキストを保持するソース
-     * @return 対応する{@link Value}
-     * @throws IOException 解析に失敗した場合
-     * @throws NullPointerException 引数に{@code null}が指定された場合
-     */
-    public static Value parse(Reader source) throws IOException {
-        if (source == null) {
-            throw new NullPointerException("source"); //$NON-NLS-1$
-        }
-        GtreeParser0 parser = new GtreeParser0(source);
-        try {
-            return parser.parse();
-        }
-        catch (ParseException e) {
-            throw (IOException) new IOException().initCause(e);
-        }
-        finally {
-            source.close();
-        }
-    }
+	
+	/**
+	 * 指定のソースから{@code Generic Tree Notation}形式のテキストを読み出し、
+	 * 対応する{@link Value}を構築する。
+	 * @param source {@code Generic Tree Notation}のテキストを保持するソース
+	 * @return 対応する{@link Value}
+	 * @throws IOException 解析に失敗した場合
+	 * @throws NullPointerException 引数に{@code null}が指定された場合
+	 */
+	public static Value parse(Reader source) throws IOException {
+		if (source == null) {
+			throw new NullPointerException("source"); //$NON-NLS-1$
+		}
+		return parse(source, Collections.<String, Value> emptyMap());
+	}
+	
+	/**
+	 * 指定のソースから{@code Generic Tree Notation}形式のテキストを読み出し、
+	 * 対応する{@link Value}を構築する。
+	 * <p>
+	 * ソース中に値の代わりに{@code $id}という形式の変数を指定することができ、
+	 * {@code id}の名前で登録された値を{@code variables}から検出して利用する。
+	 * そのような名前が{@code variables}に指定されていない場合、解析は失敗する。
+	 * </p>
+	 * @param source {@code Generic Tree Notation}のテキストを保持するソース
+	 * @param variables 変数名と束縛された値の一覧
+	 * @return 対応する{@link Value}
+	 * @throws IOException 解析に失敗した場合
+	 * @throws NullPointerException 引数に{@code null}が指定された場合
+	 */
+	public static Value parse(Reader source, Map<String, ? extends Value> variables) throws IOException {
+		if (source == null) {
+			throw new NullPointerException("source"); //$NON-NLS-1$
+		}
+		if (variables == null) {
+			throw new NullPointerException("variables"); //$NON-NLS-1$
+		}
+		GtreeParser0 parser = new GtreeParser0(source);
+		try {
+			return parser.parse(new Variables(variables));
+		} catch (ParseException e) {
+			throw (IOException) new IOException("Parse failure").initCause(e); //$NON-NLS-1$
+		} finally {
+			source.close();
+		}
+	}
 }

Added: artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Variables.java
===================================================================
--- artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Variables.java	                        (rev 0)
+++ artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Variables.java	2009-02-05 17:57:30 UTC (rev 2623)
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007-2009 Jiemamy Project and the Others.
+ * Created on 2009/02/06
+ *
+ * This file is part of Jiemamy.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.jiemamy.utils.gtree.text;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jiemamy.utils.gtree.model.Value;
+
+/**
+ * 変数表。
+ * @author Suguru ARAKAWA
+ */
+class Variables {
+	
+	/**
+	 * 値がひとつも束縛されてない変数表。
+	 */
+	public static final Variables NULL = new Variables(Collections.<String, Value> emptyMap());
+	
+	/**
+	 * 変数表。
+	 */
+	private final Map<String, Value> entity;
+	
+
+	/**
+	 * インスタンスを生成する。
+	 * @param entity 変数名と値の束縛表
+	 * @throws NullPointerException 引数に{@code null}が指定された場合
+	 */
+	public Variables(Map<String, ? extends Value> entity) {
+		super();
+		if (entity == null) {
+			throw new NullPointerException("entity"); //$NON-NLS-1$
+		}
+		this.entity = Collections.unmodifiableMap(new HashMap<String, Value>(entity));
+	}
+	
+	/**
+	 * 指定のトークンを解析して、対応する変数の内容を返す。
+	 * @param token 変数を表現するトークン
+	 * @return 対象の変数に束縛された値
+	 * @throws ParseException 指定の変数に値が束縛されていない場合
+	 */
+	public Value resolve(Token token) throws ParseException {
+		if (token == null) {
+			throw new NullPointerException("token"); //$NON-NLS-1$
+		}
+		if (token.image.startsWith("$") == false) {
+			throw new IllegalArgumentException(token.toString());
+		}
+		String name = token.image.substring(1);
+		Value bound = entity.get(name);
+		if (bound == null) {
+			throw new ParseException(MessageFormat.format("Undefined variable \"{0}\" (line {1}, column {2})", //$NON-NLS-1$
+					token.image, token.beginLine, token.endColumn));
+		}
+		return bound;
+	}
+}


Property changes on: artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/Variables.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Author Id Revision HeadURL
Added: svn:eol-style
   + native

Modified: artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/package-info.java
===================================================================
--- artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/package-info.java	2009-02-05 17:56:32 UTC (rev 2622)
+++ artemis/trunk/generic-tree/src/main/java/org/jiemamy/utils/gtree/text/package-info.java	2009-02-05 17:57:30 UTC (rev 2623)
@@ -30,6 +30,7 @@
  *     OrderedList
  *     UnorderedList
  *     Record
+ *     Variable
  * 
  * Terminal :
  *     STRING
@@ -46,6 +47,9 @@
  *     &lt; &gt;
  *     &lt; EntryList &gt;
  * 
+ * Variable :
+ *     $ IDENTIFIER
+ *     
  * ValueList :
  *     Value
  *     ValueList , Value
@@ -59,6 +63,17 @@
  * 
  * STRING :
  *     (Javaの文字列リテラル)
+ * 
+ * IDENTIFIER :
+ *     [A-Za-z0-9]+
+ * 
  * </code></pre>
+ * <p>
+ * このうち、{@code Variable}は擬似的な構文規則で、あらかじめ登録された値を
+ * 変数表から探し出し、評価結果を該当の変数に格納された値とする。
+ * 変数表には変数の名前を束縛する値の一覧を指定できるが、このとき
+ * 先頭の{@code $}を除いた識別子で変数の名前を指定する。
+ * </p>
  */
 package org.jiemamy.utils.gtree.text;
+

Modified: artemis/trunk/generic-tree/src/main/javacc/GtreeParser.jj
===================================================================
--- artemis/trunk/generic-tree/src/main/javacc/GtreeParser.jj	2009-02-05 17:56:32 UTC (rev 2622)
+++ artemis/trunk/generic-tree/src/main/javacc/GtreeParser.jj	2009-02-05 17:57:30 UTC (rev 2623)
@@ -45,14 +45,30 @@
 
 class GtreeParser0 {
     
+    private ThreadLocal<Variables> variables = new ThreadLocal<Variables>();
+    
     /**
      * Parse and returns the analyzed Generic Tree Model.
      * @return the analyzed model
      * @throws ParseException if parse was failed
      */
-    public Value parse() throws ParseException {
-        return script();
+    public Value parse(Variables vars) throws ParseException {
+        variables.set(vars);
+        try {
+            return script();
+        }
+        finally {
+            variables.set(null);
+        }
     }
+    
+    private Value resolve(Token variable) throws ParseException {
+        Variables vars = variables.get();
+        if (vars == null) {
+            vars = Variables.NULL;
+        }
+        return vars.resolve(variable);
+    }
 
     private static <T> List<T> list() {
         return new ArrayList<T>();
@@ -90,6 +106,10 @@
 }
 
 TOKEN :
+{   <VARIABLE : "$" (["A"-"Z", "a"-"z", "0"-"9", "_"])+ >
+}
+
+TOKEN :
 {   <STRING
     : "'" (<SCHAR>|<ESCAPE>)* "'"
     | "\"" (<DCHAR>|<ESCAPE>)* "\""
@@ -130,6 +150,7 @@
  *     OrderedList
  *     UnorderedList
  *     Record
+ *     Variable
  * </pre>
  */
 private Value value() :
@@ -156,6 +177,11 @@
     {
         return value;
     }
+|
+    value = variable()
+    {
+        return value;
+    }
 }
 
 /**
@@ -255,6 +281,23 @@
 
 /**
  * <pre>
+ * Variable :
+ *   "$" (Identifier)
+ * </pre>
+ */
+private Value variable() :
+{
+    Token t;
+}
+{
+    t = <VARIABLE>
+    {
+        return resolve(t);
+    }
+}
+
+/**
+ * <pre>
  * ValueList :
  *     Value
  *     ValueList "," Value

Modified: artemis/trunk/generic-tree/src/test/java/org/jiemamy/utils/gtree/text/ParserTest.java
===================================================================
--- artemis/trunk/generic-tree/src/test/java/org/jiemamy/utils/gtree/text/ParserTest.java	2009-02-05 17:56:32 UTC (rev 2622)
+++ artemis/trunk/generic-tree/src/test/java/org/jiemamy/utils/gtree/text/ParserTest.java	2009-02-05 17:57:30 UTC (rev 2623)
@@ -21,7 +21,9 @@
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.jiemamy.utils.gtree.model.Entry;
 import org.jiemamy.utils.gtree.model.Record;
@@ -200,6 +202,45 @@
             "ul", ul("D", "E"),
             "rc", rc("f", "G"))));
     }
+    
+    /**
+     * Test method for {@link Parser#parse(java.io.Reader, java.util.Map)}.
+     * @throws Exception if occur
+     */
+    @Test
+    public void testParse_Variable() throws Exception {
+        Map<String, Value> vars = new HashMap<String, Value>();
+        vars.put("a", value("Hello"));
+        Value v = parse("$a", vars);
+        assertThat(v, is(terminal("Hello")));
+    }
+    
+    /**
+     * Test method for {@link Parser#parse(java.io.Reader, java.util.Map)}.
+     * @throws Exception if occur
+     */
+    @Test
+    public void testParse_Variables() throws Exception {
+        Map<String, Value> vars = new HashMap<String, Value>();
+        vars.put("a", value("A"));
+        vars.put("b", value("B"));
+        vars.put("c", value("C"));
+        Value v = parse("<'a':$a, 'b':$b, 'c':$c>", vars);
+        assertThat(v, is(rc("a", "A", "b", "B", "c", "C")));
+    }
+    
+    /**
+     * Test method for {@link Parser#parse(java.io.Reader, java.util.Map)}.
+     * @throws Exception if occur
+     */
+    @Test(expected = IOException.class)
+    public void testParse_Variables_Unbound() throws Exception {
+        Map<String, Value> vars = new HashMap<String, Value>();
+        vars.put("a", value("A"));
+        vars.put("b", value("B"));
+        vars.put("c", value("C"));
+        parse("<'a':$a, 'b':$b, 'c':$c, 'd':$d>", vars);
+    }
 
     private Value terminal(Object content) {
         return Terminal.of(String.valueOf(content));
@@ -244,4 +285,8 @@
     private Value parse(String script) throws IOException {
         return Parser.parse(new StringReader(script));
     }
+    
+    private Value parse(String script, Map<String, ? extends Value> vars) throws IOException {
+        return Parser.parse(new StringReader(script), vars);
+    }
 }



Jiemamy-notify メーリングリストの案内
Back to archive index