[jsemver] 89/95: Refactor ExpressionParser to improve error handling

Alexandre Viau reazem-guest at moszumanska.debian.org
Mon Feb 16 14:58:34 UTC 2015


This is an automated email from the git hooks/post-receive script.

reazem-guest pushed a commit to branch master
in repository jsemver.

commit f3b43eee9c2d50681d57996a66f666eedac11582
Author: Zafar Khaja <zafarkhaja at gmail.com>
Date:   Thu Aug 14 20:29:13 2014 +0300

    Refactor ExpressionParser to improve error handling
---
 .../java/com/github/zafarkhaja/semver/Version.java |  5 ++
 .../zafarkhaja/semver/expr/ExpressionParser.java   | 59 ++++++++++------
 .../com/github/zafarkhaja/semver/expr/Lexer.java   | 43 ++++++++----
 .../semver/expr/UnexpectedTokenException.java      | 32 ++++++++-
 .../semver/expr/ExpressionParserTest.java          |  3 +-
 .../github/zafarkhaja/semver/expr/LexerTest.java   | 33 ++++++---
 .../zafarkhaja/semver/expr/LexerTokenTest.java     | 39 ++++++-----
 .../semver/expr/ParserErrorHandlingTest.java       | 80 ++++++++++++++++++++++
 8 files changed, 232 insertions(+), 62 deletions(-)

diff --git a/src/main/java/com/github/zafarkhaja/semver/Version.java b/src/main/java/com/github/zafarkhaja/semver/Version.java
index 3e33603..e49d87d 100644
--- a/src/main/java/com/github/zafarkhaja/semver/Version.java
+++ b/src/main/java/com/github/zafarkhaja/semver/Version.java
@@ -25,6 +25,8 @@ package com.github.zafarkhaja.semver;
 
 import com.github.zafarkhaja.semver.expr.Expression;
 import com.github.zafarkhaja.semver.expr.ExpressionParser;
+import com.github.zafarkhaja.semver.expr.LexerException;
+import com.github.zafarkhaja.semver.expr.UnexpectedTokenException;
 import java.util.Comparator;
 
 /**
@@ -310,6 +312,9 @@ public class Version implements Comparable<Version> {
      * @param expr the SemVer Expression
      * @return {@code true} if this version satisfies the specified
      *         SemVer Expression or {@code false} otherwise
+     * @throws ParseException in case of a general parse error
+     * @throws LexerException when encounters an illegal character
+     * @throws UnexpectedTokenException when comes across an unexpected token
      * @since 0.7.0
      */
     public boolean satisfies(String expr) {
diff --git a/src/main/java/com/github/zafarkhaja/semver/expr/ExpressionParser.java b/src/main/java/com/github/zafarkhaja/semver/expr/ExpressionParser.java
index 040fa52..486f87c 100644
--- a/src/main/java/com/github/zafarkhaja/semver/expr/ExpressionParser.java
+++ b/src/main/java/com/github/zafarkhaja/semver/expr/ExpressionParser.java
@@ -78,12 +78,14 @@ public class ExpressionParser implements Parser<Expression> {
      * @param input a string representing the SemVer Expression
      * @return the AST for the SemVer Expressions
      * @throws LexerException when encounters an illegal character
-     * @throws UnexpectedElementException when consumes a token of an unexpected type
+     * @throws UnexpectedTokenException when consumes a token of an unexpected type
      */
     @Override
     public Expression parse(String input) {
         tokens = lexer.tokenize(input);
-        return parseSemVerExpression();
+        Expression expr = parseSemVerExpression();
+        consumeNextToken(EOL);
+        return expr;
     }
 
     /**
@@ -104,13 +106,13 @@ public class ExpressionParser implements Parser<Expression> {
         Expression expr;
         if (tokens.positiveLookahead(NOT)) {
             tokens.consume();
-            tokens.consume(LEFT_PAREN);
+            consumeNextToken(LEFT_PAREN);
             expr = new Not(parseSemVerExpression());
-            tokens.consume(RIGHT_PAREN);
+            consumeNextToken(RIGHT_PAREN);
         } else if (tokens.positiveLookahead(LEFT_PAREN)) {
-            tokens.consume(LEFT_PAREN);
+            consumeNextToken(LEFT_PAREN);
             expr = parseSemVerExpression();
-            tokens.consume(RIGHT_PAREN);
+            consumeNextToken(RIGHT_PAREN);
         } else {
             expr = parseExpression();
         }
@@ -224,21 +226,21 @@ public class ExpressionParser implements Parser<Expression> {
      * @return the expression AST
      */
     private Expression parseTildeExpression() {
-        tokens.consume(TILDE);
-        int major = intOf(tokens.consume(NUMERIC).lexeme);
+        consumeNextToken(TILDE);
+        int major = intOf(consumeNextToken(NUMERIC).lexeme);
         if (!tokens.positiveLookahead(DOT)) {
             return new GreaterOrEqual(versionOf(major, 0, 0));
         }
-        tokens.consume(DOT);
-        int minor = intOf(tokens.consume(NUMERIC).lexeme);
+        consumeNextToken(DOT);
+        int minor = intOf(consumeNextToken(NUMERIC).lexeme);
         if (!tokens.positiveLookahead(DOT)) {
             return new And(
                 new GreaterOrEqual(versionOf(major, minor, 0)),
                 new Less(versionOf(major + 1, 0, 0))
             );
         }
-        tokens.consume(DOT);
-        int patch = intOf(tokens.consume(NUMERIC).lexeme);
+        consumeNextToken(DOT);
+        int patch = intOf(consumeNextToken(NUMERIC).lexeme);
         return new And(
             new GreaterOrEqual(versionOf(major, minor, patch)),
             new Less(versionOf(major, minor + 1, 0))
@@ -270,8 +272,8 @@ public class ExpressionParser implements Parser<Expression> {
      * @return the expression AST
      */
     private Expression parseVersionExpression() {
-        int major = intOf(tokens.consume(NUMERIC).lexeme);
-        tokens.consume(DOT);
+        int major = intOf(consumeNextToken(NUMERIC).lexeme);
+        consumeNextToken(DOT);
         if (tokens.positiveLookahead(STAR)) {
             tokens.consume();
             return new And(
@@ -279,9 +281,9 @@ public class ExpressionParser implements Parser<Expression> {
                 new Less(versionOf(major + 1, 0, 0))
             );
         }
-        int minor = intOf(tokens.consume(NUMERIC).lexeme);
-        tokens.consume(DOT);
-        tokens.consume(STAR);
+        int minor = intOf(consumeNextToken(NUMERIC).lexeme);
+        consumeNextToken(DOT);
+        consumeNextToken(STAR);
         return new And(
             new GreaterOrEqual(versionOf(major, minor, 0)),
             new Less(versionOf(major, minor + 1, 0))
@@ -313,7 +315,7 @@ public class ExpressionParser implements Parser<Expression> {
      */
     private Expression parseRangeExpression() {
         Expression ge = new GreaterOrEqual(parseVersion());
-        tokens.consume(HYPHEN);
+        consumeNextToken(HYPHEN);
         Expression le = new LessOrEqual(parseVersion());
         return new And(ge, le);
     }
@@ -332,16 +334,16 @@ public class ExpressionParser implements Parser<Expression> {
      * @return the parsed version
      */
     private Version parseVersion() {
-        int major = intOf(tokens.consume(NUMERIC).lexeme);
+        int major = intOf(consumeNextToken(NUMERIC).lexeme);
         int minor = 0;
         if (tokens.positiveLookahead(DOT)) {
             tokens.consume();
-            minor = intOf(tokens.consume(NUMERIC).lexeme);
+            minor = intOf(consumeNextToken(NUMERIC).lexeme);
         }
         int patch = 0;
         if (tokens.positiveLookahead(DOT)) {
             tokens.consume();
-            patch = intOf(tokens.consume(NUMERIC).lexeme);
+            patch = intOf(consumeNextToken(NUMERIC).lexeme);
         }
         return versionOf(major, minor, patch);
     }
@@ -391,4 +393,19 @@ public class ExpressionParser implements Parser<Expression> {
     private int intOf(String value) {
         return Integer.parseInt(value);
     }
+
+    /**
+     * Tries to consume the next token in the stream.
+     *
+     * @param expected the expected types of the next token
+     * @return the next token in the stream
+     * @throws UnexpectedTokenException when encounters an unexpected token type
+     */
+    private Token consumeNextToken(Token.Type... expected) {
+        try {
+            return tokens.consume(expected);
+        } catch (UnexpectedElementException e) {
+            throw new UnexpectedTokenException(e);
+        }
+    }
 }
diff --git a/src/main/java/com/github/zafarkhaja/semver/expr/Lexer.java b/src/main/java/com/github/zafarkhaja/semver/expr/Lexer.java
index b63efc1..384a681 100644
--- a/src/main/java/com/github/zafarkhaja/semver/expr/Lexer.java
+++ b/src/main/java/com/github/zafarkhaja/semver/expr/Lexer.java
@@ -64,15 +64,7 @@ class Lexer {
             LEFT_PAREN("\\("),
             RIGHT_PAREN("\\)"),
             WHITESPACE("\\s+"),
-            EOL("?!") {
-                /**
-                 * {@inheritDoc}
-                 */
-                @Override
-                public boolean isMatchedBy(Token token) {
-                    return token == null;
-                }
-            };
+            EOL("?!");
 
             /**
              * A pattern matching this type.
@@ -123,14 +115,22 @@ class Lexer {
         final String lexeme;
 
         /**
-         * Constructs a {@code Token} instance with the type and lexeme.
+         * The position of this token.
+         */
+        final int position;
+
+        /**
+         * Constructs a {@code Token} instance
+         * with the type, lexeme and position.
          *
          * @param type the type of this token
          * @param lexeme the lexeme of this token
+         * @param position the position of this token
          */
-        Token(Type type, String lexeme) {
+        Token(Type type, String lexeme, int position) {
             this.type = type;
             this.lexeme = (lexeme == null) ? "" : lexeme;
+            this.position = position;
         }
 
         /**
@@ -145,7 +145,10 @@ class Lexer {
                 return false;
             }
             Token token = (Token) other;
-            return type.equals(token.type) && lexeme.equals(token.lexeme);
+            return
+                type.equals(token.type) &&
+                lexeme.equals(token.lexeme) &&
+                position == token.position;
         }
 
         /**
@@ -156,6 +159,7 @@ class Lexer {
             int hash = 5;
             hash = 71 * hash + type.hashCode();
             hash = 71 * hash + lexeme.hashCode();
+            hash = 71 * hash + position;
             return hash;
         }
 
@@ -166,7 +170,11 @@ class Lexer {
          */
         @Override
         public String toString() {
-            return type.name() + "(" + lexeme + ")";
+            return String.format(
+                "%s(%s) at position %d",
+                type.name(),
+                lexeme, position
+            );
         }
     }
 
@@ -186,6 +194,7 @@ class Lexer {
      */
     Stream<Token> tokenize(String input) {
         List<Token> tokens = new ArrayList<Token>();
+        int tokenPos = 0;
         while (!input.isEmpty()) {
             boolean matched = false;
             for (Token.Type tokenType : Token.Type.values()) {
@@ -194,8 +203,13 @@ class Lexer {
                     matched = true;
                     input = matcher.replaceFirst("");
                     if (tokenType != Token.Type.WHITESPACE) {
-                        tokens.add(new Token(tokenType, matcher.group()));
+                        tokens.add(new Token(
+                            tokenType,
+                            matcher.group(),
+                            tokenPos
+                        ));
                     }
+                    tokenPos += matcher.end();
                     break;
                 }
             }
@@ -203,6 +217,7 @@ class Lexer {
                 throw new LexerException(input);
             }
         }
+        tokens.add(new Token(Token.Type.EOL, null, tokenPos));
         return new Stream<Token>(tokens.toArray(new Token[tokens.size()]));
     }
 }
diff --git a/src/main/java/com/github/zafarkhaja/semver/expr/UnexpectedTokenException.java b/src/main/java/com/github/zafarkhaja/semver/expr/UnexpectedTokenException.java
index 44973fd..9a9ce5a 100644
--- a/src/main/java/com/github/zafarkhaja/semver/expr/UnexpectedTokenException.java
+++ b/src/main/java/com/github/zafarkhaja/semver/expr/UnexpectedTokenException.java
@@ -24,7 +24,8 @@
 package com.github.zafarkhaja.semver.expr;
 
 import com.github.zafarkhaja.semver.ParseException;
-import com.github.zafarkhaja.semver.expr.Lexer.*;
+import com.github.zafarkhaja.semver.expr.Lexer.Token;
+import com.github.zafarkhaja.semver.util.UnexpectedElementException;
 import java.util.Arrays;
 
 /**
@@ -46,6 +47,17 @@ public class UnexpectedTokenException extends ParseException {
     private final Token.Type[] expected;
 
     /**
+     * Constructs a {@code UnexpectedTokenException} instance with
+     * the wrapped {@code UnexpectedElementException} exception.
+     *
+     * @param cause the wrapped exception
+     */
+    UnexpectedTokenException(UnexpectedElementException cause) {
+        unexpected = (Token) cause.getUnexpectedElement();
+        expected   = (Token.Type[]) cause.getExpectedElementTypes();
+    }
+
+    /**
      * Constructs a {@code UnexpectedTokenException} instance
      * with the unexpected token and the expected types.
      *
@@ -58,6 +70,24 @@ public class UnexpectedTokenException extends ParseException {
     }
 
     /**
+     * Gets the unexpected token.
+     *
+     * @return the unexpected token
+     */
+    Token getUnexpectedToken() {
+        return unexpected;
+    }
+
+    /**
+     * Gets the expected token types.
+     *
+     * @return an array of expected token types
+     */
+    Token.Type[] getExpectedTokenTypes() {
+        return expected;
+    }
+
+    /**
      * Returns the string representation of this exception
      * containing the information about the unexpected
      * token and, if available, about the expected types.
diff --git a/src/test/java/com/github/zafarkhaja/semver/expr/ExpressionParserTest.java b/src/test/java/com/github/zafarkhaja/semver/expr/ExpressionParserTest.java
index 7c0e429..226686a 100644
--- a/src/test/java/com/github/zafarkhaja/semver/expr/ExpressionParserTest.java
+++ b/src/test/java/com/github/zafarkhaja/semver/expr/ExpressionParserTest.java
@@ -24,7 +24,6 @@
 package com.github.zafarkhaja.semver.expr;
 
 import com.github.zafarkhaja.semver.Version;
-import com.github.zafarkhaja.semver.util.UnexpectedElementException;
 import org.junit.Test;
 import static org.junit.Assert.*;
 
@@ -197,7 +196,7 @@ public class ExpressionParserTest {
         ExpressionParser parser = new ExpressionParser(new Lexer());
         try {
             parser.parse("((>=1.0.1 & < 2)");
-        } catch (UnexpectedElementException e) {
+        } catch (UnexpectedTokenException e) {
             return;
         }
         fail("Should raise error if closing parenthesis is missing");
diff --git a/src/test/java/com/github/zafarkhaja/semver/expr/LexerTest.java b/src/test/java/com/github/zafarkhaja/semver/expr/LexerTest.java
index 1da42c7..6fd19a4 100644
--- a/src/test/java/com/github/zafarkhaja/semver/expr/LexerTest.java
+++ b/src/test/java/com/github/zafarkhaja/semver/expr/LexerTest.java
@@ -38,12 +38,13 @@ public class LexerTest {
     @Test
     public void shouldTokenizeVersionString() {
         Token[] expected = {
-            new Token(GREATER, ">"),
-            new Token(NUMERIC, "1"),
-            new Token(DOT,     "."),
-            new Token(NUMERIC, "0"),
-            new Token(DOT,     "."),
-            new Token(NUMERIC, "0"),
+            new Token(GREATER, ">",  0),
+            new Token(NUMERIC, "1",  1),
+            new Token(DOT,     ".",  2),
+            new Token(NUMERIC, "0",  3),
+            new Token(DOT,     ".",  4),
+            new Token(NUMERIC, "0",  5),
+            new Token(EOL,     null, 6),
         };
         Lexer lexer = new Lexer();
         Stream<Token> stream = lexer.tokenize(">1.0.0");
@@ -53,8 +54,9 @@ public class LexerTest {
     @Test
     public void shouldSkipWhitespaces() {
         Token[] expected = {
-            new Token(GREATER, ">"),
-            new Token(NUMERIC, "1"),
+            new Token(GREATER, ">",  0),
+            new Token(NUMERIC, "1",  2),
+            new Token(EOL,     null, 3),
         };
         Lexer lexer = new Lexer();
         Stream<Token> stream = lexer.tokenize("> 1");
@@ -62,6 +64,21 @@ public class LexerTest {
     }
 
     @Test
+    public void shouldEndWithEol() {
+        Token[] expected = {
+            new Token(NUMERIC, "1",  0),
+            new Token(DOT,     ".",  1),
+            new Token(NUMERIC, "2",  2),
+            new Token(DOT,     ".",  3),
+            new Token(NUMERIC, "3",  4),
+            new Token(EOL,     null, 5),
+        };
+        Lexer lexer = new Lexer();
+        Stream<Token> stream = lexer.tokenize("1.2.3");
+        assertArrayEquals(expected, stream.toArray());
+    }
+
+    @Test
     public void shouldRaiseErrorOnIllegalCharacter() {
         Lexer lexer = new Lexer();
         try {
diff --git a/src/test/java/com/github/zafarkhaja/semver/expr/LexerTokenTest.java b/src/test/java/com/github/zafarkhaja/semver/expr/LexerTokenTest.java
index 36c4729..649cc3e 100644
--- a/src/test/java/com/github/zafarkhaja/semver/expr/LexerTokenTest.java
+++ b/src/test/java/com/github/zafarkhaja/semver/expr/LexerTokenTest.java
@@ -41,23 +41,23 @@ public class LexerTokenTest {
 
         @Test
         public void shouldBeReflexive() {
-            Token token = new Token(NUMERIC, "1");
+            Token token = new Token(NUMERIC, "1", 0);
             assertTrue(token.equals(token));
         }
 
         @Test
         public void shouldBeSymmetric() {
-            Token t1 = new Token(EQUAL, "=");
-            Token t2 = new Token(EQUAL, "=");
+            Token t1 = new Token(EQUAL, "=", 0);
+            Token t2 = new Token(EQUAL, "=", 0);
             assertTrue(t1.equals(t2));
             assertTrue(t2.equals(t1));
         }
 
         @Test
         public void shouldBeTransitive() {
-            Token t1 = new Token(GREATER, ">");
-            Token t2 = new Token(GREATER, ">");
-            Token t3 = new Token(GREATER, ">");
+            Token t1 = new Token(GREATER, ">", 0);
+            Token t2 = new Token(GREATER, ">", 0);
+            Token t3 = new Token(GREATER, ">", 0);
             assertTrue(t1.equals(t2));
             assertTrue(t2.equals(t3));
             assertTrue(t1.equals(t3));
@@ -65,8 +65,8 @@ public class LexerTokenTest {
 
         @Test
         public void shouldBeConsistent() {
-            Token t1 = new Token(HYPHEN, "-");
-            Token t2 = new Token(HYPHEN, "-");
+            Token t1 = new Token(HYPHEN, "-", 0);
+            Token t2 = new Token(HYPHEN, "-", 0);
             assertTrue(t1.equals(t2));
             assertTrue(t1.equals(t2));
             assertTrue(t1.equals(t2));
@@ -74,28 +74,35 @@ public class LexerTokenTest {
 
         @Test
         public void shouldReturnFalseIfOtherVersionIsOfDifferentType() {
-            Token t1 = new Token(DOT, ".");
+            Token t1 = new Token(DOT, ".", 0);
             assertFalse(t1.equals(new String(".")));
         }
 
         @Test
         public void shouldReturnFalseIfOtherVersionIsNull() {
-            Token t1 = new Token(AND, "&");
+            Token t1 = new Token(AND, "&", 0);
             Token t2 = null;
             assertFalse(t1.equals(t2));
         }
 
         @Test
         public void shouldReturnFalseIfTypesAreDifferent() {
-            Token t1 = new Token(EQUAL, "=");
-            Token t2 = new Token(NOT_EQUAL, "!=");
+            Token t1 = new Token(EQUAL, "=", 0);
+            Token t2 = new Token(NOT_EQUAL, "!=", 0);
             assertFalse(t1.equals(t2));
         }
 
         @Test
         public void shouldReturnFalseIfLexemesAreDifferent() {
-            Token t1 = new Token(NUMERIC, "1");
-            Token t2 = new Token(NUMERIC, "2");
+            Token t1 = new Token(NUMERIC, "1", 0);
+            Token t2 = new Token(NUMERIC, "2", 0);
+            assertFalse(t1.equals(t2));
+        }
+
+        @Test
+        public void shouldReturnFalseIfPositionsAreDifferent() {
+            Token t1 = new Token(NUMERIC, "1", 1);
+            Token t2 = new Token(NUMERIC, "1", 2);
             assertFalse(t1.equals(t2));
         }
     }
@@ -104,8 +111,8 @@ public class LexerTokenTest {
 
         @Test
         public void shouldReturnSameHashCodeIfTokensAreEqual() {
-            Token t1 = new Token(NUMERIC, "1");
-            Token t2 = new Token(NUMERIC, "1");
+            Token t1 = new Token(NUMERIC, "1", 0);
+            Token t2 = new Token(NUMERIC, "1", 0);
             assertTrue(t1.equals(t2));
             assertEquals(t1.hashCode(), t2.hashCode());
         }
diff --git a/src/test/java/com/github/zafarkhaja/semver/expr/ParserErrorHandlingTest.java b/src/test/java/com/github/zafarkhaja/semver/expr/ParserErrorHandlingTest.java
new file mode 100644
index 0000000..dc1abf4
--- /dev/null
+++ b/src/test/java/com/github/zafarkhaja/semver/expr/ParserErrorHandlingTest.java
@@ -0,0 +1,80 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2014 Zafar Khaja <zafarkhaja at gmail.com>.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.github.zafarkhaja.semver.expr;
+
+import com.github.zafarkhaja.semver.expr.Lexer.Token;
+import java.util.Arrays;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import static com.github.zafarkhaja.semver.expr.Lexer.Token.Type.*;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Zafar Khaja <zafarkhaja at gmail.com>
+ */
+ at RunWith(Parameterized.class)
+public class ParserErrorHandlingTest {
+
+    private final String invalidExpr;
+    private final Token unexpected;
+    private final Token.Type[] expected;
+
+    public ParserErrorHandlingTest(
+        String invalidExpr,
+        Token unexpected,
+        Token.Type[] expected
+    ) {
+        this.invalidExpr = invalidExpr;
+        this.unexpected  = unexpected;
+        this.expected    = expected;
+    }
+
+    @Test
+    public void shouldCorrectlyHandleParseErrors() {
+        try {
+            ExpressionParser.newInstance().parse(invalidExpr);
+        } catch (UnexpectedTokenException e) {
+            assertEquals(unexpected, e.getUnexpectedToken());
+            assertArrayEquals(expected, e.getExpectedTokenTypes());
+            return;
+        }
+        fail("Uncaught exception");
+    }
+
+    @Parameters(name = "{0}")
+    public static Collection<Object[]> parameters() {
+        return Arrays.asList(new Object[][] {
+            { "1)",           new Token(RIGHT_PAREN, ")", 1),  new Token.Type[] { EOL } },
+            { "(>1.0.1",      new Token(EOL, null, 7),         new Token.Type[] { RIGHT_PAREN } },
+            { "((>=1 & <2)",  new Token(EOL, null, 11),        new Token.Type[] { RIGHT_PAREN } },
+            { ">=1.0.0 &",    new Token(EOL, null, 9),         new Token.Type[] { NUMERIC } },
+            { "(>2.0 |)",     new Token(RIGHT_PAREN, ")", 7),  new Token.Type[] { NUMERIC } },
+            { "& 1.2",        new Token(AND, "&", 0),          new Token.Type[] { NUMERIC } },
+        });
+    }
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jsemver.git



More information about the pkg-java-commits mailing list