lexer: New function for other kind of half-open range.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 4 Jun 2023 14:52:11 +0000 (07:52 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 4 Jun 2023 14:52:11 +0000 (07:52 -0700)
The existing function lex_force_num_range_halfopen() handled ranges of the
form [low,high).  There is a new need for (low,high] ranges.  This commit
adds that new function and renames the existing one so that it's obvious
which kind it handles.

src/language/commands/ctables.c
src/language/lexer/lexer.c
src/language/lexer/lexer.h

index 996ada88873ce1de379180973f7b7910e11fa2ce..0d425ce8c2733afad7c89330d0ed95a0f1c6bb43 100644 (file)
@@ -6516,7 +6516,7 @@ cmd_ctables (struct lexer *lexer, struct dataset *ds)
                 goto error;
               lex_match (lexer, T_EQUALS);
 
-              if (!lex_force_num_range_halfopen (lexer, "CILEVEL", 0, 100))
+              if (!lex_force_num_range_co (lexer, "CILEVEL", 0, 100))
                 goto error;
               t->cilevel = lex_number (lexer);
               lex_get (lexer);
@@ -6585,7 +6585,7 @@ cmd_ctables (struct lexer *lexer, struct dataset *ds)
                   else if (lex_match_id (lexer, "ALPHA"))
                     {
                       lex_match (lexer, T_EQUALS);
-                      if (!lex_force_num_range_halfopen (lexer, "ALPHA", 0, 1))
+                      if (!lex_force_num_range_co (lexer, "ALPHA", 0, 1))
                         goto error;
                       t->chisq->alpha = lex_number (lexer);
                       lex_get (lexer);
index 152318d5bc6ae4772564c3e3556c8944a8e891fd..5c1d72612a8585fe87a1131fb535f1030926e75d 100644 (file)
@@ -1058,7 +1058,7 @@ lex_force_num (struct lexer *lexer)
   return false;
 }
 
-/* If the current token is an number in the closed range [MIN,MAX], does
+/* If the current token is a number in the closed range [MIN,MAX], does
    nothing and returns true.  Otherwise, reports an error and returns false.
    If NAME is nonnull, then it is used in the error message. */
 bool
@@ -1151,12 +1151,12 @@ lex_force_num_range_closed (struct lexer *lexer, const char *name,
   return false;
 }
 
-/* If the current token is an number in the half-open range [MIN,MAX), does
+/* If the current token is a number in the half-open range [MIN,MAX), does
    nothing and returns true.  Otherwise, reports an error and returns false.
    If NAME is nonnull, then it is used in the error message. */
 bool
-lex_force_num_range_halfopen (struct lexer *lexer, const char *name,
-                              double min, double max)
+lex_force_num_range_co (struct lexer *lexer, const char *name,
+                        double min, double max)
 {
   bool is_number = lex_is_number (lexer);
   bool too_small = is_number && lex_number (lexer) < min;
@@ -1232,7 +1232,87 @@ lex_force_num_range_halfopen (struct lexer *lexer, const char *name,
   return false;
 }
 
-/* If the current token is an number in the open range (MIN,MAX), does
+/* If the current token is a number in the half-open range (MIN,MAX], does
+   nothing and returns true.  Otherwise, reports an error and returns false.
+   If NAME is nonnull, then it is used in the error message. */
+bool
+lex_force_num_range_oc (struct lexer *lexer, const char *name,
+                        double min, double max)
+{
+  bool is_number = lex_is_number (lexer);
+  bool too_small = is_number && lex_number (lexer) <= min;
+  bool too_big = is_number && lex_number (lexer) > max;
+  if (is_number && !too_small && !too_big)
+    return true;
+
+  if (min >= max)
+    {
+      /* Weird, maybe a bug in the caller.  Just report that we needed a
+         number. */
+      if (name)
+        lex_error (lexer, _("Syntax error expecting number for %s."), name);
+      else
+        lex_error (lexer, _("Syntax error expecting number."));
+    }
+  else
+    {
+      bool report_lower_bound = min > -DBL_MAX || too_small;
+      bool report_upper_bound = max < DBL_MAX || too_big;
+
+      if (report_lower_bound && report_upper_bound)
+        {
+          if (name)
+            lex_error (lexer, _("Syntax error expecting number "
+                                "in (%g,%g] for %s."),
+                       min, max, name);
+          else
+            lex_error (lexer, _("Syntax error expecting number in (%g,%g]."),
+                       min, max);
+        }
+      else if (report_lower_bound)
+        {
+          if (min == 0)
+            {
+              if (name)
+                lex_error (lexer, _("Syntax error expecting "
+                                    "positive number for %s."),
+                           name);
+              else
+                lex_error (lexer, _("Syntax error expecting positive number."));
+            }
+          else
+            {
+              if (name)
+                lex_error (lexer, _("Syntax error expecting "
+                                    "number greater than %g for %s."),
+                           min, name);
+              else
+                lex_error (lexer, _("Syntax error expecting "
+                                    "number greater than %g."), min);
+            }
+        }
+      else if (report_upper_bound)
+        {
+          if (name)
+            lex_error (lexer,
+                       _("Syntax error expecting number %g or less for %s."),
+                       max, name);
+          else
+            lex_error (lexer, _("Syntax error expecting number %g or less."),
+                       max);
+        }
+      else
+        {
+          if (name)
+            lex_error (lexer, _("Syntax error expecting number for %s."), name);
+          else
+            lex_error (lexer, _("Syntax error expecting number."));
+        }
+    }
+  return false;
+}
+
+/* If the current token is a number in the open range (MIN,MAX), does
    nothing and returns true.  Otherwise, reports an error and returns false.
    If NAME is nonnull, then it is used in the error message. */
 bool
index ccb8d73a80cd534a7e5fadba96baf4b069818d06..641d5461d8c518ca92b493854e9903f10235eff4 100644 (file)
@@ -139,8 +139,10 @@ bool lex_force_int_range (struct lexer *, const char *name,
 bool lex_force_num (struct lexer *) WARN_UNUSED_RESULT;
 bool lex_force_num_range_closed (struct lexer *, const char *name,
                                  double min, double max) WARN_UNUSED_RESULT;
-bool lex_force_num_range_halfopen (struct lexer *, const char *name,
-                                   double min, double max) WARN_UNUSED_RESULT;
+bool lex_force_num_range_co (struct lexer *, const char *name,
+                             double min, double max) WARN_UNUSED_RESULT;
+bool lex_force_num_range_oc (struct lexer *, const char *name,
+                             double min, double max) WARN_UNUSED_RESULT;
 bool lex_force_num_range_open (struct lexer *, const char *name,
                                double min, double max) WARN_UNUSED_RESULT;
 bool lex_force_id (struct lexer *) WARN_UNUSED_RESULT;