]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/util/BNF.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / util / BNF.java
old mode 100755 (executable)
new mode 100644 (file)
index 6c3d6f5..fc89a1c
-//##header\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-/*\r
- *******************************************************************************\r
- * Copyright (C) 2002-2009, International Business Machines Corporation and    *\r
- * others. All Rights Reserved.                                                *\r
- *******************************************************************************\r
- */\r
-package com.ibm.icu.dev.test.util;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-\r
-import com.ibm.icu.text.UnicodeSet;\r
-import java.util.Random;\r
-\r
-public class BNF {\r
-    private Map map = new HashMap();\r
-    private Set variables = new HashSet();\r
-    private Pick pick = null;\r
-    private Pick.Target target = null;\r
-    private Tokenizer t;\r
-    private Quoter quoter;\r
-    private Random random;\r
-    \r
-    public String next() {\r
-        return target.next();\r
-    }\r
-    \r
-    public String getInternal() {\r
-        return pick.getInternal(0, new HashSet());\r
-    }\r
-    \r
-    /*\r
-    + "weight = integer '%';"\r
-    + "range = '{' integer (',' integer?)? '}' weight*;"\r
-    + "quote = '@';"\r
-    + "star = '*' weight*;"\r
-    + "plus = '+' weight*;"\r
-    + "maybe = '?' weight?;"\r
-    + "quantifier = range | star | maybe | plus;"\r
-    + "core = string | unicodeSet | '(' alternation ')';"\r
-    + "sequence = (core quantifier*)+;"\r
-    + "alternation = sequence (weight? ('|' sequence weight?)+)?;"\r
-    + "rule = string '=' alternation;"; \r
-    \r
-    \r
-    *      Match 0 or more times\r
-    +      Match 1 or more times\r
-    ?      Match 1 or 0 times\r
-    {n}    Match exactly n times\r
-    {n,}   Match at least n times\r
-    {n,m}  Match at least n but not more than m times  \r
\r
\r
-\r
-    */\r
-    \r
-    public BNF(Random random, Quoter quoter) {\r
-        this.random = random;\r
-        this.quoter = quoter;\r
-        t = new Tokenizer();\r
-    }\r
-    \r
-    public BNF addRules(String rules) {\r
-        t.setSource(rules);        \r
-        while (addRule()) {\r
-        }\r
-        return this; // for chaining\r
-    }\r
-    \r
-    public BNF complete() {\r
-        // check that the rules match the variables, except for $root in rules\r
-        Set ruleSet = map.keySet();\r
-        // add also \r
-        variables.add("$root");\r
-        variables.addAll(t.getLookedUpItems());\r
-        if (!ruleSet.equals(variables)) {\r
-            String msg = showDiff(variables, ruleSet);\r
-            if (msg.length() != 0) msg = "Error: Missing definitions for: " + msg;\r
-            String temp = showDiff(ruleSet, variables);\r
-            if (temp.length() != 0) temp = "Warning: Defined but not used: " + temp;\r
-            if (msg.length() == 0) msg = temp;\r
-            else if (temp.length() != 0) {\r
-                msg = msg + "; " + temp;           \r
-            }\r
-            error(msg);           \r
-        } \r
-        \r
-        if (!ruleSet.equals(variables)) {\r
-            String msg = showDiff(variables, ruleSet);\r
-            if (msg.length() != 0) msg = "Missing definitions for: " + msg;\r
-            String temp = showDiff(ruleSet, variables);\r
-            if (temp.length() != 0) temp = "Defined but not used: " + temp;\r
-            if (msg.length() == 0) msg = temp;\r
-            else if (temp.length() != 0) {\r
-                msg = msg + "; " + temp;           \r
-            }\r
-            error(msg);           \r
-        } \r
-        \r
-        // replace variables by definitions\r
-        Iterator it = ruleSet.iterator();\r
-        while (it.hasNext()) {\r
-            String key = (String) it.next();\r
-            Pick expression = (Pick) map.get(key);\r
-            Iterator it2 = ruleSet.iterator();  \r
-            if (false && key.equals("$crlf")) {\r
-                System.out.println("debug") ;\r
-            }\r
-            while (it2.hasNext()) {\r
-                Object key2 = it2.next();\r
-                if (key.equals(key2)) continue;\r
-                Pick expression2 = (Pick) map.get(key2);\r
-                expression2.replace(key, expression);\r
-            }\r
-        }\r
-        pick = (Pick) map.get("$root");\r
-        target = Pick.Target.make(pick, random, quoter);\r
-        // TODO remove temp collections\r
-        return this;\r
-    }\r
-    \r
-    String showDiff(Set a, Set b) {\r
-        Set temp = new HashSet();\r
-        temp.addAll(a);\r
-        temp.removeAll(b);\r
-        if (temp.size() == 0) return "";\r
-        StringBuffer buffer = new StringBuffer();\r
-        Iterator it = temp.iterator();\r
-        while (it.hasNext()) {\r
-            if (buffer.length() != 0) buffer.append(", ");\r
-            buffer.append(it.next().toString());\r
-        }\r
-        return buffer.toString();\r
-    }\r
-    \r
-    void error(String msg) {\r
-        throw new IllegalArgumentException(msg\r
-        + "\r\n" + t.toString());\r
-    }\r
\r
-    private boolean addRule() {\r
-        int type = t.next();\r
-        if (type == Tokenizer.DONE) return false;\r
-        if (type != Tokenizer.STRING) error("missing weight");\r
-        String s = t.getString();\r
-        if (s.length() == 0 || s.charAt(0) != '$') error("missing $ in variable");\r
-        if (t.next() != '=') error("missing =");\r
-        int startBody = t.index;\r
-        Pick rule = getAlternation();\r
-        if (rule == null) error("missing expression");\r
-        t.addSymbol(s, t.getSource(), startBody, t.index);\r
-        if (t.next() != ';') error("missing ;");       \r
-        return addPick(s, rule);\r
-    }\r
-\r
-    protected boolean addPick(String s, Pick rule) {\r
-        Object temp = map.get(s);\r
-        if (temp != null) error("duplicate variable");\r
-        if (rule.name == null) rule.name(s);\r
-        map.put(s, rule);\r
-        return true;\r
-    }\r
-    \r
-    public BNF addSet(String variable, UnicodeSet set) {\r
-        if (set != null) {\r
-            String body = set.toString();\r
-            t.addSymbol(variable, body, 0, body.length());        \r
-            addPick(variable, Pick.codePoint(set));\r
-        }\r
-        return this;\r
-    }\r
-    \r
-    int maxRepeat = 99;\r
-    \r
-    Pick qualify(Pick item) {\r
-        int[] weights;\r
-        int type = t.next();\r
-        switch(type) {\r
-            case '@': \r
-                return new Pick.Quote(item);\r
-            case '~': \r
-                return new Pick.Morph(item);\r
-            case '?': \r
-                int weight = getWeight();\r
-                if (weight == NO_WEIGHT) weight = 50;\r
-                weights = new int[] {100-weight, weight};\r
-                return Pick.repeat(0, 1, weights, item);\r
-            case '*': \r
-                weights = getWeights();\r
-                return Pick.repeat(1, maxRepeat, weights, item);\r
-            case '+': \r
-                weights = getWeights();\r
-                return Pick.repeat(1, maxRepeat, weights, item);\r
-            case '{':\r
-                if (t.next() != Tokenizer.NUMBER) error("missing number");\r
-                int start = (int) t.getNumber();\r
-                int end = start;\r
-                type = t.next();\r
-                if (type == ',') {\r
-                    end = maxRepeat;\r
-                    type = t.next();\r
-                    if (type == Tokenizer.NUMBER) {\r
-                        end = (int)t.getNumber();\r
-                        type = t.next();\r
-                    }\r
-                }\r
-                if (type != '}') error("missing }");\r
-                weights = getWeights();\r
-                return Pick.repeat(start, end, weights, item);\r
-        }\r
-        t.backup();\r
-        return item;\r
-    }\r
-    \r
-    Pick getCore() {\r
-        int token = t.next();\r
-        if (token == Tokenizer.STRING) {\r
-            String s = t.getString();\r
-            if (s.charAt(0) == '$') variables.add(s);\r
-            return Pick.string(s);\r
-        }\r
-        if (token == Tokenizer.UNICODESET) {\r
-            return Pick.codePoint(t.getUnicodeSet());            \r
-        }\r
-        if (token != '(') {\r
-            t.backup();\r
-            return null;\r
-        }\r
-        Pick temp = getAlternation();\r
-        token = t.next();\r
-        if (token != ')') error("missing )");    \r
-        return temp;    \r
-    }\r
-    \r
-    Pick getSequence() {\r
-        Pick.Sequence result = null;\r
-        Pick last = null;\r
-        while (true) {\r
-            Pick item = getCore();\r
-            if (item == null) {\r
-                if (result != null) return result;\r
-                if (last != null) return last;\r
-                error("missing item");\r
-            }\r
-            // qualify it as many times as possible\r
-            Pick oldItem;\r
-            do {\r
-                oldItem = item;\r
-                item = qualify(item);\r
-            } while (item != oldItem);\r
-            // add it in\r
-            if (last == null) {\r
-                last = item;\r
-            } else {\r
-                if (result == null) result = Pick.makeSequence().and2(last);            \r
-                result = result.and2(item);\r
-            }\r
-        }\r
-    }\r
-    \r
-    // for simplicity, we just use recursive descent\r
-    Pick getAlternation() {\r
-        Pick.Alternation result = null;\r
-        Pick last = null;\r
-        int lastWeight = NO_WEIGHT;\r
-        while (true) {\r
-            Pick temp = getSequence();\r
-            if (temp == null) error("empty alternation");\r
-            int weight = getWeight();\r
-            if (weight == NO_WEIGHT) weight = 1;\r
-            if (last == null) {\r
-                last = temp;\r
-                lastWeight = weight;\r
-            } else {\r
-                if (result == null) result = Pick.makeAlternation().or2(lastWeight, last);\r
-                result = result.or2(weight, temp);   \r
-            }\r
-            int token = t.next();\r
-            if (token != '|') {\r
-                t.backup();\r
-                if (result != null) return result;\r
-                if (last != null) return last;\r
-            }\r
-        }        \r
-    }\r
-    \r
-    private static final int NO_WEIGHT = Integer.MIN_VALUE;\r
-    \r
-    int getWeight() {       \r
-        int weight;\r
-        int token = t.next();\r
-        if (token != Tokenizer.NUMBER) {\r
-            t.backup();\r
-            return NO_WEIGHT;\r
-        }\r
-        weight = (int)t.getNumber();\r
-        token = t.next();\r
-        if (token != '%') error("missing %");\r
-        return weight;\r
-    }\r
-    \r
-    int[] getWeights() {\r
-        ArrayList list = new ArrayList();\r
-        while (true) {\r
-            int weight = getWeight();\r
-            if (weight == NO_WEIGHT) break;\r
-            list.add(new Integer(weight));\r
-        }\r
-        if (list.size() == 0) return null;\r
-        int[] result = new int[list.size()];\r
-        for (int i = 0; i < list.size(); ++i) {\r
-            result[i] = ((Integer)list.get(i)).intValue();\r
-        }\r
-        return result;\r
-    }\r
-\r
-    public int getMaxRepeat() {\r
-      return maxRepeat;\r
-    }\r
-\r
-    public BNF setMaxRepeat(int maxRepeat) {\r
-      this.maxRepeat = maxRepeat;\r
-      return this;\r
-    }\r
-}\r
-//#endif\r
+//##header J2SE15
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+/*
+ *******************************************************************************
+ * Copyright (C) 2002-2009, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+package com.ibm.icu.dev.test.util;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import com.ibm.icu.text.UnicodeSet;
+import java.util.Random;
+
+public class BNF {
+    private Map map = new HashMap();
+    private Set variables = new HashSet();
+    private Pick pick = null;
+    private Pick.Target target = null;
+    private Tokenizer t;
+    private Quoter quoter;
+    private Random random;
+    
+    public String next() {
+        return target.next();
+    }
+    
+    public String getInternal() {
+        return pick.getInternal(0, new HashSet());
+    }
+    
+    /*
+    + "weight = integer '%';"
+    + "range = '{' integer (',' integer?)? '}' weight*;"
+    + "quote = '@';"
+    + "star = '*' weight*;"
+    + "plus = '+' weight*;"
+    + "maybe = '?' weight?;"
+    + "quantifier = range | star | maybe | plus;"
+    + "core = string | unicodeSet | '(' alternation ')';"
+    + "sequence = (core quantifier*)+;"
+    + "alternation = sequence (weight? ('|' sequence weight?)+)?;"
+    + "rule = string '=' alternation;"; 
+    
+    
+    *      Match 0 or more times
+    +      Match 1 or more times
+    ?      Match 1 or 0 times
+    {n}    Match exactly n times
+    {n,}   Match at least n times
+    {n,m}  Match at least n but not more than m times  
+
+    */
+    
+    public BNF(Random random, Quoter quoter) {
+        this.random = random;
+        this.quoter = quoter;
+        t = new Tokenizer();
+    }
+    
+    public BNF addRules(String rules) {
+        t.setSource(rules);        
+        while (addRule()) {
+        }
+        return this; // for chaining
+    }
+    
+    public BNF complete() {
+        // check that the rules match the variables, except for $root in rules
+        Set ruleSet = map.keySet();
+        // add also 
+        variables.add("$root");
+        variables.addAll(t.getLookedUpItems());
+        if (!ruleSet.equals(variables)) {
+            String msg = showDiff(variables, ruleSet);
+            if (msg.length() != 0) msg = "Error: Missing definitions for: " + msg;
+            String temp = showDiff(ruleSet, variables);
+            if (temp.length() != 0) temp = "Warning: Defined but not used: " + temp;
+            if (msg.length() == 0) msg = temp;
+            else if (temp.length() != 0) {
+                msg = msg + "; " + temp;           
+            }
+            error(msg);           
+        } 
+        
+        if (!ruleSet.equals(variables)) {
+            String msg = showDiff(variables, ruleSet);
+            if (msg.length() != 0) msg = "Missing definitions for: " + msg;
+            String temp = showDiff(ruleSet, variables);
+            if (temp.length() != 0) temp = "Defined but not used: " + temp;
+            if (msg.length() == 0) msg = temp;
+            else if (temp.length() != 0) {
+                msg = msg + "; " + temp;           
+            }
+            error(msg);           
+        } 
+        
+        // replace variables by definitions
+        Iterator it = ruleSet.iterator();
+        while (it.hasNext()) {
+            String key = (String) it.next();
+            Pick expression = (Pick) map.get(key);
+            Iterator it2 = ruleSet.iterator();  
+            if (false && key.equals("$crlf")) {
+                System.out.println("debug") ;
+            }
+            while (it2.hasNext()) {
+                Object key2 = it2.next();
+                if (key.equals(key2)) continue;
+                Pick expression2 = (Pick) map.get(key2);
+                expression2.replace(key, expression);
+            }
+        }
+        pick = (Pick) map.get("$root");
+        target = Pick.Target.make(pick, random, quoter);
+        // TODO remove temp collections
+        return this;
+    }
+    
+    String showDiff(Set a, Set b) {
+        Set temp = new HashSet();
+        temp.addAll(a);
+        temp.removeAll(b);
+        if (temp.size() == 0) return "";
+        StringBuffer buffer = new StringBuffer();
+        Iterator it = temp.iterator();
+        while (it.hasNext()) {
+            if (buffer.length() != 0) buffer.append(", ");
+            buffer.append(it.next().toString());
+        }
+        return buffer.toString();
+    }
+    
+    void error(String msg) {
+        throw new IllegalArgumentException(msg
+        + "\r\n" + t.toString());
+    }
+    private boolean addRule() {
+        int type = t.next();
+        if (type == Tokenizer.DONE) return false;
+        if (type != Tokenizer.STRING) error("missing weight");
+        String s = t.getString();
+        if (s.length() == 0 || s.charAt(0) != '$') error("missing $ in variable");
+        if (t.next() != '=') error("missing =");
+        int startBody = t.index;
+        Pick rule = getAlternation();
+        if (rule == null) error("missing expression");
+        t.addSymbol(s, t.getSource(), startBody, t.index);
+        if (t.next() != ';') error("missing ;");       
+        return addPick(s, rule);
+    }
+
+    protected boolean addPick(String s, Pick rule) {
+        Object temp = map.get(s);
+        if (temp != null) error("duplicate variable");
+        if (rule.name == null) rule.name(s);
+        map.put(s, rule);
+        return true;
+    }
+    
+    public BNF addSet(String variable, UnicodeSet set) {
+        if (set != null) {
+            String body = set.toString();
+            t.addSymbol(variable, body, 0, body.length());        
+            addPick(variable, Pick.codePoint(set));
+        }
+        return this;
+    }
+    
+    int maxRepeat = 99;
+    
+    Pick qualify(Pick item) {
+        int[] weights;
+        int type = t.next();
+        switch(type) {
+            case '@': 
+                return new Pick.Quote(item);
+            case '~': 
+                return new Pick.Morph(item);
+            case '?': 
+                int weight = getWeight();
+                if (weight == NO_WEIGHT) weight = 50;
+                weights = new int[] {100-weight, weight};
+                return Pick.repeat(0, 1, weights, item);
+            case '*': 
+                weights = getWeights();
+                return Pick.repeat(1, maxRepeat, weights, item);
+            case '+': 
+                weights = getWeights();
+                return Pick.repeat(1, maxRepeat, weights, item);
+            case '{':
+                if (t.next() != Tokenizer.NUMBER) error("missing number");
+                int start = (int) t.getNumber();
+                int end = start;
+                type = t.next();
+                if (type == ',') {
+                    end = maxRepeat;
+                    type = t.next();
+                    if (type == Tokenizer.NUMBER) {
+                        end = (int)t.getNumber();
+                        type = t.next();
+                    }
+                }
+                if (type != '}') error("missing }");
+                weights = getWeights();
+                return Pick.repeat(start, end, weights, item);
+        }
+        t.backup();
+        return item;
+    }
+    
+    Pick getCore() {
+        int token = t.next();
+        if (token == Tokenizer.STRING) {
+            String s = t.getString();
+            if (s.charAt(0) == '$') variables.add(s);
+            return Pick.string(s);
+        }
+        if (token == Tokenizer.UNICODESET) {
+            return Pick.codePoint(t.getUnicodeSet());            
+        }
+        if (token != '(') {
+            t.backup();
+            return null;
+        }
+        Pick temp = getAlternation();
+        token = t.next();
+        if (token != ')') error("missing )");    
+        return temp;    
+    }
+    
+    Pick getSequence() {
+        Pick.Sequence result = null;
+        Pick last = null;
+        while (true) {
+            Pick item = getCore();
+            if (item == null) {
+                if (result != null) return result;
+                if (last != null) return last;
+                error("missing item");
+            }
+            // qualify it as many times as possible
+            Pick oldItem;
+            do {
+                oldItem = item;
+                item = qualify(item);
+            } while (item != oldItem);
+            // add it in
+            if (last == null) {
+                last = item;
+            } else {
+                if (result == null) result = Pick.makeSequence().and2(last);            
+                result = result.and2(item);
+            }
+        }
+    }
+    
+    // for simplicity, we just use recursive descent
+    Pick getAlternation() {
+        Pick.Alternation result = null;
+        Pick last = null;
+        int lastWeight = NO_WEIGHT;
+        while (true) {
+            Pick temp = getSequence();
+            if (temp == null) error("empty alternation");
+            int weight = getWeight();
+            if (weight == NO_WEIGHT) weight = 1;
+            if (last == null) {
+                last = temp;
+                lastWeight = weight;
+            } else {
+                if (result == null) result = Pick.makeAlternation().or2(lastWeight, last);
+                result = result.or2(weight, temp);   
+            }
+            int token = t.next();
+            if (token != '|') {
+                t.backup();
+                if (result != null) return result;
+                if (last != null) return last;
+            }
+        }        
+    }
+    
+    private static final int NO_WEIGHT = Integer.MIN_VALUE;
+    
+    int getWeight() {       
+        int weight;
+        int token = t.next();
+        if (token != Tokenizer.NUMBER) {
+            t.backup();
+            return NO_WEIGHT;
+        }
+        weight = (int)t.getNumber();
+        token = t.next();
+        if (token != '%') error("missing %");
+        return weight;
+    }
+    
+    int[] getWeights() {
+        ArrayList list = new ArrayList();
+        while (true) {
+            int weight = getWeight();
+            if (weight == NO_WEIGHT) break;
+            list.add(new Integer(weight));
+        }
+        if (list.size() == 0) return null;
+        int[] result = new int[list.size()];
+        for (int i = 0; i < list.size(); ++i) {
+            result[i] = ((Integer)list.get(i)).intValue();
+        }
+        return result;
+    }
+
+    public int getMaxRepeat() {
+      return maxRepeat;
+    }
+
+    public BNF setMaxRepeat(int maxRepeat) {
+      this.maxRepeat = maxRepeat;
+      return this;
+    }
+}
+//#endif