lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master cb0676a 4/4: Further prune parser diagnostics


From: Greg Chicares
Subject: [lmi-commits] [lmi] master cb0676a 4/4: Further prune parser diagnostics shown to end users
Date: Mon, 6 Feb 2017 19:13:31 +0000 (UTC)

branch: master
commit cb0676a76b9a85db874b656376c44c1add4a41d4
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Further prune parser diagnostics shown to end users
    
    A diagnostic like this:
      Expected keyword chosen from { p q z }.
      Current token 'number' at position 21.
    is more helpful to compiler writers with the second line included;
    but to end users, with the second line removed.
---
 input_seq_test.cpp |   28 ++++++++++++++++++++++++++++
 input_sequence.cpp |   33 +++++++++++++++++++++++++++------
 objects.make       |    1 +
 3 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/input_seq_test.cpp b/input_seq_test.cpp
index 0d89699..197c630 100644
--- a/input_seq_test.cpp
+++ b/input_seq_test.cpp
@@ -237,6 +237,10 @@ int test_main(int, char*[])
         " Current token ';' at position 29.\n"
         ;
     check(__FILE__, __LINE__, n, d, e, m);
+    BOOST_TEST_EQUAL
+        ("Interval [ 0, 0 ) is improper: it ends before it begins."
+        ,abridge_diagnostics(m)
+        );
     }
 
     // Test grossly improper intervals.
@@ -253,6 +257,10 @@ int test_main(int, char*[])
         " Current token ';' at position 32.\n"
         ;
     check(__FILE__, __LINE__, n, d, e, m);
+    BOOST_TEST_EQUAL
+        ("Interval [ 3, 1 ) is improper: it ends before it begins."
+        ,abridge_diagnostics(m)
+        );
     }
 
     // Test an expression with gaps between intervals. Because the
@@ -282,6 +290,10 @@ int test_main(int, char*[])
         " current interval [ 2, 5 ) would begin before that."
         ;
     check(__FILE__, __LINE__, n, d, e, m);
+    BOOST_TEST_EQUAL
+        (std::string(m)
+        ,abridge_diagnostics(m)
+        );
     }
 
     // Durations with '@' prefix mean attained age.
@@ -385,6 +397,10 @@ int test_main(int, char*[])
     strvec const k{"p", "q", "z"};
     std::string w("z");
     check(__FILE__, __LINE__, n, d, e, m, k, c, false, w);
+    BOOST_TEST_EQUAL
+        (std::string(m)
+        ,abridge_diagnostics(m)
+        );
     }
 
     // Test keywords-only switch with input it forbids.
@@ -403,6 +419,10 @@ int test_main(int, char*[])
     bool const o = true;
     std::string w("z");
     check(__FILE__, __LINE__, n, d, e, m, k, c, o, w);
+    BOOST_TEST_EQUAL
+        ("Expected keyword chosen from { p q z }."
+        ,abridge_diagnostics(m)
+        );
     }
 
     // Test an expression with a gap between intervals, with the
@@ -437,6 +457,10 @@ int test_main(int, char*[])
     bool const o = true;
     std::string w("u");
     check(__FILE__, __LINE__, n, d, e, m, k, c, o, w);
+    BOOST_TEST_EQUAL
+        (std::string(m)
+        ,abridge_diagnostics(m)
+        );
     }
 
     // Duration keywords: {retirement, maturity}
@@ -463,6 +487,10 @@ int test_main(int, char*[])
         " Current token '[' at position 1.\n"
         ;
     check(__FILE__, __LINE__, n, d, e, m);
+    BOOST_TEST_EQUAL
+        ("Expected number or keyword."
+        ,abridge_diagnostics(m)
+        );
     }
 
     return 0;
diff --git a/input_sequence.cpp b/input_sequence.cpp
index da43a71..97a344f 100644
--- a/input_sequence.cpp
+++ b/input_sequence.cpp
@@ -1111,19 +1111,40 @@ void InputSequence::realize_vector()
 /// describing all the anomalies diagnosed while parsing an input
 /// sequence. When that string is not empty, it is reasonable to throw
 /// an exception constructed from it--most generally, in its entirety.
+///
 /// In the important special case where diagnostics are to be shown to
-/// end users to whom the full multiline set may be overwhelming, this
-/// function may be used to extract only the first line (without any
-/// terminal '\n'), which is presumably the most helpful element.
+/// end users, to whom the full multiline set may be overwhelming, use
+/// this function where the exception is caught. It extracts only the
+/// first line, which is presumably the most helpful element, removing
+/// that line's terminal '\n'.
+///
+/// It then strips anything SequenceParser::mark_diagnostic_context()
+/// may have added at the end (and any blanks preceding it), because
+/// end users are unlikely to know what a "token" is, or to care about
+/// the (origin-zero) offset of the error.
+///
+/// Precondition: the argument is not empty; throws otherwise.
+/// Postcondition: the return value is not empty; throws otherwise.
 
 std::string abridge_diagnostics(char const* what)
 {
     std::string s(what);
-    std::string::size_type z(s.find('\n'));
-    if(std::string::npos != z)
+    LMI_ASSERT(!s.empty());
+
+    std::string::size_type z0(s.find('\n'));
+    if(std::string::npos != z0)
         {
-        s.erase(z);
+        s.erase(z0);
         }
+
+    std::string::size_type z1(s.find("Current token"));
+    if(std::string::npos != z1)
+        {
+        s.erase(z1);
+        }
+    rtrim(s, " ");
+
+    LMI_ASSERT(!s.empty());
     return s;
 }
 
diff --git a/objects.make b/objects.make
index 0059d6e..7eb950d 100644
--- a/objects.make
+++ b/objects.make
@@ -637,6 +637,7 @@ input_seq_test$(EXEEXT): \
   $(common_test_objects) \
   input_seq_test.o \
   input_sequence.o \
+  miscellany.o \
 
 input_test$(EXEEXT): \
   $(boost_filesystem_objects) \



reply via email to

[Prev in Thread] Current Thread [Next in Thread]