diff --git a/src/adql/parser/ADQLParser.java b/src/adql/parser/ADQLParser.java index ce4f24d3bb90e57a924248e56ff015d16dcfa4e9..704d43b0adf8103419f8b2ee3ae9bca2feea7a8f 100644 --- a/src/adql/parser/ADQLParser.java +++ b/src/adql/parser/ADQLParser.java @@ -67,7 +67,7 @@ import adql.translator.TranslationException; * @see ADQLQueryFactory * * @author Grégory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de -* @version 1.4 (04/2017) +* @version 1.4 (09/2017) */ public class ADQLParser implements ADQLParserConstants { @@ -295,7 +295,11 @@ public class ADQLParser implements ADQLParserConstants { public final ADQLQuery parseQuery() throws ParseException{ stackQuery.clear(); query = null; - return Query(); + try{ + return Query(); + }catch(TokenMgrError tme){ + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** @@ -313,7 +317,11 @@ public class ADQLParser implements ADQLParserConstants { stackQuery.clear(); query = null; ReInit(new java.io.ByteArrayInputStream(q.getBytes())); - return Query(); + try{ + return Query(); + }catch(TokenMgrError tme){ + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** @@ -331,7 +339,11 @@ public class ADQLParser implements ADQLParserConstants { stackQuery.clear(); query = null; ReInit(stream); - return Query(); + try{ + return Query(); + }catch(TokenMgrError tme){ + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } public final void setDebug(boolean debug){ @@ -3912,82 +3924,6 @@ public class ADQLParser implements ADQLParserConstants { } } - private boolean jj_3R_59(){ - if (jj_3R_24()) - return true; - return false; - } - - private boolean jj_3R_58(){ - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_42()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3R_57(){ - if (jj_3R_27()) - return true; - return false; - } - - private boolean jj_3R_124(){ - if (jj_scan_token(CIRCLE)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_134()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_135()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_101()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3R_44(){ - if (jj_scan_token(SELECT)) - return true; - return false; - } - - private boolean jj_3R_56(){ - if (jj_3R_101()) - return true; - return false; - } - - private boolean jj_3R_123(){ - if (jj_scan_token(CENTROID)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_113()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3R_117(){ - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_27()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - private boolean jj_3R_16(){ if (jj_scan_token(LEFT_PAR)) return true; @@ -5612,6 +5548,82 @@ public class ADQLParser implements ADQLParserConstants { return false; } + private boolean jj_3R_59(){ + if (jj_3R_24()) + return true; + return false; + } + + private boolean jj_3R_58(){ + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_42()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; + return false; + } + + private boolean jj_3R_57(){ + if (jj_3R_27()) + return true; + return false; + } + + private boolean jj_3R_124(){ + if (jj_scan_token(CIRCLE)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_134()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_135()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_101()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; + return false; + } + + private boolean jj_3R_44(){ + if (jj_scan_token(SELECT)) + return true; + return false; + } + + private boolean jj_3R_56(){ + if (jj_3R_101()) + return true; + return false; + } + + private boolean jj_3R_123(){ + if (jj_scan_token(CENTROID)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_113()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; + return false; + } + + private boolean jj_3R_117(){ + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_27()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; + return false; + } + /** Generated Token Manager. */ public ADQLParserTokenManager token_source; SimpleCharStream jj_input_stream; diff --git a/src/adql/parser/ParseException.java b/src/adql/parser/ParseException.java index 108993a7ccccd9dfe17c2e84f088499cd734b6fe..2751dcda98e31b93bc4285bcb35884cb65c7dc8f 100644 --- a/src/adql/parser/ParseException.java +++ b/src/adql/parser/ParseException.java @@ -2,12 +2,13 @@ /* JavaCCOptions:KEEP_LINE_COL=null * * Modified by Grégory Mantelet (CDS), on March 2017 - * Modification: several small modifications. - * /!\ DO NOT RE-GENERATE THIS FILE /!\ - * In case of re-generation, replace it by - * ParseException.java.backup (but maybe after a diff - * in case of significant modifications have been done - * by a new version of JavaCC). + * Modifications: + * - several small modifications. + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by ParseException.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). */ package adql.parser; diff --git a/src/adql/parser/ParseException.java.backup b/src/adql/parser/ParseException.java.backup index 108993a7ccccd9dfe17c2e84f088499cd734b6fe..2751dcda98e31b93bc4285bcb35884cb65c7dc8f 100644 --- a/src/adql/parser/ParseException.java.backup +++ b/src/adql/parser/ParseException.java.backup @@ -2,12 +2,13 @@ /* JavaCCOptions:KEEP_LINE_COL=null * * Modified by Grégory Mantelet (CDS), on March 2017 - * Modification: several small modifications. - * /!\ DO NOT RE-GENERATE THIS FILE /!\ - * In case of re-generation, replace it by - * ParseException.java.backup (but maybe after a diff - * in case of significant modifications have been done - * by a new version of JavaCC). + * Modifications: + * - several small modifications. + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by ParseException.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). */ package adql.parser; diff --git a/src/adql/parser/TokenMgrError.java b/src/adql/parser/TokenMgrError.java index 60cb4686111c3b65f4ad36640e338d94949d231e..fa5d8aaa60363bea7b3f223dac1488421a804663 100644 --- a/src/adql/parser/TokenMgrError.java +++ b/src/adql/parser/TokenMgrError.java @@ -1,13 +1,17 @@ /* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 6.0 */ /* JavaCCOptions: * - * Modified by Grégory Mantelet (CDS), on April 2017 - * Modification: addition of position (line and column) in the original text. - * /!\ DO NOT RE-GENERATE THIS FILE /!\ - * In case of re-generation, replace it by - * TokenMgrError.java.backup (but maybe after a diff - * in case of significant modifications have been done - * by a new version of JavaCC). + * Modified by Grégory Mantelet (CDS), on Sept. 2017 + * Modifications: + * - addition of position (line and column) in the original text + * - adapt the error message so that being more explicit for humans + * and display the incorrect character as a character instead of an + * integer value + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by TokenMgrError.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). */ package adql.parser; @@ -118,7 +122,7 @@ public class TokenMgrError extends Error { * Note: You can customize the lexical error message by modifying this method. */ protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar){ - return ("Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered: " + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + "after : \"" + addEscapes(errorAfter) + "\""); + return ("Incorrect character encountered at l." + errorLine + ", c." + errorColumn + ": " + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " ('" + curChar + "'), ") + "after : \"" + addEscapes(errorAfter) + "\""); } /** diff --git a/src/adql/parser/TokenMgrError.java.backup b/src/adql/parser/TokenMgrError.java.backup index 60cb4686111c3b65f4ad36640e338d94949d231e..61b4a9c384d64f169734169ee09dd7d17cef9fc4 100644 --- a/src/adql/parser/TokenMgrError.java.backup +++ b/src/adql/parser/TokenMgrError.java.backup @@ -1,13 +1,15 @@ /* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 6.0 */ /* JavaCCOptions: * - * Modified by Grégory Mantelet (CDS), on April 2017 - * Modification: addition of position (line and column) in the original text. - * /!\ DO NOT RE-GENERATE THIS FILE /!\ - * In case of re-generation, replace it by - * TokenMgrError.java.backup (but maybe after a diff - * in case of significant modifications have been done - * by a new version of JavaCC). + * Modified by Grégory Mantelet (CDS), on Sept. 2017 + * Modifications: + * - addition of position (line and column) in the original text + * - display the incorrect character as a character instead of an integer + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by TokenMgrError.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). */ package adql.parser; @@ -118,7 +120,7 @@ public class TokenMgrError extends Error { * Note: You can customize the lexical error message by modifying this method. */ protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar){ - return ("Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered: " + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + "after : \"" + addEscapes(errorAfter) + "\""); + return ("Incorrect character encountered at l." + errorLine + ", c." + errorColumn + ": " + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " ('" + curChar + "'), ") + "after : \"" + addEscapes(errorAfter) + "\""); } /** diff --git a/src/adql/parser/adqlGrammar.jj b/src/adql/parser/adqlGrammar.jj index a4d2cb4bddd98546b95325fc5ab742d2f277183d..1de71d3864354d1c64c3219a35fb85e7c0856b65 100644 --- a/src/adql/parser/adqlGrammar.jj +++ b/src/adql/parser/adqlGrammar.jj @@ -26,7 +26,7 @@ * If the syntax is not conform to the ADQL definition an error message is printed else it will be the message "Correct syntax". * * Author: Grégory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de -* Version: 1.4 (04/2017) +* Version: 1.4 (09/2017) */ /* ########### */ @@ -89,7 +89,7 @@ import adql.translator.TranslationException; * @see ADQLQueryFactory * * @author Grégory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de -* @version 1.4 (04/2017) +* @version 1.4 (09/2017) */ public class ADQLParser { @@ -317,7 +317,11 @@ public class ADQLParser { public final ADQLQuery parseQuery() throws ParseException { stackQuery.clear(); query = null; - return Query(); + try { + return Query(); + }catch(TokenMgrError tme) { + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** @@ -335,7 +339,11 @@ public class ADQLParser { stackQuery.clear(); query = null; ReInit(new java.io.ByteArrayInputStream(q.getBytes())); - return Query(); + try { + return Query(); + }catch(TokenMgrError tme) { + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** @@ -353,7 +361,11 @@ public class ADQLParser { stackQuery.clear(); query = null; ReInit(stream); - return Query(); + try { + return Query(); + }catch(TokenMgrError tme) { + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } public final void setDebug(boolean debug){ diff --git a/test/adql/parser/TestADQLParser.java b/test/adql/parser/TestADQLParser.java index 9e6a0169e107bd917d8f0d26c884ffdd550badd5..4549cb83a2719327de2a2b6e26969df2f78fdb1e 100644 --- a/test/adql/parser/TestADQLParser.java +++ b/test/adql/parser/TestADQLParser.java @@ -158,4 +158,25 @@ public class TestADQLParser { } } + @Test + public void testIncorrectCharacter(){ + /* An identifier must be written only with digits, an underscore or + * regular latin characters: */ + try{ + (new ADQLParser()).parseQuery("select grégory FROM aTable"); + }catch(Throwable t){ + assertEquals(ParseException.class, t.getClass()); + assertEquals("Incorrect character encountered at l.1, c.10: \"\\u00e9\" ('é'), after : \"\"", t.getMessage()); + } + + // But in a string, delimited identifier or a comment, it is fine: + try{ + (new ADQLParser()).parseQuery("select 'grégory' FROM aTable"); + (new ADQLParser()).parseQuery("select \"grégory\" FROM aTable"); + (new ADQLParser()).parseQuery("select * FROM aTable -- a comment by Grégory"); + }catch(Throwable t){ + fail("This error should never occurs because all these queries have an accentuated character but at a correct place."); + } + } + }