Repository: groovy
Updated Branches:
  refs/heads/parrot b9ed6e969 -> 61d7009cd


Refine error messages handling( e.g. missing ')' )


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/61d7009c
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/61d7009c
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/61d7009c

Branch: refs/heads/parrot
Commit: 61d7009cdbf24bd5e9b2631631bec02d8c8fa47a
Parents: b9ed6e9
Author: Daniel Sun <sun...@apache.org>
Authored: Wed Nov 30 23:26:13 2016 +0800
Committer: Daniel Sun <sun...@apache.org>
Committed: Wed Nov 30 23:26:13 2016 +0800

----------------------------------------------------------------------
 .../apache/groovy/parser/antlr4/GroovyLexer.g4  | 20 +++++------
 .../apache/groovy/parser/antlr4/GroovyParser.g4 | 24 ++++++++++++-
 .../groovy/parser/antlr4/AbstractLexer.java     | 32 +++++++++++++++++
 .../groovy/parser/antlr4/AbstractParser.java    | 32 +++++++++++++++++
 .../apache/groovy/parser/antlr4/AstBuilder.java |  7 +++-
 .../groovy/parser/antlr4/GroovySyntaxError.java | 18 +++++++++-
 .../parser/antlr4/SyntaxErrorReportable.java    | 38 ++++++++++++++++++++
 7 files changed, 158 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/61d7009c/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
 
b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
index 34999f6..295c7fb 100644
--- 
a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
+++ 
b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
@@ -34,6 +34,10 @@
  */
 lexer grammar GroovyLexer;
 
+options {
+    superClass = AbstractLexer;
+}
+
 @header {
     import static org.apache.groovy.parser.antlr4.SemanticPredicates.*;
     import java.util.Deque;
@@ -165,17 +169,13 @@ lexer grammar GroovyLexer;
         this.setChannel(Token.HIDDEN_CHANNEL);
     }
 
-    private void require(boolean condition, String msg) {
-        if (condition) {
-            return;
-        }
-
-        this.syntaxError(msg);
-    }
-    private void syntaxError(String msg) {
-        throw new GroovySyntaxError(msg + this.genPositionInfo());
+    @Override
+    public int getSyntaxErrorSource() {
+        return GroovySyntaxError.LEXER;
     }
-    private String genPositionInfo() {
+
+    @Override
+    public String genPositionInfo() {
         return " @ line " + getLine() + ", column " + (getCharPositionInLine() 
+ 1);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/61d7009c/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
 
b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
index a3c6043..b70736e 100644
--- 
a/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
+++ 
b/subprojects/groovy-antlr4-grammar/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
@@ -37,6 +37,7 @@ parser grammar GroovyParser;
 options {
     tokenVocab = GroovyLexer;
     contextSuperClass = GroovyParserRuleContext;
+    superClass = AbstractParser;
 }
 
 @header {
@@ -103,6 +104,24 @@ options {
             return metaDataMap.put(key, value);
         }
     }
+
+    @Override
+    public int getSyntaxErrorSource() {
+        return GroovySyntaxError.PARSER;
+    }
+
+    @Override
+    public String genPositionInfo() {
+        Token token = _input.LT(-1);
+
+        if (null == token) {
+            return "";
+        }
+
+        return " @ line " + token.getLine() + ", column " + 
(token.getCharPositionInLine() + 1 + token.getText().length());
+    }
+
+
 }
 
 // starting point for parsing a groovy file
@@ -730,7 +749,10 @@ castParExpression
     ;
 
 parExpression
-    :   LPAREN (statementExpression | standardLambda) RPAREN
+    :   LPAREN (statementExpression | standardLambda)
+        (   RPAREN
+        |   { require(false, "Missing ')'"); }
+        )
 
     // !!!Error Alternatives!!!
     //|   LPAREN statementExpression RPAREN RPAREN+ { 
notifyErrorListeners("Too many ')'"); } // the "Too many" case has been handled 
by the lexer

http://git-wip-us.apache.org/repos/asf/groovy/blob/61d7009c/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractLexer.java
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractLexer.java
 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractLexer.java
new file mode 100644
index 0000000..b3781b4
--- /dev/null
+++ 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractLexer.java
@@ -0,0 +1,32 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.parser.antlr4;
+
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.Lexer;
+
+/**
+ * Because antlr4 does not support generating lexer with specified interface,
+ * we have to create a super class for it and implement the interface.
+ */
+public abstract class AbstractLexer extends Lexer implements 
SyntaxErrorReportable {
+    public AbstractLexer(CharStream input) {
+        super(input);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/61d7009c/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractParser.java
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractParser.java
 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractParser.java
new file mode 100644
index 0000000..44c51c4
--- /dev/null
+++ 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AbstractParser.java
@@ -0,0 +1,32 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.parser.antlr4;
+
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.Parser;
+
+/**
+ * Because antlr4 does not support generating parser with specified interface,
+ * we have to create a super class for it and implement the interface.
+ */
+public abstract class AbstractParser extends Parser implements 
SyntaxErrorReportable {
+    public AbstractParser(TokenStream input) {
+        super(input);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/61d7009c/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 23d4fa5..31124d6 100644
--- 
a/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -89,7 +89,12 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> implements Groov
         AtnManager.RRWL.readLock().lock();
         try {
             result = buildCST(PredictionMode.SLL);
-        } catch (Exception e) {
+        } catch (Throwable t) {
+            // if some syntax error occurred in the lexer, no need to retry 
the powerful LL mode
+            if (t instanceof GroovySyntaxError && GroovySyntaxError.LEXER == 
((GroovySyntaxError) t).getSource()) {
+                throw t;
+            }
+
             result = buildCST(PredictionMode.LL);
         } finally {
             AtnManager.RRWL.readLock().unlock();

http://git-wip-us.apache.org/repos/asf/groovy/blob/61d7009c/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
index fe71cc4..5dc829d 100644
--- 
a/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
+++ 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
@@ -18,11 +18,27 @@
  */
 package org.apache.groovy.parser.antlr4;
 
+import java.util.IllegalFormatCodePointException;
+
 /**
  * Represents a syntax error of groovy program
  */
 public class GroovySyntaxError extends AssertionError {
-    public GroovySyntaxError(String message) {
+    public static final int LEXER = 0;
+    public static final int PARSER = 1;
+    private int source;
+
+    public GroovySyntaxError(String message, int source) {
         super(message, null);
+
+        if (source != LEXER && source != PARSER) {
+            throw new IllegalArgumentException("Invalid syntax error source: " 
+ source);
+        }
+
+        this.source = source;
+    }
+
+    public int getSource() {
+        return source;
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/61d7009c/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
new file mode 100644
index 0000000..4cfdffe
--- /dev/null
+++ 
b/subprojects/groovy-antlr4-grammar/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.parser.antlr4;
+
+/**
+ * A SyntaxErrorReportable is a recognizer that can report syntax error
+ */
+public interface SyntaxErrorReportable {
+    default void require(boolean condition, String msg) {
+        if (condition) {
+            return;
+        }
+
+        this.throwSyntaxError(msg);
+    }
+    default void throwSyntaxError(String msg) {
+        throw new GroovySyntaxError(msg + this.genPositionInfo(), 
this.getSyntaxErrorSource());
+    }
+
+    int getSyntaxErrorSource();
+    String genPositionInfo();
+}

Reply via email to