[SCM] master: Improve expression error messages.

cagney@sourceware.org cagney@sourceware.org
Wed Dec 12 03:43:00 GMT 2007


The branch, master has been updated
       via  6e677cc7a7c3844c9d40f64034ff41a4c24f5600 (commit)
      from  18589ae514ca25c5d0b835874bd3427670deff44 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 6e677cc7a7c3844c9d40f64034ff41a4c24f5600
Author: Andrew Cagney <cagney@redhat.com>
Date:   Tue Dec 11 22:43:20 2007 -0500

    Improve expression error messages.
    
    frysk-core/frysk/expr/ChangeLog
    2007-12-11  Andrew Cagney  <cagney@redhat.com>
    
    	* TestArithmetics.java (checkErrorExpr(String,String)): New.
    	(testEndOfFileError()): New.
    	(testExpressionError()): New.
    	(checkVariableExpr(String expr, long value)): New.
    	(testMember()): New.
    	(expr(String)): Delete.
    	(checkScratchExpr(String,long)): Replace checkExpr(long,String).
    	* SyntaxException.java: New.
    	* TestVariables.java: Delete; merge into TestArithmetics.java.
    	* ExpressionFactory.java (parse(ExprSymTab,String)): Do not append
    	ETX character; handle antlr exceptions.
    	(complete(ExprSymTab,String,int,List)): Ditto.
    	* CExpr.g: Terminate the expression with EOF, not ETX.

-----------------------------------------------------------------------

Summary of changes:
 frysk-core/frysk/expr/CExpr.g                      |    5 +-
 frysk-core/frysk/expr/ChangeLog                    |   16 ++++
 frysk-core/frysk/expr/ExpressionFactory.java       |   28 ++++----
 .../{DetailedAST.java => SyntaxException.java}     |   40 +++++-----
 frysk-core/frysk/expr/TestArithmetics.java         |   40 ++++++++--
 frysk-core/frysk/expr/TestVariables.java           |   75 --------------------
 6 files changed, 82 insertions(+), 122 deletions(-)
 copy frysk-core/frysk/expr/{DetailedAST.java => SyntaxException.java} (73%)
 delete mode 100644 frysk-core/frysk/expr/TestVariables.java

First 500 lines of diff:
diff --git a/frysk-core/frysk/expr/CExpr.g b/frysk-core/frysk/expr/CExpr.g
index 037ba18..a154ff1 100644
--- a/frysk-core/frysk/expr/CExpr.g
+++ b/frysk-core/frysk/expr/CExpr.g
@@ -119,14 +119,11 @@ imaginaryTokenDefinitions
     ;
 
 /** 
-  * The start rule simply expects an expression list following by
-  * the end of text symbol (ETX \3).
-  *
   * The TabException propagates all the way up, to the start rule,
   * which then propagates it up to the calling program.
   */
 start
-    :   expressionList ETX
+    :   expressionList EOF
     ;
 
 /** 
diff --git a/frysk-core/frysk/expr/ChangeLog b/frysk-core/frysk/expr/ChangeLog
index ac90071..01f7557 100644
--- a/frysk-core/frysk/expr/ChangeLog
+++ b/frysk-core/frysk/expr/ChangeLog
@@ -1,3 +1,19 @@
+2007-12-11  Andrew Cagney  <cagney@redhat.com>
+
+	* TestArithmetics.java (checkErrorExpr(String,String)): New.
+	(testEndOfFileError()): New.
+	(testExpressionError()): New.
+	(checkVariableExpr(String expr, long value)): New.
+	(testMember()): New.
+	(expr(String)): Delete.
+	(checkScratchExpr(String,long)): Replace checkExpr(long,String).
+	* SyntaxException.java: New.
+	* TestVariables.java: Delete; merge into TestArithmetics.java.
+	* ExpressionFactory.java (parse(ExprSymTab,String)): Do not append
+	ETX character; handle antlr exceptions.
+	(complete(ExprSymTab,String,int,List)): Ditto.
+	* CExpr.g: Terminate the expression with EOF, not ETX.
+
 2007-11-28  Sami Wagiaalla  <swagiaal@redhat.com>
 
 	CompositeType.java: Renamed addStaticBitFieldMember and 
diff --git a/frysk-core/frysk/expr/ExpressionFactory.java b/frysk-core/frysk/expr/ExpressionFactory.java
index 879f399..d2d325d 100644
--- a/frysk-core/frysk/expr/ExpressionFactory.java
+++ b/frysk-core/frysk/expr/ExpressionFactory.java
@@ -54,18 +54,17 @@ public class ExpressionFactory {
     public static int complete(ExprSymTab symTab, String incomplete,
 			       int offset, List candidates) {
 	try {
-	    String input = (incomplete.substring(0, offset)
-			    + '\t'
-			    + incomplete.substring(offset)
-			    +(char) 3);
+	    String input = incomplete.substring(0, offset) + '\t';
 	    CExprLexer lexer = new CExprLexer(new StringReader(input));
 	    CExprParser parser = new CExprParser(lexer);
 	    parser.setASTNodeClass(DetailedAST.class.getName());
 	    parser.start();
 	} catch (antlr.RecognitionException e) {
-	    throw new RuntimeException(e);
+	    // Unexpected input, don't complete.
+	    return -1;
 	} catch (antlr.TokenStreamException e) {
-	    throw new RuntimeException(e);
+	    // Unexpected token, don't complete.
+	    return -1;
 	} catch (CompletionException e) {
 	    int newOffset = e.complete(symTab, candidates);
 	    Collections.sort(candidates);
@@ -78,21 +77,20 @@ public class ExpressionFactory {
 	return -1; // nothing completed.
     }
 
-
     /**
-     * Parse the string, returning an expression.
+     * Parse the string, returning an expression; or throwing
+     * SyntaxException.
      */
     public static Expression parse(ExprSymTab symTab, String expression) {
 	try {
-	    String input = expression + (char)3;
-	    CExprParser parser
-		= new CExprParser(new CExprLexer(new StringReader(input)));
+	    StringReader input = new StringReader(expression);
+	    CExprParser parser = new CExprParser(new CExprLexer(input));
 	    parser.start();
 	    return new Expression(symTab, parser.getAST());
-	} catch (antlr.RecognitionException r) {
-	    throw new RuntimeException(r);
-	} catch (antlr.TokenStreamException t) {
-	    throw new RuntimeException(t);
+	} catch (antlr.RecognitionException e) {
+	    throw new SyntaxException(expression, e);
+	} catch (antlr.TokenStreamException e) {
+	    throw new SyntaxException(expression, e);
 	}
     }
 }
diff --git a/frysk-core/frysk/expr/DetailedAST.java b/frysk-core/frysk/expr/SyntaxException.java
similarity index 73%
copy from frysk-core/frysk/expr/DetailedAST.java
copy to frysk-core/frysk/expr/SyntaxException.java
index bfe069a..1161c40 100644
--- a/frysk-core/frysk/expr/DetailedAST.java
+++ b/frysk-core/frysk/expr/SyntaxException.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2007, Red Hat Inc.
+// Copyright 2007 Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -39,31 +39,31 @@
 
 package frysk.expr;
 
-import antlr.CommonAST;
-import antlr.Token;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
 
-/** 
- * An AST that also retains the location of its token.
- *
- * For what ever reason the default ast doesn't remember the location
- * (line/col) of a token.
+/**
+ * Some sort of syntax error.
  */
 
-public class DetailedAST extends CommonAST {
+public class SyntaxException extends RuntimeException {
     static final long serialVersionUID = 1;
-    public DetailedAST() {
+
+    private static String message(String input, RecognitionException e) {
+	int cursor = e.getColumn() - 1; // antlr counts from 1.
+	if (input.length() == cursor)
+	    return "incomplete expression";
+	else
+	    return "invalid expression at: " + input.substring(cursor);
     }
-    private int column;
-    private int line;
-    public void initialize(Token t) {
-	super.initialize(t);
-	this.column = t.getColumn();
-	this.line = t.getLine();
+    SyntaxException(String input, RecognitionException e) {
+	super(message(input, e), e);
     }
-    public int getColumn() {
-	return column;
+
+    private static String message(String input, TokenStreamException e) {
+	return "unexpected input: " + e.getMessage();
     }
-    public int getLine() {
-	return line;
+    SyntaxException(String input, TokenStreamException e) {
+	super(message(input, e), e);
     }
 }
diff --git a/frysk-core/frysk/expr/TestArithmetics.java b/frysk-core/frysk/expr/TestArithmetics.java
index d70eac3..7968a76 100644
--- a/frysk-core/frysk/expr/TestArithmetics.java
+++ b/frysk-core/frysk/expr/TestArithmetics.java
@@ -40,8 +40,6 @@
 package frysk.expr;
 
 import frysk.junit.TestCase;
-import frysk.value.Value;
-import frysk.expr.ScratchSymTab;
 
 /**
  * Scratch is for the case where there isn't any symbols, basic ops
@@ -49,16 +47,42 @@ import frysk.expr.ScratchSymTab;
  */
 
 public class TestArithmetics extends TestCase {
-    private Value eval(String input) {
+    private void checkScratchExpr(String expr, long value) {
 	ExprSymTab symTab = new ScratchSymTab();
-	return ExpressionFactory.parse(symTab, input).getValue();
+	Expression e = ExpressionFactory.parse(symTab, expr);
+	assertEquals(expr, value, e.getValue().asLong());
+    }
+    public void testAdd() {
+	checkScratchExpr("1 + 2", 3);
     }
 
-    private void checkExpr(long value, String expr) {
-	assertEquals(expr, value, eval(expr).asLong());
+    private void checkVariableExpr(String expr, long value) {
+	ExprSymTab symTab = new TestbedSymTab();
+	Expression e = ExpressionFactory.parse(symTab, expr);
+	assertEquals(expr, value, e.getValue().asLong());
+    }
+    public void testMember() {
+	checkVariableExpr("a.alpha", 0x01020304);
     }
 
-    public void testAdd() {
-	checkExpr(3, "1 + 2");
+    private void checkErrorExpr(String input, String error) {
+	Throwable t = null;
+	try {
+	    ExprSymTab symTab = new ScratchSymTab();
+	    ExpressionFactory.parse(symTab, input);
+	} catch (SyntaxException e) {
+	    t = e;
+	}
+	assertNotNull("error", t);
+	assertEquals("error", error, t.getMessage());
+    }
+    public void testEndOfFileError() {
+	checkErrorExpr("&", "incomplete expression");
+    }
+    public void testExpressionError() {
+	checkErrorExpr("1 . 2", "invalid expression at: 2");
+    }
+    public void testTokenError() {
+	checkErrorExpr("1...2", "unexpected input: expecting '.', found '2'");
     }
 }
diff --git a/frysk-core/frysk/expr/TestVariables.java b/frysk-core/frysk/expr/TestVariables.java
deleted file mode 100644
index 00015a6..0000000
--- a/frysk-core/frysk/expr/TestVariables.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2007 Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.expr;
-
-import frysk.junit.TestCase;
-import frysk.value.Value;
-import java.io.StringReader;
-
-/**
- * Anything more complex than 1+1.
- */
-
-public class TestVariables extends TestCase {
-
-    private Value eval(String input) {
-	try {
-	    input += (char) 3;
-	    CExprLexer lexer = new CExprLexer(new StringReader(input));
-	    CExprParser parser = new CExprParser(lexer);
-	    parser.start();
-	    ExprSymTab symTab = new TestbedSymTab();
-	    CExprEvaluator exprEvaluator = new CExprEvaluator(symTab);
-	    return exprEvaluator.expr(parser.getAST());
-	} catch (antlr.RecognitionException e) {
-	    throw new RuntimeException(e);
-	} catch (antlr.TokenStreamException e) {
-	    throw new RuntimeException(e);
-	}
-    }
-
-    private void checkExpr(long value, String expr) {
-	assertEquals(expr, value, eval(expr).asLong());
-    }
-
-    public void testMember() {
-	checkExpr(0x01020304, "a.alpha");
-    }
-}


hooks/post-receive
--
frysk system monitor/debugger



More information about the Frysk-cvs mailing list