Changeset 3856 in josm


Ignore:
Timestamp:
Feb 5, 2011 2:07:23 PM (2 years ago)
Author:
bastiK
Message:

improve mapcss support

Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/build.xml

    r3833 r3856  
    135135                <delete dir="build" /> 
    136136                <delete dir="dist" /> 
     137        </target> 
     138 
     139        <target name="javacc"> 
     140                <exec executable="javacc"> 
     141                        <arg value="-debug_parser=false"/> 
     142                        <arg value="-debug_lookahead=false"/> 
     143                        <arg value="-debug_token_manager=false"/> 
     144                        <arg value="-output_directory=${src.dir}/org/openstreetmap/josm/gui/mappaint/mapcss/parser"/> 
     145                        <arg value="${src.dir}/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj"/> 
     146                </exec> 
    137147        </target> 
    138148 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java

    r3848 r3856  
    2121 
    2222    public static AreaElemStyle create(Cascade c) { 
    23         Color color = c.getColor("fill-color", null); 
     23        Color color = c.get("fill-color", null, Color.class); 
    2424        if (color == null) 
    2525            return null; 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java

    r3848 r3856  
    55import java.util.Arrays; 
    66import java.util.HashMap; 
     7import java.util.List; 
    78import java.util.Map; 
    89 
     
    2627     *      value, def otherwise 
    2728     */ 
    28     public <T> T get(String key, T def, Class klass) { 
     29    public <T> T get(String key, T def, Class<T> klass) { 
    2930        if (def != null && !klass.isInstance(def)) 
    3031            throw new IllegalArgumentException(); 
     
    3233        if (o == null) 
    3334            return def; 
    34         if (klass.isInstance(o)) { 
    35             @SuppressWarnings("unchecked") T res = (T) klass.cast(o); 
     35        T res = convertTo(o, klass); 
     36        if (res == null) { 
     37            System.err.println(String.format("Warning: unable to convert property %s to type %s: found %s of type %s!", key, klass, o, o.getClass())); 
     38            return def; 
     39        } else 
    3640            return res; 
    37         } 
    38         System.err.println(String.format("Warning: wrong type for mappaint property %s: %s expected, but %s of type %s found!", key, klass, o, o.getClass())); 
    39         return def; 
    4041    } 
    4142 
     
    4445    } 
    4546 
    46     public Float getFloat(String key, Float def) { 
    47         Object o = prop.get(key); 
     47    @SuppressWarnings("unchecked") 
     48    public static <T> T convertTo(Object o, Class<T> klass) { 
    4849        if (o == null) 
    49             return def; 
     50            return null; 
     51        if (klass.isInstance(o)) 
     52            return (T) o; 
     53 
     54        if (klass == float.class || klass == Float.class) 
     55            return (T) toFloat(o); 
     56 
     57        if (klass == double.class || klass == Double.class) { 
     58            o = toFloat(o); 
     59            if (o != null) { 
     60                o = new Double((Float) o); 
     61            } 
     62            return (T) o; 
     63        } 
     64 
     65        if (klass == boolean.class || klass == Boolean.class) 
     66            return (T) toBool(o); 
     67 
     68        if (klass == float[].class) { 
     69            return (T) toFloatArray(o); 
     70        } 
     71 
     72        if (klass == Color.class) { 
     73            return (T) toColor(o); 
     74        } 
     75        return null; 
     76    } 
     77 
     78    private static Float toFloat(Object o) { 
    5079        if (o instanceof Float) 
    5180            return (Float) o; 
     81        if (o instanceof Double) 
     82            return new Float((Double) o); 
    5283        if (o instanceof Integer) 
    5384            return new Float((Integer) o); 
    54         return def; 
     85        if (o instanceof String) { 
     86            try { 
     87                float f = Float.parseFloat((String) o); 
     88                return f; 
     89            } catch (NumberFormatException e) { 
     90            } 
     91        } 
     92        return null; 
    5593    } 
    5694 
    57     public Color getColor(String key, Color def) { 
    58         Object o = prop.get(key); 
    59         if (o == null) 
    60             return def; 
     95    private static Boolean toBool(Object o) { 
     96        if (o instanceof Boolean) 
     97            return (Boolean) o; 
     98        if (o instanceof String) 
     99            return Boolean.parseBoolean((String) o); 
     100        return null; 
     101    } 
     102 
     103    private static float[] toFloatArray(Object o) { 
     104        if (o instanceof float[]) 
     105            return (float[]) o; 
     106        if (o instanceof List) { 
     107            List l = (List) o; 
     108            float[] a = new float[l.size()]; 
     109            for (int i=0; i<l.size(); ++i) { 
     110                Float f = toFloat(l.get(i)); 
     111                if (f == null) 
     112                    return null; 
     113                else 
     114                    a[i] = f; 
     115            } 
     116            return a; 
     117        } 
     118        return null; 
     119    } 
     120 
     121     public static Color toColor(Object o) { 
    61122        if (o instanceof Color) 
    62123            return (Color) o; 
    63         if (o instanceof String) { 
    64             Color clr = CSSColors.get((String) o); 
    65             if (clr != null) 
    66                 return clr; 
    67             else 
    68                 return def; 
    69         } 
    70         return def; 
     124        if (o instanceof String) 
     125            return CSSColors.get((String) o); 
     126        return null; 
    71127    } 
    72128 
     
    111167        return res.append("}").toString(); 
    112168    } 
     169 
     170    public boolean containsKey(String key) { 
     171        return prop.containsKey(key); 
     172    } 
    113173} 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java

    r3848 r3856  
    1717 
    1818    protected ElemStyle(Cascade c) { 
    19         z_index = c.getFloat("z-index", 0f); 
    20         object_z_index = c.getFloat("object-z-index", 0f); 
     19        z_index = c.get("z-index", 0f, Float.class); 
     20        object_z_index = c.get("object-z-index", 0f, Float.class); 
    2121    } 
    2222 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java

    r3848 r3856  
    4848 
    4949    private static LineElemStyle createImpl(Cascade c, String prefix) { 
    50         Float width = c.getFloat(prefix + "width", null); 
     50        Float width = c.get(prefix + "width", null, Float.class); 
    5151        if (width == null) 
    5252            return null; 
    5353 
    54         float realWidth = c.getFloat(prefix + "real-width", 0f); 
    55         Color color = c.getColor(prefix + "color", null); 
     54        float realWidth = c.get(prefix + "real-width", 0f, Float.class); 
     55        Color color = c.get(prefix + "color", null, Color.class); 
    5656        if (color == null) { 
    57             color = c.getColor(prefix + "fill-color", null); 
     57            color = c.get(prefix + "fill-color", null, Color.class); 
    5858        } 
    5959        if (color == null) { 
     
    6161        } 
    6262        float[] dashes = c.get(prefix + "dashes", null, float[].class); 
    63         Color dashesBackground = c.getColor(prefix + "dashes-background-color", null); 
     63        if (dashes != null) { 
     64            boolean hasPositive = false; 
     65            for (float f : dashes) { 
     66                if (f > 0) { 
     67                    hasPositive = true; 
     68                } 
     69                if (f < 0) { 
     70                    dashes = null; 
     71                    break; 
     72                } 
     73            } 
     74            if (!hasPositive) { 
     75                dashes = null; 
     76            } 
     77        } 
     78        Color dashesBackground = c.get(prefix + "dashes-background-color", null, Color.class); 
    6479 
    6580        return new LineElemStyle(c, width, realWidth, color, dashes, dashesBackground); 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java

    r3849 r3856  
    22package org.openstreetmap.josm.gui.mappaint.mapcss; 
    33 
    4 import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    54import org.openstreetmap.josm.data.osm.Relation; 
    65import org.openstreetmap.josm.data.osm.Way; 
     
    98abstract public class Condition { 
    109 
    11     abstract public boolean applies(OsmPrimitive osm); 
     10    abstract public boolean applies(Environment e); 
    1211 
    1312    public static enum Op {EQ, NEQ} 
     
    2726 
    2827        @Override 
    29         public boolean applies(OsmPrimitive osm) { 
     28        public boolean applies(Environment e) { 
    3029            switch (op) { 
    3130                case EQ: 
    32                     return Utils.equal(osm.get(k), v); 
     31                    return Utils.equal(e.osm.get(k), v); 
    3332                case NEQ: 
    34                     return !Utils.equal(osm.get(k), v); 
     33                    return !Utils.equal(e.osm.get(k), v); 
    3534                default: 
    3635                    throw new AssertionError(); 
     
    5554 
    5655        @Override 
    57         public boolean applies(OsmPrimitive osm) { 
    58             return osm.hasKey(k) ^ not; 
     56        public boolean applies(Environment e) { 
     57            return e.osm.hasKey(k) ^ not; 
    5958        } 
    6059 
     
    7675 
    7776        @Override 
    78         public boolean applies(OsmPrimitive osm) { 
     77        public boolean applies(Environment e) { 
    7978            if ("closed".equals(id)) { 
    80                 if (osm instanceof Way && ((Way) osm).isClosed()) 
     79                if (e.osm instanceof Way && ((Way) e.osm).isClosed()) 
    8180                    return true; 
    82                 if (osm instanceof Relation && ((Relation) osm).isMultipolygon()) 
     81                if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon()) 
    8382                    return true; 
    8483                return false; 
     
    9291        } 
    9392    } 
     93     
     94    public static class ExpressionCondition extends Condition { 
     95 
     96        private Expression e; 
     97 
     98        public ExpressionCondition(Expression e) { 
     99            this.e = e; 
     100        } 
     101 
     102        @Override 
     103        public boolean applies(Environment env) { 
     104            Object o = e.evaluate(env); 
     105            if (o instanceof Boolean) 
     106                return (Boolean) o; 
     107            return false; 
     108        } 
     109 
     110        @Override 
     111        public String toString() { 
     112            return "[" + e + "]"; 
     113        } 
     114    } 
    94115 
    95116} 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java

    r3848 r3856  
    22package org.openstreetmap.josm.gui.mappaint.mapcss; 
    33 
     4import java.awt.Color; 
     5import java.lang.reflect.Array; 
     6import java.lang.reflect.InvocationTargetException; 
     7import java.lang.reflect.Method; 
     8import java.util.ArrayList; 
    49import java.util.Arrays; 
    510import java.util.List; 
    611 
     12import org.openstreetmap.josm.Main; 
     13import org.openstreetmap.josm.actions.search.SearchCompiler; 
     14import org.openstreetmap.josm.actions.search.SearchCompiler.Match; 
     15import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError; 
    716import org.openstreetmap.josm.gui.mappaint.Cascade; 
    817import org.openstreetmap.josm.tools.Utils; 
     
    4352        } 
    4453 
    45         @Override 
    46         public Object evaluate(Environment env) { 
    47             if (name.equals("eval")) { 
    48                 if (args.size() != 1) { 
     54        public static class EvalFunctions { 
     55            Environment env; 
     56 
     57            public Object eval(Object o) { 
     58                return o; 
     59            } 
     60 
     61            public static float plus(float... args) { 
     62                float res = 0; 
     63                for (float f : args) { 
     64                    res += f; 
     65                } 
     66                return res; 
     67            } 
     68 
     69            public Float minus(float... args) { 
     70                if (args.length == 0) 
     71                    return 0f; 
     72                float res = args[0]; 
     73                for (int i=1; i<args.length; ++i) { 
     74                    res -= args[i]; 
     75                } 
     76                return res; 
     77            } 
     78 
     79            public static float times(float... args) { 
     80                float res = 1; 
     81                for (float f : args) { 
     82                    res *= f; 
     83                } 
     84                return res; 
     85            } 
     86 
     87            public Float devided_by(float... args) { 
     88                if (args.length == 0) 
     89                    return 1f; 
     90                float res = args[0]; 
     91                for (int i=1; i<args.length; ++i) { 
     92                    if (args[i] == 0f) 
     93                        return null; 
     94                    res /= args[i]; 
     95                } 
     96                return res; 
     97            } 
     98 
     99            public static List list(Object... args) { 
     100                return Arrays.asList(args); 
     101            } 
     102 
     103            public Color rgb(float r, float g, float b) { 
     104                Color c = null; 
     105                try { 
     106                    c = new Color(r, g, b); 
     107                } catch (IllegalArgumentException e) { 
    49108                    return null; 
    50109                } 
    51                 return args.get(0).evaluate(env); 
    52             } 
    53              
    54             if (name.equals("prop")) { 
    55                 if (!(args.size() == 1 || args.size() == 2)) 
    56                     return null; 
    57                 Object pr = args.get(0).evaluate(env); 
    58                 if (!(pr instanceof String)) 
    59                     return null; 
     110                return c; 
     111            } 
     112 
     113            public Object prop(String key) { 
     114                return prop(key, null); 
     115            } 
     116 
     117            public Object prop(String key, String layer) { 
    60118                Cascade c; 
    61                 if (args.size() == 1) { 
     119                if (layer == null) { 
    62120                    c = env.getCascade(); 
    63121                } else { 
    64                     Object layer = args.get(1).evaluate(env); 
    65                     if (!(layer instanceof String)) 
    66                         return null; 
    67                     c = env.mc.getCascade((String) layer); 
    68                 } 
    69                 return c.get((String) pr); 
    70             } 
    71             if (name.equals("+") || name.equals("*")) { 
    72                 float result = name.equals("+") ? 0f : 1f; 
    73                 for (Expression exp : args) { 
    74                     Float f = getFloat(exp.evaluate(env)); 
    75                     if (f == null) 
    76                         return null; 
    77                     if (name.equals("+")) { 
    78                         result += f; 
    79                     } else { 
    80                         result *= f; 
     122                    c = env.mc.getCascade(layer); 
     123                } 
     124                return c.get(key); 
     125            } 
     126 
     127            public Boolean is_prop_set(String key) { 
     128                return is_prop_set(key, null); 
     129            } 
     130 
     131            public Boolean is_prop_set(String key, String layer) { 
     132                Cascade c; 
     133                if (layer == null) { 
     134                    c = env.getCascade(); 
     135                } else { 
     136                    c = env.mc.getCascade(layer); 
     137                } 
     138                return c.containsKey(key); 
     139            } 
     140 
     141            public Object cond(boolean cond, Object if_, Object else_) { 
     142                return cond ? if_ : else_; // fixme: do not evaluate the other branch 
     143            } 
     144 
     145            public boolean not(boolean b) { 
     146                return !b; 
     147            } 
     148 
     149            public boolean and(boolean... bs) { 
     150                for (boolean b : bs) {  // fixme: lazy evaluation 
     151                    if (!b) 
     152                        return false; 
     153                } 
     154                return true; 
     155            } 
     156 
     157            public boolean or(boolean... bs) { 
     158                for (boolean b : bs) { 
     159                    if (b) 
     160                        return true; 
     161                } 
     162                return false; 
     163            } 
     164 
     165            public Boolean JOSM_search(String s) { 
     166                Match m; 
     167                try { 
     168                    m = SearchCompiler.compile(s, false, false); 
     169                } catch (ParseError ex) { 
     170                    return null; 
     171                } 
     172                return m.match(env.osm); 
     173            } 
     174 
     175            public String JOSM_pref(String s, String def) { 
     176                String res = Main.pref.get(s, null); 
     177                return res != null ? res : def; 
     178            } 
     179 
     180            public Color JOSM_pref_color(String s, Color def) { 
     181                Color res = Main.pref.getColor(s, null); 
     182                return res != null ? res : def; 
     183            } 
     184        } 
     185 
     186        @Override 
     187        public Object evaluate(Environment env) { 
     188            EvalFunctions fn = new EvalFunctions(); 
     189            fn.env = env; 
     190            Method[] customMethods = EvalFunctions.class.getDeclaredMethods(); 
     191            List<Method> allMethods = new ArrayList<Method>(); 
     192            allMethods.addAll(Arrays.asList(customMethods)); 
     193            try { 
     194                allMethods.add(Math.class.getMethod("abs", float.class)); 
     195                allMethods.add(Math.class.getMethod("acos", double.class)); 
     196                allMethods.add(Math.class.getMethod("asin", double.class)); 
     197                allMethods.add(Math.class.getMethod("atan", double.class)); 
     198                allMethods.add(Math.class.getMethod("atan2", double.class, double.class)); 
     199                allMethods.add(Math.class.getMethod("ceil", double.class)); 
     200                allMethods.add(Math.class.getMethod("cos", double.class)); 
     201                allMethods.add(Math.class.getMethod("cosh", double.class)); 
     202                allMethods.add(Math.class.getMethod("exp", double.class)); 
     203                allMethods.add(Math.class.getMethod("floor", double.class)); 
     204                allMethods.add(Math.class.getMethod("log", double.class)); 
     205                allMethods.add(Math.class.getMethod("max", float.class, float.class)); 
     206                allMethods.add(Math.class.getMethod("min", float.class, float.class)); 
     207                allMethods.add(Math.class.getMethod("random")); 
     208                allMethods.add(Math.class.getMethod("round", float.class)); 
     209                allMethods.add(Math.class.getMethod("signum", double.class)); 
     210                allMethods.add(Math.class.getMethod("sin", double.class)); 
     211                allMethods.add(Math.class.getMethod("sinh", double.class)); 
     212                allMethods.add(Math.class.getMethod("sqrt", double.class)); 
     213                allMethods.add(Math.class.getMethod("tan", double.class)); 
     214                allMethods.add(Math.class.getMethod("tanh", double.class)); 
     215            } catch (NoSuchMethodException ex) { 
     216                throw new RuntimeException(ex); 
     217            } catch (SecurityException ex) { 
     218                throw  new RuntimeException(ex); 
     219            } 
     220            for (Method m : allMethods) { 
     221                if (!m.getName().equals(name)) 
     222                    continue; 
     223                Class<?>[] expectedParameterTypes = m.getParameterTypes(); 
     224                Object[] convertedArgs = new Object[expectedParameterTypes.length]; 
     225 
     226                if (expectedParameterTypes.length == 1 && expectedParameterTypes[0].isArray()) 
     227                { 
     228                    Class<?> arrayComponentType = expectedParameterTypes[0].getComponentType(); 
     229                    Object arrayArg = Array.newInstance(arrayComponentType, args.size()); 
     230                    for (int i=0; i<args.size(); ++i) 
     231                    { 
     232                        Object o = Cascade.convertTo(args.get(i).evaluate(env), arrayComponentType); 
     233                        if (o == null) 
     234                            return null; 
     235                        Array.set(arrayArg, i, o); 
    81236                    } 
     237                    convertedArgs[0] = arrayArg; 
     238                } else { 
     239                    if (args.size() != expectedParameterTypes.length) 
     240                        continue; 
     241                    for (int i=0; i<args.size(); ++i) { 
     242                        convertedArgs[i] = Cascade.convertTo(args.get(i).evaluate(env), expectedParameterTypes[i]); 
     243                        if (convertedArgs[i] == null) 
     244                            return null; 
     245                    } 
     246                } 
     247                Object result = null; 
     248                try { 
     249                    result = m.invoke(fn, convertedArgs); 
     250                } catch (IllegalAccessException ex) { 
     251                    throw new RuntimeException(ex); 
     252                } catch (IllegalArgumentException ex) { 
     253                    throw new RuntimeException(ex); 
     254                } catch (InvocationTargetException ex) { 
     255                    System.err.println(ex); 
     256                    return null; 
    82257                } 
    83258                return result; 
    84             } 
    85             if (name.equals("-")) { 
    86                 if (args.size() != 2) { 
    87                     return null; 
    88                 } 
    89                 Float fst = getFloat(args.get(0).evaluate(env)); 
    90                 Float snd = getFloat(args.get(1).evaluate(env)); 
    91                 if (fst == null || snd == null) 
    92                     return null; 
    93                 return fst - snd; 
    94259            } 
    95260            return null; 
     
    101266        } 
    102267 
    103         static Float getFloat(Object o) { 
    104             if (o instanceof Float) 
    105                 return (Float) o; 
    106             if (o instanceof Integer) 
    107                 return new Float((Integer) o); 
    108             return null; 
    109         } 
    110268    } 
    111269} 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java

    r3855 r3856  
    8787                if (s.base.equals("meta")) { 
    8888                    for (Condition cnd : s.conds) { 
    89                         if (!cnd.applies(n)) 
     89                        if (!cnd.applies(env)) 
    9090                            continue NEXT_RULE; 
    9191                    } 
     
    105105    @Override 
    106106    public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) { 
     107        Environment env = new Environment(osm, mc, null); 
    107108        for (MapCSSRule r : rules) { 
    108109            for (Selector s : r.selectors) { 
    109                 if (s.applies(osm)) { 
     110                if (s.applies(env)) { 
    110111                    if (s.range.contains(scale)) { 
    111112                        mc.range = Range.cut(mc.range, s.range); 
     
    130131                    } 
    131132 
    132                     if (sub.equals("*")) { 
     133                    if (sub.equals("*")) { // fixme: proper subparts handling 
    133134                        for (Entry<String, Cascade> entry : mc.entrySet()) { 
    134                             Environment env = new Environment(osm, mc, entry.getKey()); 
     135                            env.layer = entry.getKey(); 
    135136                            for (Instruction i : r.declaration) { 
    136137                                i.execute(env); 
     
    138139                        } 
    139140                    } else { 
    140                         Environment env = new Environment(osm, mc, sub); 
     141                        env.layer = sub; 
    141142                        for (Instruction i : r.declaration) { 
    142143                            i.execute(env); 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

    r3849 r3856  
    3434    } 
    3535 
    36     public boolean applies(OsmPrimitive osm) { 
    37         if (!baseApplies(osm)) 
     36    public boolean applies(Environment e) { 
     37        if (!baseApplies(e.osm)) 
    3838            return false; 
    3939        for (Condition c : conds) { 
    40             if (!c.applies(osm)) 
     40            if (!c.applies(e)) 
    4141                return false; 
    4242        } 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java

    r3848 r3856  
    3333 *       |            |                   | 
    3434 *     zoom       condition          instruction 
    35  *      
     35 * 
    3636 * more general: 
    37  *  
     37 * 
    3838 * way|z13-[a=b][c=d]::subpart, way|z-3[u=v]:closed::subpart2 { p1 : val; p2 : val; } 
    3939 * 
     
    141141 * comma delimited list of floats (at least 2, all >= 0) 
    142142 */ 
    143   final public float[] float_array() throws ParseException { 
     143  final public List<Float> float_array() throws ParseException { 
    144144    float f; 
    145145    List<Float> fs = new ArrayList<Float>(); 
     
    161161      } 
    162162    } 
    163         float[] a = new float[fs.size()]; 
    164         for (int i=0; i<fs.size(); ++i) { 
    165             a[i] = fs.get(i); 
    166         } 
    167         {if (true) return a;} 
     163        {if (true) return fs;} 
    168164    throw new Error("Missing return statement in function"); 
    169165  } 
     
    323319 
    324320  final public Condition condition() throws ParseException { 
     321    Condition c; 
     322    Expression e; 
     323    jj_consume_token(LSQUARE); 
     324    if (jj_2_1(2)) { 
     325      c = simple_key_condition(); 
     326      jj_consume_token(RSQUARE); 
     327                                                   {if (true) return c;} 
     328    } else if (jj_2_2(3)) { 
     329      c = simple_key_value_condition(); 
     330    } else { 
     331      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     332      case IDENT: 
     333      case UINT: 
     334      case UFLOAT: 
     335      case STRING: 
     336      case HEXCOLOR: 
     337      case LPAR: 
     338      case PLUS: 
     339      case MINUS: 
     340        e = expression(); 
     341                             c = new Condition.ExpressionCondition(e); 
     342        break; 
     343      default: 
     344        jj_la1[16] = jj_gen; 
     345        jj_consume_token(-1); 
     346        throw new ParseException(); 
     347      } 
     348    } 
     349    jj_consume_token(RSQUARE); 
     350      {if (true) return c;} 
     351    throw new Error("Missing return statement in function"); 
     352  } 
     353 
     354  final public Condition simple_key_condition() throws ParseException { 
     355    boolean not = false; 
     356    String key; 
     357    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     358    case EXCLAMATION: 
     359      jj_consume_token(EXCLAMATION); 
     360                      not = true; 
     361      break; 
     362    default: 
     363      jj_la1[17] = jj_gen; 
     364      ; 
     365    } 
     366    key = string_or_ident(); 
     367      {if (true) return new Condition.KeyCondition(key, not);} 
     368    throw new Error("Missing return statement in function"); 
     369  } 
     370 
     371  final public Condition simple_key_value_condition() throws ParseException { 
    325372    boolean not = false; 
    326373    String key; 
    327374    String val; 
    328     jj_consume_token(LSQUARE); 
    329     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
    330     case EXCLAMATION: 
    331       jj_consume_token(EXCLAMATION); 
    332                       not = true; 
    333       break; 
    334     default: 
    335       jj_la1[16] = jj_gen; 
    336       ; 
    337     } 
    338375    key = string_or_ident(); 
    339376    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     377    case EXCLAMATION_EQUAL: 
     378      jj_consume_token(EXCLAMATION_EQUAL); 
     379                            not = true; 
     380      break; 
    340381    case EQUAL: 
    341     case EXCLAMATION_EQUAL: 
    342       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
    343       case EXCLAMATION_EQUAL: 
    344         jj_consume_token(EXCLAMATION_EQUAL); 
    345                                 not = true; 
    346         break; 
    347       case EQUAL: 
    348         jj_consume_token(EQUAL); 
    349         break; 
    350       default: 
    351         jj_la1[17] = jj_gen; 
    352         jj_consume_token(-1); 
    353         throw new ParseException(); 
    354       } 
    355       val = string_or_ident(); 
    356       jj_consume_token(RSQUARE); 
    357           {if (true) return new Condition.KeyValueCondition(key, val, not ? Condition.Op.NEQ : Condition.Op.EQ);} 
     382      jj_consume_token(EQUAL); 
    358383      break; 
    359384    default: 
    360385      jj_la1[18] = jj_gen; 
    361       ; 
    362     } 
    363     jj_consume_token(RSQUARE); 
    364       {if (true) return new Condition.KeyCondition(key, not);} 
     386      jj_consume_token(-1); 
     387      throw new ParseException(); 
     388    } 
     389    val = string_or_ident(); 
     390      {if (true) return new Condition.KeyValueCondition(key, val, not ? Condition.Op.NEQ : Condition.Op.EQ);} 
    365391    throw new Error("Missing return statement in function"); 
    366392  } 
     
    373399    case EXCLAMATION: 
    374400      jj_consume_token(EXCLAMATION); 
    375                               not = true; 
     401                      not = true; 
    376402      break; 
    377403    default: 
     
    460486    jj_consume_token(COLON); 
    461487    w(); 
    462     if (jj_2_1(2)) { 
     488    if (jj_2_3(2)) { 
    463489      val = float_array(); 
    464490      w(); 
     
    498524    case STAR: 
    499525    case SLASH: 
     526    case PIPE: 
    500527    case PLUS: 
    501528    case MINUS: 
     529    case AMPERSAND: 
     530    case QUESTION: 
    502531      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
    503532      case PLUS: 
     
    505534        while (true) { 
    506535          jj_consume_token(PLUS); 
    507                        op = "+"; 
     536                       op = "plus"; 
    508537          w(); 
    509538          e = primary(); 
    510                                                      args.add(e); 
     539                                                        args.add(e); 
    511540          w(); 
    512541          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     
    524553        while (true) { 
    525554          jj_consume_token(STAR); 
    526                        op = "*"; 
     555                       op = "times"; 
    527556          w(); 
    528557          e = primary(); 
    529                                                      args.add(e); 
     558                                                         args.add(e); 
    530559          w(); 
    531560          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     
    540569        break; 
    541570      case MINUS: 
    542         jj_consume_token(MINUS); 
    543                         op = "-"; 
     571        label_9: 
     572        while (true) { 
     573          jj_consume_token(MINUS); 
     574                        op = "minus"; 
     575          w(); 
     576          e = primary(); 
     577                                                          args.add(e); 
     578          w(); 
     579          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     580          case MINUS: 
     581            ; 
     582            break; 
     583          default: 
     584            jj_la1[27] = jj_gen; 
     585            break label_9; 
     586          } 
     587        } 
     588        break; 
     589      case SLASH: 
     590        label_10: 
     591        while (true) { 
     592          jj_consume_token(SLASH); 
     593                        op = "divided_by"; 
     594          w(); 
     595          e = primary(); 
     596                                                               args.add(e); 
     597          w(); 
     598          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     599          case SLASH: 
     600            ; 
     601            break; 
     602          default: 
     603            jj_la1[28] = jj_gen; 
     604            break label_10; 
     605          } 
     606        } 
     607        break; 
     608      case AMPERSAND: 
     609        jj_consume_token(AMPERSAND); 
     610        jj_consume_token(AMPERSAND); 
     611                                        op = "and"; 
    544612        w(); 
    545613        e = primary(); 
    546                                                       args.add(e); 
     614                                                                        args.add(e); 
    547615        w(); 
    548616        break; 
    549       case SLASH: 
    550         jj_consume_token(SLASH); 
    551                         op = "/"; 
     617      case PIPE: 
     618        jj_consume_token(PIPE); 
     619        jj_consume_token(PIPE); 
     620                              op = "or"; 
    552621        w(); 
    553622        e = primary(); 
    554                                                       args.add(e); 
     623                                                             args.add(e); 
    555624        w(); 
    556625        break; 
     626      case QUESTION: 
     627        jj_consume_token(QUESTION); 
     628                           op = "cond"; 
     629        w(); 
     630        e = primary(); 
     631                                                            args.add(e); 
     632        w(); 
     633        jj_consume_token(COLON); 
     634        w(); 
     635        e = primary(); 
     636                                                                                                         args.add(e); 
     637        w(); 
     638        break; 
    557639      default: 
    558         jj_la1[27] = jj_gen; 
     640        jj_la1[29] = jj_gen; 
    559641        jj_consume_token(-1); 
    560642        throw new ParseException(); 
     
    562644      break; 
    563645    default: 
    564       jj_la1[28] = jj_gen; 
     646      jj_la1[30] = jj_gen; 
    565647      ; 
    566648    } 
    567         if (args.size() == 1) 
     649        if (op == null) 
    568650            {if (true) return args.get(0);} 
    569651        {if (true) return new FunctionExpression(op, args);} 
     
    575657    FunctionExpression fn; 
    576658    Object lit; 
    577     if (jj_2_2(2)) { 
     659    if (jj_2_4(2)) { 
    578660      // both function and identifier start with an identifier 
    579661              fn = function(); 
     
    599681        break; 
    600682      default: 
    601         jj_la1[29] = jj_gen; 
     683        jj_la1[31] = jj_gen; 
    602684        jj_consume_token(-1); 
    603685        throw new ParseException(); 
     
    617699    jj_consume_token(LPAR); 
    618700    w(); 
    619     arg = expression(); 
    620                        args.add(arg); 
    621     label_9: 
    622     while (true) { 
    623       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
    624       case COMMA: 
    625         ; 
    626         break; 
    627       default: 
    628         jj_la1[30] = jj_gen; 
    629         break label_9; 
    630       } 
    631       jj_consume_token(COMMA); 
    632       w(); 
     701    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     702    case IDENT: 
     703    case UINT: 
     704    case UFLOAT: 
     705    case STRING: 
     706    case HEXCOLOR: 
     707    case LPAR: 
     708    case PLUS: 
     709    case MINUS: 
    633710      arg = expression(); 
    634                                      args.add(arg); 
     711                           args.add(arg); 
     712      label_11: 
     713      while (true) { 
     714        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 
     715        case COMMA: 
     716          ; 
     717          break; 
     718        default: 
     719          jj_la1[32] = jj_gen; 
     720          break label_11; 
     721        } 
     722        jj_consume_token(COMMA); 
     723        w(); 
     724        arg = expression(); 
     725                                         args.add(arg); 
     726      } 
     727      break; 
     728    default: 
     729      jj_la1[33] = jj_gen; 
     730      ; 
    635731    } 
    636732    jj_consume_token(RPAR); 
     
    675771      break; 
    676772    default: 
    677       jj_la1[31] = jj_gen; 
     773      jj_la1[34] = jj_gen; 
    678774      jj_consume_token(-1); 
    679775      throw new ParseException(); 
     
    705801  } 
    706802 
    707   private boolean jj_3R_15() { 
     803  private boolean jj_2_3(int xla) { 
     804    jj_la = xla; jj_lastpos = jj_scanpos = token; 
     805    try { return !jj_3_3(); } 
     806    catch(LookaheadSuccess ls) { return true; } 
     807    finally { jj_save(2, xla); } 
     808  } 
     809 
     810  private boolean jj_2_4(int xla) { 
     811    jj_la = xla; jj_lastpos = jj_scanpos = token; 
     812    try { return !jj_3_4(); } 
     813    catch(LookaheadSuccess ls) { return true; } 
     814    finally { jj_save(3, xla); } 
     815  } 
     816 
     817  private boolean jj_3R_13() { 
     818    if (jj_3R_17()) return true; 
    708819    Token xsp; 
    709820    xsp = jj_scanpos; 
    710     if (jj_scan_token(7)) { 
     821    if (jj_3R_18()) { 
    711822    jj_scanpos = xsp; 
    712     if (jj_3R_16()) return true; 
    713     } 
     823    if (jj_scan_token(16)) return true; 
     824    } 
     825    if (jj_3R_17()) return true; 
     826    return false; 
     827  } 
     828 
     829  private boolean jj_3R_20() { 
     830    if (jj_scan_token(COMMA)) return true; 
     831    return false; 
     832  } 
     833 
     834  private boolean jj_3R_16() { 
     835    if (jj_scan_token(EXCLAMATION)) return true; 
     836    return false; 
     837  } 
     838 
     839  private boolean jj_3R_25() { 
     840    if (jj_scan_token(STRING)) return true; 
     841    return false; 
     842  } 
     843 
     844  private boolean jj_3R_12() { 
     845    Token xsp; 
     846    xsp = jj_scanpos; 
     847    if (jj_3R_16()) jj_scanpos = xsp; 
     848    if (jj_3R_17()) return true; 
    714849    return false; 
    715850  } 
    716851 
    717852  private boolean jj_3R_14() { 
     853    if (jj_3R_19()) return true; 
    718854    Token xsp; 
     855    if (jj_3R_20()) return true; 
    719856    while (true) { 
    720857      xsp = jj_scanpos; 
    721       if (jj_3R_15()) { jj_scanpos = xsp; break; } 
    722     } 
    723     return false; 
    724   } 
    725  
    726   private boolean jj_3_2() { 
    727     if (jj_3R_11()) return true; 
    728     return false; 
    729   } 
    730  
    731   private boolean jj_3R_13() { 
    732     if (jj_scan_token(COMMA)) return true; 
    733     return false; 
    734   } 
    735  
    736   private boolean jj_3R_10() { 
    737     if (jj_3R_12()) return true; 
    738     Token xsp; 
    739     if (jj_3R_13()) return true; 
    740     while (true) { 
    741       xsp = jj_scanpos; 
    742       if (jj_3R_13()) { jj_scanpos = xsp; break; } 
    743     } 
    744     return false; 
    745   } 
    746  
    747   private boolean jj_3R_11() { 
     858      if (jj_3R_20()) { jj_scanpos = xsp; break; } 
     859    } 
     860    return false; 
     861  } 
     862 
     863  private boolean jj_3R_23() { 
     864    if (jj_3R_25()) return true; 
     865    return false; 
     866  } 
     867 
     868  private boolean jj_3R_15() { 
    748869    if (jj_scan_token(IDENT)) return true; 
    749     if (jj_3R_14()) return true; 
     870    if (jj_3R_21()) return true; 
    750871    if (jj_scan_token(LPAR)) return true; 
    751872    return false; 
    752873  } 
    753874 
    754   private boolean jj_3R_16() { 
     875  private boolean jj_3R_26() { 
    755876    if (jj_scan_token(COMMENT_START)) return true; 
    756877    return false; 
    757878  } 
    758879 
    759   private boolean jj_3R_12() { 
     880  private boolean jj_3R_19() { 
    760881    Token xsp; 
    761882    xsp = jj_scanpos; 
     
    767888  } 
    768889 
     890  private boolean jj_3_2() { 
     891    if (jj_3R_13()) return true; 
     892    return false; 
     893  } 
     894 
     895  private boolean jj_3R_24() { 
     896    Token xsp; 
     897    xsp = jj_scanpos; 
     898    if (jj_scan_token(7)) { 
     899    jj_scanpos = xsp; 
     900    if (jj_3R_26()) return true; 
     901    } 
     902    return false; 
     903  } 
     904 
     905  private boolean jj_3R_21() { 
     906    Token xsp; 
     907    while (true) { 
     908      xsp = jj_scanpos; 
     909      if (jj_3R_24()) { jj_scanpos = xsp; break; } 
     910    } 
     911    return false; 
     912  } 
     913 
    769914  private boolean jj_3_1() { 
    770     if (jj_3R_10()) return true; 
     915    if (jj_3R_12()) return true; 
     916    if (jj_scan_token(RSQUARE)) return true; 
     917    return false; 
     918  } 
     919 
     920  private boolean jj_3_3() { 
     921    if (jj_3R_14()) return true; 
     922    return false; 
     923  } 
     924 
     925  private boolean jj_3_4() { 
     926    if (jj_3R_15()) return true; 
     927    return false; 
     928  } 
     929 
     930  private boolean jj_3R_18() { 
     931    if (jj_scan_token(EXCLAMATION_EQUAL)) return true; 
     932    return false; 
     933  } 
     934 
     935  private boolean jj_3R_17() { 
     936    Token xsp; 
     937    xsp = jj_scanpos; 
     938    if (jj_3R_22()) { 
     939    jj_scanpos = xsp; 
     940    if (jj_3R_23()) return true; 
     941    } 
     942    return false; 
     943  } 
     944 
     945  private boolean jj_3R_22() { 
     946    if (jj_scan_token(IDENT)) return true; 
    771947    return false; 
    772948  } 
     
    783959  private int jj_la; 
    784960  private int jj_gen; 
    785   final private int[] jj_la1 = new int[32]; 
     961  final private int[] jj_la1 = new int[35]; 
    786962  static private int[] jj_la1_0; 
     963  static private int[] jj_la1_1; 
    787964  static { 
    788965      jj_la1_init_0(); 
     966      jj_la1_init_1(); 
    789967   } 
    790968   private static void jj_la1_init_0() { 
    791       jj_la1_0 = new int[] {0xc,0x12,0x80,0x4000080,0x4000080,0x400000,0x102,0x400000,0x102,0x800000,0x81000,0x81000,0x100000,0x4,0x2000000,0x2000004,0x20000,0x50000,0x50000,0x20000,0x102,0x800,0x200000,0x800,0x300405e,0x1000000,0x100,0x3000300,0x3000300,0x300405e,0x400000,0x300005e,}; 
     969      jj_la1_0 = new int[] {0xc,0x12,0x80,0x20000080,0x20000080,0x400000,0x102,0x400000,0x102,0x1000000,0x81000,0x81000,0x100000,0x4,0x4000000,0x4000004,0x600405e,0x20000,0x50000,0x20000,0x102,0x800,0x200000,0x800,0x600405e,0x2000000,0x100,0x4000000,0x200,0x1e800300,0x1e800300,0x600405e,0x400000,0x600405e,0x600005e,}; 
    792970   } 
    793   final private JJCalls[] jj_2_rtns = new JJCalls[2]; 
     971   private static void jj_la1_init_1() { 
     972      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,}; 
     973   } 
     974  final private JJCalls[] jj_2_rtns = new JJCalls[4]; 
    794975  private boolean jj_rescan = false; 
    795976  private int jj_gc = 0; 
     
    806987    jj_ntk = -1; 
    807988    jj_gen = 0; 
    808     for (int i = 0; i < 32; i++) jj_la1[i] = -1; 
     989    for (int i = 0; i < 35; i++) jj_la1[i] = -1; 
    809990    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 
    810991  } 
     
    8211002    jj_ntk = -1; 
    8221003    jj_gen = 0; 
    823     for (int i = 0; i < 32; i++) jj_la1[i] = -1; 
     1004    for (int i = 0; i < 35; i++) jj_la1[i] = -1; 
    8241005    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 
    8251006  } 
     
    8321013    jj_ntk = -1; 
    8331014    jj_gen = 0; 
    834     for (int i = 0; i < 32; i++) jj_la1[i] = -1; 
     1015    for (int i = 0; i < 35; i++) jj_la1[i] = -1; 
    8351016    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 
    8361017  } 
     
    8431024    jj_ntk = -1; 
    8441025    jj_gen = 0; 
    845     for (int i = 0; i < 32; i++) jj_la1[i] = -1; 
     1026    for (int i = 0; i < 35; i++) jj_la1[i] = -1; 
    8461027    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 
    8471028  } 
     
    8531034    jj_ntk = -1; 
    8541035    jj_gen = 0; 
    855     for (int i = 0; i < 32; i++) jj_la1[i] = -1; 
     1036    for (int i = 0; i < 35; i++) jj_la1[i] = -1; 
    8561037    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 
    8571038  } 
     
    8631044    jj_ntk = -1; 
    8641045    jj_gen = 0; 
    865     for (int i = 0; i < 32; i++) jj_la1[i] = -1; 
     1046    for (int i = 0; i < 35; i++) jj_la1[i] = -1; 
    8661047    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 
    8671048  } 
     
    9751156  public ParseException generateParseException() { 
    9761157    jj_expentries.clear(); 
    977     boolean[] la1tokens = new boolean[30]; 
     1158    boolean[] la1tokens = new boolean[33]; 
    9781159    if (jj_kind >= 0) { 
    9791160      la1tokens[jj_kind] = true; 
    9801161      jj_kind = -1; 
    9811162    } 
    982     for (int i = 0; i < 32; i++) { 
     1163    for (int i = 0; i < 35; i++) { 
    9831164      if (jj_la1[i] == jj_gen) { 
    9841165        for (int j = 0; j < 32; j++) { 
     
    9861167            la1tokens[j] = true; 
    9871168          } 
     1169          if ((jj_la1_1[i] & (1<<j)) != 0) { 
     1170            la1tokens[32+j] = true; 
     1171          } 
    9881172        } 
    9891173      } 
    9901174    } 
    991     for (int i = 0; i < 30; i++) { 
     1175    for (int i = 0; i < 33; i++) { 
    9921176      if (la1tokens[i]) { 
    9931177        jj_expentry = new int[1]; 
     
    10161200  private void jj_rescan_token() { 
    10171201    jj_rescan = true; 
    1018     for (int i = 0; i < 2; i++) { 
     1202    for (int i = 0; i < 4; i++) { 
    10191203    try { 
    10201204      JJCalls p = jj_2_rtns[i]; 
     
    10251209            case 0: jj_3_1(); break; 
    10261210            case 1: jj_3_2(); break; 
     1211            case 2: jj_3_3(); break; 
     1212            case 3: jj_3_4(); break; 
    10271213          } 
    10281214        } 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj

    r3848 r3856  
    5454|   < SEMICOLON: ";" > 
    5555|   < COMMA: "," > 
     56|   < PIPE: "|" > 
    5657|   < PIPE_Z: "|z" > 
    5758|   < PLUS: "+" > 
    5859|   < MINUS: "-" > 
     60|   < AMPERSAND: "&" > 
     61|   < QUESTION: "?" > 
    5962|   < COMMENT_START: "/*" > : COMMENT 
    6063|   < UNEXPECTED_CHAR : ~[] > // avoid TokenMgrErrors because they are hard to recover from 
     
    157160 * comma delimited list of floats (at least 2, all >= 0) 
    158161 */ 
    159 float[] float_array() : 
     162List<Float> float_array() : 
    160163{ 
    161164    float f; 
     
    169172    )+ 
    170173    { 
    171         float[] a = new float[fs.size()]; 
    172         for (int i=0; i<fs.size(); ++i) { 
    173             a[i] = fs.get(i); 
    174         } 
    175         return a; 
     174        return fs; 
    176175    } 
    177176} 
     
    239238Condition condition() : 
    240239{ 
     240    Condition c; 
     241    Expression e; 
     242} 
     243{ 
     244    <LSQUARE> 
     245    (  
     246        LOOKAHEAD(2) 
     247            ( c=simple_key_condition() <RSQUARE> { return c; } ) 
     248        |    
     249        LOOKAHEAD(3) 
     250            c=simple_key_value_condition()  
     251        |    
     252            e=expression() { c = new Condition.ExpressionCondition(e); } 
     253    ) 
     254    <RSQUARE> 
     255    { return c; } 
     256} 
     257 
     258Condition simple_key_condition() : 
     259{ 
     260    boolean not = false; 
     261    String key; 
     262} 
     263{ 
     264    ( <EXCLAMATION> { not = true; } )? 
     265    key=string_or_ident() 
     266    { return new Condition.KeyCondition(key, not); } 
     267} 
     268 
     269Condition simple_key_value_condition() : 
     270{ 
    241271    boolean not = false; 
    242272    String key; 
     
    244274} 
    245275{ 
    246     <LSQUARE> 
    247     ( <EXCLAMATION> { not = true; } )? 
    248276    key=string_or_ident() 
    249     ( 
    250         ( <EXCLAMATION_EQUAL> { not = true; } | <EQUAL> ) 
    251         val=string_or_ident() 
    252         <RSQUARE> 
    253         { return new Condition.KeyValueCondition(key, val, not ? Condition.Op.NEQ : Condition.Op.EQ); } 
    254     )? 
    255     <RSQUARE> 
    256     { return new Condition.KeyCondition(key, not); } 
     277    ( <EXCLAMATION_EQUAL> { not = true; } | <EQUAL> ) 
     278    val=string_or_ident() 
     279    { return new Condition.KeyValueCondition(key, val, not ? Condition.Op.NEQ : Condition.Op.EQ); } 
    257280} 
    258281 
     
    331354    e=primary() { args.add(e); } w() 
    332355    ( 
    333             ( <PLUS> { op = "+"; } w() e=primary() { args.add(e); } w() )+ 
    334         | 
    335             ( <STAR> { op = "*"; } w() e=primary() { args.add(e); } w() )+ 
    336         | 
    337             ( <MINUS> { op = "-"; } w() e=primary() { args.add(e); } w() ) 
    338         | 
    339             ( <SLASH> { op = "/"; } w() e=primary() { args.add(e); } w() ) 
     356            ( <PLUS> { op = "plus"; } w() e=primary() { args.add(e); } w() )+ 
     357        | 
     358            ( <STAR> { op = "times"; } w() e=primary() { args.add(e); } w() )+ 
     359        | 
     360            ( <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w() )+ 
     361        | 
     362            ( <SLASH> { op = "divided_by"; } w() e=primary() { args.add(e); } w() )+ 
     363        | 
     364            ( <AMPERSAND> <AMPERSAND> { op = "and"; } w() e=primary() { args.add(e); } w() ) 
     365        | 
     366            ( <PIPE> <PIPE> { op = "or"; } w() e=primary() { args.add(e); } w() ) 
     367        | 
     368            ( <QUESTION> { op = "cond"; } w() e=primary() { args.add(e); } w() <COLON> w() e=primary() { args.add(e); } w() ) 
    340369    )? 
    341370    { 
    342         if (args.size() == 1) 
     371        if (op == null) 
    343372            return args.get(0); 
    344373        return new FunctionExpression(op, args); 
     
    371400    tmp=<IDENT> { name = tmp.image; } w() 
    372401    <LPAR> w() 
    373     arg=expression() { args.add(arg); } 
    374     ( <COMMA> w() arg=expression() { args.add(arg); } )* 
     402    ( 
     403        arg=expression() { args.add(arg); } 
     404        ( <COMMA> w() arg=expression() { args.add(arg); } )* 
     405    )? 
    375406    <RPAR> 
    376407    { return new FunctionExpression(name, args); } 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserConstants.java

    r3848 r3856  
    5656  int COMMA = 22; 
    5757  /** RegularExpression Id. */ 
    58   int PIPE_Z = 23; 
     58  int PIPE = 23; 
    5959  /** RegularExpression Id. */ 
    60   int PLUS = 24; 
     60  int PIPE_Z = 24; 
    6161  /** RegularExpression Id. */ 
    62   int MINUS = 25; 
     62  int PLUS = 25; 
    6363  /** RegularExpression Id. */ 
    64   int COMMENT_START = 26; 
     64  int MINUS = 26; 
    6565  /** RegularExpression Id. */ 
    66   int UNEXPECTED_CHAR = 27; 
     66  int AMPERSAND = 27; 
    6767  /** RegularExpression Id. */ 
    68   int COMMENT_END = 28; 
     68  int QUESTION = 28; 
     69  /** RegularExpression Id. */ 
     70  int COMMENT_START = 29; 
     71  /** RegularExpression Id. */ 
     72  int UNEXPECTED_CHAR = 30; 
     73  /** RegularExpression Id. */ 
     74  int COMMENT_END = 31; 
    6975 
    7076  /** Lexical state. */ 
     
    98104    "\";\"", 
    99105    "\",\"", 
     106    "\"|\"", 
    100107    "\"|z\"", 
    101108    "\"+\"", 
    102109    "\"-\"", 
     110    "\"&\"", 
     111    "\"?\"", 
    103112    "\"/*\"", 
    104113    "<UNEXPECTED_CHAR>", 
    105114    "\"*/\"", 
    106     "<token of kind 29>", 
     115    "<token of kind 32>", 
    107116  }; 
    108117 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserTokenManager.java

    r3848 r3856  
    4747         jjmatchedKind = 17; 
    4848         return jjMoveStringLiteralDfa1_0(0x40000L); 
     49      case 38: 
     50         return jjStopAtPos(0, 27); 
    4951      case 40: 
    5052         return jjStopAtPos(0, 14); 
     
    5456         return jjStopAtPos(0, 8); 
    5557      case 43: 
    56          return jjStopAtPos(0, 24); 
     58         return jjStopAtPos(0, 25); 
    5759      case 44: 
    5860         return jjStopAtPos(0, 22); 
    5961      case 45: 
    60          return jjStopAtPos(0, 25); 
     62         return jjStopAtPos(0, 26); 
    6163      case 47: 
    6264         jjmatchedKind = 9; 
    63          return jjMoveStringLiteralDfa1_0(0x4000000L); 
     65         return jjMoveStringLiteralDfa1_0(0x20000000L); 
    6466      case 58: 
    6567         jjmatchedKind = 19; 
     
    6971      case 61: 
    7072         return jjStopAtPos(0, 16); 
     73      case 63: 
     74         return jjStopAtPos(0, 28); 
    7175      case 91: 
    7276         return jjStopAtPos(0, 12); 
     
    7680         return jjStopAtPos(0, 10); 
    7781      case 124: 
    78          return jjMoveStringLiteralDfa1_0(0x800000L); 
     82         jjmatchedKind = 23; 
     83         return jjMoveStringLiteralDfa1_0(0x1000000L); 
    7984      case 125: 
    8085         return jjStopAtPos(0, 11); 
     
    9398   { 
    9499      case 42: 
    95          if ((active0 & 0x4000000L) != 0L) 
    96             return jjStopAtPos(1, 26); 
     100         if ((active0 & 0x20000000L) != 0L) 
     101            return jjStopAtPos(1, 29); 
    97102         break; 
    98103      case 58: 
     
    105110         break; 
    106111      case 122: 
    107          if ((active0 & 0x800000L) != 0L) 
    108             return jjStopAtPos(1, 23); 
     112         if ((active0 & 0x1000000L) != 0L) 
     113            return jjStopAtPos(1, 24); 
    109114         break; 
    110115      default : 
     
    346351   { 
    347352      case 42: 
    348          return jjMoveStringLiteralDfa1_1(0x10000000L); 
     353         return jjMoveStringLiteralDfa1_1(0x80000000L); 
    349354      default : 
    350355         return 1; 
     
    360365   { 
    361366      case 47: 
    362          if ((active0 & 0x10000000L) != 0L) 
    363             return jjStopAtPos(1, 28); 
     367         if ((active0 & 0x80000000L) != 0L) 
     368            return jjStopAtPos(1, 31); 
    364369         break; 
    365370      default : 
     
    388393"", null, null, null, null, null, null, null, "\52", "\57", "\173", "\175",  
    389394"\133", "\135", "\50", "\51", "\75", "\41", "\41\75", "\72", "\72\72", "\73", "\54",  
    390 "\174\172", "\53", "\55", "\57\52", null, "\52\57", null, }; 
     395"\174", "\174\172", "\53", "\55", "\46", "\77", "\57\52", null, "\52\57", null, }; 
    391396 
    392397/** Lexer state names. */ 
     
    399404public static final int[] jjnewLexState = { 
    400405   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
    401    -1, 1, -1, 0, -1,  
     406   -1, -1, -1, -1, 1, -1, 0, -1,  
    402407}; 
    403408static final long[] jjtoToken = { 
    404    0x1fffffdfL,  
     409   0xffffffdfL,  
    405410}; 
    406411static final long[] jjtoSkip = { 
    407    0x20000000L,  
     412   0x100000000L,  
    408413}; 
    409414protected SimpleCharStream input_stream; 
     
    513518       jjmatchedPos = 0; 
    514519       curPos = jjMoveStringLiteralDfa0_0(); 
    515        if (jjmatchedPos == 0 && jjmatchedKind > 27) 
     520       if (jjmatchedPos == 0 && jjmatchedKind > 30) 
    516521       { 
    517           jjmatchedKind = 27; 
     522          jjmatchedKind = 30; 
    518523       } 
    519524       break; 
     
    522527       jjmatchedPos = 0; 
    523528       curPos = jjMoveStringLiteralDfa0_1(); 
    524        if (jjmatchedPos == 0 && jjmatchedKind > 29) 
     529       if (jjmatchedPos == 0 && jjmatchedKind > 32) 
    525530       { 
    526           jjmatchedKind = 29; 
     531          jjmatchedKind = 32; 
    527532       } 
    528533       break; 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/xml/LinePrototype.java

    r3836 r3856  
    33 
    44import java.awt.Color; 
     5import java.util.List; 
    56 
    67import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 
     
    1415    public Integer realWidth; // the real width of this line in meter 
    1516    public Color color; 
    16     protected float[] dashed; 
     17    protected List<Float> dashed; 
    1718    public Color dashedColor; 
    1819 
     
    4142    } 
    4243 
    43     public float[] getDashed() { 
     44    public List<Float> getDashed() { 
    4445        return dashed; 
    4546    } 
    4647 
    47     public void setDashed(float[] dashed) { 
    48         if (dashed == null || dashed.length == 0) { 
    49             this.dashed = dashed; 
     48    public void setDashed(List<Float> dashed) { 
     49        if (dashed == null || dashed.isEmpty()) { 
     50            this.dashed = null; 
    5051            return; 
    5152        } 
    5253 
    5354        boolean found = false; 
    54         for (int i=0; i<dashed.length; i++) { 
    55             if (dashed[i] > 0) { 
     55        for (Float f : dashed) { 
     56            if (f == null) { 
     57                this.dashed = null; 
     58                return; 
     59            } 
     60            if (f > 0) { 
    5661                found = true; 
    5762            } 
    58             if (dashed[i] < 0) { 
    59                 System.out.println(I18n.tr("Illegal dash pattern, values must be positive")); 
     63            if (f < 0) { 
     64                System.err.println(I18n.tr("Illegal dash pattern, values must be positive")); 
     65                this.dashed = null; 
     66                return; 
    6067            } 
    6168        } 
     
    6370            this.dashed = dashed; 
    6471        } else { 
    65             System.out.println(I18n.tr("Illegal dash pattern, at least one value must be > 0")); 
     72            System.err.println(I18n.tr("Illegal dash pattern, at least one value must be > 0")); 
    6673        } 
    6774    } 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java

    r3855 r3856  
    303303                def.putOrClear("dashes-background-color", p.line.dashedColor); 
    304304            } 
    305             Float refWidth = def.getFloat("width", null); 
     305            Float refWidth = def.get("width", null, Float.class); 
    306306            if (refWidth != null && p.linemods != null) { 
    307307                int numOver = 0, numUnder = 0; 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSourceHandler.java

    r3836 r3856  
    33 
    44import java.awt.Color; 
     5import java.util.Arrays; 
    56import java.util.Collection; 
    67import java.util.LinkedList; 
     
    9192                line.realWidth=Integer.parseInt(atts.getValue(count)); 
    9293            } else if (atts.getQName(count).equals("dashed")) { 
    93                 float[] dashed; 
     94                Float[] dashed; 
    9495                try { 
    9596                    String[] parts = atts.getValue(count).split(","); 
    96                     dashed = new float[parts.length]; 
     97                    dashed = new Float[parts.length]; 
    9798                    for (int i = 0; i < parts.length; i++) { 
    98                         dashed[i] = (Integer.parseInt(parts[i])); 
     99                        dashed[i] = (float) Integer.parseInt(parts[i]); 
    99100                    } 
    100101                } catch (NumberFormatException nfe) { 
    101102                    boolean isDashed = Boolean.parseBoolean(atts.getValue(count)); 
    102103                    if(isDashed) { 
    103                         dashed = new float[]{9}; 
     104                        dashed = new Float[]{9f}; 
    104105                    } else { 
    105106                        dashed = null; 
    106107                    } 
    107108                } 
    108                 line.setDashed(dashed); 
     109                line.setDashed(dashed == null ? null : Arrays.asList(dashed)); 
    109110            } else if (atts.getQName(count).equals("dashedcolour")) { 
    110111                line.dashedColor=convertColor(atts.getValue(count)); 
Note: See TracChangeset for help on using the changeset viewer.