← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~nbrinza/zorba/error-messages into lp:zorba

 

Nicolae Brinza has proposed merging lp:~nbrinza/zorba/error-messages into lp:zorba.

Commit message:
Parser error messages contain the actual offending QName.

Requested reviews:
  Nicolae Brinza (nbrinza)
  Zorba Coders (zorba-coders)
Related bugs:
  Bug #867227 in Zorba: "Confusing error message"
  https://bugs.launchpad.net/zorba/+bug/867227
  Bug #867357 in Zorba: "Improved parser error message"
  https://bugs.launchpad.net/zorba/+bug/867357
  Bug #949064 in Zorba: "The faulty QName should be printed in the parser error messages"
  https://bugs.launchpad.net/zorba/+bug/949064
  Bug #997045 in Zorba: "EQName regressions"
  https://bugs.launchpad.net/zorba/+bug/997045
  Bug #1072644 in Zorba: "broken error location"
  https://bugs.launchpad.net/zorba/+bug/1072644

For more details, see:
https://code.launchpad.net/~nbrinza/zorba/error-messages/+merge/142697

Parser error messages contain the actual offending QName.
-- 
https://code.launchpad.net/~nbrinza/zorba/error-messages/+merge/142697
Your team Zorba Coders is requested to review the proposed merge of lp:~nbrinza/zorba/error-messages into lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-01-10 10:44:36 +0000
+++ ChangeLog	2013-01-10 14:11:27 +0000
@@ -31,6 +31,7 @@
   * Convert LET vars whose domain sequence has exactly one item to FOR vars.
 
 Bug Fixes/Other Changes:
+  * Fixed bug #949064  (faulty QName should be printed in the error message)
   * Fixed bug #1072644 (broken parser error location)
   * Change XQXQ (XQuery-for-XQuery) module now part of Zorba core
   * Fixed mustCopyInputNodes() method of no-copy, and jsoniq functions.

=== modified file 'src/compiler/parser/symbol_table.cpp'
--- src/compiler/parser/symbol_table.cpp	2012-09-19 21:16:15 +0000
+++ src/compiler/parser/symbol_table.cpp	2013-01-10 14:11:27 +0000
@@ -56,8 +56,9 @@
 }
 
 symbol_table::symbol_table(uint32_t initial_heapsize)
-:
-	heap(initial_heapsize)
+  :
+  heap(initial_heapsize),
+  last_qname(-1)
 {
 }
 
@@ -107,7 +108,8 @@
 
 off_t symbol_table::put_ncname(char const* text, uint32_t length)
 {
-	return heap.put(text, 0, length);
+  last_qname = heap.put(text, 0, length);
+  return last_qname;
 }
 
 off_t symbol_table::put_qname(char const* text, uint32_t length, bool do_trim_start, bool do_trim_end, bool is_eqname)
@@ -125,7 +127,9 @@
   }
 
   if (!is_eqname)
-    return heap.put(text, 0, length);
+  {
+    last_qname = heap.put(text, 0, length);
+  }
   else
   {
     // EQName:  Q{prefix}name
@@ -138,8 +142,10 @@
     off_t uri = put_uri(prefix.c_str(), prefix.size());
     name = get(uri) + ":" + name;
 
-    return heap.put(name.c_str(), 0, name.size());
+    last_qname = heap.put(name.c_str(), 0, name.size());
   }
+  
+  return last_qname;
 }
 
 off_t symbol_table::put_uri(char const* text, uint32_t length)
@@ -226,15 +232,19 @@
 
 std::string symbol_table::get(off_t id)
 {
-	uint32_t n = heap.get_length0(id);
-	char *buf;
-	buf = (char*)malloc(n+1);
-	heap.get0(id, buf, 0, n+1);
-	std::string retstr = string(buf, 0, n);
-	free(buf);
-	return retstr;
+  uint32_t n = heap.get_length0(id);  
+  char *buf;
+  buf = (char*)malloc(n+1);
+  heap.get0(id, buf, 0, n+1);
+  std::string retstr = string(buf, 0, n);
+  free(buf);
+  return retstr;
 }
 
+std::string symbol_table::get_last_qname()
+{
+  return get(last_qname);
+}
 
 }	/* namespace zorba */
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/compiler/parser/symbol_table.h'
--- src/compiler/parser/symbol_table.h	2012-09-19 21:16:15 +0000
+++ src/compiler/parser/symbol_table.h	2013-01-10 14:11:27 +0000
@@ -28,14 +28,15 @@
 
 class ZORBA_DLL_PUBLIC symbol_table
 {
-protected:	// state
-	fxcharheap heap;
-
-public:			// ctor,dtor
-	symbol_table(uint32_t initial_heapsize=1024);
-	~symbol_table();
-
-public:			// table interface
+protected:  // state
+  fxcharheap heap;
+  off_t last_qname; // will store the offset of the last added qname or ncname
+
+public:     // ctor,dtor
+  symbol_table(uint32_t initial_heapsize=1024);
+  ~symbol_table();
+
+public:     // table interface
   off_t put(char const* text);
 
   /* Accepted values for normalizationType:
@@ -43,22 +44,25 @@
    * normalizationType = 1 -- EOL normalization
    * normalizationType = 2 -- Attribute value normalization
    */
-	off_t put(char const* text, uint32_t length, int normalizationType = 0);
+  off_t put(char const* text, uint32_t length, int normalizationType = 0);
 
-	off_t put_ncname(char const* text, uint32_t length);
-	off_t put_qname(char const* text, uint32_t length,
+  off_t put_ncname(char const* text, uint32_t length);
+  off_t put_qname(char const* text, uint32_t length,
                   bool do_trim_start = false, bool do_trim_end = false, bool is_eqname = false);
-	off_t put_uri(char const* text, uint32_t length);
-	off_t put_varname(char const* text, uint32_t length);
-	off_t put_entityref(char const* text, uint32_t length);
-	off_t put_charref(char const* text, uint32_t length);
-	off_t put_stringlit(char const* text, uint32_t length);
-	off_t put_commentcontent(char const* text, uint32_t length);
-
-	std::string get(off_t id);
-	uint32_t size() const;
-
-	xs_decimal* decimalval(char const* text, uint32_t length);
+  off_t put_uri(char const* text, uint32_t length);
+  off_t put_varname(char const* text, uint32_t length);
+  off_t put_entityref(char const* text, uint32_t length);
+  off_t put_charref(char const* text, uint32_t length);
+  off_t put_stringlit(char const* text, uint32_t length);
+  off_t put_commentcontent(char const* text, uint32_t length);
+  
+  uint32_t size() const;
+  
+  std::string get(off_t id);
+  
+  std::string get_last_qname(); // It will return the last added qname or ncname
+
+  xs_decimal* decimalval(char const* text, uint32_t length);
   xs_double* doubleval(char const* text, uint32_t length);   // Will return NULL if std::range_error is raised
   xs_integer* integerval(char const* text, uint32_t length); // Will return NULL if std::range_error is raised
 

=== modified file 'src/compiler/parser/xquery_parser.cpp'
--- src/compiler/parser/xquery_parser.cpp	2013-01-08 16:08:11 +0000
+++ src/compiler/parser/xquery_parser.cpp	2013-01-10 14:11:27 +0000
@@ -5134,7 +5134,7 @@
 #line 2711 "/home/colea/xquery_bzr/error-messages/src/compiler/parser/xquery_parser.y"
     {
       (yyval.node) = (yysemantic_stack_[(3) - (3)].node); // to prevent the Bison warning
-      error((yylocation_stack_[(3) - (2)]), "syntax error, unexpected QName \""
+      error((yylocation_stack_[(3) - (2)]), "syntax error, unexpected qualified name \""
           + static_cast<VarInDeclList*>((yysemantic_stack_[(3) - (3)].node))->operator[](0)->get_var_name()->get_qname().str() + "\" (missing \"$\" sign?)");
       delete (yysemantic_stack_[(3) - (3)].node);
       YYERROR;
@@ -17802,7 +17802,7 @@
     if (prevErr != NULL)
     {
       // Error message heuristics: if the current error message has the "(missing comma "," between expressions?)" text,
-      // and the old message has a "','" text, the replace the old message with the new one. Unfortunately this 
+      // and the old message has a "','" text, then replace the old message with the new one. Unfortunately this 
       // makes the parser error messages harder to internationalize.
       if (msg.find("(missing comma \",\" between expressions?)") != string::npos
           &&
@@ -17810,9 +17810,14 @@
         return;
     }
 
-    // remove the double quoting "''" from every token description
+    // Replace the first occurrence of "unexpected "'QName'"" with "unexpected qualified name %actual_qname%"
     string message = msg;
     int pos;
+    std::string unexpected_qname = "unexpected \"'QName'\"";
+    if ((pos = message.find(unexpected_qname)) != -1)
+      message = message.substr(0, pos) + "unexpected qualified name \"" + driver.symtab.get_last_qname() + "\"" + message.substr(pos+unexpected_qname.length());
+
+    // remove the double quoting "''" from every token description
     while ((pos = message.find("\"'")) != -1 || (pos = message.find("'\"")) != -1)
       message.replace(pos, 2, "\"");
     driver.set_expr(new ParseErrorNode(driver.createQueryLoc(loc), err::XPST0003, message));

=== modified file 'src/compiler/parser/xquery_parser.y'
--- src/compiler/parser/xquery_parser.y	2013-01-08 16:08:11 +0000
+++ src/compiler/parser/xquery_parser.y	2013-01-10 14:11:27 +0000
@@ -2710,7 +2710,7 @@
     FOR error VarInDeclList
     {
       $$ = $3; // to prevent the Bison warning
-      error(@2, "syntax error, unexpected QName \""
+      error(@2, "syntax error, unexpected qualified name \""
           + static_cast<VarInDeclList*>($3)->operator[](0)->get_var_name()->get_qname().str() + "\" (missing \"$\" sign?)");
       delete $3;
       YYERROR;
@@ -6987,7 +6987,7 @@
     if (prevErr != NULL)
     {
       // Error message heuristics: if the current error message has the "(missing comma "," between expressions?)" text,
-      // and the old message has a "','" text, the replace the old message with the new one. Unfortunately this 
+      // and the old message has a "','" text, then replace the old message with the new one. Unfortunately this 
       // makes the parser error messages harder to internationalize.
       if (msg.find("(missing comma \",\" between expressions?)") != string::npos
           &&
@@ -6995,9 +6995,14 @@
         return;
     }
 
-    // remove the double quoting "''" from every token description
+    // Replace the first occurrence of "unexpected "'QName'"" with "unexpected qualified name %actual_qname%"
     string message = msg;
     int pos;
+    std::string unexpected_qname = "unexpected \"'QName'\"";
+    if ((pos = message.find(unexpected_qname)) != -1)
+      message = message.substr(0, pos) + "unexpected qualified name \"" + driver.symtab.get_last_qname() + "\"" + message.substr(pos+unexpected_qname.length());
+
+    // remove the double quoting "''" from every token description
     while ((pos = message.find("\"'")) != -1 || (pos = message.find("'\"")) != -1)
       message.replace(pos, 2, "\"");
     driver.set_expr(new ParseErrorNode(driver.createQueryLoc(loc), err::XPST0003, message));

=== added file 'test/rbkt/ExpQueryResults/zorba/parser/syntax-errors/unexpected-qname-03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/parser/syntax-errors/unexpected-qname-03.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/parser/syntax-errors/unexpected-qname-03.xml.res	2013-01-10 14:11:27 +0000
@@ -0,0 +1,1 @@
+true
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/parser/syntax-errors/unexpected-qname-03.xq'
--- test/rbkt/Queries/zorba/parser/syntax-errors/unexpected-qname-03.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/parser/syntax-errors/unexpected-qname-03.xq	2013-01-10 14:11:27 +0000
@@ -0,0 +1,20 @@
+(:
+  Syntax error with an improved error message:
+  unexpected qualified name %actual_qname%
+:)
+    
+import module namespace refl = "http://www.zorba-xquery.com/modules/reflection";;
+declare namespace err="http://www.w3.org/2005/xqt-errors";;
+
+let $query :=
+'local:f bad()'
+
+return
+try 
+{
+  refl:eval($query)
+}
+catch err:XPST0003
+{
+  $err:description eq 'invalid expression: syntax error, unexpected qualified name "bad", expecting "end of file" or "," or "}"'
+}


Follow ups