Changeset 8256 in josm for trunk


Ignore:
Timestamp:
2015-04-25T00:44:00+02:00 (10 years ago)
Author:
bastiK
Message:

mapcss: improve expression parsing
Now it respects operator precedence (C/C++ style) and allows
mix of plus and minus like this:

3 + 2 * 5 - 2 + 10

This is parsed as

(((3 + (2 * 5)) - 2) + 10)

Location:
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java

    r8253 r8256  
    618618
    619619        /**
     620         * Determines if the objects {@code a} and {@code b} are not equal.
     621         * @param a First object
     622         * @param b Second object
     623         * @return {@code false} if objects are equal, {@code true} otherwise
     624         * @see Object#equals(Object)
     625         */
     626        public static boolean not_equal(Object a, Object b) {
     627            return !equal(a,b);
     628        }
     629        /**
    620630         * Determines whether the JOSM search with {@code searchStr} applies to the object.
    621631         * @param env the environment
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj

    r8087 r8256  
    1010import java.io.InputStream;
    1111import java.util.ArrayList;
     12import java.util.Arrays;
     13import java.util.Collections;
    1214import java.util.List;
    1315
     
    854856}
    855857
    856 Expression expression():
    857 {
    858     List<Expression> args = new ArrayList<Expression>();
     858/**
     859 * General expression.
     860 * Separate production rule for each level of operator precedence (recursive descent).
     861 */
     862Expression expression() :
     863{
     864    Expression e;
     865}
     866{
     867    e=conditional_expression()
     868    {
     869        return e;
     870    }
     871}
     872
     873Expression conditional_expression() :
     874{
     875    Expression e, e1, e2;
     876    String op = null;
     877}
     878{
     879    e=or_expression()
     880    (
     881        <QUESTION> w()
     882        e1=conditional_expression()
     883        <COLON> w()
     884        e2=conditional_expression()
     885        {
     886            e = ExpressionFactory.createFunctionExpression("cond", Arrays.asList(e, e1, e2));
     887        }
     888    )?
     889    {
     890        return e;
     891    }
     892}
     893
     894Expression or_expression() :
     895{
     896    Expression e, e2;
     897    String op = null;
     898}
     899{
     900    e=and_expression()
     901    (
     902        <PIPE> <PIPE> w()
     903        e2=and_expression()
     904        {
     905            e = ExpressionFactory.createFunctionExpression("or", Arrays.asList(e, e2));
     906        }
     907    )*
     908    {
     909        return e;
     910    }
     911}
     912
     913Expression and_expression() :
     914{
     915    Expression e, e2;
     916    String op = null;
     917}
     918{
     919    e=relational_expression()
     920    (
     921        <AMPERSAND> <AMPERSAND> w()
     922        e2=relational_expression()
     923        {
     924            e = ExpressionFactory.createFunctionExpression("and", Arrays.asList(e, e2));
     925        }
     926    )*
     927    {
     928        return e;
     929    }
     930}
     931
     932Expression relational_expression() :
     933{
     934    Expression e, e2;
     935    String op = null;
     936}
     937{
     938    e=additive_expression()
     939    (
     940        (
     941            <GREATER_EQUAL> { op = "greater_equal"; }
     942            |
     943            <LESS_EQUAL> { op = "less_equal"; }
     944            |
     945            <GREATER> { op = "greater"; }
     946            |
     947            <LESS> { op = "less"; }
     948            |
     949            <EQUAL> ( <EQUAL> )? { op = "equal"; }
     950            |
     951            <EXCLAMATION> <EQUAL> { op = "not_equal"; }
     952        ) w()
     953        e2=additive_expression()
     954        {
     955            e = ExpressionFactory.createFunctionExpression(op, Arrays.asList(e, e2));
     956        }
     957    )?
     958    {
     959        return e;
     960    }
     961}
     962
     963Expression additive_expression() :
     964{
     965    Expression e, e2;
     966    String op = null;
     967}
     968{
     969    e=multiplicative_expression()
     970    (
     971        ( <PLUS> { op = "plus"; } | <MINUS> { op = "minus"; } ) w()
     972        e2=multiplicative_expression()
     973        {
     974            e = ExpressionFactory.createFunctionExpression(op, Arrays.asList(e, e2));
     975        }
     976    )*
     977    {
     978        return e;
     979    }
     980}
     981
     982Expression multiplicative_expression() :
     983{
     984    Expression e, e2;
     985    String op = null;
     986}
     987{
     988    e=unary_expression()
     989    (
     990        ( <STAR> { op = "times"; } | <SLASH> { op = "divided_by"; } ) w()
     991        e2=unary_expression()
     992        {
     993            e = ExpressionFactory.createFunctionExpression(op, Arrays.asList(e, e2));
     994        }
     995    )*
     996    {
     997        return e;
     998    }
     999}
     1000
     1001Expression unary_expression() :
     1002{
    8591003    Expression e;
    8601004    String op = null;
     
    8621006{
    8631007    (
    864         <EXCLAMATION> { op = "not"; } w() e=primary() { args.add(e); } w()
    865     |
    866         <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w()
    867     |
    868 
    869         (
    870             e=primary() { args.add(e); } w()
    871             (
    872                     ( <PLUS> { op = "plus"; } w() e=primary() { args.add(e); } w() )+
    873                 |
    874                     ( <STAR> { op = "times"; } w() e=primary() { args.add(e); } w() )+
    875                 |
    876                     ( <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w() )+
    877                 |
    878                     ( <SLASH> { op = "divided_by"; } w() e=primary() { args.add(e); } w() )+
    879                 |
    880                     <GREATER_EQUAL> { op = "greater_equal"; } w() e=primary() { args.add(e); } w()
    881                 |
    882                     <LESS_EQUAL> { op = "less_equal"; } w() e=primary() { args.add(e); } w()
    883                 |
    884                     <GREATER> { op = "greater"; } w() e=primary() { args.add(e); } w()
    885                 |
    886                     <EQUAL> ( <EQUAL> )? { op = "equal"; } w() e=primary() { args.add(e); } w()
    887                 |
    888                     <LESS> { op = "less"; } w() e=primary() { args.add(e); } w()
    889                 |
    890                     <AMPERSAND> <AMPERSAND> { op = "and"; } w() e=primary() { args.add(e); } w()
    891                 |
    892                     <PIPE> <PIPE> { op = "or"; } w() e=primary() { args.add(e); } w()
    893                 |
    894                     <QUESTION> { op = "cond"; } w() e=primary() { args.add(e); } w() <COLON> w() e=primary() { args.add(e); } w()
    895             )?
    896         )
    897     )
     1008        <MINUS> { op = "minus"; } w()
     1009    |
     1010        <EXCLAMATION> { op = "not"; } w()
     1011    )?
     1012    e=primary() w()
    8981013    {
    8991014        if (op == null)
    900             return args.get(0);
    901         return ExpressionFactory.createFunctionExpression(op, args);
     1015            return e;
     1016        return ExpressionFactory.createFunctionExpression(op, Collections.singletonList(e));
    9021017    }
    9031018}
Note: See TracChangeset for help on using the changeset viewer.