pspp-dev
[Top][All Lists]
Advanced

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

[q2c 05/12] lexer: New function lex_error_expecting().


From: Ben Pfaff
Subject: [q2c 05/12] lexer: New function lex_error_expecting().
Date: Sat, 5 Nov 2011 20:11:27 -0700

This centralizes some fairly common strings into lexer.c.
---
 src/language/data-io/get-data.c       |    7 ++-
 src/language/data-io/get.c            |    2 +-
 src/language/data-io/save-translate.c |   18 ++++----
 src/language/data-io/save.c           |    8 ++--
 src/language/dictionary/attributes.c  |    2 +-
 src/language/expressions/parse.c      |    3 +-
 src/language/lexer/lexer.c            |   75 ++++++++++++++++++++++++++++++++-
 src/language/lexer/lexer.h            |    2 +
 src/language/stats/aggregate.c        |    2 +-
 src/language/utilities/include.c      |   10 ++---
 src/language/utilities/set.q          |    2 +-
 tests/language/control/do-repeat.at   |    2 +-
 tests/language/data-io/inpt-pgm.at    |    2 +-
 13 files changed, 103 insertions(+), 32 deletions(-)

diff --git a/src/language/data-io/get-data.c b/src/language/data-io/get-data.c
index 9b878c5..4274f95 100644
--- a/src/language/data-io/get-data.c
+++ b/src/language/data-io/get-data.c
@@ -35,6 +35,7 @@
 #include "language/data-io/placement-parser.h"
 #include "language/lexer/format-parser.h"
 #include "language/lexer/lexer.h"
+#include "libpspp/cast.h"
 #include "libpspp/i18n.h"
 #include "libpspp/message.h"
 
@@ -345,7 +346,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
                            DP_DELIMITED, &has_type);
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "FIXED", "DELIMITED");
+              lex_error_expecting (lexer, "FIXED", "DELIMITED", NULL_SENTINEL);
               goto error;
             }
           if (!ok)
@@ -383,7 +384,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
             }
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "LINE", "VARIABLES");
+              lex_error_expecting (lexer, "LINE", "VARIABLES", NULL_SENTINEL);
               goto error;
             }
         }
@@ -494,7 +495,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         break;
       else
         {
-          lex_error (lexer, _("expecting %s"), "VARIABLES");
+          lex_error_expecting (lexer, "VARIABLES", NULL_SENTINEL);
           goto error;
         }
     }
diff --git a/src/language/data-io/get.c b/src/language/data-io/get.c
index 0e542ef..ea65b5c 100644
--- a/src/language/data-io/get.c
+++ b/src/language/data-io/get.c
@@ -96,7 +96,7 @@ parse_read_command (struct lexer *lexer, struct dataset *ds, 
enum reader_command
            type = PFM_TAPE;
          else
            {
-             lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+             lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
               goto error;
            }
        }
diff --git a/src/language/data-io/save-translate.c 
b/src/language/data-io/save-translate.c
index f6487c5..cbed4b1 100644
--- a/src/language/data-io/save-translate.c
+++ b/src/language/data-io/save-translate.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -115,7 +115,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             type = TAB_FILE;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "CSV", "TAB");
+              lex_error_expecting (lexer, "CSV", "TAB", NULL_SENTINEL);
               goto error;
             }
         }
@@ -132,7 +132,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             recode_user_missing = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "IGNORE", "RECODE");
+              lex_error_expecting (lexer, "IGNORE", "RECODE", NULL_SENTINEL);
               goto error;
             }
         }
@@ -145,7 +145,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             use_value_labels = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "VALUES", "LABELS");
+              lex_error_expecting (lexer, "VALUES", "LABELS", NULL_SENTINEL);
               goto error;
             }
         }
@@ -193,8 +193,8 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                     decimal = ',';
                   else
                     {
-                      lex_error (lexer, _("expecting %s or %s"),
-                                 "DOT", "COMMA");
+                      lex_error_expecting (lexer, "DOT", "COMMA",
+                                           NULL_SENTINEL);
                       goto error;
                     }
                 }
@@ -207,8 +207,8 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                     use_print_formats = true;
                   else
                     {
-                      lex_error (lexer, _("expecting %s or %s"),
-                                 "PLAIN", "VARIABLE");
+                      lex_error_expecting (lexer, "PLAIN", "VARIABLE",
+                                           NULL_SENTINEL);
                       goto error;
                     }
                 }
@@ -225,7 +225,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             retain_unselected = false;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+              lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
               goto error;
             }
         }
diff --git a/src/language/data-io/save.c b/src/language/data-io/save.c
index cf84736..66cdd45 100644
--- a/src/language/data-io/save.c
+++ b/src/language/data-io/save.c
@@ -213,8 +213,8 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
             cw = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"),
-                         "READONLY", "WRITEABLE");
+              lex_error_expecting (lexer, "READONLY", "WRITEABLE",
+                                   NULL_SENTINEL);
               goto error;
             }
           sysfile_opts.create_writeable = porfile_opts.create_writeable = cw;
@@ -228,7 +228,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
             *retain_unselected = false;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+              lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
               goto error;
             }
         }
@@ -256,7 +256,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
             porfile_opts.type = PFM_TAPE;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+              lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
               goto error;
             }
         }
diff --git a/src/language/dictionary/attributes.c 
b/src/language/dictionary/attributes.c
index c7598d1..fc9cc9a 100644
--- a/src/language/dictionary/attributes.c
+++ b/src/language/dictionary/attributes.c
@@ -197,7 +197,7 @@ parse_attributes (struct lexer *lexer, const char 
*dict_encoding,
         command = DELETE;
       else if (command == UNKNOWN)
         {
-          lex_error (lexer, _("expecting %s or %s"), "ATTRIBUTE=", "DELETE=");
+          lex_error_expecting (lexer, "ATTRIBUTE=", "DELETE=", NULL_SENTINEL);
           return CMD_FAILURE;
         }
 
diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c
index ed5a070..32c2e61 100644
--- a/src/language/expressions/parse.c
+++ b/src/language/expressions/parse.c
@@ -1268,8 +1268,7 @@ parse_function (struct lexer *lexer, struct expression *e)
           break;
         else if (!lex_match (lexer, T_COMMA))
           {
-            lex_error (lexer, _("expecting `,' or `)' invoking %s function"),
-                       first->name);
+            lex_error_expecting (lexer, ",", ")", NULL_SENTINEL);
             goto fail;
           }
       }
diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c
index 5f1cc4b..a356b38 100644
--- a/src/language/lexer/lexer.c
+++ b/src/language/lexer/lexer.c
@@ -268,6 +268,75 @@ lex_next_error (struct lexer *lexer, int n0, int n1, const 
char *format, ...)
   va_end (args);
 }
 
+/* Prints a syntax error message saying that OPTION0 or one of the other
+   strings following it, up to the first NULL, is expected. */
+void
+lex_error_expecting (struct lexer *lexer, const char *option0, ...)
+{
+  enum { MAX_OPTIONS = 8 };
+  const char *options[MAX_OPTIONS + 1];
+  va_list args;
+  int n;
+
+  va_start (args, option0);
+  options[0] = option0;
+  n = 0;
+  while (n + 1 < MAX_OPTIONS && options[n] != NULL)
+    options[++n] = va_arg (args, const char *);
+  va_end (args);
+
+  switch (n)
+    {
+    case 0:
+      lex_error (lexer, NULL);
+      break;
+
+    case 1:
+      lex_error (lexer, _("expecting %s"), options[0]);
+      break;
+
+    case 2:
+      lex_error (lexer, _("expecting %s or %s"), options[0], options[1]);
+      break;
+
+    case 3:
+      lex_error (lexer, _("expecting %s, %s, or %s"), options[0], options[1],
+                 options[2]);
+      break;
+
+    case 4:
+      lex_error (lexer, _("expecting %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3]);
+      break;
+
+    case 5:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4]);
+      break;
+
+    case 6:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4],
+                 options[5]);
+      break;
+
+    case 7:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4],
+                 options[5], options[6]);
+      break;
+
+    case 8:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4],
+                 options[5], options[6], options[7]);
+      break;
+
+    default:
+      NOT_REACHED ();
+    }
+}
+
 /* Reports an error to the effect that subcommand SBC may only be
    specified once. */
 void
@@ -491,7 +560,7 @@ lex_force_match_id (struct lexer *lexer, const char 
*identifier)
     return true;
   else
     {
-      lex_error (lexer, _("expecting `%s'"), identifier);
+      lex_error_expecting (lexer, identifier, NULL_SENTINEL);
       return false;
     }
 }
@@ -508,7 +577,9 @@ lex_force_match (struct lexer *lexer, enum token_type type)
     }
   else
     {
-      lex_error (lexer, _("expecting `%s'"), token_type_to_string (type));
+      char *s = xasprintf ("`%s'", token_type_to_string (type));
+      lex_error_expecting (lexer, s, NULL_SENTINEL);
+      free (s);
       return false;
     }
 }
diff --git a/src/language/lexer/lexer.h b/src/language/lexer/lexer.h
index 0a3e6c3..b0787e8 100644
--- a/src/language/lexer/lexer.h
+++ b/src/language/lexer/lexer.h
@@ -155,6 +155,8 @@ void lex_next_error (struct lexer *, int n0, int n1, const 
char *, ...)
   PRINTF_FORMAT (4, 5);
 int lex_end_of_command (struct lexer *);
 
+void lex_error_expecting (struct lexer *, const char *, ...) SENTINEL(0);
+
 void lex_sbc_only_once (const char *);
 void lex_sbc_missing (struct lexer *, const char *);
 
diff --git a/src/language/stats/aggregate.c b/src/language/stats/aggregate.c
index fed7656..f4cbaac 100644
--- a/src/language/stats/aggregate.c
+++ b/src/language/stats/aggregate.c
@@ -223,7 +223,7 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
          lex_match (lexer, T_EQUALS);
          if (!lex_match_id (lexer, "COLUMNWISE"))
            {
-             lex_error (lexer, _("expecting %s"), "COLUMNWISE");
+             lex_error_expecting (lexer, "COLUMNWISE", NULL);
               goto error;
            }
          agr.missing = COLUMNWISE;
diff --git a/src/language/utilities/include.c b/src/language/utilities/include.c
index bcee162..89da3b9 100644
--- a/src/language/utilities/include.c
+++ b/src/language/utilities/include.c
@@ -106,8 +106,8 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum 
variant variant)
            syntax_mode = LEX_SYNTAX_AUTO;
          else
            {
-             lex_error (lexer, _("expecting %s, %s, or %s after %s"),
-                         "BATCH", "INTERACTIVE", "AUTO", "SYNTAX");
+             lex_error_expecting (lexer, "BATCH", "INTERACTIVE", "AUTO",
+                                   NULL_SENTINEL);
              goto exit;
            }
        }
@@ -124,8 +124,7 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum 
variant variant)
            }
          else
            {
-             lex_error (lexer, _("expecting %s or %s after %s"),
-                         "YES", "NO", "CD");
+             lex_error_expecting (lexer, "YES", "NO", NULL_SENTINEL);
              goto exit;
            }
        }
@@ -142,8 +141,7 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum 
variant variant)
            }
          else
            {
-             lex_error (lexer, _("expecting %s or %s after %s"),
-                         "CONTINUE", "STOP", "ERROR");
+             lex_error_expecting (lexer, "CONTINUE", "STOP", NULL_SENTINEL);
              goto exit;
            }
        }
diff --git a/src/language/utilities/set.q b/src/language/utilities/set.q
index c538c8c..8b892c7 100644
--- a/src/language/utilities/set.q
+++ b/src/language/utilities/set.q
@@ -331,7 +331,7 @@ stc_custom_tnumbers (struct lexer *lexer,
     }
   else
     {
-      lex_error (lexer, _("expecting VALUES, LABELS or BOTH"));
+      lex_error_expecting (lexer, "VALUES", "LABELS", "BOTH", NULL_SENTINEL);
       return 0;
     }
 
diff --git a/tests/language/control/do-repeat.at 
b/tests/language/control/do-repeat.at
index 4421ba6..75c0e77 100644
--- a/tests/language/control/do-repeat.at
+++ b/tests/language/control/do-repeat.at
@@ -145,6 +145,6 @@ DATA LIST NOTABLE /x 1.
 DO REPEAT y = 1 TO 10.
 ])
 AT_CHECK([pspp -O format=csv do-repeat.sps], [1], [dnl
-error: DO REPEAT: Syntax error at end of input: expecting `END'.
+error: DO REPEAT: Syntax error at end of input: expecting END.
 ])
 AT_CLEANUP
diff --git a/tests/language/data-io/inpt-pgm.at 
b/tests/language/data-io/inpt-pgm.at
index f048d37..03f9a2a 100644
--- a/tests/language/data-io/inpt-pgm.at
+++ b/tests/language/data-io/inpt-pgm.at
@@ -28,6 +28,6 @@ END INPUT PROGRAM.
 DESCRIPTIVES x.
 ])
 AT_CHECK([pspp -O format=csv input-program.sps], [1], [dnl
-error: DESCRIPTIVES: Syntax error at end of input: expecting `BEGIN'.
+error: DESCRIPTIVES: Syntax error at end of input: expecting BEGIN.
 ])
 AT_CLEANUP
-- 
1.7.2.5




reply via email to

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