? diffs
? errfile.patch
? lexer.patch
? doc/.dirstamp
? gl/.deps
? gl/Makefile
? gl/Makefile.am
? gl/Makefile.in
? gl/alloca.c
? gl/alloca.h
? gl/alloca_.h
? gl/asnprintf.c
? gl/asprintf.c
? gl/byteswap_.h
? gl/c-ctype.c
? gl/c-ctype.h
? gl/c-strtod.c
? gl/c-strtod.h
? gl/charset.alias
? gl/config.charset
? gl/configmake.h
? gl/error.c
? gl/error.h
? gl/exit.h
? gl/exitfail.c
? gl/exitfail.h
? gl/full-read.c
? gl/full-read.h
? gl/full-write.c
? gl/full-write.h
? gl/getdelim.c
? gl/getdelim.h
? gl/gethostname.c
? gl/getline.c
? gl/getline.h
? gl/getlogin_r.c
? gl/getlogin_r.h
? gl/getopt.c
? gl/getopt1.c
? gl/getopt_.h
? gl/getopt_int.h
? gl/gettext.h
? gl/intprops.h
? gl/lbrkprop.h
? gl/linebreak.c
? gl/linebreak.h
? gl/localcharset.c
? gl/localcharset.h
? gl/mbchar.c
? gl/mbchar.h
? gl/mbuiter.h
? gl/memcasecmp.c
? gl/memcasecmp.h
? gl/memchr.c
? gl/memcmp.c
? gl/memmem.c
? gl/memmem.h
? gl/memmove.c
? gl/mempcpy.c
? gl/mempcpy.h
? gl/memset.c
? gl/minmax.h
? gl/printf-args.c
? gl/printf-args.h
? gl/printf-parse.c
? gl/printf-parse.h
? gl/progname.c
? gl/progname.h
? gl/readlink.c
? gl/ref-add.sed
? gl/ref-add.sin
? gl/ref-del.sed
? gl/ref-del.sin
? gl/safe-read.c
? gl/safe-read.h
? gl/safe-write.c
? gl/safe-write.h
? gl/size_max.h
? gl/snprintf.c
? gl/snprintf.h
? gl/stat-macros.h
? gl/stdbool_.h
? gl/stdint.h
? gl/stdint_.h
? gl/stpcpy.c
? gl/stpcpy.h
? gl/strcase.h
? gl/strcasecmp.c
? gl/strcspn.c
? gl/strerror.c
? gl/strftime.c
? gl/strftime.h
? gl/strncasecmp.c
? gl/strndup.c
? gl/strndup.h
? gl/strnlen.c
? gl/strnlen.h
? gl/strnlen1.c
? gl/strnlen1.h
? gl/strpbrk.c
? gl/strpbrk.h
? gl/strsep.c
? gl/strsep.h
? gl/strstr.c
? gl/strstr.h
? gl/strtod.c
? gl/strtok_r.c
? gl/strtok_r.h
? gl/strtol.c
? gl/strtoul.c
? gl/time_r.c
? gl/time_r.h
? gl/utf16-ucs4.h
? gl/utf8-ucs4.h
? gl/vasnprintf.c
? gl/vasnprintf.h
? gl/vasprintf.c
? gl/vasprintf.h
? gl/vsnprintf.c
? gl/vsnprintf.h
? gl/wcwidth.h
? gl/xalloc-die.c
? gl/xalloc.h
? gl/xasprintf.c
? gl/xmalloc.c
? gl/xreadlink.c
? gl/xreadlink.h
? gl/xsize.h
? gl/xstrndup.c
? gl/xstrndup.h
? gl/xvasprintf.c
? gl/xvasprintf.h
? gl/m4/absolute-header.m4
? gl/m4/alloca.m4
? gl/m4/assert.m4
? gl/m4/byteswap.m4
? gl/m4/c-strtod.m4
? gl/m4/codeset.m4
? gl/m4/eoverflow.m4
? gl/m4/error.m4
? gl/m4/exitfail.m4
? gl/m4/extensions.m4
? gl/m4/getdelim.m4
? gl/m4/gethostname.m4
? gl/m4/getline.m4
? gl/m4/getlogin_r.m4
? gl/m4/getopt.m4
? gl/m4/gettext.m4
? gl/m4/glibc2.m4
? gl/m4/glibc21.m4
? gl/m4/gnulib-cache.m4
? gl/m4/gnulib-comp.m4
? gl/m4/gnulib-tool.m4
? gl/m4/iconv.m4
? gl/m4/intdiv0.m4
? gl/m4/intl.m4
? gl/m4/intldir.m4
? gl/m4/intmax.m4
? gl/m4/intmax_t.m4
? gl/m4/inttypes-pri.m4
? gl/m4/inttypes_h.m4
? gl/m4/lcmessage.m4
? gl/m4/lib-ld.m4
? gl/m4/lib-link.m4
? gl/m4/lib-prefix.m4
? gl/m4/linebreak.m4
? gl/m4/localcharset.m4
? gl/m4/lock.m4
? gl/m4/longdouble.m4
? gl/m4/longlong.m4
? gl/m4/mbchar.m4
? gl/m4/mbiter.m4
? gl/m4/mbrtowc.m4
? gl/m4/mbstate_t.m4
? gl/m4/memcasecmp.m4
? gl/m4/memchr.m4
? gl/m4/memcmp.m4
? gl/m4/memmem.m4
? gl/m4/memmove.m4
? gl/m4/mempcpy.m4
? gl/m4/memset.m4
? gl/m4/minmax.m4
? gl/m4/nls.m4
? gl/m4/onceonly_2_57.m4
? gl/m4/po.m4
? gl/m4/printf-posix.m4
? gl/m4/progtest.m4
? gl/m4/readlink.m4
? gl/m4/safe-read.m4
? gl/m4/safe-write.m4
? gl/m4/size_max.m4
? gl/m4/snprintf.m4
? gl/m4/ssize_t.m4
? gl/m4/stdarg.m4
? gl/m4/stdbool.m4
? gl/m4/stdint.m4
? gl/m4/stdint_h.m4
? gl/m4/stpcpy.m4
? gl/m4/strcase.m4
? gl/m4/strcspn.m4
? gl/m4/strerror.m4
? gl/m4/strftime.m4
? gl/m4/strndup.m4
? gl/m4/strnlen.m4
? gl/m4/strpbrk.m4
? gl/m4/strsep.m4
? gl/m4/strstr.m4
? gl/m4/strtod.m4
? gl/m4/strtok_r.m4
? gl/m4/strtol.m4
? gl/m4/strtoul.m4
? gl/m4/time_r.m4
? gl/m4/tm_gmtoff.m4
? gl/m4/uintmax_t.m4
? gl/m4/ulonglong.m4
? gl/m4/unistd_h.m4
? gl/m4/utf-ucs4.m4
? gl/m4/vasnprintf.m4
? gl/m4/vasprintf.m4
? gl/m4/visibility.m4
? gl/m4/vsnprintf.m4
? gl/m4/wchar_t.m4
? gl/m4/wcwidth.m4
? gl/m4/wint_t.m4
? gl/m4/xalloc.m4
? gl/m4/xreadlink.m4
? gl/m4/xsize.m4
? gl/m4/xstrndup.m4
? gl/m4/xvasprintf.m4
? intl/ChangeLog
? intl/Makefile
? intl/Makefile.in
? intl/VERSION
? intl/bindtextdom.c
? intl/config.charset
? intl/dcgettext.c
? intl/dcigettext.c
? intl/dcngettext.c
? intl/dgettext.c
? intl/dngettext.c
? intl/eval-plural.h
? intl/explodename.c
? intl/finddomain.c
? intl/gettext.c
? intl/gettextP.h
? intl/gmo.h
? intl/hash-string.h
? intl/intl-compat.c
? intl/l10nflist.c
? intl/langprefs.c
? intl/libgnuintl.h.in
? intl/loadinfo.h
? intl/loadmsgcat.c
? intl/localcharset.c
? intl/localcharset.h
? intl/locale.alias
? intl/localealias.c
? intl/localename.c
? intl/log.c
? intl/ngettext.c
? intl/os2compat.c
? intl/os2compat.h
? intl/osdep.c
? intl/plural-exp.c
? intl/plural-exp.h
? intl/plural.c
? intl/plural.y
? intl/printf-args.c
? intl/printf-args.h
? intl/printf-parse.c
? intl/printf-parse.h
? intl/printf.c
? intl/ref-add.sin
? intl/ref-del.sin
? intl/relocatable.c
? intl/relocatable.h
? intl/textdomain.c
? intl/vasnprintf.c
? intl/vasnprintf.h
? intl/vasnwprintf.h
? intl/wprintf-parse.h
? intl/xsize.h
? lib/gsl-extras/.deps
? lib/gsl-extras/.dirstamp
? lib/gtksheet/.deps
? lib/gtksheet/.dirstamp
? lib/linreg/.deps
? lib/linreg/.dirstamp
? m4/Makefile.am
? m4/codeset.m4
? m4/gettext.m4
? m4/glibc2.m4
? m4/glibc21.m4
? m4/iconv.m4
? m4/intdiv0.m4
? m4/intmax.m4
? m4/inttypes-pri.m4
? m4/inttypes.m4
? m4/inttypes_h.m4
? m4/isc-posix.m4
? m4/lcmessage.m4
? m4/lib-ld.m4
? m4/lib-link.m4
? m4/lib-prefix.m4
? m4/longdouble.m4
? m4/longlong.m4
? m4/nls.m4
? m4/po.m4
? m4/printf-posix.m4
? m4/progtest.m4
? m4/signed.m4
? m4/size_max.m4
? m4/stdint_h.m4
? m4/uintmax_t.m4
? m4/ulonglong.m4
? m4/wchar_t.m4
? m4/wint_t.m4
? m4/xsize.m4
? src/data/.deps
? src/data/.dirstamp
? src/language/.deps
? src/language/.dirstamp
? src/language/control/.deps
? src/language/control/.dirstamp
? src/language/data-io/.deps
? src/language/data-io/.dirstamp
? src/language/data-io/file-handle.c
? src/language/data-io/list.c
? src/language/dictionary/.deps
? src/language/dictionary/.dirstamp
? src/language/expressions/.deps
? src/language/expressions/.dirstamp
? src/language/lexer/.deps
? src/language/lexer/.dirstamp
? src/language/lexer/q2c
? src/language/stats/.deps
? src/language/stats/.dirstamp
? src/language/stats/correlations.c
? src/language/stats/crosstabs.c
? src/language/stats/examine.c
? src/language/stats/frequencies.c
? src/language/stats/means.c
? src/language/stats/oneway.c
? src/language/stats/rank.c
? src/language/stats/regression.c
? src/language/stats/t-test.c
? src/language/tests/.deps
? src/language/tests/.dirstamp
? src/language/utilities/.deps
? src/language/utilities/.dirstamp
? src/language/utilities/set.c
? src/language/xforms/.deps
? src/language/xforms/.dirstamp
? src/libpspp/.deps
? src/libpspp/.dirstamp
? src/libpspp/version.c
? src/math/.deps
? src/math/.dirstamp
? src/math/linreg/.deps
? src/math/linreg/.dirstamp
? src/math/ts/.deps
? src/math/ts/.dirstamp
? src/output/.deps
? src/output/.dirstamp
? src/output/charts/.deps
? src/output/charts/.dirstamp
? src/ui/.deps
? src/ui/.dirstamp
? src/ui/gui/.deps
? src/ui/gui/.dirstamp
? src/ui/gui/psppire
? src/ui/terminal/.deps
? src/ui/terminal/.dirstamp
? src/ui/terminal/pspp
? tests/formats/.deps
? tests/formats/.dirstamp
? tests/formats/inexactify
? tests/libpspp/.deps
? tests/libpspp/.dirstamp
? tests/libpspp/ll-test
? tests/libpspp/llx-test
Index: src/language/command.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/command.c,v
retrieving revision 1.18
diff -b -w -U3 -r1.18 command.c
--- src/language/command.c	26 Oct 2006 06:16:36 -0000	1.18
+++ src/language/command.c	11 Nov 2006 00:13:11 -0000
@@ -108,7 +108,7 @@
     enum states states;         /* States in which command is allowed. */
     enum flags flags;           /* Other command requirements. */
     const char *name;		/* Command name. */
-    int (*function) (struct dataset *);	/* Function to call. */
+    int (*function) (struct lexer *, struct dataset *);	/* Function to call. */
   };
 
 /* Define the command array. */
@@ -130,22 +130,22 @@
 
 /* Command parser. */
 
-static const struct command *parse_command_name (void);
-static enum cmd_result do_parse_command (struct dataset *ds, enum cmd_state);
+static const struct command *parse_command_name (struct lexer *lexer);
+static enum cmd_result do_parse_command (struct lexer *, struct dataset *, enum cmd_state);
 
 /* Parses an entire command, from command name to terminating
    dot.  On failure, skips to the terminating dot.
    Returns the command's success or failure result. */
 enum cmd_result
-cmd_parse (struct dataset *ds, enum cmd_state state) 
+cmd_parse (struct lexer *lexer, struct dataset *ds, enum cmd_state state) 
 {
   int result;
   
   som_new_series ();
 
-  result = do_parse_command (ds, state);
+  result = do_parse_command (lexer, ds, state);
   if (cmd_result_is_failure (result)) 
-    lex_discard_rest_of_command ();
+    lex_discard_rest_of_command (lexer);
 
   unset_cmd_algorithm ();
   dict_clear_aux (dataset_dict (ds));
@@ -156,18 +156,18 @@
 /* Parses an entire command, from command name to terminating
    dot. */
 static enum cmd_result
-do_parse_command (struct dataset *ds, enum cmd_state state)
+do_parse_command (struct lexer *lexer, struct dataset *ds, enum cmd_state state)
 {
   const struct command *command;
   enum cmd_result result;
 
-  /* Read the command's first token. */
+  /* Read the command's first lex_token (lexer). */
   getl_set_prompt_style (GETL_PROMPT_FIRST);
   set_completion_state (state);
-  lex_get ();
-  if (token == T_STOP)
+  lex_get (lexer);
+  if (lex_token (lexer) == T_STOP)
     return CMD_EOF;
-  else if (token == '.') 
+  else if (lex_token (lexer) == '.') 
     {
       /* Null commands can result from extra empty lines. */
       return CMD_SUCCESS; 
@@ -175,7 +175,7 @@
   getl_set_prompt_style (GETL_PROMPT_LATER);
 
   /* Parse the command name. */
-  command = parse_command_name ();
+  command = parse_command_name (lexer);
   if (command == NULL)
     return CMD_FAILURE;
   else if (command->function == NULL) 
@@ -203,7 +203,7 @@
   /* Execute command. */
   msg_set_command_name (command->name);
   tab_set_command_name (command->name);
-  result = command->function (ds);
+  result = command->function (lexer, ds);
   tab_set_command_name (NULL);
   msg_set_command_name (NULL);
     
@@ -441,10 +441,10 @@
 /* Flags an error that the command whose name is given by the
    WORD_CNT words in WORDS is unknown. */
 static void
-unknown_command_error (char *const words[], size_t word_cnt) 
+unknown_command_error (struct lexer *lexer, char *const words[], size_t word_cnt) 
 {
   if (word_cnt == 0) 
-    lex_error (_("expecting command name"));
+    lex_error (lexer, _("expecting command name"));
   else 
     {
       struct string s;
@@ -468,29 +468,30 @@
    struct command if successful.
    If not successful, return a null pointer. */
 static const struct command *
-parse_command_name (void)
+parse_command_name (struct lexer *lexer)
 {
   char *words[16];
   int word_cnt;
   int complete_word_cnt;
   int dash_possible;
 
-  if (token == T_EXP || token == '*' || token == '[') 
+  if (lex_token (lexer) == T_EXP || 
+		  lex_token (lexer) == '*' || lex_token (lexer) == '[') 
     return find_command ("COMMENT");
 
   dash_possible = 0;
   word_cnt = complete_word_cnt = 0;
-  while (token == T_ID || (dash_possible && token == '-')) 
+  while (lex_token (lexer) == T_ID || (dash_possible && lex_token (lexer) == '-')) 
     {
       int cmd_match_cnt;
       
       assert (word_cnt < sizeof words / sizeof *words);
-      if (token == T_ID) 
+      if (lex_token (lexer) == T_ID) 
         {
-          words[word_cnt] = ds_xstrdup (&tokstr);
+          words[word_cnt] = ds_xstrdup (lex_tokstr (lexer));
           str_uppercase (words[word_cnt]); 
         }
-      else if (token == '-')
+      else if (lex_token (lexer) == '-')
         words[word_cnt] = xstrdup ("-");
       word_cnt++;
 
@@ -504,7 +505,7 @@
           if (command != NULL) 
             {
               if (!(command->flags & F_KEEP_FINAL_TOKEN))
-                lex_get ();
+                lex_get (lexer);
               free_words (words, word_cnt);
               return command;
             }
@@ -515,7 +516,7 @@
           if (get_complete_match (words, word_cnt) != NULL)
             complete_word_cnt = word_cnt;
         }
-      lex_get ();
+      lex_get (lexer);
     }
 
   /* If we saw a complete command name earlier, drop back to
@@ -542,9 +543,9 @@
         {
           word_cnt--;
           if (strcmp (words[word_cnt], "-")) 
-            lex_put_back_id (words[word_cnt]);
+            lex_put_back_id (lexer, words[word_cnt]);
           else
-            lex_put_back ('-');
+            lex_put_back (lexer, '-');
           free (words[word_cnt]);
         }
 
@@ -553,7 +554,7 @@
     }
 
   /* We didn't get a valid command name. */
-  unknown_command_error (words, word_cnt);
+  unknown_command_error (lexer, words, word_cnt);
   free_words (words, word_cnt);
   return NULL;
 }
@@ -649,40 +650,40 @@
 
 /* Parse and execute FINISH command. */
 int
-cmd_finish (struct dataset *ds UNUSED)
+cmd_finish (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   return CMD_FINISH;
 }
 
 /* Parses the N command. */
 int
-cmd_n_of_cases (struct dataset *ds)
+cmd_n_of_cases (struct lexer *lexer, struct dataset *ds)
 {
   /* Value for N. */
   int x;
 
-  if (!lex_force_int ())
+  if (!lex_force_int (lexer))
     return CMD_FAILURE;
-  x = lex_integer ();
-  lex_get ();
-  if (!lex_match_id ("ESTIMATED"))
+  x = lex_integer (lexer);
+  lex_get (lexer);
+  if (!lex_match_id (lexer, "ESTIMATED"))
     dict_set_case_limit (dataset_dict (ds), x);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses, performs the EXECUTE procedure. */
 int
-cmd_execute (struct dataset *ds)
+cmd_execute (struct lexer *lexer, struct dataset *ds)
 {
   if (!procedure (ds, NULL, NULL))
     return CMD_CASCADING_FAILURE;
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses, performs the ERASE command. */
 int
-cmd_erase (struct dataset *ds UNUSED)
+cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   if (get_safer_mode ()) 
     { 
@@ -690,16 +691,16 @@
       return CMD_FAILURE; 
     } 
   
-  if (!lex_force_match_id ("FILE"))
+  if (!lex_force_match_id (lexer, "FILE"))
     return CMD_FAILURE;
-  lex_match ('=');
-  if (!lex_force_string ())
+  lex_match (lexer, '=');
+  if (!lex_force_string (lexer))
     return CMD_FAILURE;
 
-  if (remove (ds_cstr (&tokstr)) == -1)
+  if (remove (ds_cstr (lex_tokstr (lexer))) == -1)
     {
       msg (SW, _("Error removing `%s': %s."),
-	   ds_cstr (&tokstr), strerror (errno));
+	   ds_cstr (lex_tokstr (lexer)), strerror (errno));
       return CMD_FAILURE;
     }
 
@@ -763,27 +764,27 @@
 /* Parses the HOST command argument and executes the specified
    command.  Returns a suitable command return code. */
 static int
-run_command (void)
+run_command (struct lexer *lexer)
 {
   const char *cmd;
   int string;
 
   /* Handle either a string argument or a full-line argument. */
   {
-    int c = lex_look_ahead ();
+    int c = lex_look_ahead (lexer);
 
     if (c == '\'' || c == '"')
       {
-	lex_get ();
-	if (!lex_force_string ())
+	lex_get (lexer);
+	if (!lex_force_string (lexer))
 	  return CMD_FAILURE;
-	cmd = ds_cstr (&tokstr);
+	cmd = ds_cstr (lex_tokstr (lexer));
 	string = 1;
       }
     else
       {
-	cmd = lex_rest_of_line (NULL);
-        lex_discard_line ();
+	cmd = lex_rest_of_line (lexer, NULL);
+        lex_discard_line (lexer);
 	string = 0;
       }
   }
@@ -795,23 +796,21 @@
   /* Finish parsing. */
   if (string)
     {
-      lex_get ();
+      lex_get (lexer);
 
-      if (token != '.')
+      if (lex_token (lexer) != '.')
 	{
-	  lex_error (_("expecting end of command"));
+	  lex_error (lexer, _("expecting end of command"));
 	  return CMD_FAILURE;
 	}
     }
-  else
-    token = '.';
 
   return CMD_SUCCESS;
 }
 
 /* Parses, performs the HOST command. */
 int
-cmd_host (struct dataset *ds UNUSED)
+cmd_host (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   int code;
 
@@ -824,18 +823,18 @@
 #ifdef unix
   /* Figure out whether to invoke an interactive shell or to execute a
      single shell command. */
-  if (lex_look_ahead () == '.')
+  if (lex_look_ahead (lexer) == '.')
     {
-      lex_get ();
+      lex_get (lexer);
       code = shell () ? CMD_FAILURE : CMD_SUCCESS;
     }
   else
-    code = run_command ();
+    code = run_command (lexer);
 #else /* !unix */
   /* Make sure that the system has a command interpreter, then run a
      command. */
   if (system (NULL) != 0)
-    code = run_command ();
+    code = run_command (lexer);
   else
     {
       msg (SE, _("No operating system support for this command."));
@@ -848,17 +847,17 @@
 
 /* Parses, performs the NEW FILE command. */
 int
-cmd_new_file (struct dataset *ds)
+cmd_new_file (struct lexer *lexer, struct dataset *ds)
 {
   discard_variables (ds);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses a comment. */
 int
-cmd_comment (struct dataset *ds UNUSED)
+cmd_comment (struct lexer *lexer, struct dataset *ds UNUSED)
 {
-  lex_skip_comment ();
+  lex_skip_comment (lexer);
   return CMD_SUCCESS;
 }
Index: src/language/command.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/command.h,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 command.h
--- src/language/command.h	26 Oct 2006 06:16:36 -0000	1.6
+++ src/language/command.h	11 Nov 2006 00:13:11 -0000
@@ -55,7 +55,9 @@
   };
 
 struct dataset;
-enum cmd_result cmd_parse (struct dataset *ds, enum cmd_state);
+struct lexer; 
+
+enum cmd_result cmd_parse (struct lexer *lexer, struct dataset *ds, enum cmd_state);
 
 struct command;
 const char *cmd_complete (const char *, const struct command **);
@@ -63,7 +65,7 @@
 struct dataset;
 
 /* Prototype all the command functions. */
-#define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) int FUNCTION (struct dataset *);
+#define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) int FUNCTION (struct lexer *, struct dataset *);
 #define UNIMPL_CMD(NAME, DESCRIPTION)
 #include "command.def"
 #undef DEF_CMD
Index: src/language/control/do-if.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/do-if.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 do-if.c
--- src/language/control/do-if.c	26 Oct 2006 06:16:36 -0000	1.9
+++ src/language/control/do-if.c	11 Nov 2006 00:13:11 -0000
@@ -83,7 +83,7 @@
 
 static const struct ctl_class do_if_class;
 
-static int parse_clause (struct do_if_trns *, struct dataset *ds);
+static int parse_clause (struct lexer *, struct do_if_trns *, struct dataset *ds);
 static void add_clause (struct do_if_trns *,
                         struct expression *condition, int target_index);
 static void add_else (struct do_if_trns *);
@@ -98,7 +98,7 @@
 
 /* Parse DO IF. */
 int
-cmd_do_if (struct dataset *ds)
+cmd_do_if (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = xmalloc (sizeof *do_if);
   do_if->clauses = NULL;
@@ -109,34 +109,34 @@
   add_transformation_with_finalizer (ds, do_if_finalize_func,
                                      do_if_trns_proc, do_if_trns_free, do_if);
 
-  return parse_clause (do_if, ds);
+  return parse_clause (lexer, do_if, ds);
 }
 
 /* Parse ELSE IF. */
 int
-cmd_else_if (struct dataset *ds)
+cmd_else_if (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = ctl_stack_top (&do_if_class);
   if (do_if == NULL || !must_not_have_else (do_if))
     return CMD_CASCADING_FAILURE;
-  return parse_clause (do_if, ds);
+  return parse_clause (lexer, do_if, ds);
 }
 
 /* Parse ELSE. */
 int
-cmd_else (struct dataset *ds)
+cmd_else (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = ctl_stack_top (&do_if_class);
   assert (ds == do_if->ds);
   if (do_if == NULL || !must_not_have_else (do_if))
     return CMD_CASCADING_FAILURE;
   add_else (do_if);
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parse END IF. */
 int
-cmd_end_if (struct dataset *ds)
+cmd_end_if (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = ctl_stack_top (&do_if_class);
   assert (ds == do_if->ds);
@@ -146,7 +146,7 @@
 
   ctl_stack_pop (do_if);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Closes out DO_IF, by adding a sentinel ELSE clause if
@@ -197,17 +197,17 @@
    corresponding clause to DO_IF.  Checks for end of command and
    returns a command return code. */
 static int
-parse_clause (struct do_if_trns *do_if, struct dataset *ds)
+parse_clause (struct lexer *lexer, struct do_if_trns *do_if, struct dataset *ds)
 {
   struct expression *condition;
 
-  condition = expr_parse (ds, EXPR_BOOLEAN);
+  condition = expr_parse (lexer, ds, EXPR_BOOLEAN);
   if (condition == NULL)
     return CMD_CASCADING_FAILURE;
 
   add_clause (do_if, condition, next_transformation (ds));
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Adds a clause to DO_IF that tests for the given CONDITION and,
Index: src/language/control/loop.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/loop.c,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 loop.c
--- src/language/control/loop.c	26 Oct 2006 06:16:36 -0000	1.10
+++ src/language/control/loop.c	11 Nov 2006 00:13:12 -0000
@@ -87,27 +87,27 @@
 static trns_free_func loop_trns_free;
 
 static struct loop_trns *create_loop_trns (struct dataset *);
-static bool parse_if_clause (struct loop_trns *, struct expression **);
-static bool parse_index_clause (struct loop_trns *, char index_var_name[]);
+static bool parse_if_clause (struct lexer *, struct loop_trns *, struct expression **);
+static bool parse_index_clause (struct lexer *, struct loop_trns *, char index_var_name[]);
 static void close_loop (void *);
 
 /* LOOP. */
 
 /* Parses LOOP. */
 int
-cmd_loop (struct dataset *ds)
+cmd_loop (struct lexer *lexer, struct dataset *ds)
 {
   struct loop_trns *loop;
   char index_var_name[LONG_NAME_LEN + 1];
   bool ok = true;
 
   loop = create_loop_trns (ds);
-  while (token != '.' && ok) 
+  while (lex_token (lexer) != '.' && ok) 
     {
-      if (lex_match_id ("IF")) 
-        ok = parse_if_clause (loop, &loop->loop_condition);
+      if (lex_match_id (lexer, "IF")) 
+        ok = parse_if_clause (lexer, loop, &loop->loop_condition);
       else
-        ok = parse_index_clause (loop, index_var_name);
+        ok = parse_index_clause (lexer, loop, index_var_name);
     }
 
   /* Find index variable and create if necessary. */
@@ -126,7 +126,7 @@
 
 /* Parses END LOOP. */
 int
-cmd_end_loop (struct dataset *ds)
+cmd_end_loop (struct lexer *lexer, struct dataset *ds)
 {
   struct loop_trns *loop;
   bool ok = true;
@@ -138,10 +138,10 @@
   assert (loop->ds == ds);
   
   /* Parse syntax. */
-  if (lex_match_id ("IF"))
-    ok = parse_if_clause (loop, &loop->end_loop_condition);
+  if (lex_match_id (lexer, "IF"))
+    ok = parse_if_clause (lexer, loop, &loop->end_loop_condition);
   if (ok)
-    ok = lex_end_of_command () == CMD_SUCCESS;
+    ok = lex_end_of_command (lexer) == CMD_SUCCESS;
 
   if (!ok)
     loop->max_pass_count = 0;
@@ -153,7 +153,7 @@
 
 /* Parses BREAK. */
 int
-cmd_break (struct dataset *ds)
+cmd_break (struct lexer *lexer, struct dataset *ds)
 {
   struct ctl_stmt *loop = ctl_stack_search (&loop_class);
   if (loop == NULL)
@@ -161,7 +161,7 @@
 
   add_transformation (ds, break_trns_proc, NULL, loop);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Closes a LOOP construct by emitting the END LOOP
@@ -187,9 +187,10 @@
    resulting expression to *CONDITION.
    Returns true if successful, false on failure. */
 static bool
-parse_if_clause (struct loop_trns *loop, struct expression **condition) 
+parse_if_clause (struct lexer *lexer, 
+		 struct loop_trns *loop, struct expression **condition) 
 {
-  *condition = expr_parse_pool (loop->pool, loop->ds, EXPR_BOOLEAN);
+  *condition = expr_parse_pool (lexer, loop->pool, loop->ds, EXPR_BOOLEAN);
   return *condition != NULL;
 }
 
@@ -197,29 +198,30 @@
    Stores the index variable's name in INDEX_VAR_NAME[].
    Returns true if successful, false on failure. */
 static bool
-parse_index_clause (struct loop_trns *loop, char index_var_name[]) 
+parse_index_clause (struct lexer *lexer, struct loop_trns *loop, char index_var_name[]) 
 {
-  if (token != T_ID) 
+  if (lex_token (lexer) != T_ID) 
     {
-      lex_error (NULL);
+      lex_error (lexer, NULL);
       return false;
     }
-  strcpy (index_var_name, tokid);
-  lex_get ();
+  strcpy (index_var_name, lex_tokid (lexer));
+  lex_get (lexer);
 
-  if (!lex_force_match ('='))
+  if (!lex_force_match (lexer, '='))
     return false;
 
-  loop->first_expr = expr_parse_pool (loop->pool, loop->ds, EXPR_NUMBER);
+  loop->first_expr = expr_parse_pool (lexer, loop->pool, 
+				      loop->ds, EXPR_NUMBER);
   if (loop->first_expr == NULL)
     return false;
 
   for (;;)
     {
       struct expression **e;
-      if (lex_match (T_TO)) 
+      if (lex_match (lexer, T_TO)) 
         e = &loop->last_expr;
-      else if (lex_match (T_BY)) 
+      else if (lex_match (lexer, T_BY)) 
         e = &loop->by_expr;
       else
         break;
@@ -229,13 +231,13 @@
           lex_sbc_only_once (e == &loop->last_expr ? "TO" : "BY");
           return false;
         }
-      *e = expr_parse_pool (loop->pool, loop->ds, EXPR_NUMBER);
+      *e = expr_parse_pool (lexer, loop->pool, loop->ds, EXPR_NUMBER);
       if (*e == NULL)
         return false;
     }
   if (loop->last_expr == NULL) 
     {
-      lex_sbc_missing ("TO");
+      lex_sbc_missing (lexer, "TO");
       return false;
     }
   if (loop->by_expr == NULL)
Index: src/language/control/repeat.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/repeat.c,v
retrieving revision 1.14
diff -b -w -U3 -r1.14 repeat.c
--- src/language/control/repeat.c	28 Oct 2006 08:31:23 -0000	1.14
+++ src/language/control/repeat.c	11 Nov 2006 00:13:12 -0000
@@ -83,13 +83,13 @@
     bool print;                         /* Print lines as executed? */
   };
 
-static bool parse_specification (struct repeat_block *);
-static bool parse_lines (struct repeat_block *);
+static bool parse_specification (struct lexer *, struct repeat_block *);
+static bool parse_lines (struct lexer *, struct repeat_block *);
 static void create_vars (struct repeat_block *);
 
-static int parse_ids (const struct dictionary *dict, struct repeat_entry *, struct pool *);
-static int parse_numbers (struct repeat_entry *, struct pool *);
-static int parse_strings (struct repeat_entry *, struct pool *);
+static int parse_ids (struct lexer *, const struct dictionary *dict, struct repeat_entry *, struct pool *);
+static int parse_numbers (struct lexer *, struct repeat_entry *, struct pool *);
+static int parse_strings (struct lexer *, struct repeat_entry *, struct pool *);
 
 static void do_repeat_filter (struct string *line, void *block);
 static bool do_repeat_read (struct string *line, char **file_name,
@@ -97,14 +97,14 @@
 static void do_repeat_close (void *block);
 
 int
-cmd_do_repeat (struct dataset *ds)
+cmd_do_repeat (struct lexer *lexer, struct dataset *ds)
 {
   struct repeat_block *block;
 
   block = pool_create_container (struct repeat_block, pool);
   block->ds = ds;
 
-  if (!parse_specification (block) || !parse_lines (block))
+  if (!parse_specification (lexer, block) || !parse_lines (lexer, block))
     goto error;
   
   create_vars (block);
@@ -124,7 +124,7 @@
 /* Parses the whole DO REPEAT command specification.
    Returns success. */
 static bool
-parse_specification (struct repeat_block *block) 
+parse_specification (struct lexer *lexer, struct repeat_block *block) 
 {
   char first_name[LONG_NAME_LEN + 1];
 
@@ -138,16 +138,16 @@
       int count;
 
       /* Get a stand-in variable name and make sure it's unique. */
-      if (!lex_force_id ())
+      if (!lex_force_id (lexer))
 	return false;
-      if (dict_lookup_var (dict, tokid))
+      if (dict_lookup_var (dict, lex_tokid (lexer)))
         msg (SW, _("Dummy variable name \"%s\" hides dictionary "
                    "variable \"%s\"."),
-             tokid, tokid);
+             lex_tokid (lexer), lex_tokid (lexer));
       for (iter = block->macros; iter != NULL; iter = iter->next)
-	if (!strcasecmp (iter->id, tokid))
+	if (!strcasecmp (iter->id, lex_tokid (lexer)))
 	  {
-	    msg (SE, _("Dummy variable name \"%s\" is given twice."), tokid);
+	    msg (SE, _("Dummy variable name \"%s\" is given twice."), lex_tokid (lexer));
 	    return false;
 	  }
 
@@ -155,31 +155,31 @@
          list. */
       e = pool_alloc (block->pool, sizeof *e);
       e->next = block->macros;
-      strcpy (e->id, tokid);
+      strcpy (e->id, lex_tokid (lexer));
       block->macros = e;
 
       /* Skip equals sign. */
-      lex_get ();
-      if (!lex_force_match ('='))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, '='))
 	return false;
 
       /* Get the details of the variable's possible values. */
-      if (token == T_ID)
-	count = parse_ids (dict, e, block->pool);
-      else if (lex_is_number ())
-	count = parse_numbers (e, block->pool);
-      else if (token == T_STRING)
-	count = parse_strings (e, block->pool);
+      if (lex_token (lexer) == T_ID)
+	count = parse_ids (lexer, dict, e, block->pool);
+      else if (lex_is_number (lexer))
+	count = parse_numbers (lexer, e, block->pool);
+      else if (lex_token (lexer) == T_STRING)
+	count = parse_strings (lexer, e, block->pool);
       else
 	{
-	  lex_error (NULL);
+	  lex_error (lexer, NULL);
 	  return false;
 	}
       if (count == 0)
 	return false;
-      if (token != '/' && token != '.') 
+      if (lex_token (lexer) != '/' && lex_token (lexer) != '.') 
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return false;
         }
 
@@ -200,9 +200,9 @@
 	  return false;
 	}
 
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
 
   return true;
 }
@@ -265,7 +265,7 @@
 /* Read all the lines we are going to substitute, inside the DO
    REPEAT...END REPEAT block. */
 static bool
-parse_lines (struct repeat_block *block) 
+parse_lines (struct lexer *lexer, struct repeat_block *block) 
 {
   char *previous_file_name;
   struct line_list **last_line;
@@ -284,7 +284,7 @@
       struct string cur_line_copy;
       bool dot;
 
-      if (! lex_get_line_raw ())
+      if (! lex_get_line_raw (lexer))
         return false;
 
       /* If the current file has changed then record the fact. */
@@ -293,7 +293,7 @@
           || !strcmp (cur_file_name, previous_file_name))
         previous_file_name = pool_strdup (block->pool, cur_file_name);
 
-      ds_init_string (&cur_line_copy, lex_entire_line_ds () );
+      ds_init_string (&cur_line_copy, lex_entire_line_ds (lexer) );
       ds_rtrim (&cur_line_copy, ss_cstr (CC_SPACES));
       dot = ds_chomp (&cur_line_copy, get_endcmd ());
 
@@ -303,7 +303,7 @@
         {
         if (nesting_level-- == 0)
           {
-            lex_discard_line ();
+            lex_discard_line (lexer);
 	    ds_destroy (&cur_line_copy);
             return true;
           } 
@@ -321,7 +321,7 @@
       ds_destroy (&cur_line_copy);
     }
 
-  lex_discard_line ();
+  lex_discard_line (lexer);
   return true;
 }
 
@@ -347,11 +347,13 @@
 
 /* Parses a set of ids for DO REPEAT. */
 static int
-parse_ids (const struct dictionary *dict, struct repeat_entry *e, struct pool *pool)
+parse_ids (struct lexer *lexer, const struct dictionary *dict, 
+	   struct repeat_entry *e, struct pool *pool)
 {
   size_t n = 0;
   e->type = VAR_NAMES;
-  return parse_mixed_vars_pool (dict, pool, &e->replacement, &n, PV_NONE) ? n : 0;
+  return parse_mixed_vars_pool (lexer, dict, pool, 
+				&e->replacement, &n, PV_NONE) ? n : 0;
 }
 
 /* Adds STRING to E's list of replacements, which has *USED
@@ -370,7 +372,7 @@
 
 /* Parses a list of numbers for DO REPEAT. */
 static int
-parse_numbers (struct repeat_entry *e, struct pool *pool)
+parse_numbers (struct lexer *lexer, struct repeat_entry *e, struct pool *pool)
 {
   size_t used = 0;
   size_t allocated = 0;
@@ -383,23 +385,23 @@
       long a, b, i;
 
       /* Parse A TO B into a, b. */
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	return 0;
-      a = lex_integer ();
+      a = lex_integer (lexer);
 
-      lex_get ();
-      if (token == T_TO)
+      lex_get (lexer);
+      if (lex_token (lexer) == T_TO)
 	{
-	  lex_get ();
-	  if (!lex_force_int ())
+	  lex_get (lexer);
+	  if (!lex_force_int (lexer))
 	    return 0;
-	  b = lex_integer ();
+	  b = lex_integer (lexer);
           if (b < a) 
             {
               msg (SE, _("%ld TO %ld is an invalid range."), a, b);
               return 0;
             }
-	  lex_get ();
+	  lex_get (lexer);
 	}
       else
         b = a;
@@ -409,16 +411,16 @@
                          e, pool, &used, &allocated);
 
 
-      lex_match (',');
+      lex_match (lexer, ',');
     }
-  while (token != '/' && token != '.');
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
   return used;
 }
 
 /* Parses a list of strings for DO REPEAT. */
 int
-parse_strings (struct repeat_entry *e, struct pool *pool)
+parse_strings (struct lexer *lexer, struct repeat_entry *e, struct pool *pool)
 {
   size_t used = 0;
   size_t allocated = 0;
@@ -430,26 +432,26 @@
     {
       char *string;
       
-      if (token != T_STRING)
+      if (lex_token (lexer) != T_STRING)
 	{
 	  msg (SE, _("String expected."));
 	  return 0;
 	}
 
-      string = lex_token_representation ();
+      string = lex_token_representation (lexer);
       pool_register (pool, free, string);
       add_replacement (string, e, pool, &used, &allocated);
 
-      lex_get ();
-      lex_match (',');
+      lex_get (lexer);
+      lex_match (lexer, ',');
     }
-  while (token != '/' && token != '.');
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
   return used;
 }
 
 int
-cmd_end_repeat (struct dataset *ds UNUSED)
+cmd_end_repeat (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   msg (SE, _("No matching DO REPEAT."));
   return CMD_CASCADING_FAILURE;
Index: src/language/control/temporary.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/temporary.c,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 temporary.c
--- src/language/control/temporary.c	26 Oct 2006 06:16:36 -0000	1.6
+++ src/language/control/temporary.c	11 Nov 2006 00:13:12 -0000
@@ -41,12 +41,12 @@
 
 /* Parses the TEMPORARY command. */
 int
-cmd_temporary (struct dataset *ds)
+cmd_temporary (struct lexer *lexer, struct dataset *ds)
 {
   if (!proc_in_temporary_transformations (ds))
     proc_start_temporary_transformations (ds);
   else
     msg (SE, _("This command may only appear once between "
                "procedures and procedure-like commands."));
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
Index: src/language/data-io/data-list.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/data-list.c,v
retrieving revision 1.23
diff -b -w -U3 -r1.23 data-list.c
--- src/language/data-io/data-list.c	3 Nov 2006 04:53:51 -0000	1.23
+++ src/language/data-io/data-list.c	11 Nov 2006 00:13:12 -0000
@@ -103,9 +103,9 @@
 
 static const struct case_source_class data_list_source_class;
 
-static bool parse_fixed (struct dictionary *dict, 
+static bool parse_fixed (struct lexer *, struct dictionary *dict, 
 			 struct pool *tmp_pool, struct data_list_pgm *);
-static bool parse_free (struct dictionary *dict, 
+static bool parse_free (struct lexer *, struct dictionary *dict, 
 			struct pool *tmp_pool, struct data_list_pgm *);
 static void dump_fixed_table (const struct ll_list *,
                               const struct file_handle *, int record_cnt);
@@ -116,7 +116,7 @@
 static trns_proc_func data_list_trns_proc;
 
 int
-cmd_data_list (struct dataset *ds)
+cmd_data_list (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct data_list_pgm *dls;
@@ -139,26 +139,26 @@
 
   tmp_pool = pool_create_subpool (dls->pool);
 
-  while (token != '/')
+  while (lex_token (lexer) != '/')
     {
-      if (lex_match_id ("FILE"))
+      if (lex_match_id (lexer, "FILE"))
 	{
-	  lex_match ('=');
-	  fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
+	  lex_match (lexer, '=');
+	  fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
 	  if (fh == NULL)
 	    goto error;
 	}
-      else if (lex_match_id ("RECORDS"))
+      else if (lex_match_id (lexer, "RECORDS"))
 	{
-	  lex_match ('=');
-	  lex_match ('(');
-	  if (!lex_force_int ())
+	  lex_match (lexer, '=');
+	  lex_match (lexer, '(');
+	  if (!lex_force_int (lexer))
 	    goto error;
-	  dls->record_cnt = lex_integer ();
-	  lex_get ();
-	  lex_match (')');
+	  dls->record_cnt = lex_integer (lexer);
+	  lex_get (lexer);
+	  lex_match (lexer, ')');
 	}
-      else if (lex_match_id ("END"))
+      else if (lex_match_id (lexer, "END"))
 	{
 	  if (dls->end)
 	    {
@@ -166,32 +166,32 @@
 	      goto error;
 	    }
 	  
-	  lex_match ('=');
-	  if (!lex_force_id ())
+	  lex_match (lexer, '=');
+	  if (!lex_force_id (lexer))
 	    goto error;
-	  dls->end = dict_lookup_var (dataset_dict (ds), tokid);
+	  dls->end = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer));
 	  if (!dls->end) 
-            dls->end = dict_create_var_assert (dataset_dict (ds), tokid, 0);
-	  lex_get ();
+            dls->end = dict_create_var_assert (dataset_dict (ds), lex_tokid (lexer), 0);
+	  lex_get (lexer);
 	}
-      else if (token == T_ID)
+      else if (lex_token (lexer) == T_ID)
 	{
-          if (lex_match_id ("NOTABLE"))
+          if (lex_match_id (lexer, "NOTABLE"))
             table = 0;
-          else if (lex_match_id ("TABLE"))
+          else if (lex_match_id (lexer, "TABLE"))
             table = 1;
           else 
             {
               int type;
-              if (lex_match_id ("FIXED"))
+              if (lex_match_id (lexer, "FIXED"))
                 type = DLS_FIXED;
-              else if (lex_match_id ("FREE"))
+              else if (lex_match_id (lexer, "FREE"))
                 type = DLS_FREE;
-              else if (lex_match_id ("LIST"))
+              else if (lex_match_id (lexer, "LIST"))
                 type = DLS_LIST;
               else 
                 {
-                  lex_error (NULL);
+                  lex_error (lexer, NULL);
                   goto error;
                 }
 
@@ -204,35 +204,35 @@
 	      dls->type = type;
 
               if ((dls->type == DLS_FREE || dls->type == DLS_LIST)
-                  && lex_match ('(')) 
+                  && lex_match (lexer, '(')) 
                 {
-                  while (!lex_match (')'))
+                  while (!lex_match (lexer, ')'))
                     {
                       int delim;
 
-                      if (lex_match_id ("TAB"))
+                      if (lex_match_id (lexer, "TAB"))
                         delim = '\t';
-                      else if (token == T_STRING && ds_length (&tokstr) == 1)
+                      else if (lex_token (lexer) == T_STRING && ds_length (lex_tokstr (lexer)) == 1)
 			{
-			  delim = ds_first (&tokstr);
-			  lex_get ();
+			  delim = ds_first (lex_tokstr (lexer));
+			  lex_get (lexer);
 			}
                       else 
                         {
-                          lex_error (NULL);
+                          lex_error (lexer, NULL);
                           goto error;
                         }
 
                       ds_put_char (&dls->delims, delim);
 
-                      lex_match (',');
+                      lex_match (lexer, ',');
                     }
                 }
             }
         }
       else
 	{
-	  lex_error (NULL);
+	  lex_error (lexer, NULL);
 	  goto error;
 	}
     }
@@ -245,11 +245,11 @@
   if (table == -1)
     table = dls->type != DLS_FREE;
 
-  ok = (dls->type == DLS_FIXED ? parse_fixed : parse_free) (dict, tmp_pool, dls);
+  ok = (dls->type == DLS_FIXED ? parse_fixed : parse_free) (lexer, dict, tmp_pool, dls);
   if (!ok)
     goto error;
 
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto error;
 
   if (table)
@@ -260,7 +260,7 @@
 	dump_free_table (dls, fh);
     }
 
-  dls->reader = dfm_open_reader (fh);
+  dls->reader = dfm_open_reader (fh, lexer);
   if (dls->reader == NULL)
     goto error;
 
@@ -285,14 +285,14 @@
    needed once parsing is complete.  Returns true only if
    successful. */
 static bool
-parse_fixed (struct dictionary *dict, 
+parse_fixed (struct lexer *lexer, struct dictionary *dict, 
 	     struct pool *tmp_pool, struct data_list_pgm *dls)
 {
   int last_nonempty_record;
   int record = 0;
   int column = 1;
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
       char **names;
       size_t name_cnt, name_idx;
@@ -300,9 +300,10 @@
       size_t format_cnt;
 
       /* Parse everything. */
-      if (!parse_record_placement (&record, &column)
-          || !parse_DATA_LIST_vars_pool (tmp_pool, &names, &name_cnt, PV_NONE)
-          || !parse_var_placements (tmp_pool, name_cnt, true,
+      if (!parse_record_placement (lexer, &record, &column)
+          || !parse_DATA_LIST_vars_pool (lexer, tmp_pool, 
+					 &names, &name_cnt, PV_NONE)
+          || !parse_var_placements (lexer, tmp_pool, name_cnt, true,
                                     &formats, &format_cnt))
         return false;
 
@@ -437,30 +438,32 @@
    them to DLS.  Uses TMP_POOL for data that is not needed once
    parsing is complete.  Returns true only if successful. */
 static bool
-parse_free (struct dictionary *dict, struct pool *tmp_pool, struct data_list_pgm *dls)
+parse_free (struct lexer *lexer, struct dictionary *dict, struct pool *tmp_pool, 
+		struct data_list_pgm *dls)
 {
-  lex_get ();
-  while (token != '.')
+  lex_get (lexer);
+  while (lex_token (lexer) != '.')
     {
       struct fmt_spec input, output;
       char **name;
       size_t name_cnt;
       size_t i;
 
-      if (!parse_DATA_LIST_vars_pool (tmp_pool, &name, &name_cnt, PV_NONE))
+      if (!parse_DATA_LIST_vars_pool (lexer, tmp_pool, 
+				      &name, &name_cnt, PV_NONE))
 	return 0;
 
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
 	{
-	  if (!parse_format_specifier (&input)
+	  if (!parse_format_specifier (lexer, &input)
               || !fmt_check_input (&input)
-              || !lex_force_match (')')) 
+              || !lex_force_match (lexer, ')')) 
             return NULL;
 	  output = fmt_for_output_from_input (&input);
 	}
       else
 	{
-	  lex_match ('*');
+	  lex_match (lexer, '*');
           input = fmt_for_input (FMT_F, 8, 0);
 	  output = *get_format ();
 	}
Index: src/language/data-io/data-reader.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/data-reader.c,v
retrieving revision 1.15
diff -b -w -U3 -r1.15 data-reader.c
--- src/language/data-io/data-reader.c	28 Oct 2006 08:31:23 -0000	1.15
+++ src/language/data-io/data-reader.c	11 Nov 2006 00:13:12 -0000
@@ -64,6 +64,7 @@
     FILE *file;                 /* Associated file. */
     size_t pos;                 /* Offset in line of current character. */
     unsigned eof_cnt;           /* # of attempts to advance past EOF. */
+    struct lexer *lexer;        /* The lexer reading the file */
   };
 
 /* Closes reader R opened by dfm_open_reader(). */
@@ -111,7 +112,7 @@
    file between BEGIN FILE and END FILE.  Returns a reader if
    successful, or a null pointer otherwise. */
 struct dfm_reader *
-dfm_open_reader (struct file_handle *fh)
+dfm_open_reader (struct file_handle *fh, struct lexer *lexer)
 {
   struct dfm_reader *r;
   void **rp;
@@ -124,6 +125,7 @@
   
   r = xmalloc (sizeof *r);
   r->fh = fh;
+  r->lexer = lexer ;
   ds_init_empty (&r->line);
   ds_init_empty (&r->scratch);
   r->flags = DFM_ADVANCE;
@@ -163,14 +165,14 @@
     {
       r->flags |= DFM_SAW_BEGIN_DATA;
 
-      while (token == '.')
-        lex_get ();
-      if (!lex_force_match_id ("BEGIN") || !lex_force_match_id ("DATA"))
+      while (lex_token (r->lexer) == '.')
+        lex_get (r->lexer);
+      if (!lex_force_match_id (r->lexer, "BEGIN") || !lex_force_match_id (r->lexer, "DATA"))
         return false;
       getl_set_prompt_style (GETL_PROMPT_DATA);
     }
       
-  if (!lex_get_line_raw ())
+  if (!lex_get_line_raw (r->lexer))
     {
       msg (SE, _("Unexpected end-of-file while reading data in BEGIN "
                  "DATA.  This probably indicates "
@@ -180,14 +182,14 @@
       return false;
     }
 
-  if (ds_length (lex_entire_line_ds() ) >= 8
-      && !strncasecmp (lex_entire_line (), "end data", 8))
+  if (ds_length (lex_entire_line_ds (r->lexer) ) >= 8
+      && !strncasecmp (lex_entire_line (r->lexer), "end data", 8))
     {
-      lex_discard_line ();
+      lex_discard_line (r->lexer);
       return false;
     }
 
-  ds_assign_string (&r->line, lex_entire_line_ds () );
+  ds_assign_string (&r->line, lex_entire_line_ds (r->lexer) );
 
   return true;
 }
@@ -424,7 +426,7 @@
 
 /* Perform BEGIN DATA...END DATA as a procedure in itself. */
 int
-cmd_begin_data (struct dataset *ds)
+cmd_begin_data (struct lexer *lexer, struct dataset *ds)
 {
   struct dfm_reader *r;
   bool ok;
@@ -437,7 +439,7 @@
     }
 
   /* Open inline file. */
-  r = dfm_open_reader (fh_inline_file ());
+  r = dfm_open_reader (fh_inline_file (), lexer);
   r->flags |= DFM_SAW_BEGIN_DATA;
 
   /* Input procedure reads from inline file. */
Index: src/language/data-io/data-reader.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/data-reader.h,v
retrieving revision 1.2
diff -b -w -U3 -r1.2 data-reader.h
--- src/language/data-io/data-reader.h	9 Jun 2006 22:51:24 -0000	1.2
+++ src/language/data-io/data-reader.h	11 Nov 2006 00:13:12 -0000
@@ -31,9 +31,10 @@
 
 struct file_handle;
 struct string;
+struct lexer;
 
 /* Input. */
-struct dfm_reader *dfm_open_reader (struct file_handle *);
+struct dfm_reader *dfm_open_reader (struct file_handle *, struct lexer *);
 void dfm_close_reader (struct dfm_reader *);
 bool dfm_reader_error (const struct dfm_reader *);
 unsigned dfm_eof (struct dfm_reader *);
Index: src/language/data-io/file-handle.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/file-handle.h,v
retrieving revision 1.2
diff -b -w -U3 -r1.2 file-handle.h
--- src/language/data-io/file-handle.h	15 Mar 2006 03:29:10 -0000	1.2
+++ src/language/data-io/file-handle.h	11 Nov 2006 00:13:12 -0000
@@ -26,6 +26,7 @@
 #include <stddef.h>
 #include <data/file-handle-def.h>
 
-struct file_handle *fh_parse (enum fh_referent);
+struct lexer ;
+struct file_handle *fh_parse (struct lexer *, enum fh_referent);
 
 #endif /* !file_handle.h */
Index: src/language/data-io/file-handle.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/file-handle.q,v
retrieving revision 1.8
diff -b -w -U3 -r1.8 file-handle.q
--- src/language/data-io/file-handle.q	26 Oct 2006 06:16:36 -0000	1.8
+++ src/language/data-io/file-handle.q	11 Nov 2006 00:13:12 -0000
@@ -51,7 +51,7 @@
 /* (functions) */
 
 int
-cmd_file_handle (struct dataset *ds)
+cmd_file_handle (struct lexer *lexer, struct dataset *ds)
 {
   char handle_name[LONG_NAME_LEN + 1];
   struct fh_properties properties = *fh_default_properties ();
@@ -59,9 +59,9 @@
   struct cmd_file_handle cmd;
   struct file_handle *handle;
 
-  if (!lex_force_id ())
+  if (!lex_force_id (lexer))
     return CMD_CASCADING_FAILURE;
-  str_copy_trunc (handle_name, sizeof handle_name, tokid);
+  str_copy_trunc (handle_name, sizeof handle_name, lex_tokid (lexer));
 
   handle = fh_from_name (handle_name);
   if (handle != NULL)
@@ -72,19 +72,19 @@
       return CMD_CASCADING_FAILURE;
     }
 
-  lex_get ();
-  if (!lex_force_match ('/'))
+  lex_get (lexer);
+  if (!lex_force_match (lexer, '/'))
     return CMD_CASCADING_FAILURE;
 
-  if (!parse_file_handle (ds, &cmd, NULL))
+  if (!parse_file_handle (lexer, ds, &cmd, NULL))
     return CMD_CASCADING_FAILURE;
 
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto lossage;
 
   if (cmd.s_name == NULL && cmd.mode != FH_SCRATCH)
     {
-      lex_sbc_missing ("NAME");
+      lex_sbc_missing (lexer, "NAME");
       goto lossage;
     }
 
@@ -127,13 +127,13 @@
 }
 
 int
-cmd_close_file_handle (struct dataset *ds UNUSED) 
+cmd_close_file_handle (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   struct file_handle *handle;
 
-  if (!lex_force_id ())
+  if (!lex_force_id (lexer))
     return CMD_CASCADING_FAILURE;
-  handle = fh_from_name (tokid);
+  handle = fh_from_name (lex_tokid (lexer));
   if (handle == NULL)
     return CMD_CASCADING_FAILURE;
 
@@ -164,39 +164,39 @@
    file handle are restricted to those in REFERENT_MASK.  Returns
    the file handle when successful, a null pointer on failure. */
 struct file_handle *
-fh_parse (enum fh_referent referent_mask)
+fh_parse (struct lexer *lexer, enum fh_referent referent_mask)
 {
   struct file_handle *handle;
 
-  if (lex_match_id ("INLINE")) 
+  if (lex_match_id (lexer, "INLINE")) 
     handle = fh_inline_file ();
   else 
     {
-      if (token != T_ID && token != T_STRING)
+      if (lex_token (lexer) != T_ID && lex_token (lexer) != T_STRING)
         {
-          lex_error (_("expecting a file name or handle name"));
+          lex_error (lexer, _("expecting a file name or handle name"));
           return NULL;
         }
 
       handle = NULL;
-      if (token == T_ID) 
-        handle = fh_from_name (tokid);
+      if (lex_token (lexer) == T_ID) 
+        handle = fh_from_name (lex_tokid (lexer));
       if (handle == NULL) 
-        handle = fh_from_file_name (ds_cstr (&tokstr)); 
+        handle = fh_from_file_name (ds_cstr (lex_tokstr (lexer))); 
       if (handle == NULL)
         {
-          if (token != T_ID || tokid[0] != '#' || get_syntax () != ENHANCED) 
+          if (lex_token (lexer) != T_ID || lex_tokid (lexer)[0] != '#' || get_syntax () != ENHANCED) 
             {
-              char *file_name = ds_cstr (&tokstr);
+              char *file_name = ds_cstr (lex_tokstr (lexer));
               char *handle_name = xasprintf ("\"%s\"", file_name);
               handle = fh_create_file (handle_name, file_name,
                                        fh_default_properties ());
               free (handle_name);
             }
           else
-            handle = fh_create_scratch (tokid);
+            handle = fh_create_scratch (lex_tokid (lexer));
         }
-      lex_get ();
+      lex_get (lexer);
     }
 
   if (!(fh_get_referent (handle) & referent_mask)) 
Index: src/language/data-io/get.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/get.c,v
retrieving revision 1.20
diff -b -w -U3 -r1.20 get.c
--- src/language/data-io/get.c	3 Nov 2006 04:53:51 -0000	1.20
+++ src/language/data-io/get.c	11 Nov 2006 00:13:13 -0000
@@ -60,7 +60,7 @@
                       const struct ccase *, struct ccase *);
 static void destroy_case_map (struct case_map *);
 
-static bool parse_dict_trim (struct dictionary *);
+static bool parse_dict_trim (struct lexer *, struct dictionary *);
 
 /* Reading system and portable files. */
 
@@ -85,7 +85,7 @@
 
 /* Parses a GET or IMPORT command. */
 static int
-parse_read_command (struct dataset *ds, enum reader_command type)
+parse_read_command (struct lexer *lexer, struct dataset *ds, enum reader_command type)
 {
   struct case_reader_pgm *pgm = NULL;
   struct file_handle *fh = NULL;
@@ -93,27 +93,27 @@
 
   for (;;)
     {
-      lex_match ('/');
+      lex_match (lexer, '/');
 
-      if (lex_match_id ("FILE") || token == T_STRING)
+      if (lex_match_id (lexer, "FILE") || lex_token (lexer) == T_STRING)
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 
-	  fh = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+	  fh = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
 	  if (fh == NULL)
             goto error;
 	}
-      else if (type == IMPORT_CMD && lex_match_id ("TYPE"))
+      else if (type == IMPORT_CMD && lex_match_id (lexer, "TYPE"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 
-	  if (lex_match_id ("COMM"))
+	  if (lex_match_id (lexer, "COMM"))
 	    type = PFM_COMM;
-	  else if (lex_match_id ("TAPE"))
+	  else if (lex_match_id (lexer, "TAPE"))
 	    type = PFM_TAPE;
 	  else
 	    {
-	      lex_error (_("expecting COMM or TAPE"));
+	      lex_error (lexer, _("expecting COMM or TAPE"));
               goto error;
 	    }
 	}
@@ -123,7 +123,7 @@
   
   if (fh == NULL) 
     {
-      lex_sbc_missing ("FILE");
+      lex_sbc_missing (lexer, "FILE");
       goto error;
     }
               
@@ -140,10 +140,10 @@
   
   start_case_map (dict);
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      lex_match ('/');
-      if (!parse_dict_trim (dict))
+      lex_match (lexer, '/');
+      if (!parse_dict_trim (lexer, dict))
         goto error;
     }
 
@@ -227,16 +227,16 @@
 
 /* GET. */
 int
-cmd_get (struct dataset *ds) 
+cmd_get (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_read_command (ds, GET_CMD);
+  return parse_read_command (lexer, ds, GET_CMD);
 }
 
 /* IMPORT. */
 int
-cmd_import (struct dataset *ds) 
+cmd_import (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_read_command (ds, IMPORT_CMD);
+  return parse_read_command (lexer, ds, IMPORT_CMD);
 }
 
 /* Writing system and portable files. */ 
@@ -290,7 +290,7 @@
 
    On failure, returns a null pointer. */
 static struct case_writer *
-parse_write_command (struct dataset *ds, 
+parse_write_command (struct lexer *lexer, struct dataset *ds, 
 		     enum writer_type writer_type,
                      enum command_type command_type,
                      bool *retain_unselected)
@@ -327,10 +327,10 @@
   start_case_map (dict);
   dict_delete_scratch_vars (dict);
 
-  lex_match ('/');
+  lex_match (lexer, '/');
   for (;;)
     {
-      if (lex_match_id ("OUTFILE"))
+      if (lex_match_id (lexer, "OUTFILE"))
 	{
           if (handle != NULL) 
             {
@@ -338,88 +338,88 @@
               goto error; 
             }
           
-	  lex_match ('=');
+	  lex_match (lexer, '=');
       
-	  handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+	  handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
 	  if (handle == NULL)
 	    goto error;
 	}
-      else if (lex_match_id ("NAMES"))
+      else if (lex_match_id (lexer, "NAMES"))
         print_short_names = true;
-      else if (lex_match_id ("PERMISSIONS")) 
+      else if (lex_match_id (lexer, "PERMISSIONS")) 
         {
           bool cw;
           
-          lex_match ('=');
-          if (lex_match_id ("READONLY"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "READONLY"))
             cw = false;
-          else if (lex_match_id ("WRITEABLE"))
+          else if (lex_match_id (lexer, "WRITEABLE"))
             cw = true;
           else
             {
-              lex_error (_("expecting %s or %s"), "READONLY", "WRITEABLE");
+              lex_error (lexer, _("expecting %s or %s"), "READONLY", "WRITEABLE");
               goto error;
             }
           sysfile_opts.create_writeable = porfile_opts.create_writeable = cw;
         }
-      else if (command_type == PROC_CMD && lex_match_id ("UNSELECTED")) 
+      else if (command_type == PROC_CMD && lex_match_id (lexer, "UNSELECTED")) 
         {
-          lex_match ('=');
-          if (lex_match_id ("RETAIN"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "RETAIN"))
             *retain_unselected = true;
-          else if (lex_match_id ("DELETE"))
+          else if (lex_match_id (lexer, "DELETE"))
             *retain_unselected = false;
           else
             {
-              lex_error (_("expecting %s or %s"), "RETAIN", "DELETE");
+              lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
               goto error;
             }
         }
-      else if (writer_type == SYSFILE_WRITER && lex_match_id ("COMPRESSED"))
+      else if (writer_type == SYSFILE_WRITER && lex_match_id (lexer, "COMPRESSED"))
 	sysfile_opts.compress = true;
-      else if (writer_type == SYSFILE_WRITER && lex_match_id ("UNCOMPRESSED"))
+      else if (writer_type == SYSFILE_WRITER && lex_match_id (lexer, "UNCOMPRESSED"))
 	sysfile_opts.compress = false;
-      else if (writer_type == SYSFILE_WRITER && lex_match_id ("VERSION"))
+      else if (writer_type == SYSFILE_WRITER && lex_match_id (lexer, "VERSION"))
 	{
-	  lex_match ('=');
-	  if (!lex_force_int ())
+	  lex_match (lexer, '=');
+	  if (!lex_force_int (lexer))
             goto error;
-          sysfile_opts.version = lex_integer ();
-          lex_get ();
+          sysfile_opts.version = lex_integer (lexer);
+          lex_get (lexer);
 	}
-      else if (writer_type == PORFILE_WRITER && lex_match_id ("TYPE")) 
+      else if (writer_type == PORFILE_WRITER && lex_match_id (lexer, "TYPE")) 
         {
-          lex_match ('=');
-          if (lex_match_id ("COMMUNICATIONS"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "COMMUNICATIONS"))
             porfile_opts.type = PFM_COMM;
-          else if (lex_match_id ("TAPE"))
+          else if (lex_match_id (lexer, "TAPE"))
             porfile_opts.type = PFM_TAPE;
           else
             {
-              lex_error (_("expecting %s or %s"), "COMM", "TAPE");
+              lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
               goto error;
             }
         }
-      else if (writer_type == PORFILE_WRITER && lex_match_id ("DIGITS")) 
+      else if (writer_type == PORFILE_WRITER && lex_match_id (lexer, "DIGITS")) 
         {
-          lex_match ('=');
-          if (!lex_force_int ())
+          lex_match (lexer, '=');
+          if (!lex_force_int (lexer))
             goto error;
-          porfile_opts.digits = lex_integer ();
-          lex_get ();
+          porfile_opts.digits = lex_integer (lexer);
+          lex_get (lexer);
         }
-      else if (!parse_dict_trim (dict))
+      else if (!parse_dict_trim (lexer, dict))
         goto error;
       
-      if (!lex_match ('/'))
+      if (!lex_match (lexer, '/'))
 	break;
     }
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto error;
 
   if (handle == NULL) 
     {
-      lex_sbc_missing ("OUTFILE");
+      lex_sbc_missing (lexer, "OUTFILE");
       goto error;
     }
 
@@ -474,14 +474,14 @@
 
 /* Parses and performs the SAVE or EXPORT procedure. */
 static int
-parse_output_proc (struct dataset *ds, enum writer_type writer_type)
+parse_output_proc (struct lexer *lexer, struct dataset *ds, enum writer_type writer_type)
 {
   bool retain_unselected;
   struct variable *saved_filter_variable;
   struct case_writer *aw;
   bool ok;
 
-  aw = parse_write_command (ds, writer_type, PROC_CMD, &retain_unselected);
+  aw = parse_write_command (lexer, ds, writer_type, PROC_CMD, &retain_unselected);
   if (aw == NULL) 
     return CMD_CASCADING_FAILURE;
 
@@ -504,15 +504,15 @@
 }
 
 int
-cmd_save (struct dataset *ds) 
+cmd_save (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_proc (ds, SYSFILE_WRITER);
+  return parse_output_proc (lexer, ds, SYSFILE_WRITER);
 }
 
 int
-cmd_export (struct dataset *ds) 
+cmd_export (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_proc (ds, PORFILE_WRITER);
+  return parse_output_proc (lexer, ds, PORFILE_WRITER);
 }
 
 /* XSAVE and XEXPORT. */
@@ -528,10 +528,10 @@
 
 /* Parses the XSAVE or XEXPORT transformation command. */
 static int
-parse_output_trns (struct dataset *ds, enum writer_type writer_type) 
+parse_output_trns (struct lexer *lexer, struct dataset *ds, enum writer_type writer_type) 
 {
   struct output_trns *t = xmalloc (sizeof *t);
-  t->aw = parse_write_command (ds, writer_type, XFORM_CMD, NULL);
+  t->aw = parse_write_command (lexer, ds, writer_type, XFORM_CMD, NULL);
   if (t->aw == NULL) 
     {
       free (t);
@@ -569,50 +569,50 @@
 
 /* XSAVE command. */
 int
-cmd_xsave (struct dataset *ds) 
+cmd_xsave (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_trns (ds, SYSFILE_WRITER);
+  return parse_output_trns (lexer, ds, SYSFILE_WRITER);
 }
 
 /* XEXPORT command. */
 int
-cmd_xexport (struct dataset *ds) 
+cmd_xexport (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_trns (ds, PORFILE_WRITER);
+  return parse_output_trns (lexer, ds, PORFILE_WRITER);
 }
 
-static bool rename_variables (struct dictionary *dict);
-static bool drop_variables (struct dictionary *dict);
-static bool keep_variables (struct dictionary *dict);
+static bool rename_variables (struct lexer *lexer, struct dictionary *dict);
+static bool drop_variables (struct lexer *, struct dictionary *dict);
+static bool keep_variables (struct lexer *, struct dictionary *dict);
 
 /* Commands that read and write system files share a great deal
    of common syntactic structure for rearranging and dropping
    variables.  This function parses this syntax and modifies DICT
    appropriately.  Returns true on success, false on failure. */
 static bool
-parse_dict_trim (struct dictionary *dict)
+parse_dict_trim (struct lexer *lexer, struct dictionary *dict)
 {
-  if (lex_match_id ("MAP")) 
+  if (lex_match_id (lexer, "MAP")) 
     {
       /* FIXME. */
       return true;
     }
-  else if (lex_match_id ("DROP"))
-    return drop_variables (dict);
-  else if (lex_match_id ("KEEP"))
-    return keep_variables (dict);
-  else if (lex_match_id ("RENAME"))
-    return rename_variables (dict);
+  else if (lex_match_id (lexer, "DROP"))
+    return drop_variables (lexer, dict);
+  else if (lex_match_id (lexer, "KEEP"))
+    return keep_variables (lexer, dict);
+  else if (lex_match_id (lexer, "RENAME"))
+    return rename_variables (lexer, dict);
   else
     {
-      lex_error (_("expecting a valid subcommand"));
+      lex_error (lexer, _("expecting a valid subcommand"));
       return false;
     }
 }
 
 /* Parses and performs the RENAME subcommand of GET and SAVE. */
 static bool
-rename_variables (struct dictionary *dict)
+rename_variables (struct lexer *lexer, struct dictionary *dict)
 {
   size_t i;
 
@@ -625,29 +625,29 @@
 
   int group;
 
-  lex_match ('=');
-  if (token != '(')
+  lex_match (lexer, '=');
+  if (lex_token (lexer) != '(')
     {
       struct variable *v;
 
-      v = parse_variable (dict);
+      v = parse_variable (lexer, dict);
       if (v == NULL)
 	return 0;
-      if (!lex_force_match ('=')
-	  || !lex_force_id ())
+      if (!lex_force_match (lexer, '=')
+	  || !lex_force_id (lexer))
 	return 0;
-      if (dict_lookup_var (dict, tokid) != NULL)
+      if (dict_lookup_var (dict, lex_tokid (lexer)) != NULL)
 	{
 	  msg (SE, _("Cannot rename %s as %s because there already exists "
 		     "a variable named %s.  To rename variables with "
 		     "overlapping names, use a single RENAME subcommand "
 		     "such as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, "
-		     "\"/RENAME (A B C=B C A)\"."), v->name, tokid, tokid);
+		     "\"/RENAME (A B C=B C A)\"."), v->name, lex_tokid (lexer), lex_tokid (lexer));
 	  return 0;
 	}
       
-      dict_rename_var (dict, v, tokid);
-      lex_get ();
+      dict_rename_var (dict, v, lex_tokid (lexer));
+      lex_get (lexer);
       return 1;
     }
 
@@ -655,18 +655,18 @@
   v = NULL;
   new_names = 0;
   group = 1;
-  while (lex_match ('('))
+  while (lex_match (lexer, '('))
     {
       size_t old_nv = nv;
 
-      if (!parse_variables (dict, &v, &nv, PV_NO_DUPLICATE | PV_APPEND))
+      if (!parse_variables (lexer, dict, &v, &nv, PV_NO_DUPLICATE | PV_APPEND))
 	goto done;
-      if (!lex_match ('='))
+      if (!lex_match (lexer, '='))
 	{
 	  msg (SE, _("`=' expected after variable list."));
 	  goto done;
 	}
-      if (!parse_DATA_LIST_vars (&new_names, &nn, PV_APPEND | PV_NO_SCRATCH))
+      if (!parse_DATA_LIST_vars (lexer, &new_names, &nn, PV_APPEND | PV_NO_SCRATCH))
 	goto done;
       if (nn != nv)
 	{
@@ -676,7 +676,7 @@
 	       (unsigned) (nv - old_nv), (unsigned) (nn - old_nv), group);
 	  goto done;
 	}
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
 	goto done;
       group++;
     }
@@ -700,13 +700,13 @@
 /* Parses and performs the DROP subcommand of GET and SAVE.
    Returns true if successful, false on failure.*/
 static bool
-drop_variables (struct dictionary *dict)
+drop_variables (struct lexer *lexer, struct dictionary *dict)
 {
   struct variable **v;
   size_t nv;
 
-  lex_match ('=');
-  if (!parse_variables (dict, &v, &nv, PV_NONE))
+  lex_match (lexer, '=');
+  if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
     return false;
   dict_delete_vars (dict, v, nv);
   free (v);
@@ -722,14 +722,14 @@
 /* Parses and performs the KEEP subcommand of GET and SAVE.
    Returns true if successful, false on failure.*/
 static bool
-keep_variables (struct dictionary *dict)
+keep_variables (struct lexer *lexer, struct dictionary *dict)
 {
   struct variable **v;
   size_t nv;
   size_t i;
 
-  lex_match ('=');
-  if (!parse_variables (dict, &v, &nv, PV_NONE))
+  lex_match (lexer, '=');
+  if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
     return false;
 
   /* Move the specified variables to the beginning. */
@@ -810,7 +810,7 @@
 
 /* Parse and execute the MATCH FILES command. */
 int
-cmd_match_files (struct dataset *ds)
+cmd_match_files (struct lexer *lexer, struct dataset *ds)
 {
   struct mtf_proc mtf;
   struct mtf_file *first_table = NULL;
@@ -833,22 +833,22 @@
   mtf.seq_nums = NULL;
   dict_set_case_limit (mtf.dict, dict_get_case_limit (dataset_dict (ds)));
 
-  lex_match ('/');
-  while (token == T_ID
-         && (lex_id_match ("FILE", tokid) || lex_id_match ("TABLE", tokid)))
+  lex_match (lexer, '/');
+  while (lex_token (lexer) == T_ID
+         && (lex_id_match ("FILE", lex_tokid (lexer)) || lex_id_match ("TABLE", lex_tokid (lexer))))
     {
       struct mtf_file *file = xmalloc (sizeof *file);
 
-      if (lex_match_id ("FILE"))
+      if (lex_match_id (lexer, "FILE"))
         file->type = MTF_FILE;
-      else if (lex_match_id ("TABLE"))
+      else if (lex_match_id (lexer, "TABLE"))
         {
           file->type = MTF_TABLE;
           saw_table = true;
         }
       else
         NOT_REACHED ();
-      lex_match ('=');
+      lex_match (lexer, '=');
 
       file->by = NULL;
       file->handle = NULL;
@@ -883,7 +883,7 @@
           first_table->prev = file;
         }
 
-      if (lex_match ('*'))
+      if (lex_match (lexer, '*'))
         {
           file->handle = NULL;
           file->reader = NULL;
@@ -913,7 +913,7 @@
         }
       else
         {
-          file->handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+          file->handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
           if (file->handle == NULL)
             goto error;
 
@@ -924,18 +924,18 @@
           case_create (&file->input, dict_get_next_value_idx (file->dict));
         }
 
-      while (lex_match ('/'))
-        if (lex_match_id ("RENAME")) 
+      while (lex_match (lexer, '/'))
+        if (lex_match_id (lexer, "RENAME")) 
           {
-            if (!rename_variables (file->dict))
+            if (!rename_variables (lexer, file->dict))
               goto error; 
           }
-        else if (lex_match_id ("IN"))
+        else if (lex_match_id (lexer, "IN"))
           {
-            lex_match ('=');
-            if (token != T_ID)
+            lex_match (lexer, '=');
+            if (lex_token (lexer) != T_ID)
               {
-                lex_error (NULL);
+                lex_error (lexer, NULL);
                 goto error;
               }
 
@@ -945,17 +945,17 @@
                            "TABLE."));
                 goto error;
               }
-            file->in_name = xstrdup (tokid);
-            lex_get ();
+            file->in_name = xstrdup (lex_tokid (lexer));
+            lex_get (lexer);
             saw_in = true;
           }
 
       mtf_merge_dictionary (mtf.dict, file);
     }
   
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      if (lex_match (T_BY))
+      if (lex_match (lexer, T_BY))
 	{
           struct variable **by;
           
@@ -965,8 +965,8 @@
 	      goto error;
 	    }
 	      
-	  lex_match ('=');
-	  if (!parse_variables (mtf.dict, &by, &mtf.by_cnt,
+	  lex_match (lexer, '=');
+	  if (!parse_variables (lexer, mtf.dict, &by, &mtf.by_cnt,
 				PV_NO_DUPLICATE | PV_NO_SCRATCH))
 	    goto error;
 
@@ -991,7 +991,7 @@
             }
           free (by);
 	}
-      else if (lex_match_id ("FIRST")) 
+      else if (lex_match_id (lexer, "FIRST")) 
         {
           if (mtf.first[0] != '\0')
             {
@@ -999,13 +999,13 @@
               goto error;
             }
 	      
-	  lex_match ('=');
-          if (!lex_force_id ())
+	  lex_match (lexer, '=');
+          if (!lex_force_id (lexer))
             goto error;
-          strcpy (mtf.first, tokid);
-          lex_get ();
+          strcpy (mtf.first, lex_tokid (lexer));
+          lex_get (lexer);
         }
-      else if (lex_match_id ("LAST")) 
+      else if (lex_match_id (lexer, "LAST")) 
         {
           if (mtf.last[0] != '\0')
             {
@@ -1013,35 +1013,35 @@
               goto error;
             }
 	      
-	  lex_match ('=');
-          if (!lex_force_id ())
+	  lex_match (lexer, '=');
+          if (!lex_force_id (lexer))
             goto error;
-          strcpy (mtf.last, tokid);
-          lex_get ();
+          strcpy (mtf.last, lex_tokid (lexer));
+          lex_get (lexer);
         }
-      else if (lex_match_id ("MAP"))
+      else if (lex_match_id (lexer, "MAP"))
 	{
 	  /* FIXME. */
 	}
-      else if (lex_match_id ("DROP")) 
+      else if (lex_match_id (lexer, "DROP")) 
         {
-          if (!drop_variables (mtf.dict))
+          if (!drop_variables (lexer, mtf.dict))
             goto error;
         }
-      else if (lex_match_id ("KEEP")) 
+      else if (lex_match_id (lexer, "KEEP")) 
         {
-          if (!keep_variables (mtf.dict))
+          if (!keep_variables (lexer, mtf.dict))
             goto error;
         }
       else
 	{
-	  lex_error (NULL);
+	  lex_error (lexer, NULL);
 	  goto error;
 	}
 
-      if (!lex_match ('/') && token != '.') 
+      if (!lex_match (lexer, '/') && lex_token (lexer) != '.') 
         {
-          lex_end_of_command ();
+          lex_end_of_command (lexer);
           goto error;
         }
     }
Index: src/language/data-io/inpt-pgm.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/inpt-pgm.c,v
retrieving revision 1.16
diff -b -w -U3 -r1.16 inpt-pgm.c
--- src/language/data-io/inpt-pgm.c	26 Oct 2006 06:16:36 -0000	1.16
+++ src/language/data-io/inpt-pgm.c	11 Nov 2006 00:13:13 -0000
@@ -103,15 +103,15 @@
 }
 
 int
-cmd_input_program (struct dataset *ds)
+cmd_input_program (struct lexer *lexer, struct dataset *ds)
 {
   struct input_program_pgm *inp;
   size_t i;
   bool saw_END_CASE = false;
 
   discard_variables (ds);
-  if (token != '.')
-    return lex_end_of_command ();
+  if (lex_token (lexer) != '.')
+    return lex_end_of_command (lexer);
 
   inp = xmalloc (sizeof *inp);
   inp->trns_chain = NULL;
@@ -120,7 +120,7 @@
   inside_input_program = true;
   for (;;) 
     {
-      enum cmd_result result = cmd_parse (ds, CMD_STATE_INPUT_PROGRAM);
+      enum cmd_result result = cmd_parse (lexer, ds, CMD_STATE_INPUT_PROGRAM);
       if (result == CMD_END_INPUT_PROGRAM)
         break;
       else if (result == CMD_END_CASE) 
@@ -181,7 +181,7 @@
 }
 
 int
-cmd_end_input_program (struct dataset *ds UNUSED)
+cmd_end_input_program (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   assert (in_input_program ());
   return CMD_END_INPUT_PROGRAM; 
@@ -288,12 +288,12 @@
   };
 
 int
-cmd_end_case (struct dataset *ds UNUSED)
+cmd_end_case (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   assert (in_input_program ());
-  if (token == '.')
+  if (lex_token (lexer) == '.')
     return CMD_END_CASE;
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Sends the current case as the source's output. */
@@ -319,7 +319,7 @@
 
 /* Parses REREAD command. */
 int
-cmd_reread (struct dataset *ds)
+cmd_reread (struct lexer *lexer, struct dataset *ds)
 {
   struct file_handle *fh;       /* File to be re-read. */
   struct expression *e;         /* Expression for column to set. */
@@ -327,11 +327,11 @@
 
   fh = fh_get_default_handle ();
   e = NULL;
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      if (lex_match_id ("COLUMN"))
+      if (lex_match_id (lexer, "COLUMN"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 	  
 	  if (e)
 	    {
@@ -340,14 +340,14 @@
 	      return CMD_CASCADING_FAILURE;
 	    }
 	  
-	  e = expr_parse (ds, EXPR_NUMBER);
+	  e = expr_parse (lexer, ds, EXPR_NUMBER);
 	  if (!e)
 	    return CMD_CASCADING_FAILURE;
 	}
-      else if (lex_match_id ("FILE"))
+      else if (lex_match_id (lexer, "FILE"))
 	{
-	  lex_match ('=');
-          fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
+	  lex_match (lexer, '=');
+          fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
 	  if (fh == NULL)
 	    {
 	      expr_free (e);
@@ -356,13 +356,13 @@
 	}
       else
 	{
-	  lex_error (NULL);
+	  lex_error (lexer, NULL);
 	  expr_free (e);
 	}
     }
 
   t = xmalloc (sizeof *t);
-  t->reader = dfm_open_reader (fh);
+  t->reader = dfm_open_reader (fh, lexer);
   t->column = e;
   add_transformation (ds, reread_trns_proc, reread_trns_free, t);
 
@@ -405,13 +405,13 @@
 
 /* Parses END FILE command. */
 int
-cmd_end_file (struct dataset *ds)
+cmd_end_file (struct lexer *lexer, struct dataset *ds)
 {
   assert (in_input_program ());
 
   add_transformation (ds, end_file_trns_proc, NULL, NULL);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Executes an END FILE transformation. */
Index: src/language/data-io/list.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/list.q,v
retrieving revision 1.19
diff -b -w -U3 -r1.19 list.q
--- src/language/data-io/list.q	5 Nov 2006 05:20:53 -0000	1.19
+++ src/language/data-io/list.q	11 Nov 2006 00:13:13 -0000
@@ -130,12 +130,12 @@
     
 /* Parses and executes the LIST procedure. */
 int
-cmd_list (struct dataset *ds)
+cmd_list (struct lexer *lexer, struct dataset *ds)
 {
   struct variable casenum_var;
   bool ok;
 
-  if (!parse_list (ds, &cmd, NULL))
+  if (!parse_list (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
   
   /* Fill in defaults. */
Index: src/language/data-io/matrix-data.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/matrix-data.c,v
retrieving revision 1.16
diff -b -w -U3 -r1.16 matrix-data.c
--- src/language/data-io/matrix-data.c	3 Nov 2006 04:53:51 -0000	1.16
+++ src/language/data-io/matrix-data.c	11 Nov 2006 00:13:14 -0000
@@ -170,11 +170,11 @@
 					     const void *pb);
 static bool read_matrices_without_rowtype (struct dataset *ds, struct matrix_data_pgm *);
 static bool read_matrices_with_rowtype (struct dataset *ds, struct matrix_data_pgm *);
-static int string_to_content_type (char *, int *);
+static int string_to_content_type (const char *, int *);
 static void attach_mxd_aux (struct variable *, int var_type, int sub_type);
 
 int
-cmd_matrix_data (struct dataset *ds)
+cmd_matrix_data (struct lexer *lexer, struct dataset *ds)
 {
   struct pool *pool;
   struct matrix_data_pgm *mx;
@@ -204,11 +204,11 @@
   mx->n_contents = 0;
   mx->n_continuous = 0;
   mx->first_continuous = 0;
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      lex_match ('/');
+      lex_match (lexer, '/');
 
-      if (lex_match_id ("VARIABLES"))
+      if (lex_match_id (lexer, "VARIABLES"))
 	{
 	  char **v;
 	  size_t nv;
@@ -220,8 +220,8 @@
 	    }
 	  seen |= 1;
 	  
-	  lex_match ('=');
-	  if (!parse_DATA_LIST_vars (&v, &nv, PV_NO_DUPLICATE))
+	  lex_match (lexer, '=');
+	  if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NO_DUPLICATE))
 	    goto lossage;
 	  
 	  {
@@ -262,43 +262,43 @@
                                                  "ROWTYPE_", 8);
           attach_mxd_aux (mx->rowtype_, MXD_ROWTYPE, 0);
 	}
-      else if (lex_match_id ("FILE"))
+      else if (lex_match_id (lexer, "FILE"))
 	{
-	  lex_match ('=');
-	  fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
+	  lex_match (lexer, '=');
+	  fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
 	  if (fh == NULL)
 	    goto lossage;
 	}
-      else if (lex_match_id ("FORMAT"))
+      else if (lex_match_id (lexer, "FORMAT"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 
-	  while (token == T_ID)
+	  while (lex_token (lexer) == T_ID)
 	    {
-	      if (lex_match_id ("LIST"))
+	      if (lex_match_id (lexer, "LIST"))
 		mx->fmt = LIST;
-	      else if (lex_match_id ("FREE"))
+	      else if (lex_match_id (lexer, "FREE"))
 		mx->fmt = FREE;
-	      else if (lex_match_id ("LOWER"))
+	      else if (lex_match_id (lexer, "LOWER"))
 		mx->section = LOWER;
-	      else if (lex_match_id ("UPPER"))
+	      else if (lex_match_id (lexer, "UPPER"))
 		mx->section = UPPER;
-	      else if (lex_match_id ("FULL"))
+	      else if (lex_match_id (lexer, "FULL"))
 		mx->section = FULL;
-	      else if (lex_match_id ("DIAGONAL"))
+	      else if (lex_match_id (lexer, "DIAGONAL"))
 		mx->diag = DIAGONAL;
-	      else if (lex_match_id ("NODIAGONAL"))
+	      else if (lex_match_id (lexer, "NODIAGONAL"))
 		mx->diag = NODIAGONAL;
 	      else 
 		{
-		  lex_error (_("in FORMAT subcommand"));
+		  lex_error (lexer, _("in FORMAT subcommand"));
 		  goto lossage;
 		}
 	    }
 	}
-      else if (lex_match_id ("SPLIT"))
+      else if (lex_match_id (lexer, "SPLIT"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 
 	  if (seen & 2)
 	    {
@@ -307,17 +307,17 @@
 	    }
 	  seen |= 2;
 	  
-	  if (token != T_ID)
+	  if (lex_token (lexer) != T_ID)
 	    {
-	      lex_error (_("in SPLIT subcommand"));
+	      lex_error (lexer, _("in SPLIT subcommand"));
 	      goto lossage;
 	    }
 	  
-	  if (dict_lookup_var (dataset_dict (ds), tokid) == NULL
-	      && (lex_look_ahead () == '.' || lex_look_ahead () == '/'))
+	  if (dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL
+	      && (lex_look_ahead (lexer) == '.' || lex_look_ahead (lexer) == '/'))
 	    {
-	      if (!strcasecmp (tokid, "ROWTYPE_")
-                  || !strcasecmp (tokid, "VARNAME_"))
+	      if (!strcasecmp (lex_tokid (lexer), "ROWTYPE_")
+                  || !strcasecmp (lex_tokid (lexer), "VARNAME_"))
 		{
 		  msg (SE, _("Split variable may not be named ROWTYPE_ "
 			     "or VARNAME_."));
@@ -325,9 +325,9 @@
 		}
 
 	      mx->single_split = dict_create_var_assert (dataset_dict (ds),
-                                                         tokid, 0);
+                                                         lex_tokid (lexer), 0);
               attach_mxd_aux (mx->single_split, MXD_CONTINUOUS, 0);
-	      lex_get ();
+	      lex_get (lexer);
 
               dict_set_split_vars (dataset_dict (ds), &mx->single_split, 1);
 	    }
@@ -336,7 +336,8 @@
 	      struct variable **split;
 	      size_t n;
 
-	      if (!parse_variables (dataset_dict (ds), &split, &n, PV_NO_DUPLICATE))
+	      if (!parse_variables (lexer, dataset_dict (ds), 
+				    &split, &n, PV_NO_DUPLICATE))
 		goto lossage;
 
               dict_set_split_vars (dataset_dict (ds), split, n);
@@ -354,7 +355,7 @@
 		if (mv->var_type != MXD_CONTINUOUS)
 		  {
 		    msg (SE, _("Split variable %s is already another type."),
-			 tokid);
+			 lex_tokid (lexer));
 		    goto lossage;
 		  }
                 var_clear_aux (split[i]);
@@ -362,9 +363,9 @@
               }
 	  }
 	}
-      else if (lex_match_id ("FACTORS"))
+      else if (lex_match_id (lexer, "FACTORS"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 	  
 	  if (seen & 4)
 	    {
@@ -373,7 +374,7 @@
 	    }
 	  seen |= 4;
 
-	  if (!parse_variables (dataset_dict (ds), &mx->factors, &mx->n_factors,
+	  if (!parse_variables (lexer, dataset_dict (ds), &mx->factors, &mx->n_factors,
                                 PV_NONE))
 	    goto lossage;
 	  
@@ -388,7 +389,7 @@
 		if (mv->var_type != MXD_CONTINUOUS)
 		  {
 		    msg (SE, _("Factor variable %s is already another type."),
-			 tokid);
+			 lex_tokid (lexer));
 		    goto lossage;
 		  }
                 var_clear_aux (v);
@@ -396,9 +397,9 @@
 	      }
 	  }
 	}
-      else if (lex_match_id ("CELLS"))
+      else if (lex_match_id (lexer, "CELLS"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 	  
 	  if (mx->cells != -1)
 	    {
@@ -406,18 +407,18 @@
 	      goto lossage;
 	    }
 
-	  if (!lex_is_integer () || lex_integer () < 1)
+	  if (!lex_is_integer (lexer) || lex_integer (lexer) < 1)
 	    {
-	      lex_error (_("expecting positive integer"));
+	      lex_error (lexer, _("expecting positive integer"));
 	      goto lossage;
 	    }
 
-	  mx->cells = lex_integer ();
-	  lex_get ();
+	  mx->cells = lex_integer (lexer);
+	  lex_get (lexer);
 	}
-      else if (lex_match_id ("N"))
+      else if (lex_match_id (lexer, "N"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 
 	  if (mx->pop_n != -1)
 	    {
@@ -425,16 +426,16 @@
 	      goto lossage;
 	    }
 
-	  if (!lex_is_integer () || lex_integer () < 1)
+	  if (!lex_is_integer (lexer) || lex_integer (lexer) < 1)
 	    {
-	      lex_error (_("expecting positive integer"));
+	      lex_error (lexer, _("expecting positive integer"));
 	      goto lossage;
 	    }
 
-	  mx->pop_n = lex_integer ();
-	  lex_get ();
+	  mx->pop_n = lex_integer (lexer);
+	  lex_get (lexer);
 	}
-      else if (lex_match_id ("CONTENTS"))
+      else if (lex_match_id (lexer, "CONTENTS"))
 	{
 	  int inside_parens = 0;
 	  unsigned collide = 0;
@@ -447,7 +448,7 @@
 	    }
 	  seen |= 8;
 
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 	  
 	  {
 	    int i;
@@ -458,7 +459,7 @@
 
 	  for (;;)
 	    {
-	      if (lex_match ('('))
+	      if (lex_match (lexer, '('))
 		{
 		  if (inside_parens)
 		    {
@@ -468,7 +469,7 @@
 		  inside_parens = 1;
 		  item = LPAREN;
 		}
-	      else if (lex_match (')'))
+	      else if (lex_match (lexer, ')'))
 		{
 		  if (!inside_parens)
 		    {
@@ -488,20 +489,20 @@
 		  int content_type;
 		  int collide_index;
 		  
-		  if (token != T_ID)
+		  if (lex_token (lexer) != T_ID)
 		    {
-		      lex_error (_("in CONTENTS subcommand"));
+		      lex_error (lexer, _("in CONTENTS subcommand"));
 		      goto lossage;
 		    }
 
-		  content_type = string_to_content_type (tokid,
+		  content_type = string_to_content_type (lex_tokid (lexer),
 							 &collide_index);
 		  if (content_type == -1)
 		    {
-		      lex_error (_("in CONTENTS subcommand"));
+		      lex_error (lexer, _("in CONTENTS subcommand"));
 		      goto lossage;
 		    }
-		  lex_get ();
+		  lex_get (lexer);
 
 		  if (collide & (1 << collide_index))
 		    {
@@ -516,7 +517,7 @@
 		}
 	      mx->contents[mx->n_contents++] = item;
 
-	      if (token == '/' || token == '.')
+	      if (lex_token (lexer) == '/' || lex_token (lexer) == '.')
 		break;
 	    }
 
@@ -529,14 +530,14 @@
 	}
       else 
 	{
-	  lex_error (NULL);
+	  lex_error (lexer, NULL);
 	  goto lossage;
 	}
     }
   
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       goto lossage;
     }
   
@@ -623,7 +624,7 @@
       goto lossage;
     }
 
-  mx->reader = dfm_open_reader (fh);
+  mx->reader = dfm_open_reader (fh, lexer);
   if (mx->reader == NULL)
     goto lossage;
 
@@ -651,7 +652,7 @@
    as a bit-index) which can be used for determining whether a related
    statistic has already been used. */
 static int
-string_to_content_type (char *s, int *collide)
+string_to_content_type (const char *s, int *collide)
 {
   static const struct
     {
Index: src/language/data-io/placement-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/placement-parser.c,v
retrieving revision 1.2
diff -b -w -U3 -r1.2 placement-parser.c
--- src/language/data-io/placement-parser.c	3 Nov 2006 04:53:51 -0000	1.2
+++ src/language/data-io/placement-parser.c	11 Nov 2006 00:13:14 -0000
@@ -44,9 +44,9 @@
     PRS_TYPE_NEW_REC            /* Next record. */
   };
 
-static bool fixed_parse_columns (struct pool *, size_t var_cnt, bool for_input,
+static bool fixed_parse_columns (struct lexer *, struct pool *, size_t var_cnt, bool for_input,
                                  struct fmt_spec **, size_t *);
-static bool fixed_parse_fortran (struct pool *, bool for_input,
+static bool fixed_parse_fortran (struct lexer *l, struct pool *, bool for_input,
                                  struct fmt_spec **, size_t *);
 
 /* Parses Fortran-like or column-based specifications for placing
@@ -65,18 +65,18 @@
    Uses POOL for allocation.  When the caller is finished
    interpreting *FORMATS, POOL may be destroyed. */
 bool
-parse_var_placements (struct pool *pool, size_t var_cnt, bool for_input,
+parse_var_placements (struct lexer *lexer, struct pool *pool, size_t var_cnt, bool for_input,
                       struct fmt_spec **formats, size_t *format_cnt) 
 {
   assert (var_cnt > 0);
-  if (lex_is_number ())
-    return fixed_parse_columns (pool, var_cnt, for_input, formats, format_cnt);
-  else if (lex_match ('(')) 
+  if (lex_is_number (lexer))
+    return fixed_parse_columns (lexer, pool, var_cnt, for_input, formats, format_cnt);
+  else if (lex_match (lexer, '(')) 
     {
       size_t assignment_cnt;
       size_t i;
 
-      if (!fixed_parse_fortran (pool, for_input, formats, format_cnt))
+      if (!fixed_parse_fortran (lexer, pool, for_input, formats, format_cnt))
         return false; 
 
       assignment_cnt = 0;
@@ -103,14 +103,14 @@
 
 /* Implements parse_var_placements for column-based formats. */
 static bool
-fixed_parse_columns (struct pool *pool, size_t var_cnt, bool for_input,
+fixed_parse_columns (struct lexer *lexer, struct pool *pool, size_t var_cnt, bool for_input,
                      struct fmt_spec **formats, size_t *format_cnt)
 {
   struct fmt_spec format;
   int fc, lc;
   size_t i;
 
-  if (!parse_column_range (&fc, &lc, NULL))
+  if ( !parse_column_range (lexer, &fc, &lc, NULL) )
     return false;
 
   /* Divide columns evenly. */    
@@ -124,28 +124,28 @@
     }
 
   /* Format specifier. */
-  if (lex_match ('('))
+  if (lex_match (lexer, '('))
     {
       /* Get format type. */
-      if (token == T_ID)
+      if (lex_token (lexer) == T_ID)
 	{
-	  if (!parse_format_specifier_name (&format.type))
+	  if (!parse_format_specifier_name (lexer, &format.type))
             return false;
-	  lex_match (',');
+	  lex_match (lexer, ',');
 	}
       else
 	format.type = FMT_F;
 
       /* Get decimal places. */
-      if (lex_is_integer ())
+      if (lex_is_integer (lexer))
 	{
-	  format.d = lex_integer ();
-	  lex_get ();
+	  format.d = lex_integer (lexer);
+	  lex_get (lexer);
 	}
       else
 	format.d = 0;
 
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
 	return false;
     }
   else
@@ -167,14 +167,14 @@
 
 /* Implements parse_var_placements for Fortran-like formats. */
 static bool
-fixed_parse_fortran (struct pool *pool, bool for_input,
+fixed_parse_fortran (struct lexer *lexer, struct pool *pool, bool for_input,
                      struct fmt_spec **formats, size_t *format_cnt)
 {
   size_t formats_allocated = 0;
   size_t formats_used = 0;
 
   *formats = NULL;
-  while (!lex_match (')'))
+  while (!lex_match (lexer, ')'))
     {
       struct fmt_spec f;
       struct fmt_spec *new_formats;
@@ -183,19 +183,19 @@
       size_t formats_needed;
       
       /* Parse count. */
-      if (lex_is_integer ())
+      if (lex_is_integer (lexer))
 	{
-	  count = lex_integer ();
-	  lex_get ();
+	  count = lex_integer (lexer);
+	  lex_get (lexer);
 	}
       else
 	count = 1;
 
       /* Parse format specifier. */
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
         {
           /* Call ourselves recursively to handle parentheses. */
-          if (!fixed_parse_fortran (pool, for_input,
+          if (!fixed_parse_fortran (lexer, pool, for_input,
                                     &new_formats, &new_format_cnt))
             return false;
         }
@@ -203,13 +203,13 @@
         {
           new_formats = &f;
           new_format_cnt = 1;
-          if (lex_match ('/'))
+          if (lex_match (lexer, '/'))
             f.type = PRS_TYPE_NEW_REC;
           else
             {
               char type[FMT_TYPE_LEN_MAX + 1];
               
-              if (!parse_abstract_format_specifier (type, &f.w, &f.d))
+              if (!parse_abstract_format_specifier (lexer, type, &f.w, &f.d))
                 return false;
 
               if (!strcasecmp (type, "T")) 
@@ -254,7 +254,7 @@
           formats_used += new_format_cnt;
         }
 
-      lex_match (',');
+      lex_match (lexer, ',');
     }
 
   *format_cnt = formats_used;
@@ -299,27 +299,27 @@
    successful, false if the syntax was invalid or the values
    specified did not make sense. */
 bool
-parse_column_range (int *first_column, int *last_column,
+parse_column_range (struct lexer *lexer, int *first_column, int *last_column,
                     bool *range_specified) 
 {
   /* First column. */
-  if (!lex_force_int ())
+  if (!lex_force_int (lexer))
     return false;
-  *first_column = lex_integer ();
+  *first_column = lex_integer (lexer);
   if (*first_column < 1)
     {
       msg (SE, _("Column positions for fields must be positive."));
       return false;
     }
-  lex_get ();
+  lex_get (lexer);
 
   /* Last column. */
-  lex_negative_to_dash ();
-  if (lex_match ('-'))
+  lex_negative_to_dash (lexer);
+  if (lex_match (lexer, '-'))
     {
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	return false;
-      *last_column = lex_integer ();
+      *last_column = lex_integer (lexer);
       if (*last_column < 1)
 	{
 	  msg (SE, _("Column positions for fields must be positive."));
@@ -334,7 +334,7 @@
 
       if (range_specified)
         *range_specified = true;
-      lex_get ();
+      lex_get (lexer);
     }
   else 
     {
@@ -354,23 +354,23 @@
 
    Returns true if successful, false on syntax error. */
 bool
-parse_record_placement (int *record, int *column) 
+parse_record_placement (struct lexer *lexer, int *record, int *column) 
 {
-  while (lex_match ('/'))
+  while (lex_match (lexer, '/'))
     {
-      if (lex_is_integer ())
+      if (lex_is_integer (lexer))
         {
-          if (lex_integer () <= *record)
+          if (lex_integer (lexer) <= *record)
             {
               msg (SE, _("The record number specified, %ld, is at or "
                          "before the previous record, %d.  Data "
                          "fields must be listed in order of "
                          "increasing record number."),
-                   lex_integer (), *record);
+                   lex_integer (lexer), *record);
               return false;
             }
-          *record = lex_integer ();
-          lex_get ();
+          *record = lex_integer (lexer);
+          lex_get (lexer);
         }
       else
         (*record)++;
Index: src/language/data-io/placement-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/placement-parser.h,v
retrieving revision 1.2
diff -b -w -U3 -r1.2 placement-parser.h
--- src/language/data-io/placement-parser.h	3 Nov 2006 04:53:51 -0000	1.2
+++ src/language/data-io/placement-parser.h	11 Nov 2006 00:13:14 -0000
@@ -25,13 +25,14 @@
 
 struct fmt_spec;
 struct pool;
+struct lexer;
 
-bool parse_record_placement (int *record, int *column);
-bool parse_var_placements (struct pool *, size_t var_cnt, bool for_input,
+bool parse_record_placement (struct lexer *, int *record, int *column);
+bool parse_var_placements (struct lexer *, struct pool *, size_t var_cnt, bool for_input,
                            struct fmt_spec **, size_t *format_cnt);
 bool execute_placement_format (const struct fmt_spec *,
                                int *record, int *column);
-bool parse_column_range (int *first_column, int *last_column,
+bool parse_column_range (struct lexer *, int *first_column, int *last_column,
                          bool *range_specified);
 
 #endif /* language/data-io/placement-parser.h */
Index: src/language/data-io/print-space.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/print-space.c,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 print-space.c
--- src/language/data-io/print-space.c	1 Nov 2006 02:22:35 -0000	1.6
+++ src/language/data-io/print-space.c	11 Nov 2006 00:13:14 -0000
@@ -47,32 +47,32 @@
 static trns_free_func print_space_trns_free;
 
 int
-cmd_print_space (struct dataset *ds)
+cmd_print_space (struct lexer *lexer, struct dataset *ds)
 {
   struct print_space_trns *trns;
   struct file_handle *handle;
   struct expression *expr;
   struct dfm_writer *writer;
 
-  if (lex_match_id ("OUTFILE"))
+  if (lex_match_id (lexer, "OUTFILE"))
     {
-      lex_match ('=');
+      lex_match (lexer, '=');
 
-      handle = fh_parse (FH_REF_FILE);
+      handle = fh_parse (lexer, FH_REF_FILE);
       if (handle == NULL)
 	return CMD_FAILURE;
-      lex_get ();
+      lex_get (lexer);
     }
   else
     handle = NULL;
 
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      expr = expr_parse (ds, EXPR_NUMBER);
-      if (token != '.')
+      expr = expr_parse (lexer, ds, EXPR_NUMBER);
+      if (lex_token (lexer) != '.')
 	{
 	  expr_free (expr);
-	  lex_error (_("expecting end of command"));
+	  lex_error (lexer, _("expecting end of command"));
 	  return CMD_FAILURE;
 	}
     }
Index: src/language/data-io/print.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/print.c,v
retrieving revision 1.19
diff -b -w -U3 -r1.19 print.c
--- src/language/data-io/print.c	5 Nov 2006 05:20:53 -0000	1.19
+++ src/language/data-io/print.c	11 Nov 2006 00:13:14 -0000
@@ -96,11 +96,11 @@
     WRITE
   };
 
-static int internal_cmd_print (struct dataset *ds, 
+static int internal_cmd_print (struct lexer *, struct dataset *ds, 
 			       enum which_formats, bool eject);
 static trns_proc_func print_trns_proc;
 static trns_free_func print_trns_free;
-static bool parse_specs (struct pool *tmp_pool, struct print_trns *,
+static bool parse_specs (struct lexer *, struct pool *tmp_pool, struct print_trns *,
 			 struct dictionary *dict, enum which_formats);
 static void dump_table (struct print_trns *, const struct file_handle *);
 
@@ -108,28 +108,28 @@
 
 /* Parses PRINT command. */
 int
-cmd_print (struct dataset *ds)
+cmd_print (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_print (ds, PRINT, false);
+  return internal_cmd_print (lexer, ds, PRINT, false);
 }
 
 /* Parses PRINT EJECT command. */
 int
-cmd_print_eject (struct dataset *ds)
+cmd_print_eject (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_print (ds, PRINT, true);
+  return internal_cmd_print (lexer, ds, PRINT, true);
 }
 
 /* Parses WRITE command. */
 int
-cmd_write (struct dataset *ds)
+cmd_write (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_print (ds, WRITE, false);
+  return internal_cmd_print (lexer, ds, WRITE, false);
 }
 
 /* Parses the output commands. */
 static int
-internal_cmd_print (struct dataset *ds, 
+internal_cmd_print (struct lexer *lexer, struct dataset *ds, 
 		    enum which_formats which_formats, bool eject)
 {
   bool print_table = 0;
@@ -149,33 +149,33 @@
   tmp_pool = pool_create_subpool (trns->pool);
 
   /* Parse the command options. */
-  while (token != '/' && token != '.')
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.')
     {
-      if (lex_match_id ("OUTFILE"))
+      if (lex_match_id (lexer, "OUTFILE"))
 	{
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 
-	  fh = fh_parse (FH_REF_FILE);
+	  fh = fh_parse (lexer, FH_REF_FILE);
 	  if (fh == NULL)
 	    goto error;
 	}
-      else if (lex_match_id ("RECORDS"))
+      else if (lex_match_id (lexer, "RECORDS"))
 	{
-	  lex_match ('=');
-	  lex_match ('(');
-	  if (!lex_force_int ())
+	  lex_match (lexer, '=');
+	  lex_match (lexer, '(');
+	  if (!lex_force_int (lexer))
 	    goto error;
-	  trns->record_cnt = lex_integer ();
-	  lex_get ();
-	  lex_match (')');
+	  trns->record_cnt = lex_integer (lexer);
+	  lex_get (lexer);
+	  lex_match (lexer, ')');
 	}
-      else if (lex_match_id ("TABLE"))
+      else if (lex_match_id (lexer, "TABLE"))
 	print_table = true;
-      else if (lex_match_id ("NOTABLE"))
+      else if (lex_match_id (lexer, "NOTABLE"))
 	print_table = false;
       else
 	{
-	  lex_error (_("expecting a valid subcommand"));
+	  lex_error (lexer, _("expecting a valid subcommand"));
 	  goto error;
 	}
     }
@@ -185,10 +185,10 @@
   trns->include_prefix = which_formats == PRINT && fh != NULL;
 
   /* Parse variables and strings. */
-  if (!parse_specs (tmp_pool, trns, dataset_dict (ds), which_formats))
+  if (!parse_specs (lexer, tmp_pool, trns, dataset_dict (ds), which_formats))
     goto error;
 
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto error;
 
   if (fh != NULL)
@@ -214,9 +214,9 @@
   return CMD_FAILURE;
 }
 
-static bool parse_string_argument (struct print_trns *,
+static bool parse_string_argument (struct lexer *, struct print_trns *,
                                    int record, int *column);
-static bool parse_variable_argument (const struct dictionary *, 
+static bool parse_variable_argument (struct lexer *, const struct dictionary *, 
 				     struct print_trns *,
                                      struct pool *tmp_pool,
                                      int *record, int *column,
@@ -226,35 +226,35 @@
    PRINT, PRINT EJECT, or WRITE command into the prt structure.
    Returns success. */
 static bool
-parse_specs (struct pool *tmp_pool, struct print_trns *trns,
+parse_specs (struct lexer *lexer, struct pool *tmp_pool, struct print_trns *trns,
 	     struct dictionary *dict, 
              enum which_formats which_formats)
 {
   int record = 0;
   int column = 1;
 
-  if (token == '.') 
+  if (lex_token (lexer) == '.') 
     {
       trns->record_cnt = 1;
       return true;
     }
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
       bool ok;
 
-      if (!parse_record_placement (&record, &column))
+      if (!parse_record_placement (lexer, &record, &column))
         return false;
 
-      if (token == T_STRING)
-	ok = parse_string_argument (trns, record, &column);
+      if (lex_token (lexer) == T_STRING)
+	ok = parse_string_argument (lexer, trns, record, &column);
       else
-	ok = parse_variable_argument (dict, trns, tmp_pool, &record, &column,
+	ok = parse_variable_argument (lexer, dict, trns, tmp_pool, &record, &column,
                                       which_formats);
       if (!ok)
 	return 0;
 
-      lex_match (',');
+      lex_match (lexer, ',');
     }
 
   if (trns->record_cnt != 0 && trns->record_cnt != record)
@@ -268,23 +268,23 @@
 
 /* Parses a string argument to the PRINT commands.  Returns success. */
 static bool
-parse_string_argument (struct print_trns *trns, int record, int *column)
+parse_string_argument (struct lexer *lexer, struct print_trns *trns, int record, int *column)
 {
   struct prt_out_spec *spec = pool_alloc (trns->pool, sizeof *spec);
   spec->type = PRT_LITERAL;
   spec->record = record;
   spec->first_column = *column;
-  ds_init_string (&spec->string, &tokstr);
+  ds_init_string (&spec->string, lex_tokstr (lexer));
   ds_register_pool (&spec->string, trns->pool);
-  lex_get ();
+  lex_get (lexer);
 
   /* Parse the included column range. */
-  if (lex_is_number ())
+  if (lex_is_number (lexer))
     {
       int first_column, last_column;
       bool range_specified;
 
-      if (!parse_column_range (&first_column, &last_column, &range_specified)) 
+      if (!parse_column_range (lexer, &first_column, &last_column, &range_specified)) 
         return false; 
 
       spec->first_column = first_column;
@@ -301,7 +301,7 @@
    to fixed_parse_compatible() or fixed_parse_fortran() as appropriate.
    Returns success. */
 static bool
-parse_variable_argument (const struct dictionary *dict,
+parse_variable_argument (struct lexer *lexer, const struct dictionary *dict,
 			 struct print_trns *trns, struct pool *tmp_pool,
                          int *record, int *column,
                          enum which_formats which_formats)
@@ -312,12 +312,13 @@
   size_t format_cnt;
   bool add_space;
   
-  if (!parse_variables_pool (tmp_pool, dict, &vars, &var_cnt, PV_DUPLICATE))
+  if (!parse_variables_pool (lexer, tmp_pool, dict, 
+			     &vars, &var_cnt, PV_DUPLICATE))
     return false;
 
-  if (lex_is_number () || token == '(')
+  if (lex_is_number (lexer) || lex_token (lexer) == '(')
     {
-      if (!parse_var_placements (tmp_pool, var_cnt, false,
+      if (!parse_var_placements (lexer, tmp_pool, var_cnt, false,
                                  &formats, &format_cnt))
         return false;
       add_space = false;
@@ -326,7 +327,7 @@
     {
       size_t i;
 
-      lex_match ('*');
+      lex_match (lexer, '*');
       
       formats = pool_nmalloc (tmp_pool, var_cnt, sizeof *formats);
       format_cnt = var_cnt;
Index: src/language/dictionary/apply-dictionary.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/apply-dictionary.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 apply-dictionary.c
--- src/language/dictionary/apply-dictionary.c	26 Oct 2006 06:16:36 -0000	1.9
+++ src/language/dictionary/apply-dictionary.c	11 Nov 2006 00:13:14 -0000
@@ -39,7 +39,7 @@
 
 /* Parses and executes APPLY DICTIONARY. */
 int
-cmd_apply_dictionary (struct dataset *ds)
+cmd_apply_dictionary (struct lexer *lexer, struct dataset *ds)
 {
   struct file_handle *handle;
   struct any_reader *reader;
@@ -49,9 +49,9 @@
 
   int i;
   
-  lex_match_id ("FROM");
-  lex_match ('=');
-  handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+  lex_match_id (lexer, "FROM");
+  lex_match (lexer, '=');
+  handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
   if (!handle)
     return CMD_FAILURE;
 
@@ -136,5 +136,5 @@
   
   any_reader_close (reader);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
Index: src/language/dictionary/formats.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/formats.c,v
retrieving revision 1.12
diff -b -w -U3 -r1.12 formats.c
--- src/language/dictionary/formats.c	3 Nov 2006 04:53:51 -0000	1.12
+++ src/language/dictionary/formats.c	11 Nov 2006 00:13:14 -0000
@@ -42,28 +42,28 @@
     FORMATS_WRITE = 002
   };
 
-static int internal_cmd_formats (struct dataset *ds, int);
+static int internal_cmd_formats (struct lexer *, struct dataset *ds, int);
 
 int
-cmd_print_formats (struct dataset *ds)
+cmd_print_formats (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_formats (ds, FORMATS_PRINT);
+  return internal_cmd_formats (lexer, ds, FORMATS_PRINT);
 }
 
 int
-cmd_write_formats (struct dataset *ds)
+cmd_write_formats (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_formats (ds, FORMATS_WRITE);
+  return internal_cmd_formats (lexer, ds, FORMATS_WRITE);
 }
 
 int
-cmd_formats (struct dataset *ds)
+cmd_formats (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_formats (ds, FORMATS_PRINT | FORMATS_WRITE);
+  return internal_cmd_formats (lexer, ds, FORMATS_PRINT | FORMATS_WRITE);
 }
 
 static int
-internal_cmd_formats (struct dataset *ds, int which)
+internal_cmd_formats (struct lexer *lexer, struct dataset *ds, int which)
 {
   /* Variables. */
   struct variable **v;
@@ -80,24 +80,24 @@
 
   for (;;)
     {
-      if (token == '.')
+      if (lex_token (lexer) == '.')
 	break;
 
-      if (!parse_variables (dataset_dict (ds), &v, &cv, PV_NUMERIC))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &cv, PV_NUMERIC))
 	return CMD_FAILURE;
       type = v[0]->type;
 
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
 	{
 	  msg (SE, _("`(' expected after variable list."));
 	  goto fail;
 	}
-      if (!parse_format_specifier (&f)
+      if (!parse_format_specifier (lexer, &f)
           || !fmt_check_output (&f)
           || !fmt_check_type_compat (&f, NUMERIC))
 	goto fail;
 
-      if (!lex_match (')'))
+      if (!lex_match (lexer, ')'))
 	{
 	  msg (SE, _("`)' expected after output format."));
 	  goto fail;
Index: src/language/dictionary/missing-values.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/missing-values.c,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 missing-values.c
--- src/language/dictionary/missing-values.c	3 Nov 2006 04:53:51 -0000	1.10
+++ src/language/dictionary/missing-values.c	11 Nov 2006 00:13:14 -0000
@@ -37,7 +37,7 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_missing_values (struct dataset *ds)
+cmd_missing_values (struct lexer *lexer, struct dataset *ds)
 {
   struct variable **v;
   size_t nv;
@@ -45,23 +45,23 @@
   int retval = CMD_FAILURE;
   bool deferred_errors = false;
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE)) 
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE)) 
         goto done;
 
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
         {
-          lex_error (_("expecting `('"));
+          lex_error (lexer, _("expecting `('"));
           goto done;
         }
 
       for (i = 0; i < nv; i++)
         mv_init (&v[i]->miss, v[i]->width);
 
-      if (!lex_match (')')) 
+      if (!lex_match (lexer, ')')) 
         {
           struct missing_values mv;
 
@@ -79,12 +79,12 @@
           if (v[0]->type == NUMERIC) 
             {
               mv_init (&mv, 0);
-              while (!lex_match (')'))
+              while (!lex_match (lexer, ')'))
                 {
                   double x, y;
                   bool ok;
 
-                  if (!parse_num_range (&x, &y, &v[0]->print))
+                  if (!parse_num_range (lexer, &x, &y, &v[0]->print))
                     goto done;
                   
                   ok = (x == y
@@ -93,35 +93,39 @@
                   if (!ok)
                     deferred_errors = true;
 
-                  lex_match (',');
+                  lex_match (lexer, ',');
                 }
             }
           else 
             {
+	      struct string value;
+
               mv_init (&mv, MAX_SHORT_STRING);
-              while (!lex_match (')')) 
+              while (!lex_match (lexer, ')')) 
                 {
-                  if (!lex_force_string ())
+                  if (!lex_force_string (lexer))
                     {
                       deferred_errors = true;
                       break;
                     }
 
-                  if (ds_length (&tokstr) > MAX_SHORT_STRING) 
+		  ds_init_string (&value, lex_tokstr (lexer));
+
+                  if (ds_length (&value) > MAX_SHORT_STRING) 
                     {
-                      ds_truncate (&tokstr, MAX_SHORT_STRING);
+                      ds_truncate (&value, MAX_SHORT_STRING);
                       msg (SE, _("Truncating missing value to short string "
                                  "length (%d characters)."),
                            MAX_SHORT_STRING);
                     }
                   else
-                    ds_rpad (&tokstr, MAX_SHORT_STRING, ' ');
+                    ds_rpad (&value, MAX_SHORT_STRING, ' ');
 
-                  if (!mv_add_str (&mv, ds_data (&tokstr)))
+                  if (!mv_add_str (&mv, ds_data (&value)))
                     deferred_errors = true;
 
-                  lex_get ();
-                  lex_match (',');
+                  lex_get (lexer);
+                  lex_match (lexer, ',');
                 }
             }
           
@@ -142,11 +146,11 @@
             }
         }
 
-      lex_match ('/');
+      lex_match (lexer, '/');
       free (v);
       v = NULL;
     }
-  retval = lex_end_of_command ();
+  retval = lex_end_of_command (lexer);
   
  done:
   free (v);
Index: src/language/dictionary/modify-variables.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/modify-variables.c,v
retrieving revision 1.11
diff -b -w -U3 -r1.11 modify-variables.c
--- src/language/dictionary/modify-variables.c	29 Oct 2006 09:51:36 -0000	1.11
+++ src/language/dictionary/modify-variables.c	11 Nov 2006 00:13:14 -0000
@@ -78,7 +78,7 @@
 
 /* Performs MODIFY VARS command. */
 int
-cmd_modify_vars (struct dataset *ds)
+cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
 {
   /* Bits indicated whether we've already encountered a subcommand of
      this type. */
@@ -105,10 +105,10 @@
   vm.drop_cnt = 0;
 
   /* Parse each subcommand. */
-  lex_match ('/');
+  lex_match (lexer, '/');
   for (;;)
     {
-      if (lex_match_id ("REORDER"))
+      if (lex_match_id (lexer, "REORDER"))
 	{
 	  struct variable **v = NULL;
 	  size_t nv = 0;
@@ -120,21 +120,21 @@
 	    }
 	  already_encountered |= 1;
 
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 	  do
 	    {
               struct ordering ordering;
 	      size_t prev_nv = nv;
 
 	      ordering.forward = ordering.positional = 1;
-	      if (lex_match_id ("FORWARD"));
-	      else if (lex_match_id ("BACKWARD"))
+	      if (lex_match_id (lexer, "FORWARD"));
+	      else if (lex_match_id (lexer, "BACKWARD"))
 		ordering.forward = 0;
-	      if (lex_match_id ("POSITIONAL"));
-	      else if (lex_match_id ("ALPHA"))
+	      if (lex_match_id (lexer, "POSITIONAL"));
+	      else if (lex_match_id (lexer, "ALPHA"))
 		ordering.positional = 0;
 
-	      if (lex_match (T_ALL) || token == '/' || token == '.')
+	      if (lex_match (lexer, T_ALL) || lex_token (lexer) == '/' || lex_token (lexer) == '.')
 		{
 		  if (prev_nv != 0)
 		    {
@@ -146,19 +146,19 @@
 		}
 	      else
 		{
-		  if (!lex_match ('('))
+		  if (!lex_match (lexer, '('))
 		    {
 		      msg (SE, _("`(' expected on REORDER subcommand."));
 		      free (v);
 		      goto done;
 		    }
-		  if (!parse_variables (dataset_dict (ds), &v, &nv,
+		  if (!parse_variables (lexer, dataset_dict (ds), &v, &nv,
 					PV_APPEND | PV_NO_DUPLICATE))
 		    {
 		      free (v);
 		      goto done;
 		    }
-		  if (!lex_match (')'))
+		  if (!lex_match (lexer, ')'))
 		    {
 		      msg (SE, _("`)' expected following variable names on "
 			   "REORDER subcommand."));
@@ -169,12 +169,12 @@
 	      sort (&v[prev_nv], nv - prev_nv, sizeof *v,
                     compare_variables_given_ordering, &ordering);
 	    }
-	  while (token != '/' && token != '.');
+	  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
 	  vm.reorder_vars = v;
           vm.reorder_cnt = nv;
 	}
-      else if (lex_match_id ("RENAME"))
+      else if (lex_match_id (lexer, "RENAME"))
 	{
 	  if (already_encountered & 2)
 	    {
@@ -183,27 +183,29 @@
 	    }
 	  already_encountered |= 2;
 
-	  lex_match ('=');
+	  lex_match (lexer, '=');
 	  do
 	    {
 	      size_t prev_nv_1 = vm.rename_cnt;
 	      size_t prev_nv_2 = vm.rename_cnt;
 
-	      if (!lex_match ('('))
+	      if (!lex_match (lexer, '('))
 		{
 		  msg (SE, _("`(' expected on RENAME subcommand."));
 		  goto done;
 		}
-	      if (!parse_variables (dataset_dict (ds), &vm.rename_vars, &vm.rename_cnt,
+	      if (!parse_variables (lexer, dataset_dict (ds), 
+				    &vm.rename_vars, &vm.rename_cnt,
 				    PV_APPEND | PV_NO_DUPLICATE))
 		goto done;
-	      if (!lex_match ('='))
+	      if (!lex_match (lexer, '='))
 		{
 		  msg (SE, _("`=' expected between lists of new and old variable "
 		       "names on RENAME subcommand."));
 		  goto done;
 		}
-	      if (!parse_DATA_LIST_vars (&vm.new_names, &prev_nv_1, PV_APPEND))
+	      if (!parse_DATA_LIST_vars (lexer, &vm.new_names, 
+					 &prev_nv_1, PV_APPEND))
 		goto done;
 	      if (prev_nv_1 != vm.rename_cnt)
 		{
@@ -216,16 +218,16 @@
 		  vm.new_names = NULL;
 		  goto done;
 		}
-	      if (!lex_match (')'))
+	      if (!lex_match (lexer, ')'))
 		{
 		  msg (SE, _("`)' expected after variable lists on RENAME "
 		       "subcommand."));
 		  goto done;
 		}
 	    }
-	  while (token != '.' && token != '/');
+	  while (lex_token (lexer) != '.' && lex_token (lexer) != '/');
 	}
-      else if (lex_match_id ("KEEP"))
+      else if (lex_match_id (lexer, "KEEP"))
 	{
 	  struct variable **keep_vars, **all_vars, **drop_vars;
 	  size_t keep_cnt, all_cnt, drop_cnt;
@@ -238,8 +240,8 @@
 	    }
 	  already_encountered |= 4;
 
-	  lex_match ('=');
-	  if (!parse_variables (dataset_dict (ds), &keep_vars, &keep_cnt, PV_NONE))
+	  lex_match (lexer, '=');
+	  if (!parse_variables (lexer, dataset_dict (ds), &keep_vars, &keep_cnt, PV_NONE))
 	    goto done;
 
 	  /* Transform the list of variables to keep into a list of
@@ -268,7 +270,7 @@
           vm.drop_vars = drop_vars;
           vm.drop_cnt = drop_cnt;
 	}
-      else if (lex_match_id ("DROP"))
+      else if (lex_match_id (lexer, "DROP"))
 	{
 	  struct variable **drop_vars;
 	  size_t drop_cnt;
@@ -282,13 +284,13 @@
 	    }
 	  already_encountered |= 4;
 
-	  lex_match ('=');
-	  if (!parse_variables (dataset_dict (ds), &drop_vars, &drop_cnt, PV_NONE))
+	  lex_match (lexer, '=');
+	  if (!parse_variables (lexer, dataset_dict (ds), &drop_vars, &drop_cnt, PV_NONE))
 	    goto done;
           vm.drop_vars = drop_vars;
           vm.drop_cnt = drop_cnt;
 	}
-      else if (lex_match_id ("MAP"))
+      else if (lex_match_id (lexer, "MAP"))
 	{
           struct dictionary *temp = dict_clone (dataset_dict (ds));
           int success = rearrange_dict (temp, &vm);
@@ -300,21 +302,21 @@
 	}
       else
 	{
-	  if (token == T_ID)
-	    msg (SE, _("Unrecognized subcommand name `%s'."), tokid);
+	  if (lex_token (lexer) == T_ID)
+	    msg (SE, _("Unrecognized subcommand name `%s'."), lex_tokid (lexer));
 	  else
 	    msg (SE, _("Subcommand name expected."));
 	  goto done;
 	}
 
-      if (token == '.')
+      if (lex_token (lexer) == '.')
 	break;
-      if (token != '/')
+      if (lex_token (lexer) != '/')
 	{
 	  msg (SE, _("`/' or `.' expected."));
 	  goto done;
 	}
-      lex_get ();
+      lex_get (lexer);
     }
 
   if (already_encountered & (1 | 4))
Index: src/language/dictionary/numeric.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/numeric.c,v
retrieving revision 1.15
diff -b -w -U3 -r1.15 numeric.c
--- src/language/dictionary/numeric.c	5 Nov 2006 05:20:53 -0000	1.15
+++ src/language/dictionary/numeric.c	11 Nov 2006 00:13:14 -0000
@@ -37,7 +37,7 @@
 
 /* Parses the NUMERIC command. */
 int
-cmd_numeric (struct dataset *ds)
+cmd_numeric (struct lexer *lexer, struct dataset *ds)
 {
   size_t i;
 
@@ -51,13 +51,13 @@
 
   do
     {
-      if (!parse_DATA_LIST_vars (&v, &nv, PV_NONE))
+      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NONE))
 	return CMD_FAILURE;
 
       /* Get the optional format specification. */
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
 	{
-	  if (!parse_format_specifier (&f))
+	  if (!parse_format_specifier (lexer, &f))
 	    goto fail;
 	  if (fmt_is_string (f.type))
 	    {
@@ -67,7 +67,7 @@
 	      goto fail;
 	    }
 
-	  if (!lex_match (')'))
+	  if (!lex_match (lexer, ')'))
 	    {
 	      msg (SE, _("`)' expected after output format."));
 	      goto fail;
@@ -94,9 +94,9 @@
 	free (v[i]);
       free (v);
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
   /* If we have an error at a point where cleanup is required,
      flow-of-control comes here. */
@@ -109,7 +109,7 @@
 
 /* Parses the STRING command. */
 int
-cmd_string (struct dataset *ds)
+cmd_string (struct lexer *lexer, struct dataset *ds)
 {
   size_t i;
 
@@ -125,12 +125,12 @@
 
   do
     {
-      if (!parse_DATA_LIST_vars (&v, &nv, PV_NONE))
+      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NONE))
 	return CMD_FAILURE;
 
-      if (!lex_force_match ('(')
-          || !parse_format_specifier (&f)
-          || !lex_force_match (')'))
+      if (!lex_force_match (lexer, '(')
+          || !parse_format_specifier (lexer, &f)
+          || !lex_force_match (lexer, ')'))
 	goto fail;
       if (!fmt_is_string (f.type))
 	{
@@ -160,9 +160,9 @@
 	free (v[i]);
       free (v);
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
   /* If we have an error at a point where cleanup is required,
      flow-of-control comes here. */
@@ -175,18 +175,18 @@
 
 /* Parses the LEAVE command. */
 int
-cmd_leave (struct dataset *ds)
+cmd_leave (struct lexer *lexer, struct dataset *ds)
 {
   struct variable **v;
   size_t nv;
 
   size_t i;
 
-  if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+  if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
     return CMD_CASCADING_FAILURE;
   for (i = 0; i < nv; i++)
     v[i]->leave = true;
   free (v);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
Index: src/language/dictionary/rename-variables.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/rename-variables.c,v
retrieving revision 1.7
diff -b -w -U3 -r1.7 rename-variables.c
--- src/language/dictionary/rename-variables.c	26 Oct 2006 06:16:36 -0000	1.7
+++ src/language/dictionary/rename-variables.c	11 Nov 2006 00:13:14 -0000
@@ -38,7 +38,7 @@
 /* The code for this function is very similar to the code for the
    RENAME subcommand of MODIFY VARS. */
 int
-cmd_rename_variables (struct dataset *ds)
+cmd_rename_variables (struct lexer *lexer, struct dataset *ds)
 {
   struct variable **rename_vars = NULL;
   char **rename_new_names = NULL;
@@ -56,20 +56,20 @@
       size_t prev_nv_1 = rename_cnt;
       size_t prev_nv_2 = rename_cnt;
 
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
 	{
 	  msg (SE, _("`(' expected."));
 	  goto lossage;
 	}
-      if (!parse_variables (dataset_dict (ds), &rename_vars, &rename_cnt,
+      if (!parse_variables (lexer, dataset_dict (ds), &rename_vars, &rename_cnt,
 			    PV_APPEND | PV_NO_DUPLICATE))
 	goto lossage;
-      if (!lex_match ('='))
+      if (!lex_match (lexer, '='))
 	{
 	  msg (SE, _("`=' expected between lists of new and old variable names."));
 	  goto lossage;
 	}
-      if (!parse_DATA_LIST_vars (&rename_new_names, &prev_nv_1, PV_APPEND))
+      if (!parse_DATA_LIST_vars (lexer, &rename_new_names, &prev_nv_1, PV_APPEND))
 	goto lossage;
       if (prev_nv_1 != rename_cnt)
 	{
@@ -85,13 +85,13 @@
 	  rename_new_names = NULL;
 	  goto lossage;
 	}
-      if (!lex_match (')'))
+      if (!lex_match (lexer, ')'))
 	{
 	  msg (SE, _("`)' expected after variable names."));
 	  goto lossage;
 	}
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
 
   if (!dict_rename_vars (dataset_dict (ds),
                          rename_vars, rename_new_names, rename_cnt,
Index: src/language/dictionary/split-file.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/split-file.c,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 split-file.c
--- src/language/dictionary/split-file.c	5 Nov 2006 05:20:53 -0000	1.10
+++ src/language/dictionary/split-file.c	11 Nov 2006 00:13:14 -0000
@@ -42,9 +42,9 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_split_file (struct dataset *ds)
+cmd_split_file (struct lexer *lexer, struct dataset *ds)
 {
-  if (lex_match_id ("OFF"))
+  if (lex_match_id (lexer, "OFF"))
     dict_set_split_vars (dataset_dict (ds), NULL, 0);
   else
     {
@@ -52,17 +52,17 @@
       size_t n;
 
       /* For now, ignore SEPARATE and LAYERED. */
-      (void) ( lex_match_id ("SEPARATE") || lex_match_id ("LAYERED") );
+      (void) ( lex_match_id (lexer, "SEPARATE") || lex_match_id (lexer, "LAYERED") );
       
-      lex_match (T_BY);
-      if (!parse_variables (dataset_dict (ds), &v, &n, PV_NO_DUPLICATE))
+      lex_match (lexer, T_BY);
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &n, PV_NO_DUPLICATE))
 	return CMD_CASCADING_FAILURE;
 
       dict_set_split_vars (dataset_dict (ds), v, n);
       free (v);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Dumps out the values of all the split variables for the case C. */
Index: src/language/dictionary/sys-file-info.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/sys-file-info.c,v
retrieving revision 1.13
diff -b -w -U3 -r1.13 sys-file-info.c
--- src/language/dictionary/sys-file-info.c	3 Nov 2006 04:53:51 -0000	1.13
+++ src/language/dictionary/sys-file-info.c	11 Nov 2006 00:13:15 -0000
@@ -78,7 +78,7 @@
 
 /* SYSFILE INFO utility. */
 int
-cmd_sysfile_info (struct dataset *ds UNUSED)
+cmd_sysfile_info (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   struct file_handle *h;
   struct dictionary *d;
@@ -88,10 +88,10 @@
   int r, nr;
   int i;
 
-  lex_match_id ("FILE");
-  lex_match ('=');
+  lex_match_id (lexer, "FILE");
+  lex_match (lexer, '=');
 
-  h = fh_parse (FH_REF_FILE);
+  h = fh_parse (lexer, FH_REF_FILE);
   if (!h)
     return CMD_FAILURE;
 
@@ -170,7 +170,7 @@
 
   dict_destroy (d);
   
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* DISPLAY utility. */
@@ -181,7 +181,7 @@
 static void display_vectors (const struct dictionary *dict, int sorted);
 
 int
-cmd_display (struct dataset *ds)
+cmd_display (struct lexer *lexer, struct dataset *ds)
 {
   /* Whether to sort the list of variables alphabetically. */
   int sorted;
@@ -190,14 +190,14 @@
   size_t n;
   struct variable **vl;
 
-  if (lex_match_id ("MACROS"))
+  if (lex_match_id (lexer, "MACROS"))
     display_macros ();
-  else if (lex_match_id ("DOCUMENTS"))
+  else if (lex_match_id (lexer, "DOCUMENTS"))
     display_documents (dataset_dict (ds));
-  else if (lex_match_id ("FILE"))
+  else if (lex_match_id (lexer, "FILE"))
     {
       som_blank_line ();
-      if (!lex_force_match_id ("LABEL"))
+      if (!lex_force_match_id (lexer, "LABEL"))
 	return CMD_FAILURE;
       if (dict_get_label (dataset_dict (ds)) == NULL)
 	tab_output_text (TAB_LEFT,
@@ -216,12 +216,12 @@
       const char **cp;
       int as;
 
-      sorted = lex_match_id ("SORTED");
+      sorted = lex_match_id (lexer, "SORTED");
 
       for (cp = sbc; *cp; cp++)
-	if (token == T_ID && lex_id_match (*cp, tokid))
+	if (lex_token (lexer) == T_ID && lex_id_match (*cp, lex_tokid (lexer)))
 	  {
-	    lex_get ();
+	    lex_get (lexer);
 	    break;
 	  }
       as = cp - sbc;
@@ -235,13 +235,13 @@
 	  return CMD_SUCCESS;
 	}
 
-      lex_match ('/');
-      lex_match_id ("VARIABLES");
-      lex_match ('=');
+      lex_match (lexer, '/');
+      lex_match_id (lexer, "VARIABLES");
+      lex_match (lexer, '=');
 
-      if (token != '.')
+      if (lex_token (lexer) != '.')
 	{
-	  if (!parse_variables (dataset_dict (ds), &vl, &n, PV_NONE))
+	  if (!parse_variables (lexer, dataset_dict (ds), &vl, &n, PV_NONE))
 	    {
 	      free (vl);
 	      return CMD_FAILURE;
@@ -278,7 +278,7 @@
       free (vl);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 static void
Index: src/language/dictionary/value-labels.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/value-labels.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 value-labels.c
--- src/language/dictionary/value-labels.c	26 Oct 2006 06:16:36 -0000	1.9
+++ src/language/dictionary/value-labels.c	11 Nov 2006 00:13:15 -0000
@@ -38,39 +38,40 @@
 
 /* Declarations. */
 
-static int do_value_labels (const struct dictionary *dict, int);
+static int do_value_labels (struct lexer *, 
+			    const struct dictionary *dict, int);
 static int verify_val_labs (struct variable **vars, size_t var_cnt);
 static void erase_labels (struct variable **vars, size_t var_cnt);
-static int get_label (struct variable **vars, size_t var_cnt);
+static int get_label (struct lexer *, struct variable **vars, size_t var_cnt);
 
 /* Stubs. */
 
 int
-cmd_value_labels (struct dataset *ds)
+cmd_value_labels (struct lexer *lexer, struct dataset *ds)
 {
-  return do_value_labels (dataset_dict (ds), 1);
+  return do_value_labels (lexer, dataset_dict (ds), 1);
 }
 
 int
-cmd_add_value_labels (struct dataset *ds)
+cmd_add_value_labels (struct lexer *lexer, struct dataset *ds)
 {
-  return do_value_labels (dataset_dict (ds), 0);
+  return do_value_labels (lexer, dataset_dict (ds), 0);
 }
 
 /* Do it. */
 
 static int
-do_value_labels (const struct dictionary *dict, int erase)
+do_value_labels (struct lexer *lexer, const struct dictionary *dict, int erase)
 {
   struct variable **vars; /* Variable list. */
   size_t var_cnt;         /* Number of variables. */
   int parse_err=0;        /* true if error parsing variables */
 
-  lex_match ('/');
+  lex_match (lexer, '/');
   
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      parse_err = !parse_variables (dict, &vars, &var_cnt, 
+      parse_err = !parse_variables (lexer, dict, &vars, &var_cnt, 
 				    PV_SAME_TYPE) ;
       if (var_cnt < 1)
 	{
@@ -81,17 +82,17 @@
         goto lossage;
       if (erase)
         erase_labels (vars, var_cnt);
-      while (token != '/' && token != '.')
-	if (!get_label (vars, var_cnt))
+      while (lex_token (lexer) != '/' && lex_token (lexer) != '.')
+	if (!get_label (lexer, vars, var_cnt))
           goto lossage;
 
-      if (token != '/')
+      if (lex_token (lexer) != '/')
 	{
 	free (vars);
 	break;
 	}
 
-      lex_get ();
+      lex_get (lexer);
 
       free (vars);
     }
@@ -99,7 +100,7 @@
   if (parse_err)
     return CMD_FAILURE;
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
  lossage:
   free (vars);
@@ -141,54 +142,56 @@
 /* Parse all the labels for the VAR_CNT variables in VARS and add
    the specified labels to those variables.  */
 static int
-get_label (struct variable **vars, size_t var_cnt)
+get_label (struct lexer *lexer, struct variable **vars, size_t var_cnt)
 {
   /* Parse all the labels and add them to the variables. */
   do
     {
       union value value;
-      char *label;
+      struct string label;
       size_t i;
 
       /* Set value. */
       if (vars[0]->type == ALPHA)
 	{
-	  if (token != T_STRING)
+	  if (lex_token (lexer) != T_STRING)
 	    {
-              lex_error (_("expecting string"));
+              lex_error (lexer, _("expecting string"));
 	      return 0;
 	    }
-	  buf_copy_str_rpad (value.s, MAX_SHORT_STRING, ds_cstr (&tokstr));
+	  buf_copy_str_rpad (value.s, MAX_SHORT_STRING, ds_cstr (lex_tokstr (lexer)));
 	}
       else
 	{
-	  if (!lex_is_number ())
+	  if (!lex_is_number (lexer))
 	    {
-	      lex_error (_("expecting integer"));
+	      lex_error (lexer, _("expecting integer"));
 	      return 0;
 	    }
-	  if (!lex_is_integer ())
-	    msg (SW, _("Value label `%g' is not integer."), tokval);
-	  value.f = tokval;
+	  if (!lex_is_integer (lexer))
+	    msg (SW, _("Value label `%g' is not integer."), lex_tokval (lexer));
+	  value.f = lex_tokval (lexer);
 	}
-      lex_get ();
+      lex_get (lexer);
 
       /* Set label. */
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
 	return 0;
-      if (ds_length (&tokstr) > 60)
+      
+      ds_init_string (&label, lex_tokstr (lexer));
+
+      if (ds_length (&label) > 60)
 	{
 	  msg (SW, _("Truncating value label to 60 characters."));
-	  ds_truncate (&tokstr, 60);
+	  ds_truncate (&label, 60);
 	}
-      label = ds_cstr (&tokstr);
 
       for (i = 0; i < var_cnt; i++)
-        val_labs_replace (vars[i]->val_labs, value, label);
+        val_labs_replace (vars[i]->val_labs, value, ds_cstr (&label));
 
-      lex_get ();
+      lex_get (lexer);
     }
-  while (token != '/' && token != '.');
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
   return 1;
 }
Index: src/language/dictionary/variable-display.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/variable-display.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 variable-display.c
--- src/language/dictionary/variable-display.c	26 Oct 2006 06:16:36 -0000	1.9
+++ src/language/dictionary/variable-display.c	11 Nov 2006 00:13:15 -0000
@@ -36,7 +36,7 @@
    It affects nothing but GUIs
 */
 int
-cmd_variable_alignment (struct dataset *ds)
+cmd_variable_alignment (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -46,16 +46,16 @@
       size_t i;
       enum alignment align;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match('(') ) 
+      if ( lex_force_match (lexer, '(') ) 
 	{
-	  if ( lex_match_id("LEFT"))
+	  if ( lex_match_id (lexer, "LEFT"))
 	    align = ALIGN_LEFT;
-	  else if ( lex_match_id("RIGHT"))
+	  else if ( lex_match_id (lexer, "RIGHT"))
 	    align = ALIGN_RIGHT;
-	  else if ( lex_match_id("CENTER"))
+	  else if ( lex_match_id (lexer, "CENTER"))
 	    align = ALIGN_CENTRE;
 	  else 
             {
@@ -63,7 +63,7 @@
               return CMD_FAILURE; 
             }
 
-	  lex_force_match(')');
+	  lex_force_match (lexer, ')');
 	}
       else 
         {
@@ -75,12 +75,12 @@
 	v[i]->alignment = align;
 
 
-      while (token == '/')
-	lex_get ();
+      while (lex_token (lexer) == '/')
+	lex_get (lexer);
       free (v);
 
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }
 
@@ -89,7 +89,7 @@
    It affects nothing but GUIs
 */
 int
-cmd_variable_width (struct dataset *ds)
+cmd_variable_width (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -97,33 +97,33 @@
       size_t nv;
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match('(') ) 
+      if ( lex_force_match (lexer, '(') ) 
 	{
-	  if ( lex_force_int()) 
-	    lex_get();
+	  if ( lex_force_int (lexer)) 
+	    lex_get (lexer);
 	  else
 	    return CMD_FAILURE;
-	  lex_force_match(')');
+	  lex_force_match (lexer, ')');
 	}
 
       for( i = 0 ; i < nv ; ++i ) 
-	  v[i]->display_width = tokval;
+	  v[i]->display_width = lex_tokval (lexer);
 
-      while (token == '/')
-	lex_get ();
+      while (lex_token (lexer) == '/')
+	lex_get (lexer);
       free (v);
 
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }
 
 /* Set variables' measurement level */
 int
-cmd_variable_level (struct dataset *ds)
+cmd_variable_level (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -132,16 +132,16 @@
       enum measure level;
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match('(') ) 
+      if ( lex_force_match (lexer, '(') ) 
 	{
-	  if ( lex_match_id("SCALE"))
+	  if ( lex_match_id (lexer, "SCALE"))
 	    level = MEASURE_SCALE;
-	  else if ( lex_match_id("ORDINAL"))
+	  else if ( lex_match_id (lexer, "ORDINAL"))
 	    level = MEASURE_ORDINAL;
-	  else if ( lex_match_id("NOMINAL"))
+	  else if ( lex_match_id (lexer, "NOMINAL"))
 	    level = MEASURE_NOMINAL;
 	  else 
             {
@@ -149,7 +149,7 @@
               return CMD_FAILURE; 
             }
 
-	  lex_force_match(')');
+	  lex_force_match (lexer, ')');
 	}
       else
         {
@@ -161,11 +161,11 @@
 	v[i]->measure = level ;
 
 
-      while (token == '/')
-	lex_get ();
+      while (lex_token (lexer) == '/')
+	lex_get (lexer);
       free (v);
 
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }
Index: src/language/dictionary/variable-label.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/variable-label.c,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 variable-label.c
--- src/language/dictionary/variable-label.c	26 Oct 2006 06:16:36 -0000	1.10
+++ src/language/dictionary/variable-label.c	11 Nov 2006 00:13:15 -0000
@@ -35,42 +35,45 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_variable_labels (struct dataset *ds)
+cmd_variable_labels (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
       struct variable **v;
+      struct string label;
       size_t nv;
 
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if (token != T_STRING)
+      if (lex_token (lexer) != T_STRING)
 	{
 	  msg (SE, _("String expected for variable label."));
 	  free (v);
 	  return CMD_FAILURE;
 	}
-      if (ds_length (&tokstr) > 255)
+
+      ds_init_string (&label, lex_tokstr (lexer) );
+      if (ds_length (&label) > 255)
 	{
 	  msg (SW, _("Truncating variable label to 255 characters."));
-	  ds_truncate (&tokstr, 255);
+	  ds_truncate (&label, 255);
 	}
       for (i = 0; i < nv; i++)
 	{
 	  if (v[i]->label)
 	    free (v[i]->label);
-	  v[i]->label = ds_xstrdup (&tokstr);
+	  v[i]->label = ds_xstrdup (&label);
 	}
 
-      lex_get ();
-      while (token == '/')
-	lex_get ();
+      lex_get (lexer);
+      while (lex_token (lexer) == '/')
+	lex_get (lexer);
       free (v);
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }
 
Index: src/language/dictionary/vector.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/vector.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 vector.c
--- src/language/dictionary/vector.c	26 Oct 2006 06:16:36 -0000	1.9
+++ src/language/dictionary/vector.c	11 Nov 2006 00:13:15 -0000
@@ -37,7 +37,7 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_vector (struct dataset *ds)
+cmd_vector (struct lexer *lexer, struct dataset *ds)
 {
   /* Just to be different, points to a set of null terminated strings
      containing the names of the vectors to be created.  The list
@@ -58,9 +58,9 @@
   do
     {
       /* Get the name(s) of the new vector(s). */
-      if (!lex_force_id ())
+      if (!lex_force_id (lexer))
 	return CMD_CASCADING_FAILURE;
-      while (token == T_ID)
+      while (lex_token (lexer) == T_ID)
 	{
 	  if (cp + 16 > endp)
 	    {
@@ -71,27 +71,27 @@
 	    }
 
 	  for (cp2 = cp; cp2 < cp; cp2 += strlen (cp))
-	    if (!strcasecmp (cp2, tokid))
+	    if (!strcasecmp (cp2, lex_tokid (lexer)))
 	      {
-		msg (SE, _("Vector name %s is given twice."), tokid);
+		msg (SE, _("Vector name %s is given twice."), lex_tokid (lexer));
 		goto fail;
 	      }
 
-	  if (dict_lookup_vector (dict, tokid))
+	  if (dict_lookup_vector (dict, lex_tokid (lexer)))
 	    {
-	      msg (SE, _("There is already a vector with name %s."), tokid);
+	      msg (SE, _("There is already a vector with name %s."), lex_tokid (lexer));
 	      goto fail;
 	    }
 
-	  cp = stpcpy (cp, tokid) + 1;
-	  lex_get ();
-	  lex_match (',');
+	  cp = stpcpy (cp, lex_tokid (lexer)) + 1;
+	  lex_get (lexer);
+	  lex_match (lexer, ',');
 	}
       *cp++ = 0;
 
       /* Now that we have the names it's time to check for the short
          or long forms. */
-      if (lex_match ('='))
+      if (lex_match (lexer, '='))
 	{
 	  /* Long form. */
           struct variable **v;
@@ -106,14 +106,14 @@
 	      goto fail;
 	    }
 
-	  if (!parse_variables (dict, &v, &nv,
+	  if (!parse_variables (lexer, dict, &v, &nv,
                                 PV_SAME_TYPE | PV_DUPLICATE))
 	    goto fail;
 
           dict_create_vector (dict, vecnames, v, nv);
           free (v);
 	}
-      else if (lex_match ('('))
+      else if (lex_match (lexer, '('))
 	{
 	  int i;
 
@@ -128,16 +128,16 @@
           struct variable **v;
           int nv;
 
-	  if (!lex_force_int ())
+	  if (!lex_force_int (lexer))
 	    return CMD_CASCADING_FAILURE;
-	  nv = lex_integer ();
-	  lex_get ();
+	  nv = lex_integer (lexer);
+	  lex_get (lexer);
 	  if (nv <= 0)
 	    {
 	      msg (SE, _("Vectors must have at least one element."));
 	      goto fail;
 	    }
-	  if (!lex_force_match (')'))
+	  if (!lex_force_match (lexer, ')'))
 	    goto fail;
 
 	  /* First check that all the generated variable names
@@ -196,11 +196,11 @@
       free (vecnames);
       vecnames = NULL;
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
 
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       goto fail;
     }
   return CMD_SUCCESS;
Index: src/language/dictionary/weight.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/weight.c,v
retrieving revision 1.7
diff -b -w -U3 -r1.7 weight.c
--- src/language/dictionary/weight.c	26 Oct 2006 06:16:36 -0000	1.7
+++ src/language/dictionary/weight.c	11 Nov 2006 00:13:15 -0000
@@ -34,17 +34,17 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_weight (struct dataset *ds)
+cmd_weight (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
-  if (lex_match_id ("OFF"))
+  if (lex_match_id (lexer, "OFF"))
     dict_set_weight (dataset_dict (ds), NULL);
   else
     {
       struct variable *v;
 
-      lex_match (T_BY);
-      v = parse_variable (dict);
+      lex_match (lexer, T_BY);
+      v = parse_variable (lexer, dict);
       if (!v)
 	return CMD_CASCADING_FAILURE;
       if (v->type == ALPHA)
@@ -61,5 +61,5 @@
       dict_set_weight (dict, v);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
Index: src/language/expressions/evaluate.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/evaluate.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 evaluate.c
--- src/language/expressions/evaluate.c	3 Nov 2006 04:53:51 -0000	1.9
+++ src/language/expressions/evaluate.c	11 Nov 2006 00:13:15 -0000
@@ -109,7 +109,7 @@
 #include <language/command.h>
 
 int
-cmd_debug_evaluate (struct dataset *dsother UNUSED)
+cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED)
 {
   bool optimize = true;
   int retval = CMD_FAILURE;
@@ -124,38 +124,38 @@
   for (;;) 
     {
       struct dictionary *d = NULL;
-      if (lex_match_id ("NOOPTIMIZE"))
+      if (lex_match_id (lexer, "NOOPTIMIZE"))
         optimize = 0;
-      else if (lex_match_id ("POSTFIX"))
+      else if (lex_match_id (lexer, "POSTFIX"))
         dump_postfix = 1;
-      else if (lex_match ('('))
+      else if (lex_match (lexer, '('))
         {
           char name[LONG_NAME_LEN + 1];
           struct variable *v;
           size_t old_value_cnt;
           int width;
 
-          if (!lex_force_id ())
+          if (!lex_force_id (lexer))
             goto done;
-          strcpy (name, tokid);
+          strcpy (name, lex_tokid (lexer));
 
-          lex_get ();
-          if (!lex_force_match ('='))
+          lex_get (lexer);
+          if (!lex_force_match (lexer, '='))
             goto done;
 
-          if (lex_is_number ())
+          if (lex_is_number (lexer))
             {
               width = 0;
-              fprintf (stderr, "(%s = %.2f)", name, tokval); 
+              fprintf (stderr, "(%s = %.2f)", name, lex_tokval (lexer)); 
             }
-          else if (token == T_STRING) 
+          else if (lex_token (lexer) == T_STRING) 
             {
-              width = ds_length (&tokstr);
-              fprintf (stderr, "(%s = \"%.2s\")", name, ds_cstr (&tokstr)); 
+              width = ds_length (lex_tokstr (lexer));
+              fprintf (stderr, "(%s = \"%.2s\")", name, ds_cstr (lex_tokstr (lexer))); 
             }
           else
             {
-              lex_error (_("expecting number or string"));
+              lex_error (lexer, _("expecting number or string"));
               goto done;
             }
 	  
@@ -181,32 +181,32 @@
           else
             case_resize (c, old_value_cnt, dict_get_next_value_idx (d));
 
-          if (lex_is_number ())
-            case_data_rw (c, v->fv)->f = tokval;
+          if (lex_is_number (lexer))
+            case_data_rw (c, v->fv)->f = lex_tokval (lexer);
           else
-            memcpy (case_data_rw (c, v->fv)->s, ds_data (&tokstr),
+            memcpy (case_data_rw (c, v->fv)->s, ds_data (lex_tokstr (lexer)),
                     v->width);
-          lex_get ();
+          lex_get (lexer);
 
-          if (!lex_force_match (')'))
+          if (!lex_force_match (lexer, ')'))
             goto done;
         }
       else 
         break;
     }
-  if (token != '/') 
+  if (lex_token (lexer) != '/') 
     {
-      lex_force_match ('/');
+      lex_force_match (lexer, '/');
       goto done;
     }
 
   if ( ds != NULL ) 
     fprintf(stderr, "; ");
-  fprintf (stderr, "%s => ", lex_rest_of_line (NULL));
-  lex_get ();
+  fprintf (stderr, "%s => ", lex_rest_of_line (lexer, NULL));
+  lex_get (lexer);
 
-  expr = expr_parse_any (ds, optimize);
-  if (!expr || lex_end_of_command () != CMD_SUCCESS)
+  expr = expr_parse_any (lexer, ds, optimize);
+  if (!expr || lex_end_of_command (lexer) != CMD_SUCCESS)
     {
       if (expr != NULL)
         expr_free (expr);
Index: src/language/expressions/parse.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/parse.c,v
retrieving revision 1.17
diff -b -w -U3 -r1.17 parse.c
--- src/language/expressions/parse.c	3 Nov 2006 04:53:51 -0000	1.17
+++ src/language/expressions/parse.c	11 Nov 2006 00:13:15 -0000
@@ -45,7 +45,7 @@
 /* Declarations. */
 
 /* Recursive descent parser in order of increasing precedence. */
-typedef union any_node *parse_recursively_func (struct expression *);
+typedef union any_node *parse_recursively_func (struct lexer *, struct expression *);
 static parse_recursively_func parse_or, parse_and, parse_not;
 static parse_recursively_func parse_rel, parse_add, parse_mul;
 static parse_recursively_func parse_neg, parse_exp;
@@ -73,7 +73,7 @@
    Returns the new expression if successful or a null pointer
    otherwise. */
 struct expression *
-expr_parse (struct dataset *ds, enum expr_type type) 
+expr_parse (struct lexer *lexer, struct dataset *ds, enum expr_type type) 
 {
   union any_node *n;
   struct expression *e;
@@ -81,7 +81,7 @@
   assert (type == EXPR_NUMBER || type == EXPR_STRING || type == EXPR_BOOLEAN);
 
   e = expr_create (ds);
-  n = parse_or (e);
+  n = parse_or (lexer, e);
   if (n != NULL && type_check (e, &n, type))
     return finish_expression (expr_optimize (n, e), e);
   else
@@ -95,11 +95,12 @@
    expr_parse(), and sets up so that destroying POOL will free
    the expression as well. */
 struct expression *
-expr_parse_pool (struct pool *pool,
+expr_parse_pool (struct lexer *lexer, 
+		 struct pool *pool,
 		 struct dataset *ds, 
                  enum expr_type type) 
 {
-  struct expression *e = expr_parse (ds, type);
+  struct expression *e = expr_parse (lexer, ds, type);
   if (e != NULL)
     pool_add_subpool (pool, e->expr_pool);
   return e;
@@ -114,13 +115,13 @@
 }
 
 struct expression *
-expr_parse_any (struct dataset *ds, bool optimize)
+expr_parse_any (struct lexer *lexer, struct dataset *ds, bool optimize)
 {
   union any_node *n;
   struct expression *e;
 
   e = expr_create (ds);
-  n = parse_or (e);
+  n = parse_or (lexer, e);
   if (n == NULL)
     {
       expr_free (e);
@@ -469,7 +470,7 @@
    On failure, returns false and, if OPERATOR is non-null, sets
    *OPERATOR to a null pointer. */
 static bool
-match_operator (const struct operator ops[], size_t op_cnt,
+match_operator (struct lexer *lexer, const struct operator ops[], size_t op_cnt,
                 const struct operator **operator) 
 {
   const struct operator *op;
@@ -477,8 +478,8 @@
   for (op = ops; op < ops + op_cnt; op++)
     {
       if (op->token == '-')
-        lex_negative_to_dash ();
-      if (lex_match (op->token)) 
+        lex_negative_to_dash (lexer);
+      if (lex_match (lexer, op->token)) 
         {
           if (operator != NULL)
             *operator = op;
@@ -529,7 +530,7 @@
    is non-null, then it will be issued as a warning if more than
    one operator/operand pair is parsed. */
 static union any_node *
-parse_binary_operators (struct expression *e, union any_node *node,
+parse_binary_operators (struct lexer *lexer, struct expression *e, union any_node *node,
                         const struct operator ops[], size_t op_cnt,
                         parse_recursively_func *parse_next_level,
                         const char *chain_warning)
@@ -542,7 +543,7 @@
   if (node == NULL)
     return node;
 
-  for (op_count = 0; match_operator (ops, op_cnt, &operator); op_count++)
+  for (op_count = 0; match_operator (lexer, ops, op_cnt, &operator); op_count++)
     {
       union any_node *rhs;
 
@@ -552,7 +553,7 @@
 
       /* Parse the right-hand side and coerce to type
          OPERAND_TYPE. */
-      rhs = parse_next_level (e);
+      rhs = parse_next_level (lexer, e);
       if (!type_coercion (e, operand_type, &rhs, operator->name))
         return NULL;
       node = expr_allocate_binary (e, operator->type, node, rhs);
@@ -565,7 +566,7 @@
 }
 
 static union any_node *
-parse_inverting_unary_operator (struct expression *e,
+parse_inverting_unary_operator (struct lexer *lexer, struct expression *e,
                                 const struct operator *op,
                                 parse_recursively_func *parse_next_level) 
 {
@@ -575,10 +576,10 @@
   check_operator (op, 1, get_operand_type (op));
 
   op_count = 0;
-  while (match_operator (op, 1, NULL))
+  while (match_operator (lexer, op, 1, NULL))
     op_count++;
 
-  node = parse_next_level (e);
+  node = parse_next_level (lexer, e);
   if (op_count > 0
       && type_coercion (e, get_operand_type (op), &node, op->name)
       && op_count % 2 != 0)
@@ -589,36 +590,37 @@
 
 /* Parses the OR level. */
 static union any_node *
-parse_or (struct expression *e)
+parse_or (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = 
     { T_OR, OP_OR, "logical disjunction (\"OR\")" };
   
-  return parse_binary_operators (e, parse_and (e), &op, 1, parse_and, NULL);
+  return parse_binary_operators (lexer, e, parse_and (lexer, e), &op, 1, parse_and, NULL);
 }
 
 /* Parses the AND level. */
 static union any_node *
-parse_and (struct expression *e)
+parse_and (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = 
     { T_AND, OP_AND, "logical conjunction (\"AND\")" };
   
-  return parse_binary_operators (e, parse_not (e), &op, 1, parse_not, NULL);
+  return parse_binary_operators (lexer, e, parse_not (lexer, e), 
+				 &op, 1, parse_not, NULL);
 }
 
 /* Parses the NOT level. */
 static union any_node *
-parse_not (struct expression *e)
+parse_not (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op
     = { T_NOT, OP_NOT, "logical negation (\"NOT\")" };
-  return parse_inverting_unary_operator (e, &op, parse_rel);
+  return parse_inverting_unary_operator (lexer, e, &op, parse_rel);
 }
 
 /* Parse relational operators. */
 static union any_node *
-parse_rel (struct expression *e)
+parse_rel (struct lexer *lexer, struct expression *e)
 {
   const char *chain_warning = 
     _("Chaining relational operators (e.g. \"a < b < c\") will "
@@ -628,7 +630,7 @@
       "If chaining is really intended, parentheses will disable "
       "this warning (e.g. \"(a < b) < c\".)");
 
-  union any_node *node = parse_add (e);
+  union any_node *node = parse_add (lexer, e);
 
   if (node == NULL)
     return NULL;
@@ -649,7 +651,8 @@
             { T_NE, OP_NE, "numeric inequality (\"<>\")" },
           };
 
-        return parse_binary_operators (e, node, ops, sizeof ops / sizeof *ops,
+        return parse_binary_operators (lexer, e, node, ops, 
+				       sizeof ops / sizeof *ops,
                                        parse_add, chain_warning);
       }
       
@@ -666,7 +669,8 @@
             { T_NE, OP_NE_STRING, "string inequality (\"<>\")" },
           };
 
-        return parse_binary_operators (e, node, ops, sizeof ops / sizeof *ops,
+        return parse_binary_operators (lexer, e, node, ops, 
+				       sizeof ops / sizeof *ops,
                                        parse_add, chain_warning);
       }
       
@@ -677,7 +681,7 @@
 
 /* Parses the addition and subtraction level. */
 static union any_node *
-parse_add (struct expression *e)
+parse_add (struct lexer *lexer, struct expression *e)
 {
   static const struct operator ops[] = 
     {
@@ -685,14 +689,14 @@
       { '-', OP_SUB, "subtraction (\"-\")" },
     };
   
-  return parse_binary_operators (e, parse_mul (e),
+  return parse_binary_operators (lexer, e, parse_mul (lexer, e),
                                  ops, sizeof ops / sizeof *ops,
                                  parse_mul, NULL);
 }
 
 /* Parses the multiplication and division level. */
 static union any_node *
-parse_mul (struct expression *e)
+parse_mul (struct lexer *lexer, struct expression *e)
 {
   static const struct operator ops[] = 
     {
@@ -700,21 +704,21 @@
       { '/', OP_DIV, "division (\"/\")" },
     };
   
-  return parse_binary_operators (e, parse_neg (e),
+  return parse_binary_operators (lexer, e, parse_neg (lexer, e),
                                  ops, sizeof ops / sizeof *ops,
                                  parse_neg, NULL);
 }
 
 /* Parses the unary minus level. */
 static union any_node *
-parse_neg (struct expression *e)
+parse_neg (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = { '-', OP_NEG, "negation (\"-\")" };
-  return parse_inverting_unary_operator (e, &op, parse_exp);
+  return parse_inverting_unary_operator (lexer, e, &op, parse_exp);
 }
 
 static union any_node *
-parse_exp (struct expression *e)
+parse_exp (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = 
     { T_EXP, OP_POW, "exponentiation (\"**\")" };
@@ -725,17 +729,17 @@
       "That is, \"a**b**c\" equals \"(a**b)**c\", not as \"a**(b**c)\".  "
       "To disable this warning, insert parentheses.");
 
-  return parse_binary_operators (e, parse_primary (e), &op, 1,
+  return parse_binary_operators (lexer, e, parse_primary (lexer, e), &op, 1,
                                  parse_primary, chain_warning);
 }
 
 /* Parses system variables. */
 static union any_node *
-parse_sysvar (struct expression *e)
+parse_sysvar (struct lexer *lexer, struct expression *e)
 {
-  if (lex_match_id ("$CASENUM"))
+  if (lex_match_id (lexer, "$CASENUM"))
     return expr_allocate_nullary (e, OP_CASENUM);
-  else if (lex_match_id ("$DATE"))
+  else if (lex_match_id (lexer, "$DATE"))
     {
       static const char *months[12] =
         {
@@ -753,13 +757,13 @@
 
       return expr_allocate_string_buffer (e, temp_buf, strlen (temp_buf));
     }
-  else if (lex_match_id ("$TRUE"))
+  else if (lex_match_id (lexer, "$TRUE"))
     return expr_allocate_boolean (e, 1.0);
-  else if (lex_match_id ("$FALSE"))
+  else if (lex_match_id (lexer, "$FALSE"))
     return expr_allocate_boolean (e, 0.0);
-  else if (lex_match_id ("$SYSMIS"))
+  else if (lex_match_id (lexer, "$SYSMIS"))
     return expr_allocate_number (e, SYSMIS);
-  else if (lex_match_id ("$JDATE"))
+  else if (lex_match_id (lexer, "$JDATE"))
     {
       time_t time = time_of_last_procedure (e->ds);
       struct tm *tm = localtime (&time);
@@ -767,7 +771,7 @@
                                                        tm->tm_mon + 1,
                                                        tm->tm_mday));
     }
-  else if (lex_match_id ("$TIME"))
+  else if (lex_match_id (lexer, "$TIME"))
     {
       time_t time = time_of_last_procedure (e->ds);
       struct tm *tm = localtime (&time);
@@ -779,45 +783,45 @@
                                    + tm->tm_min * 60.
                                    + tm->tm_sec);
     }
-  else if (lex_match_id ("$LENGTH"))
+  else if (lex_match_id (lexer, "$LENGTH"))
     return expr_allocate_number (e, get_viewlength ());
-  else if (lex_match_id ("$WIDTH"))
+  else if (lex_match_id (lexer, "$WIDTH"))
     return expr_allocate_number (e, get_viewwidth ());
   else
     {
-      msg (SE, _("Unknown system variable %s."), tokid);
+      msg (SE, _("Unknown system variable %s."), lex_tokid (lexer));
       return NULL;
     }
 }
 
 /* Parses numbers, varnames, etc. */
 static union any_node *
-parse_primary (struct expression *e)
+parse_primary (struct lexer *lexer, struct expression *e)
 {
-  switch (token)
+  switch (lex_token (lexer))
     {
     case T_ID:
-      if (lex_look_ahead () == '(') 
+      if (lex_look_ahead (lexer) == '(') 
         {
           /* An identifier followed by a left parenthesis may be
              a vector element reference.  If not, it's a function
              call. */
-          if (e->ds != NULL && dict_lookup_vector (dataset_dict (e->ds), tokid) != NULL) 
-            return parse_vector_element (e);
+          if (e->ds != NULL && dict_lookup_vector (dataset_dict (e->ds), lex_tokid (lexer)) != NULL) 
+            return parse_vector_element (lexer, e);
           else
-            return parse_function (e);
+            return parse_function (lexer, e);
         }
-      else if (tokid[0] == '$')
+      else if (lex_tokid (lexer)[0] == '$')
         {
           /* $ at the beginning indicates a system variable. */
-          return parse_sysvar (e);
+          return parse_sysvar (lexer, e);
         }
-      else if (e->ds != NULL && dict_lookup_var (dataset_dict (e->ds), tokid))
+      else if (e->ds != NULL && dict_lookup_var (dataset_dict (e->ds), lex_tokid (lexer)))
         {
           /* It looks like a user variable.
              (It could be a format specifier, but we'll assume
              it's a variable unless proven otherwise. */
-          return allocate_unary_variable (e, parse_variable (dataset_dict (e->ds)));
+          return allocate_unary_variable (e, parse_variable (lexer, dataset_dict (e->ds)));
         }
       else 
         {
@@ -826,14 +830,14 @@
           bool ok;
           
           msg_disable ();
-          ok = parse_format_specifier (&fmt);
+          ok = parse_format_specifier (lexer, &fmt);
           msg_enable ();
 
           if (ok)
             return expr_allocate_format (e, &fmt);
 
           /* All attempts failed. */
-          msg (SE, _("Unknown identifier %s."), tokid);
+          msg (SE, _("Unknown identifier %s."), lex_tokid (lexer));
           return NULL;
         }
       break;
@@ -841,40 +845,40 @@
     case T_POS_NUM: 
     case T_NEG_NUM: 
       {
-        union any_node *node = expr_allocate_number (e, tokval);
-        lex_get ();
+        union any_node *node = expr_allocate_number (e, lex_tokval (lexer) );
+        lex_get (lexer);
         return node; 
       }
 
     case T_STRING:
       {
         union any_node *node = expr_allocate_string_buffer (
-          e, ds_cstr (&tokstr), ds_length (&tokstr));
-	lex_get ();
+          e, ds_cstr (lex_tokstr (lexer) ), ds_length (lex_tokstr (lexer) ));
+	lex_get (lexer);
 	return node;
       }
 
     case '(':
       {
         union any_node *node;
-	lex_get ();
-	node = parse_or (e);
-	if (node != NULL && !lex_match (')'))
+	lex_get (lexer);
+	node = parse_or (lexer, e);
+	if (node != NULL && !lex_match (lexer, ')'))
 	  {
-	    lex_error (_("expecting `)'"));
+	    lex_error (lexer, _("expecting `)'"));
             return NULL;
 	  }
         return node;
       }
 
     default:
-      lex_error (_("in expression"));
+      lex_error (lexer, _("in expression"));
       return NULL;
     }
 }
 
 static union any_node *
-parse_vector_element (struct expression *e)
+parse_vector_element (struct lexer *lexer, struct expression *e)
 {
   const struct vector *vector;
   union any_node *element;
@@ -882,19 +886,19 @@
   /* Find vector, skip token.
      The caller must already have verified that the current token
      is the name of a vector. */
-  vector = dict_lookup_vector (dataset_dict (e->ds), tokid);
+  vector = dict_lookup_vector (dataset_dict (e->ds), lex_tokid (lexer));
   assert (vector != NULL);
-  lex_get ();
+  lex_get (lexer);
 
   /* Skip left parenthesis token.
      The caller must have verified that the lookahead is a left
      parenthesis. */
-  assert (token == '(');
-  lex_get ();
+  assert (lex_token (lexer) == '(');
+  lex_get (lexer);
 
-  element = parse_or (e);
+  element = parse_or (lexer, e);
   if (!type_coercion (e, OP_number, &element, "vector indexing")
-      || !lex_match (')'))
+      || !lex_match (lexer, ')'))
     return NULL;
 
   return expr_allocate_binary (e, (vector->var[0]->type == NUMERIC
@@ -1155,7 +1159,7 @@
 }
 
 static union any_node *
-parse_function (struct expression *e)
+parse_function (struct lexer *lexer, struct expression *e)
 {
   int min_valid;
   const struct operation *f, *first, *last;
@@ -1168,17 +1172,17 @@
 
   union any_node *n;
 
-  ds_init_string (&func_name, &tokstr);
-  min_valid = extract_min_valid (ds_cstr (&tokstr));
-  if (!lookup_function (ds_cstr (&tokstr), &first, &last)) 
+  ds_init_string (&func_name, lex_tokstr (lexer));
+  min_valid = extract_min_valid (ds_cstr (lex_tokstr (lexer)));
+  if (!lookup_function (ds_cstr (lex_tokstr (lexer)), &first, &last)) 
     {
-      msg (SE, _("No function or vector named %s."), ds_cstr (&tokstr));
+      msg (SE, _("No function or vector named %s."), ds_cstr (lex_tokstr (lexer)));
       ds_destroy (&func_name);
       return NULL;
     }
 
-  lex_get ();
-  if (!lex_force_match ('(')) 
+  lex_get (lexer);
+  if (!lex_force_match (lexer, '(')) 
     {
       ds_destroy (&func_name);
       return NULL; 
@@ -1186,16 +1190,16 @@
   
   args = NULL;
   arg_cnt = arg_cap = 0;
-  if (token != ')')
+  if (lex_token (lexer) != ')')
     for (;;)
       {
-        if (token == T_ID && lex_look_ahead () == 'T')
+        if (lex_token (lexer) == T_ID && lex_look_ahead (lexer) == 'T')
           {
             struct variable **vars;
             size_t var_cnt;
             size_t i;
 
-            if (!parse_variables (dataset_dict (e->ds), &vars, &var_cnt, PV_SINGLE))
+            if (!parse_variables (lexer, dataset_dict (e->ds), &vars, &var_cnt, PV_SINGLE))
               goto fail;
             for (i = 0; i < var_cnt; i++)
               add_arg (&args, &arg_cnt, &arg_cap,
@@ -1204,17 +1208,17 @@
           }
         else
           {
-            union any_node *arg = parse_or (e);
+            union any_node *arg = parse_or (lexer, e);
             if (arg == NULL)
               goto fail;
 
             add_arg (&args, &arg_cnt, &arg_cap, arg);
           }
-        if (lex_match (')'))
+        if (lex_match (lexer, ')'))
           break;
-        else if (!lex_match (','))
+        else if (!lex_match (lexer, ','))
           {
-            lex_error (_("expecting `,' or `)' invoking %s function"),
+            lex_error (lexer, _("expecting `,' or `)' invoking %s function"),
                        first->name);
             goto fail;
           }
Index: src/language/expressions/private.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/private.h,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 private.h
--- src/language/expressions/private.h	26 Oct 2006 06:16:36 -0000	1.6
+++ src/language/expressions/private.h	11 Nov 2006 00:13:15 -0000
@@ -168,7 +168,7 @@
     struct pool *eval_pool;     /* Pool for evaluation temporaries. */
   };
 
-struct expression *expr_parse_any (struct dataset *,  bool optimize);
+struct expression *expr_parse_any (struct lexer *lexer, struct dataset *,  bool optimize);
 void expr_debug_print_postfix (const struct expression *);
 
 union any_node *expr_optimize (union any_node *, struct expression *);
Index: src/language/expressions/public.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/public.h,v
retrieving revision 1.2
diff -b -w -U3 -r1.2 public.h
--- src/language/expressions/public.h	26 Oct 2006 06:16:36 -0000	1.2
+++ src/language/expressions/public.h	11 Nov 2006 00:13:15 -0000
@@ -36,9 +36,11 @@
 struct pool;
 union value;
 struct dataset ;
+struct lexer ;
 
-struct expression *expr_parse (struct dataset *, enum expr_type);
-struct expression *expr_parse_pool (struct pool *,
+struct expression *expr_parse (struct lexer *lexer, struct dataset *, enum expr_type);
+struct expression *expr_parse_pool (struct lexer *, 
+				    struct pool *,
 				    struct dataset *,
                                     enum expr_type);
 void expr_free (struct expression *);
Index: src/language/lexer/format-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/format-parser.c,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 format-parser.c
--- src/language/lexer/format-parser.c	3 Nov 2006 04:53:51 -0000	1.6
+++ src/language/lexer/format-parser.c	11 Nov 2006 00:13:15 -0000
@@ -47,18 +47,18 @@
    format.  Both width and decimals are considered optional.  If
    missing, *WIDTH or *DECIMALS or both will be set to 0. */
 bool
-parse_abstract_format_specifier (char type[FMT_TYPE_LEN_MAX + 1],
+parse_abstract_format_specifier (struct lexer *lexer, char type[FMT_TYPE_LEN_MAX + 1],
                                  int *width, int *decimals) 
 {
   struct substring s;
   struct substring type_ss, width_ss, decimals_ss;
   bool has_decimals;
 
-  if (token != T_ID)
+  if (lex_token (lexer) != T_ID)
     goto error;
 
   /* Extract pieces. */
-  s = ds_ss (&tokstr);
+  s = ds_ss (lex_tokstr (lexer));
   ss_get_chars (&s, ss_span (s, ss_cstr (CC_LETTERS)), &type_ss);
   ss_get_chars (&s, ss_span (s, ss_cstr (CC_DIGITS)), &width_ss);
   if (ss_match_char (&s, '.')) 
@@ -85,25 +85,25 @@
   *width = strtol (ss_data (width_ss), NULL, 10);
   *decimals = has_decimals ? strtol (ss_data (decimals_ss), NULL, 10) : 0;
 
-  lex_get ();
+  lex_get (lexer);
   return true;
 
  error:
-  lex_error (_("expecting valid format specifier"));
+  lex_error (lexer, _("expecting valid format specifier"));
   return false;
 }
 
-/* Parses a format specifier from the token stream and returns
+/* Parses a format specifier from the lex_token (lexer) stream and returns
    true only if successful.  Emits an error message on
    failure.  The caller should call check_input_specifier() or
    check_output_specifier() on the parsed format as
    necessary.  */
 bool
-parse_format_specifier (struct fmt_spec *format)
+parse_format_specifier (struct lexer *lexer, struct fmt_spec *format)
 {
   char type[FMT_TYPE_LEN_MAX + 1];
 
-  if (!parse_abstract_format_specifier (type, &format->w, &format->d))
+  if (!parse_abstract_format_specifier (lexer, type, &format->w, &format->d))
     return false;
 
   if (!fmt_from_name (type, &format->type))
@@ -118,18 +118,18 @@
 /* Parses a token containing just the name of a format type and
    returns true if successful. */
 bool
-parse_format_specifier_name (enum fmt_type *type) 
+parse_format_specifier_name (struct lexer *lexer, enum fmt_type *type) 
 {
-  if (token != T_ID) 
+  if (lex_token (lexer) != T_ID) 
     {
-      lex_error (_("expecting format type"));
+      lex_error (lexer, _("expecting format type"));
       return false;
     }
-  if (!fmt_from_name (ds_cstr (&tokstr), type))
+  if (!fmt_from_name (ds_cstr (lex_tokstr (lexer)), type))
     {
-      msg (SE, _("Unknown format type \"%s\"."), ds_cstr (&tokstr));
+      msg (SE, _("Unknown format type \"%s\"."), ds_cstr (lex_tokstr (lexer)));
       return false;
     }
-  lex_get ();
+  lex_get (lexer);
   return true;
 }
Index: src/language/lexer/format-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/format-parser.h,v
retrieving revision 1.3
diff -b -w -U3 -r1.3 format-parser.h
--- src/language/lexer/format-parser.h	5 Nov 2006 05:20:53 -0000	1.3
+++ src/language/lexer/format-parser.h	11 Nov 2006 00:13:15 -0000
@@ -24,9 +24,12 @@
 
 #include <data/format.h>
 
-bool parse_abstract_format_specifier (char type[FMT_TYPE_LEN_MAX + 1],
+
+struct lexer;
+
+bool parse_abstract_format_specifier (struct lexer *, char type[FMT_TYPE_LEN_MAX + 1],
                                       int *width, int *decimals);
-bool parse_format_specifier (struct fmt_spec *);
-bool parse_format_specifier_name (enum fmt_type *type);
+bool parse_format_specifier (struct lexer *, struct fmt_spec *);
+bool parse_format_specifier_name (struct lexer *, enum fmt_type *type);
 
 #endif /* language/lexer/format-parser.h. */
Index: src/language/lexer/lexer.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/lexer.c,v
retrieving revision 1.11
diff -b -w -U3 -r1.11 lexer.c
--- src/language/lexer/lexer.c	28 Oct 2006 08:31:23 -0000	1.11
+++ src/language/lexer/lexer.c	11 Nov 2006 00:13:16 -0000
@@ -45,38 +45,34 @@
 #define DUMP_TOKENS 1
 */
 
+struct lexer 
+{
+  struct string line_buffer;
 
-/* Current token. */
-int token;
-
-/* T_POS_NUM, T_NEG_NUM: the token's value. */
-double tokval;
+  bool (*read_line) (struct string *, bool *);
 
-/* T_ID: the identifier. */
-char tokid[LONG_NAME_LEN + 1];
+  int token;      /* Current token. */
+  double tokval;  /* T_POS_NUM, T_NEG_NUM: the token's value. */
 
-/* T_ID, T_STRING: token string value.
-   For T_ID, this is not truncated as is tokid. */
-struct string tokstr;
+  char tokid [LONG_NAME_LEN + 1];   /* T_ID: the identifier. */
 
-/* Static variables. */
+  struct string tokstr;   /* T_ID, T_STRING: token string value.
+  			    For T_ID, this is not truncated as is 
+  			    tokid. */
 
-/* Pointer to next token in line_buffer. */
-static char *prog;
+  char *prog; /* Pointer to next token in line_buffer. */
+  bool dot;   /* True only if this line ends with a terminal dot. */
+  bool eof;   /* True only if the last token returned was T_STOP. */
 
-/* True only if this line ends with a terminal dot. */
-static bool dot;
+  int put_token ; /* If nonzero, next token returned by lex_get().
+  		    Used only in exceptional circumstances. */
 
-/* True only if the last token returned was T_STOP. */
-static bool eof;
+  struct string put_tokstr;
+  double put_tokval;
+};
 
-/* If nonzero, next token returned by lex_get().
-   Used only in exceptional circumstances. */
-static int put_token;
-static struct string put_tokstr;
-static double put_tokval;
 
-static int parse_id (void);
+static int parse_id (struct lexer *);
 
 /* How a string represents its contents. */
 enum string_type 
@@ -87,7 +83,7 @@
     HEX_STRING          /* Hexadecimal digits. */
   };
 
-static int parse_string (enum string_type);
+static int parse_string (struct lexer *, enum string_type);
 
 #if DUMP_TOKENS
 static void dump_token (void);
@@ -95,66 +91,68 @@
 
 /* Initialization. */
 
-static struct string line_buffer;
-
-static bool (*lex_read_line) (struct string *, bool *);
-
 /* Initializes the lexer. */
-void
-lex_init (bool (*read_line_func) (struct string *, bool *))
+struct lexer *
+lex_create (bool (*read_line_func) (struct string *, bool *))
 {
-  ds_init_empty (&tokstr);
-  ds_init_empty (&put_tokstr);
-  ds_init_empty (&line_buffer);
-  lex_read_line = read_line_func;
+  struct lexer *lexer = xzalloc (sizeof (*lexer));
+
+  ds_init_empty (&lexer->tokstr);
+  ds_init_empty (&lexer->put_tokstr);
+  ds_init_empty (&lexer->line_buffer);
+  lexer->read_line = read_line_func;
 
-  if (!lex_get_line ())
-    eof = true;
+  if (!lex_get_line (lexer))
+    lexer->eof = true;
+
+  return lexer;
 }
 
 void
-lex_done (void)
+lex_destroy (struct lexer *lexer)
 {
-  ds_destroy (&put_tokstr);
-  ds_destroy (&tokstr);
-  ds_destroy (&line_buffer);
+  ds_destroy (&lexer->put_tokstr);
+  ds_destroy (&lexer->tokstr);
+  ds_destroy (&lexer->line_buffer);
+
+  free (lexer);
 }
 
 
 /* Common functions. */
 
-/* Copies put_token, put_tokstr, put_tokval into token, tokstr,
+/* Copies put_token, lexer->put_tokstr, put_tokval into token, tokstr,
    tokval, respectively, and sets tokid appropriately. */
 static void
-restore_token (void) 
+restore_token (struct lexer *lexer) 
 {
-  assert (put_token != 0);
-  token = put_token;
-  ds_assign_string (&tokstr, &put_tokstr);
-  str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
-  tokval = put_tokval;
-  put_token = 0;
+  assert (lexer->put_token != 0);
+  lexer->token = lexer->put_token;
+  ds_assign_string (&lexer->tokstr, &lexer->put_tokstr);
+  str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
+  lexer->tokval = lexer->put_tokval;
+  lexer->put_token = 0;
 }
 
-/* Copies token, tokstr, tokval into put_token, put_tokstr,
-   put_tokval respectively. */
+/* Copies token, tokstr, lexer->tokval into lexer->put_token, put_tokstr,
+   put_lexer->tokval respectively. */
 static void
-save_token (void) 
+save_token (struct lexer *lexer) 
 {
-  put_token = token;
-  ds_assign_string (&put_tokstr, &tokstr);
-  put_tokval = tokval;
+  lexer->put_token = lexer->token;
+  ds_assign_string (&lexer->put_tokstr, &lexer->tokstr);
+  lexer->put_tokval = lexer->tokval;
 }
 
 /* Parses a single token, setting appropriate global variables to
    indicate the token's attributes. */
 void
-lex_get (void)
+lex_get (struct lexer *lexer)
 {
   /* If a token was pushed ahead, return it. */
-  if (put_token)
+  if (lexer->put_token)
     {
-      restore_token ();
+      restore_token (lexer);
 #if DUMP_TOKENS
       dump_token ();
 #endif
@@ -165,41 +163,41 @@
   for (;;)
     {
       /* Skip whitespace. */
-      if (eof) 
+      if (lexer->eof) 
         {
-          token = T_STOP;
+          lexer->token = T_STOP;
           return;
         }
 
       for (;;)
 	{
-	  while (isspace ((unsigned char) *prog))
-	    prog++;
-	  if (*prog)
+	  while (isspace ((unsigned char) *lexer->prog))
+	    lexer->prog++;
+	  if (*lexer->prog)
 	    break;
 
-	  if (dot)
+	  if (lexer->dot)
 	    {
-	      dot = 0;
-	      token = '.';
+	      lexer->dot = 0;
+	      lexer->token = '.';
 #if DUMP_TOKENS
 	      dump_token ();
 #endif
 	      return;
 	    }
-	  else if (!lex_get_line ())
+	  else if (!lex_get_line (lexer))
 	    {
-	      eof = true;
-	      token = T_STOP;
+	      lexer->eof = true;
+	      lexer->token = T_STOP;
 #if DUMP_TOKENS
 	      dump_token ();
 #endif
 	      return;
 	    }
 
-	  if (put_token)
+	  if (lexer->put_token)
 	    {
-              restore_token ();
+              restore_token (lexer);
 #if DUMP_TOKENS
 	      dump_token ();
 #endif
@@ -209,9 +207,9 @@
 
 
       /* Actually parse the token. */
-      ds_clear (&tokstr);
+      ds_clear (&lexer->tokstr);
       
-      switch (*prog)
+      switch (*lexer->prog)
 	{
 	case '-': case '.':
 	case '0': case '1': case '2': case '3': case '4':
@@ -226,151 +224,151 @@
 	       want it as a number.  When the syntax calls for a `-'
 	       token, lex_negative_to_dash() must be used to break
 	       negative numbers into two tokens. */
-	    if (*prog == '-')
+	    if (*lexer->prog == '-')
 	      {
-		ds_put_char (&tokstr, *prog++);
-		while (isspace ((unsigned char) *prog))
-		  prog++;
+		ds_put_char (&lexer->tokstr, *lexer->prog++);
+		while (isspace ((unsigned char) *lexer->prog))
+		  lexer->prog++;
 
-		if (!isdigit ((unsigned char) *prog) && *prog != '.')
+		if (!isdigit ((unsigned char) *lexer->prog) && *lexer->prog != '.')
 		  {
-		    token = '-';
+		    lexer->token = '-';
 		    break;
 		  }
-                token = T_NEG_NUM;
+                lexer->token = T_NEG_NUM;
 	      }
             else 
-              token = T_POS_NUM;
+              lexer->token = T_POS_NUM;
                 
 	    /* Parse the number, copying it into tokstr. */
-	    while (isdigit ((unsigned char) *prog))
-	      ds_put_char (&tokstr, *prog++);
-	    if (*prog == '.')
-	      {
-		ds_put_char (&tokstr, *prog++);
-		while (isdigit ((unsigned char) *prog))
-		  ds_put_char (&tokstr, *prog++);
-	      }
-	    if (*prog == 'e' || *prog == 'E')
-	      {
-		ds_put_char (&tokstr, *prog++);
-		if (*prog == '+' || *prog == '-')
-		  ds_put_char (&tokstr, *prog++);
-		while (isdigit ((unsigned char) *prog))
-		  ds_put_char (&tokstr, *prog++);
+	    while (isdigit ((unsigned char) *lexer->prog))
+	      ds_put_char (&lexer->tokstr, *lexer->prog++);
+	    if (*lexer->prog == '.')
+	      {
+		ds_put_char (&lexer->tokstr, *lexer->prog++);
+		while (isdigit ((unsigned char) *lexer->prog))
+		  ds_put_char (&lexer->tokstr, *lexer->prog++);
+	      }
+	    if (*lexer->prog == 'e' || *lexer->prog == 'E')
+	      {
+		ds_put_char (&lexer->tokstr, *lexer->prog++);
+		if (*lexer->prog == '+' || *lexer->prog == '-')
+		  ds_put_char (&lexer->tokstr, *lexer->prog++);
+		while (isdigit ((unsigned char) *lexer->prog))
+		  ds_put_char (&lexer->tokstr, *lexer->prog++);
 	      }
 
 	    /* Parse as floating point. */
-	    tokval = strtod (ds_cstr (&tokstr), &tail);
+	    lexer->tokval = strtod (ds_cstr (&lexer->tokstr), &tail);
 	    if (*tail)
 	      {
 		msg (SE, _("%s does not form a valid number."),
-		     ds_cstr (&tokstr));
-		tokval = 0.0;
+		     ds_cstr (&lexer->tokstr));
+		lexer->tokval = 0.0;
 
-		ds_clear (&tokstr);
-		ds_put_char (&tokstr, '0');
+		ds_clear (&lexer->tokstr);
+		ds_put_char (&lexer->tokstr, '0');
 	      }
 
 	    break;
 	  }
 
 	case '\'': case '"':
-	  token = parse_string (CHARACTER_STRING);
+	  lexer->token = parse_string (lexer, CHARACTER_STRING);
 	  break;
 
 	case '(': case ')': case ',': case '=': case '+': case '/':
-	  token = *prog++;
+	  lexer->token = *lexer->prog++;
 	  break;
 
 	case '*':
-	  if (*++prog == '*')
+	  if (*++lexer->prog == '*')
 	    {
-	      prog++;
-	      token = T_EXP;
+	      lexer->prog++;
+	      lexer->token = T_EXP;
 	    }
 	  else
-	    token = '*';
+	    lexer->token = '*';
 	  break;
 
 	case '<':
-	  if (*++prog == '=')
+	  if (*++lexer->prog == '=')
 	    {
-	      prog++;
-	      token = T_LE;
+	      lexer->prog++;
+	      lexer->token = T_LE;
 	    }
-	  else if (*prog == '>')
+	  else if (*lexer->prog == '>')
 	    {
-	      prog++;
-	      token = T_NE;
+	      lexer->prog++;
+	      lexer->token = T_NE;
 	    }
 	  else
-	    token = T_LT;
+	    lexer->token = T_LT;
 	  break;
 
 	case '>':
-	  if (*++prog == '=')
+	  if (*++lexer->prog == '=')
 	    {
-	      prog++;
-	      token = T_GE;
+	      lexer->prog++;
+	      lexer->token = T_GE;
 	    }
 	  else
-	    token = T_GT;
+	    lexer->token = T_GT;
 	  break;
 
 	case '~':
-	  if (*++prog == '=')
+	  if (*++lexer->prog == '=')
 	    {
-	      prog++;
-	      token = T_NE;
+	      lexer->prog++;
+	      lexer->token = T_NE;
 	    }
 	  else
-	    token = T_NOT;
+	    lexer->token = T_NOT;
 	  break;
 
 	case '&':
-	  prog++;
-	  token = T_AND;
+	  lexer->prog++;
+	  lexer->token = T_AND;
 	  break;
 
 	case '|':
-	  prog++;
-	  token = T_OR;
+	  lexer->prog++;
+	  lexer->token = T_OR;
 	  break;
 
         case 'b': case 'B':
-          if (prog[1] == '\'' || prog[1] == '"')
-            token = parse_string (BINARY_STRING);
+          if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
+            lexer->token = parse_string (lexer, BINARY_STRING);
           else
-            token = parse_id ();
+            lexer->token = parse_id (lexer);
           break;
           
         case 'o': case 'O':
-          if (prog[1] == '\'' || prog[1] == '"')
-            token = parse_string (OCTAL_STRING);
+          if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
+            lexer->token = parse_string (lexer, OCTAL_STRING);
           else
-            token = parse_id ();
+            lexer->token = parse_id (lexer);
           break;
           
         case 'x': case 'X':
-          if (prog[1] == '\'' || prog[1] == '"')
-            token = parse_string (HEX_STRING);
+          if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
+            lexer->token = parse_string (lexer, HEX_STRING);
           else
-            token = parse_id ();
+            lexer->token = parse_id (lexer);
           break;
           
 	default:
-          if (lex_is_id1 (*prog)) 
+          if (lex_is_id1 (*lexer->prog)) 
             {
-              token = parse_id ();
+              lexer->token = parse_id (lexer);
               break; 
             }
           else
             {
-              if (isgraph ((unsigned char) *prog))
-                msg (SE, _("Bad character in input: `%c'."), *prog++);
+              if (isgraph ((unsigned char) *lexer->prog))
+                msg (SE, _("Bad character in input: `%c'."), *lexer->prog++);
               else
-                msg (SE, _("Bad character in input: `\\%o'."), *prog++);
+                msg (SE, _("Bad character in input: `\\%o'."), *lexer->prog++);
               continue; 
             }
         }
@@ -386,14 +384,14 @@
    tokstr.
    Returns the correct token type. */
 static int
-parse_id (void) 
+parse_id (struct lexer *lexer) 
 {
-  const char *start = prog;
-  prog = lex_skip_identifier (start);
+  const char *start = lexer->prog;
+  lexer->prog = lex_skip_identifier (start);
 
-  ds_put_substring (&tokstr, ss_buffer (start, prog - start));
-  str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
-  return lex_id_to_token (ds_cstr (&tokstr), ds_length (&tokstr));
+  ds_put_substring (&lexer->tokstr, ss_buffer (start, lexer->prog - start));
+  str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
+  return lex_id_to_token (ds_cstr (&lexer->tokstr), ds_length (&lexer->tokstr));
 }
 
 /* Reports an error to the effect that subcommand SBC may only be
@@ -407,23 +405,23 @@
 /* Reports an error to the effect that subcommand SBC is
    missing. */
 void
-lex_sbc_missing (const char *sbc) 
+lex_sbc_missing (struct lexer *lexer, const char *sbc) 
 {
-  lex_error (_("missing required subcommand %s"), sbc);
+  lex_error (lexer, _("missing required subcommand %s"), sbc);
 }
 
 /* Prints a syntax error message containing the current token and
    given message MESSAGE (if non-null). */
 void
-lex_error (const char *message, ...)
+lex_error (struct lexer *lexer, const char *message, ...)
 {
   char *token_rep;
   char where[128];
 
-  token_rep = lex_token_representation ();
-  if (token == T_STOP)
+  token_rep = lex_token_representation (lexer);
+  if (lexer->token == T_STOP)
     strcpy (where, "end of file");
-  else if (token == '.')
+  else if (lexer->token == '.')
     strcpy (where, "end of command");
   else
     snprintf (where, sizeof where, "`%s'", token_rep);
@@ -449,11 +447,11 @@
    If not, flags a syntax error and returns an error command
    completion code. */
 int
-lex_end_of_command (void)
+lex_end_of_command (struct lexer *lexer)
 {
-  if (token != '.')
+  if (lexer->token != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       return CMD_FAILURE;
     }
   else
@@ -464,38 +462,38 @@
 
 /* Returns true if the current token is a number. */
 bool
-lex_is_number (void) 
+lex_is_number (struct lexer *lexer) 
 {
-  return token == T_POS_NUM || token == T_NEG_NUM;
+  return lexer->token == T_POS_NUM || lexer->token == T_NEG_NUM;
 }
 
 /* Returns the value of the current token, which must be a
    floating point number. */
 double
-lex_number (void)
+lex_number (struct lexer *lexer)
 {
-  assert (lex_is_number ());
-  return tokval;
+  assert (lex_is_number (lexer));
+  return lexer->tokval;
 }
 
 /* Returns true iff the current token is an integer. */
 bool
-lex_is_integer (void)
+lex_is_integer (struct lexer *lexer)
 {
-  return (lex_is_number ()
-	  && tokval != NOT_LONG
-	  && tokval >= LONG_MIN
-	  && tokval <= LONG_MAX
-	  && floor (tokval) == tokval);
+  return (lex_is_number (lexer)
+	  && lexer->tokval != NOT_LONG
+	  && lexer->tokval >= LONG_MIN
+	  && lexer->tokval <= LONG_MAX
+	  && floor (lexer->tokval) == lexer->tokval);
 }
 
 /* Returns the value of the current token, which must be an
    integer. */
 long
-lex_integer (void)
+lex_integer (struct lexer *lexer)
 {
-  assert (lex_is_integer ());
-  return tokval;
+  assert (lex_is_integer (lexer));
+  return lexer->tokval;
 }
   
 /* Token matching functions. */
@@ -503,11 +501,11 @@
 /* If TOK is the current token, skips it and returns true
    Otherwise, returns false. */
 bool
-lex_match (int t)
+lex_match (struct lexer *lexer, int t)
 {
-  if (token == t)
+  if (lexer->token == t)
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
@@ -519,11 +517,11 @@
    letters.
    Otherwise, returns false. */
 bool
-lex_match_id (const char *s)
+lex_match_id (struct lexer *lexer, const char *s)
 {
-  if (token == T_ID && lex_id_match (s, tokid))
+  if (lexer->token == T_ID && lex_id_match (s, lexer->tokid))
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
@@ -533,11 +531,11 @@
 /* If the current token is integer N, skips it and returns true.
    Otherwise, returns false. */
 bool
-lex_match_int (int x)
+lex_match_int (struct lexer *lexer, int x)
 {
-  if (lex_is_integer () && lex_integer () == x)
+  if (lex_is_integer (lexer) && lex_integer (lexer) == x)
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
@@ -550,16 +548,16 @@
    nonzero.
    Otherwise, reports an error and returns zero. */
 bool
-lex_force_match_id (const char *s)
+lex_force_match_id (struct lexer *lexer, const char *s)
 {
-  if (token == T_ID && lex_id_match (s, tokid))
+  if (lexer->token == T_ID && lex_id_match (s, lexer->tokid))
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
     {
-      lex_error (_("expecting `%s'"), s);
+      lex_error (lexer, _("expecting `%s'"), s);
       return false;
     }
 }
@@ -567,16 +565,16 @@
 /* If the current token is T, skips the token.  Otherwise, reports an
    error and returns from the current function with return value false. */
 bool
-lex_force_match (int t)
+lex_force_match (struct lexer *lexer, int t)
 {
-  if (token == t)
+  if (lexer->token == t)
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
     {
-      lex_error (_("expecting `%s'"), lex_token_name (t));
+      lex_error (lexer, _("expecting `%s'"), lex_token_name (t));
       return false;
     }
 }
@@ -584,13 +582,13 @@
 /* If this token is a string, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_string (void)
+lex_force_string (struct lexer *lexer)
 {
-  if (token == T_STRING)
+  if (lexer->token == T_STRING)
     return true;
   else
     {
-      lex_error (_("expecting string"));
+      lex_error (lexer, _("expecting string"));
       return false;
     }
 }
@@ -598,13 +596,13 @@
 /* If this token is an integer, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_int (void)
+lex_force_int (struct lexer *lexer)
 {
-  if (lex_is_integer ())
+  if (lex_is_integer (lexer))
     return true;
   else
     {
-      lex_error (_("expecting integer"));
+      lex_error (lexer, _("expecting integer"));
       return false;
     }
 }
@@ -612,27 +610,28 @@
 /* If this token is a number, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_num (void)
+lex_force_num (struct lexer *lexer)
 {
-  if (lex_is_number ())
+  if (lex_is_number (lexer))
     return true;
   else
     {
-      lex_error (_("expecting number"));
+      lex_error (lexer, _("expecting number"));
       return false;
     }
+  NOT_REACHED ();
 }
 	
 /* If this token is an identifier, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_id (void)
+lex_force_id (struct lexer *lexer)
 {
-  if (token == T_ID)
+  if (lexer->token == T_ID)
     return true;
   else
     {
-      lex_error (_("expecting identifier"));
+      lex_error (lexer, _("expecting identifier"));
       return false;
     }
 }
@@ -645,76 +644,76 @@
    alphanumeric return value doesn't guarantee an ID token, it could
    also be a reserved-word token. */
 int
-lex_look_ahead (void)
+lex_look_ahead (struct lexer *lexer)
 {
-  if (put_token)
-    return put_token;
+  if (lexer->put_token)
+    return lexer->put_token;
 
   for (;;)
     {
-      if (eof)
+      if (lexer->eof)
         return 0;
 
       for (;;)
 	{
-	  while (isspace ((unsigned char) *prog))
-	    prog++;
-	  if (*prog)
+	  while (isspace ((unsigned char) *lexer->prog))
+	    lexer->prog++;
+	  if (*lexer->prog)
 	    break;
 
-	  if (dot)
+	  if (lexer->dot)
 	    return '.';
-	  else if (!lex_get_line ())
+	  else if (!lex_get_line (lexer))
             return 0;
 
-	  if (put_token) 
-	    return put_token;
+	  if (lexer->put_token) 
+	    return lexer->put_token;
 	}
 
-      if ((toupper ((unsigned char) *prog) == 'X'
-	   || toupper ((unsigned char) *prog) == 'B'
-           || toupper ((unsigned char) *prog) == 'O')
-	  && (prog[1] == '\'' || prog[1] == '"'))
+      if ((toupper ((unsigned char) *lexer->prog) == 'X'
+	   || toupper ((unsigned char) *lexer->prog) == 'B'
+           || toupper ((unsigned char) *lexer->prog) == 'O')
+	  && (lexer->prog[1] == '\'' || lexer->prog[1] == '"'))
 	return '\'';
 
-      return *prog;
+      return *lexer->prog;
     }
 }
 
 /* Makes the current token become the next token to be read; the
    current token is set to T. */
 void
-lex_put_back (int t)
+lex_put_back (struct lexer *lexer, int t)
 {
-  save_token ();
-  token = t;
+  save_token (lexer);
+  lexer->token = t;
 }
 
 /* Makes the current token become the next token to be read; the
    current token is set to the identifier ID. */
 void
-lex_put_back_id (const char *id)
+lex_put_back_id (struct lexer *lexer, const char *id)
 {
   assert (lex_id_to_token (id, strlen (id)) == T_ID);
-  save_token ();
-  token = T_ID;
-  ds_assign_cstr (&tokstr, id);
-  str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
+  save_token (lexer);
+  lexer->token = T_ID;
+  ds_assign_cstr (&lexer->tokstr, id);
+  str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
 }
 
 /* Weird line processing functions. */
 
 /* Returns the entire contents of the current line. */
 const char *
-lex_entire_line (void)
+lex_entire_line (struct lexer *lexer)
 {
-  return ds_cstr (&line_buffer);
+  return ds_cstr (&lexer->line_buffer);
 }
 
 const struct string *
-lex_entire_line_ds (void)
+lex_entire_line_ds (struct lexer *lexer)
 {
-  return &line_buffer;
+  return &lexer->line_buffer;
 }
 
 /* As lex_entire_line(), but only returns the part of the current line
@@ -722,22 +721,22 @@
    If END_DOT is non-null, stores nonzero into *END_DOT if the line
    ends with a terminal dot, or zero if it doesn't. */
 const char *
-lex_rest_of_line (int *end_dot)
+lex_rest_of_line (struct lexer *lexer, int *end_dot)
 {
   if (end_dot)
-    *end_dot = dot;
-  return prog;
+    *end_dot = lexer->dot;
+  return lexer->prog;
 }
 
 /* Causes the rest of the current input line to be ignored for
    tokenization purposes. */
 void
-lex_discard_line (void)
+lex_discard_line (struct lexer *lexer)
 {
-  ds_cstr (&line_buffer);  /* Ensures ds_end points to something valid */
-  prog = ds_end (&line_buffer);
-  dot = false;
-  put_token = 0;
+  ds_cstr (&lexer->line_buffer);  /* Ensures ds_end points to something valid */
+  lexer->prog = ds_end (&lexer->line_buffer);
+  lexer->dot = false;
+  lexer->put_token = 0;
 }
 
 
@@ -749,15 +748,15 @@
    the user doesn't want to finish typing a command that will be
    ignored anyway. */
 void
-lex_discard_rest_of_command (void) 
+lex_discard_rest_of_command (struct lexer *lexer) 
 {
   if (!getl_is_interactive ())
     {
-      while (token != T_STOP && token != '.')
-	lex_get ();
+      while (lexer->token != T_STOP && lexer->token != '.')
+	lex_get (lexer);
     }
   else 
-    lex_discard_line (); 
+    lex_discard_line (lexer); 
 }
 
 /* Weird line reading functions. */
@@ -812,29 +811,29 @@
 
 /* Reads a line, without performing any preprocessing */
 bool 
-lex_get_line_raw (void)
+lex_get_line_raw (struct lexer *lexer)
 {
   bool dummy;
-  return lex_read_line (&line_buffer, &dummy);
+  return lexer->read_line (&lexer->line_buffer, &dummy);
 }
 
 /* Reads a line for use by the tokenizer, and preprocesses it by
    removing comments, stripping trailing whitespace and the
    terminal dot, and removing leading indentors. */
 bool
-lex_get_line (void)
+lex_get_line (struct lexer *lexer)
 {
-  struct string *line = &line_buffer;
+  struct string *line = &lexer->line_buffer;
   bool interactive;
 
-  if (!lex_read_line (line, &interactive))
+  if (!lexer->read_line (line, &interactive))
     return false;
 
   strip_comments (line);
   ds_rtrim (line, ss_cstr (CC_SPACES));
   
   /* Check for and remove terminal dot. */
-  dot = (ds_chomp (line, get_endcmd ())
+  lexer->dot = (ds_chomp (line, get_endcmd ())
          || (ds_is_empty (line) && get_nulline ()));
   
   /* Strip leading indentors or insert a terminal dot (unless the
@@ -846,10 +845,10 @@
       if (first == '+' || first == '-')
 	*ds_data (line) = ' ';
       else if (first != EOF && !isspace (first))
-	put_token = '.';
+	lexer->put_token = '.';
     }
 
-  prog = ds_cstr (line);
+  lexer->prog = ds_cstr (line);
 
   return true;
 }
@@ -876,16 +875,16 @@
 /* Returns an ASCII representation of the current token as a
    malloc()'d string. */
 char *
-lex_token_representation (void)
+lex_token_representation (struct lexer *lexer)
 {
   char *token_rep;
   
-  switch (token)
+  switch (lexer->token)
     {
     case T_ID:
     case T_POS_NUM:
     case T_NEG_NUM:
-      return ds_xstrdup (&tokstr);
+      return ds_xstrdup (&lexer->tokstr);
       break;
 
     case T_STRING:
@@ -893,14 +892,14 @@
 	int hexstring = 0;
 	char *sp, *dp;
 
-	for (sp = ds_cstr (&tokstr); sp < ds_end (&tokstr); sp++)
+	for (sp = ds_cstr (&lexer->tokstr); sp < ds_end (&lexer->tokstr); sp++)
 	  if (!isprint ((unsigned char) *sp))
 	    {
 	      hexstring = 1;
 	      break;
 	    }
 	      
-	token_rep = xmalloc (2 + ds_length (&tokstr) * 2 + 1 + 1);
+	token_rep = xmalloc (2 + ds_length (&lexer->tokstr) * 2 + 1 + 1);
 
 	dp = token_rep;
 	if (hexstring)
@@ -908,14 +907,14 @@
 	*dp++ = '\'';
 
 	if (!hexstring)
-	  for (sp = ds_cstr (&tokstr); *sp; )
+	  for (sp = ds_cstr (&lexer->tokstr); *sp; )
 	    {
 	      if (*sp == '\'')
 		*dp++ = '\'';
 	      *dp++ = (unsigned char) *sp++;
 	    }
 	else
-	  for (sp = ds_cstr (&tokstr); sp < ds_end (&tokstr); sp++)
+	  for (sp = ds_cstr (&lexer->tokstr); sp < ds_end (&lexer->tokstr); sp++)
 	    {
 	      *dp++ = (((unsigned char) *sp) >> 4)["0123456789ABCDEF"];
 	      *dp++ = (((unsigned char) *sp) & 15)["0123456789ABCDEF"];
@@ -936,12 +935,12 @@
       return xstrdup ("**");
 
     default:
-      if (token >= T_FIRST_KEYWORD && token <= T_LAST_KEYWORD)
-	return xstrdup (keywords [token - T_FIRST_KEYWORD]);
+      if (lexer->token >= T_FIRST_KEYWORD && lexer->token <= T_LAST_KEYWORD)
+	return xstrdup (keywords [lexer->token - T_FIRST_KEYWORD]);
       else
 	{
 	  token_rep = xmalloc (2);
-	  token_rep[0] = token;
+	  token_rep[0] = lexer->token;
 	  token_rep[1] = '\0';
 	  return token_rep;
 	}
@@ -957,44 +956,44 @@
    of syntax then this function is called to rip it off of a
    number. */
 void
-lex_negative_to_dash (void)
+lex_negative_to_dash (struct lexer *lexer)
 {
-  if (token == T_NEG_NUM)
+  if (lexer->token == T_NEG_NUM)
     {
-      token = T_POS_NUM;
-      tokval = -tokval;
-      ds_assign_substring (&tokstr, ds_substr (&tokstr, 1, SIZE_MAX));
-      save_token ();
-      token = '-';
+      lexer->token = T_POS_NUM;
+      lexer->tokval = -lexer->tokval;
+      ds_assign_substring (&lexer->tokstr, ds_substr (&lexer->tokstr, 1, SIZE_MAX));
+      save_token (lexer);
+      lexer->token = '-';
     }
 }
    
 /* We're not at eof any more. */
 void
-lex_reset_eof (void)
+lex_reset_eof (struct lexer *lexer)
 {
-  eof = false;
+  lexer->eof = false;
 }
 
 /* Skip a COMMENT command. */
 void
-lex_skip_comment (void)
+lex_skip_comment (struct lexer *lexer)
 {
   for (;;)
     {
-      if (!lex_get_line ()) 
+      if (!lex_get_line (lexer)) 
         {
-          put_token = T_STOP;
-          eof = true;
+          lexer->put_token = T_STOP;
+          lexer->eof = true;
           return;
         }
       
-      if (put_token == '.')
+      if (lexer->put_token == '.')
 	break;
 
-      ds_cstr (&line_buffer); /* Ensures ds_end will point to a valid char */
-      prog = ds_end (&line_buffer);
-      if (dot)
+      ds_cstr (&lexer->line_buffer); /* Ensures ds_end will point to a valid char */
+      lexer->prog = ds_end (&lexer->line_buffer);
+      if (lexer->dot)
 	break;
     }
 }
@@ -1005,7 +1004,8 @@
    hex digits, according to TYPE.  The string is converted to
    characters having the specified values. */
 static void
-convert_numeric_string_to_char_string (enum string_type type)
+convert_numeric_string_to_char_string (struct lexer *lexer, 
+				       enum string_type type)
 {
   const char *base_name;
   int base;
@@ -1035,13 +1035,13 @@
       NOT_REACHED ();
     }
   
-  byte_cnt = ds_length (&tokstr) / chars_per_byte;
-  if (ds_length (&tokstr) % chars_per_byte)
+  byte_cnt = ds_length (&lexer->tokstr) / chars_per_byte;
+  if (ds_length (&lexer->tokstr) % chars_per_byte)
     msg (SE, _("String of %s digits has %d characters, which is not a "
 	       "multiple of %d."),
-	 base_name, ds_length (&tokstr), chars_per_byte);
+	 base_name, ds_length (&lexer->tokstr), chars_per_byte);
 
-  p = ds_cstr (&tokstr);
+  p = ds_cstr (&lexer->tokstr);
   for (i = 0; i < byte_cnt; i++)
     {
       int value;
@@ -1071,88 +1071,88 @@
 	  value = value * base + v;
 	}
 
-      ds_cstr (&tokstr)[i] = (unsigned char) value;
+      ds_cstr (&lexer->tokstr)[i] = (unsigned char) value;
     }
 
-  ds_truncate (&tokstr, byte_cnt);
+  ds_truncate (&lexer->tokstr, byte_cnt);
 }
 
 /* Parses a string from the input buffer into tokstr.  The input
-   buffer pointer prog must point to the initial single or double
+   buffer pointer lexer->prog must point to the initial single or double
    quote.  TYPE indicates the type of string to be parsed.
    Returns token type. */
 static int 
-parse_string (enum string_type type)
+parse_string (struct lexer *lexer, enum string_type type)
 {
   if (type != CHARACTER_STRING)
-    prog++;
+    lexer->prog++;
 
   /* Accumulate the entire string, joining sections indicated by +
      signs. */
   for (;;)
     {
       /* Single or double quote. */
-      int c = *prog++;
+      int c = *lexer->prog++;
       
       /* Accumulate section. */
       for (;;)
 	{
 	  /* Check end of line. */
-	  if (*prog == '\0')
+	  if (*lexer->prog == '\0')
 	    {
 	      msg (SE, _("Unterminated string constant."));
 	      goto finish;
 	    }
 	  
 	  /* Double quote characters to embed them in strings. */
-	  if (*prog == c)
+	  if (*lexer->prog == c)
 	    {
-	      if (prog[1] == c)
-		prog++;
+	      if (lexer->prog[1] == c)
+		lexer->prog++;
 	      else
 		break;
 	    }
 
-	  ds_put_char (&tokstr, *prog++);
+	  ds_put_char (&lexer->tokstr, *lexer->prog++);
 	}
-      prog++;
+      lexer->prog++;
 
       /* Skip whitespace after final quote mark. */
-      if (eof)
+      if (lexer->eof)
 	break;
       for (;;)
 	{
-	  while (isspace ((unsigned char) *prog))
-	    prog++;
-	  if (*prog)
+	  while (isspace ((unsigned char) *lexer->prog))
+	    lexer->prog++;
+	  if (*lexer->prog)
 	    break;
 
-	  if (dot)
+	  if (lexer->dot)
 	    goto finish;
 
-	  if (!lex_get_line ())
+	  if (!lex_get_line (lexer))
             goto finish;
 	}
 
       /* Skip plus sign. */
-      if (*prog != '+')
+      if (*lexer->prog != '+')
 	break;
-      prog++;
+      lexer->prog++;
 
       /* Skip whitespace after plus sign. */
-      if (eof)
+      if (lexer->eof)
 	break;
       for (;;)
 	{
-	  while (isspace ((unsigned char) *prog))
-	    prog++;
-	  if (*prog)
+	  while (isspace ((unsigned char) *lexer->prog))
+	    lexer->prog++;
+	  if (*lexer->prog)
 	    break;
 
-	  if (dot)
+	  if (lexer->dot)
 	    goto finish;
 
-	  if (!lex_get_line ())
+	  if (!lex_get_line (lexer))
             {
               msg (SE, _("Unexpected end of file in string concatenation."));
               goto finish;
@@ -1160,7 +1160,7 @@
 	}
 
       /* Ensure that a valid string follows. */
-      if (*prog != '\'' && *prog != '"')
+      if (*lexer->prog != '\'' && *lexer->prog != '"')
 	{
 	  msg (SE, _("String expected following `+'."));
 	  goto finish;
@@ -1171,13 +1171,13 @@
      into one large string. */
 finish:
   if (type != CHARACTER_STRING)
-    convert_numeric_string_to_char_string (type);
+    convert_numeric_string_to_char_string (lexer, type);
 
-  if (ds_length (&tokstr) > 255)
+  if (ds_length (&lexer->tokstr) > 255)
     {
       msg (SE, _("String exceeds 255 characters in length (%d characters)."),
-	   ds_length (&tokstr));
-      ds_truncate (&tokstr, 255);
+	   ds_length (&lexer->tokstr));
+      ds_truncate (&lexer->tokstr, 255);
     }
       
   return T_STRING;
@@ -1187,7 +1187,7 @@
 /* Reads one token from the lexer and writes a textual representation
    on stdout for debugging purposes. */
 static void
-dump_token (void)
+dump_token (struct lexer *lexer)
 {
   {
     const char *curfn;
@@ -1198,19 +1198,19 @@
       fprintf (stderr, "%s:%d\t", curfn, curln);
   }
   
-  switch (token)
+  switch (lexer->token)
     {
     case T_ID:
-      fprintf (stderr, "ID\t%s\n", tokid);
+      fprintf (stderr, "ID\t%s\n", lexer->tokid);
       break;
 
     case T_POS_NUM:
     case T_NEG_NUM:
-      fprintf (stderr, "NUM\t%f\n", tokval);
+      fprintf (stderr, "NUM\t%f\n", lexer->tokval);
       break;
 
     case T_STRING:
-      fprintf (stderr, "STRING\t\"%s\"\n", ds_cstr (&tokstr));
+      fprintf (stderr, "STRING\t\"%s\"\n", ds_cstr (&lexer->tokstr));
       break;
 
     case T_STOP:
@@ -1226,11 +1226,39 @@
       break;
 
     default:
-      if (token >= T_FIRST_KEYWORD && token <= T_LAST_KEYWORD)
+      if (lexer->token >= T_FIRST_KEYWORD && lexer->token <= T_LAST_KEYWORD)
 	fprintf (stderr, "KEYWORD\t%s\n", lex_token_name (token));
       else
-	fprintf (stderr, "PUNCT\t%c\n", token);
+	fprintf (stderr, "PUNCT\t%c\n", lexer->token);
       break;
     }
 }
 #endif /* DUMP_TOKENS */
+
+
+/* Token Accessor Functions */
+
+int 
+lex_token (struct lexer *lexer)
+{
+  return lexer->token;
+}
+
+
+double 
+lex_tokval (struct lexer *lexer)
+{
+  return lexer->tokval;
+}
+
+const char *
+lex_tokid (struct lexer *lexer)
+{
+  return lexer->tokid;
+}
+
+const struct string *
+lex_tokstr (struct lexer *lexer)
+{
+  return &lexer->tokstr;
+}
Index: src/language/lexer/lexer.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/lexer.h,v
retrieving revision 1.7
diff -b -w -U3 -r1.7 lexer.h
--- src/language/lexer/lexer.h	28 Oct 2006 08:31:23 -0000	1.7
+++ src/language/lexer/lexer.h	11 Nov 2006 00:13:16 -0000
@@ -23,70 +23,74 @@
 #include <data/variable.h>
 #include <ctype.h>
 #include <stdbool.h>
-
 #include <data/identifier.h>
 
-
-extern int token;
-extern double tokval;
-extern char tokid[LONG_NAME_LEN + 1];
-extern struct string tokstr;
-
 #include <stddef.h>
 
+struct lexer ;
+
 /* Initialization. */
-void lex_init (bool (*)(struct string *, bool*));
-void lex_done (void);
+struct lexer * lex_create (bool (*)(struct string *, bool*));
+void lex_destroy (struct lexer *);
+
+
+
 
 /* Common functions. */
-void lex_get (void);
-void lex_error (const char *, ...);
+void lex_get (struct lexer *);
+void lex_error (struct lexer *, const char *, ...);
 void lex_sbc_only_once (const char *);
-void lex_sbc_missing (const char *);
-int lex_end_of_command (void);
+void lex_sbc_missing (struct lexer *, const char *);
+int lex_end_of_command (struct lexer *);
 
 /* Token testing functions. */
-bool lex_is_number (void);
-double lex_number (void);
-bool lex_is_integer (void);
-long lex_integer (void);
+bool lex_is_number (struct lexer *);
+double lex_number (struct lexer *);
+bool lex_is_integer (struct lexer *);
+long lex_integer (struct lexer *);
 
 /* Token matching functions. */
-bool lex_match (int);
-bool lex_match_id (const char *);
-bool lex_match_int (int);
+bool lex_match (struct lexer *, int);
+bool lex_match_id (struct lexer *, const char *);
+bool lex_match_int (struct lexer *, int);
 
 /* Forcible matching functions. */
-bool lex_force_match (int);
-bool lex_force_match_id (const char *);
-bool lex_force_int (void);
-bool lex_force_num (void);
-bool lex_force_id (void);
-bool lex_force_string (void);
+bool lex_force_match (struct lexer *, int);
+bool lex_force_match_id (struct lexer *, const char *);
+bool lex_force_int (struct lexer *);
+bool lex_force_num (struct lexer *);
+bool lex_force_id (struct lexer *);
+bool lex_force_string (struct lexer *);
 	
 /* Weird token functions. */
-int lex_look_ahead (void);
-void lex_put_back (int);
-void lex_put_back_id (const char *tokid);
+int lex_look_ahead (struct lexer *);
+void lex_put_back (struct lexer *, int);
+void lex_put_back_id (struct lexer *, const char *tokid);
 
 /* Weird line processing functions. */
-const char *lex_entire_line (void);
-const struct string *lex_entire_line_ds (void);
-const char *lex_rest_of_line (int *end_dot);
-void lex_discard_line (void);
-void lex_discard_rest_of_command (void);
+const char *lex_entire_line (struct lexer *);
+const struct string *lex_entire_line_ds (struct lexer *);
+const char *lex_rest_of_line (struct lexer *, int *end_dot);
+void lex_discard_line (struct lexer *);
+void lex_discard_rest_of_command (struct lexer *);
 
 /* Weird line reading functions. */
-bool lex_get_line (void);
-bool lex_get_line_raw (void);
+bool lex_get_line (struct lexer *);
+bool lex_get_line_raw (struct lexer *);
 
 /* Token names. */
 const char *lex_token_name (int);
-char *lex_token_representation (void);
+char *lex_token_representation (struct lexer *);
+
+/* Token accessors */
+int lex_token (struct lexer *);
+double lex_tokval (struct lexer *);
+const char *lex_tokid (struct lexer *);
+const struct string *lex_tokstr (struct lexer *);
 
 /* Really weird functions. */
-void lex_negative_to_dash (void);
-void lex_reset_eof (void);
-void lex_skip_comment (void);
+void lex_negative_to_dash (struct lexer *);
+void lex_reset_eof (struct lexer *);
+void lex_skip_comment (struct lexer *);
 
 #endif /* !lexer_h */
Index: src/language/lexer/q2c.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/q2c.c,v
retrieving revision 1.17
diff -b -w -U3 -r1.17 q2c.c
--- src/language/lexer/q2c.c	26 Oct 2006 06:16:36 -0000	1.17
+++ src/language/lexer/q2c.c	11 Nov 2006 00:13:16 -0000
@@ -40,22 +40,22 @@
 #define MAX_TOK_LEN 1024
 
 /* argv[0]. */
-char *program_name;
+static char *program_name;
 
 /* Have the input and output files been opened yet? */
-bool is_open;
+static bool is_open;
 
 /* Input, output files. */
-FILE *in, *out;
+static FILE *in, *out;
 
 /* Input, output file names. */
-char *ifn, *ofn;
+static char *ifn, *ofn;
 
 /* Input, output file line number. */
-int ln, oln = 1;
+static int ln, oln = 1;
 
 /* Input line buffer, current position. */
-char *buf, *cp;
+static char *buf, *cp;
 
 /* Token types. */
 enum
@@ -65,14 +65,14 @@
   };
 
 /* Current token: either one of the above, or a single character. */
-int token;
+static int token;
 
 /* Token string value. */
-char *tokstr;
+static char *tokstr;
 
 /* Utility functions. */
 
-char nullstr[] = "";
+static char nullstr[] = "";
 
 /* Close all open files and delete the output file, on failure. */
 static void
@@ -1177,7 +1177,7 @@
 	      dump (0, "/* Prototype for custom subcommands of %s. */",
 		    cmdname);
 	    }
-	  dump (0, "static int %scustom_%s (struct dataset *, struct cmd_%s *, void *);",
+	  dump (0, "static int %scustom_%s (struct lexer *, struct dataset *, struct cmd_%s *, void *);",
 		st_lower (prefix), st_lower (sbc->name),
 		make_identifier (cmdname));
 	}
@@ -1189,7 +1189,7 @@
   /* Prototypes for parsing and freeing functions. */
   {
     dump (0, "/* Command parsing functions. */");
-    dump (0, "static int parse_%s (struct dataset *, struct cmd_%s *, void *);",
+    dump (0, "static int parse_%s (struct lexer *, struct dataset *, struct cmd_%s *, void *);",
 	  make_identifier (cmdname), make_identifier (cmdname));
     dump (0, "static void free_%s (struct cmd_%s *);",
 	  make_identifier (cmdname), make_identifier (cmdname));
@@ -1342,17 +1342,17 @@
     t++;
       
   if (is_keyword (t))
-    sprintf (s, "lex_match (T_%s)", t);
+    sprintf (s, "lex_match (lexer, T_%s)", t);
   else if (!strcmp (t, "ON") || !strcmp (t, "YES"))
-    strcpy (s, "(lex_match_id (\"ON\") || lex_match_id (\"YES\") "
-	    "|| lex_match_id (\"TRUE\"))");
+    strcpy (s, "(lex_match_id (lexer, \"ON\") || lex_match_id (lexer, \"YES\") "
+	    "|| lex_match_id (lexer, \"TRUE\"))");
   else if (!strcmp (t, "OFF") || !strcmp (t, "NO"))
-    strcpy (s, "(lex_match_id (\"OFF\") || lex_match_id (\"NO\") "
-	    "|| lex_match_id (\"FALSE\"))");
+    strcpy (s, "(lex_match_id (lexer, \"OFF\") || lex_match_id (lexer, \"NO\") "
+	    "|| lex_match_id (lexer, \"FALSE\"))");
   else if (isdigit ((unsigned char) t[0]))
-    sprintf (s, "lex_match_int (%s)", t);
+    sprintf (s, "lex_match_int (lexer, %s)", t);
   else
-    sprintf (s, "lex_match_id (\"%s\")", t);
+    sprintf (s, "lex_match_id (lexer, \"%s\")", t);
   
   return s;
 }
@@ -1416,12 +1416,12 @@
 	    {
 	      if (s->optvalue)
 		{
-		  dump (1, "if (lex_match ('('))");
+		  dump (1, "if (lex_match (lexer, '('))");
 		  dump (1, "{");
 		}
 	      else
 		{
-		  dump (1, "if (!lex_match ('('))");
+		  dump (1, "if (!lex_match (lexer, '('))");
 		  dump (1, "{");
 		  dump (0, "msg (SE, _(\"`(' expected after %s "
 			"specifier of %s subcommand.\"));",
@@ -1434,26 +1434,26 @@
 
 	  if (s->value == VAL_INT)
 	    {
-	      dump (1, "if (!lex_is_integer ())");
+	      dump (1, "if (!lex_is_integer (lexer))");
 	      dump (1, "{");
 	      dump (0, "msg (SE, _(\"%s specifier of %s subcommand "
 		    "requires an integer argument.\"));",
 		    s->specname, sbc->name);
 	      dump (0, "goto lossage;");
 	      dump (-1, "}");
-	      dump (-1, "p->%s%s = lex_integer ();",
+	      dump (-1, "p->%s%s = lex_integer (lexer);",
 		    sbc->prefix, st_lower (s->valname));
 	    }
 	  else
 	    {
-	      dump (1, "if (!lex_is_number ())");
+	      dump (1, "if (!lex_is_number (lexer))");
 	      dump (1, "{");
 	      dump (0, "msg (SE, _(\"Number expected after %s "
 		    "specifier of %s subcommand.\"));",
 		    s->specname, sbc->name);
 	      dump (0, "goto lossage;");
 	      dump (-1, "}");
-	      dump (-1, "p->%s%s = tokval;", sbc->prefix,
+	      dump (-1, "p->%s%s = lex_tokval (lexer);", sbc->prefix,
 		    st_lower (s->valname));
 	    }
 	  
@@ -1480,11 +1480,11 @@
 	      outdent ();
 	    }
 	  
-	  dump (0, "lex_get ();");
+	  dump (0, "lex_get (lexer);");
 	  
 	  if (s->valtype == VT_PAREN)
 	    {
-	      dump (1, "if (!lex_match (')'))");
+	      dump (1, "if (!lex_match (lexer, ')'))");
 	      dump (1, "{");
 	      dump (0, "msg (SE, _(\"`)' expected after argument for "
 		    "%s specifier of %s.\"));",
@@ -1520,7 +1520,7 @@
     {
       int count;
 
-      dump (1, "while (token != '/' && token != '.')");
+      dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')");
       dump (1, "{");
       
       {
@@ -1571,20 +1571,20 @@
 	  {
 	    dump (1, "else");
 	    dump (1, "{");
-	    dump (0, "lex_error (NULL);");
+	    dump (0, "lex_error (lexer, NULL);");
 	    dump (0, "goto lossage;");
 	    dump (-1, "}");
 	    outdent ();
 	  }
       }
 
-      dump (0, "lex_match (',');");
+      dump (0, "lex_match (lexer, ',');");
       dump (-1, "}");
       outdent ();
     }
   else if (sbc->type == SBC_VARLIST)
     {
-      dump (1, "if (!parse_variables (dataset_dict (ds), &p->%sv_%s, &p->%sn_%s, "
+      dump (1, "if (!parse_variables (lexer, dataset_dict (ds), &p->%sv_%s, &p->%sn_%s, "
 	    "PV_APPEND%s%s))",
 	    st_lower (sbc->prefix), st_lower (sbc->name),
 	    st_lower (sbc->prefix), st_lower (sbc->name),
@@ -1595,7 +1595,7 @@
     }
   else if (sbc->type == SBC_VAR)
     {
-      dump (0, "p->%sv_%s = parse_variable (dataset_dict (ds));",
+      dump (0, "p->%sv_%s = parse_variable (lexer, dataset_dict (ds));",
 	    st_lower (sbc->prefix), st_lower (sbc->name));
       dump (1, "if (!p->%sv_%s)",
 	    st_lower (sbc->prefix), st_lower (sbc->name));
@@ -1609,12 +1609,12 @@
 	  dump (1, "{");
 	  dump (0, "int x;");
 	}
-      dump (1, "if (!lex_force_string ())");
+      dump (1, "if (!lex_force_string (lexer))");
       dump (0, "return false;");
       outdent ();
       if (sbc->restriction)
 	{
-	  dump (0, "x = ds_length (&tokstr);");
+	  dump (0, "x = ds_length (lex_tokstr (lexer));");
 	  dump (1, "if (!(%s))", sbc->restriction);
 	  dump (1, "{");
 	  dump (0, "msg (SE, _(\"String for %s must be %s.\"));",
@@ -1624,28 +1624,28 @@
 	  outdent ();
 	}
       dump (0, "free(p->s_%s);", st_lower(sbc->name) );
-      dump (0, "p->s_%s = ds_xstrdup (&tokstr);",
+      dump (0, "p->s_%s = ds_xstrdup (lex_tokstr (lexer));",
 	    st_lower (sbc->name));
-      dump (0, "lex_get ();");
+      dump (0, "lex_get (lexer);");
       if (sbc->restriction)
 	dump (-1, "}");
     }
   else if (sbc->type == SBC_DBL)
     {
-      dump (1, "if (!lex_force_num ())");
+      dump (1, "if (!lex_force_num (lexer))");
       dump (0, "goto lossage;");
-      dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_number ();", 
+      dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_number (lexer);", 
 	    st_lower (sbc->name), st_lower (sbc->name) );
-      dump (0, "lex_get();");
+      dump (0, "lex_get(lexer);");
     }
   else if (sbc->type == SBC_INT)
     {
       dump(1, "{");
       dump(0, "int x;");
-      dump (1, "if (!lex_force_int ())");
+      dump (1, "if (!lex_force_int (lexer))");
       dump (0, "goto lossage;");
-      dump (-1, "x = lex_integer ();");
-      dump (0, "lex_get();");
+      dump (-1, "x = lex_integer (lexer);");
+      dump (0, "lex_get(lexer);");
       if (sbc->restriction)
        {
 	  char buf[1024];
@@ -1664,11 +1664,11 @@
     }
   else if (sbc->type == SBC_PINT)
     {
-      dump (0, "lex_match ('(');");
-      dump (1, "if (!lex_force_int ())");
+      dump (0, "lex_match (lexer, '(');");
+      dump (1, "if (!lex_force_int (lexer))");
       dump (0, "goto lossage;");
-      dump (-1, "p->n_%s = lex_integer ();", st_lower (sbc->name));
-      dump (0, "lex_match (')');");
+      dump (-1, "p->n_%s = lex_integer (lexer);", st_lower (sbc->name));
+      dump (0, "lex_match (lexer, ')');");
     }
   else if (sbc->type == SBC_DBL_LIST)
     {
@@ -1678,25 +1678,25 @@
       dump (0, "goto lossage;");
       dump (-1,"}");
 
-      dump (1, "while (token != '/' && token != '.')");
+      dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')");
       dump (1, "{");
-      dump (0, "lex_match(',');");
-      dump (0, "if (!lex_force_num ())");
+      dump (0, "lex_match (lexer, ',');");
+      dump (0, "if (!lex_force_num (lexer))");
       dump (1, "{");
       dump (0, "goto lossage;");
       dump (-1,"}");
 
-      dump (0, "subc_list_double_push(&p->dl_%s[p->sbc_%s-1],lex_number ());", 
+      dump (0, "subc_list_double_push (&p->dl_%s[p->sbc_%s-1], lex_number (lexer));", 
 	    st_lower (sbc->name),st_lower (sbc->name)
 	    );
 
-      dump (0, "lex_get();");
+      dump (0, "lex_get (lexer);");
       dump (-1,"}");
 
     }
   else if (sbc->type == SBC_CUSTOM)
     {
-      dump (1, "switch (%scustom_%s (ds, p, aux))",
+      dump (1, "switch (%scustom_%s (lexer, ds, p, aux))",
 	    st_lower (prefix), st_lower (sbc->name));
       dump (0, "{");
       dump (1, "case 0:");
@@ -1706,7 +1706,7 @@
       dump (0, "break;");
       dump (-1, "case 2:");
       indent ();
-      dump (0, "lex_error (NULL);");
+      dump (0, "lex_error (lexer, NULL);");
       dump (0, "goto lossage;");
       dump (-1, "default:");
       indent ();
@@ -1725,7 +1725,7 @@
   indent = 0;
 
   dump (0, "static int");
-  dump (0, "parse_%s (struct dataset *ds%s, struct cmd_%s *p, void *aux UNUSED)",
+  dump (0, "parse_%s (struct lexer *lexer, struct dataset *ds%s, struct cmd_%s *p, void *aux UNUSED)",
         make_identifier (cmdname),
 	(def && ( def->type == SBC_VARLIST && def->type == SBC_CUSTOM))?"":" UNUSED",
 	make_identifier (cmdname));
@@ -1740,19 +1740,19 @@
   if (def && (def->type == SBC_VARLIST))
     {
       if (def->type == SBC_VARLIST)
-	dump (1, "if (token == T_ID "
-              "&& dict_lookup_var (dataset_dict (ds), tokid) != NULL "
-	      "&& lex_look_ahead () != '=')");
+	dump (1, "if (lex_token (lexer) == T_ID "
+              "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != NULL "
+	      "&& lex_look_ahead (lexer) != '=')");
       else
 	{
-	  dump (0, "if ((token == T_ID "
-                "&& dict_lookup_var (dataset_dict (ds), tokid) "
+	  dump (0, "if ((lex_token (lexer) == T_ID "
+                "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) "
 		"&& lex_look_ahead () != '=')");
 	  dump (1, "     || token == T_ALL)");
 	}
       dump (1, "{");
       dump (0, "p->sbc_%s++;", st_lower (def->name));
-      dump (1, "if (!parse_variables (dataset_dict (ds), &p->%sv_%s, &p->%sn_%s, "
+      dump (1, "if (!parse_variables (lexer, dataset_dict (ds), &p->%sv_%s, &p->%sn_%s, "
 	    "PV_APPEND))",
 	    st_lower (def->prefix), st_lower (def->name),
 	    st_lower (def->prefix), st_lower (def->name));
@@ -1763,7 +1763,7 @@
     }
   else if (def && def->type == SBC_CUSTOM)
     {
-      dump (1, "switch (%scustom_%s (ds, p, aux))",
+      dump (1, "switch (%scustom_%s (lexer, ds, p, aux))",
 	    st_lower (prefix), st_lower (def->name));
       dump (0, "{");
       dump (1, "case 0:");
@@ -1791,7 +1791,7 @@
 	f = 1;
 	dump (1, "{");
 
-	dump (0, "lex_match ('=');");
+	dump (0, "lex_match (lexer, '=');");
 	dump (0, "p->sbc_%s++;", st_lower (sbc->name));
 	if (sbc->arity != ARITY_MANY)
 	  {
@@ -1811,15 +1811,15 @@
 
 
   /* Now deal with the /ALGORITHM subcommand implicit to all commands */
-  dump(1,"else if ( get_syntax() != COMPATIBLE && lex_match_id(\"ALGORITHM\"))");
+  dump(1,"else if ( get_syntax() != COMPATIBLE && lex_match_id(lexer, \"ALGORITHM\"))");
   dump(1,"{");
 
-  dump (0, "lex_match ('=');");
+  dump (0, "lex_match (lexer, '=');");
 
-  dump(1,"if (lex_match_id(\"COMPATIBLE\"))");
+  dump(1,"if (lex_match_id(lexer, \"COMPATIBLE\"))");
   dump(0,"set_cmd_algorithm(COMPATIBLE);");
   outdent();
-  dump(1,"else if (lex_match_id(\"ENHANCED\"))");
+  dump(1,"else if (lex_match_id(lexer, \"ENHANCED\"))");
   dump(0,"set_cmd_algorithm(ENHANCED);");
 
   dump (-1, "}");
@@ -1827,14 +1827,14 @@
 
 
   
-  dump (1, "if (!lex_match ('/'))");
+  dump (1, "if (!lex_match (lexer, '/'))");
   dump (0, "break;");
   dump (-2, "}");
   outdent ();
   dump (0, nullstr);
-  dump (1, "if (token != '.')");
+  dump (1, "if (lex_token (lexer) != '.')");
   dump (1, "{");
-  dump (0, "lex_error (_(\"expecting end of command\"));");
+  dump (0, "lex_error (lexer, _(\"expecting end of command\"));");
   dump (0, "goto lossage;");
   dump (-1, "}");
   dump (0, nullstr);
Index: src/language/lexer/range-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/range-parser.c,v
retrieving revision 1.4
diff -b -w -U3 -r1.4 range-parser.c
--- src/language/lexer/range-parser.c	3 Nov 2006 04:53:51 -0000	1.4
+++ src/language/lexer/range-parser.c	11 Nov 2006 00:13:16 -0000
@@ -31,7 +31,7 @@
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-static bool parse_number (double *, const struct fmt_spec *);
+static bool parse_number (struct lexer *, double *, const struct fmt_spec *);
 
 /* Parses and stores a numeric value, or a range of the form "x
    THRU y".  Open-ended ranges may be specified as "LO(WEST) THRU
@@ -42,18 +42,18 @@
    string values are also accepted, and converted to numeric
    values using the specified format. */
 bool
-parse_num_range (double *x, double *y, const struct fmt_spec *f) 
+parse_num_range (struct lexer *lexer, double *x, double *y, const struct fmt_spec *f) 
 {
-  if (lex_match_id ("LO") || lex_match_id ("LOWEST"))
+  if (lex_match_id (lexer, "LO") || lex_match_id (lexer, "LOWEST"))
     *x = LOWEST;
-  else if (!parse_number (x, f))
+  else if (!parse_number (lexer, x, f))
     return false;
 
-  if (lex_match_id ("THRU")) 
+  if (lex_match_id (lexer, "THRU")) 
     {
-      if (lex_match_id ("HI") || lex_match_id ("HIGHEST"))
+      if (lex_match_id (lexer, "HI") || lex_match_id (lexer, "HIGHEST"))
         *y = HIGHEST;
-      else if (!parse_number (y, f))
+      else if (!parse_number (lexer, y, f))
         return false;
 
       if (*y < *x) 
@@ -90,27 +90,27 @@
    string values are also accepted, and converted to numeric
    values using the specified format. */
 static bool
-parse_number (double *x, const struct fmt_spec *f)
+parse_number (struct lexer *lexer, double *x, const struct fmt_spec *f)
 {
-  if (lex_is_number ()) 
+  if (lex_is_number (lexer)) 
     {
-      *x = lex_number ();
-      lex_get ();
+      *x = lex_number (lexer);
+      lex_get (lexer);
       return true;
     }
-  else if (token == T_STRING && f != NULL) 
+  else if (lex_token (lexer) == T_STRING && f != NULL) 
     {
       struct data_in di;
       union value v;
-      di.s = ds_data (&tokstr);
-      di.e = ds_end (&tokstr);
+      di.s = ds_data (lex_tokstr (lexer));
+      di.e = ds_end (lex_tokstr (lexer));
       di.v = &v;
       di.flags = 0;
       di.f1 = 1;
-      di.f2 = ds_length (&tokstr);
+      di.f2 = ds_length (lex_tokstr (lexer));
       di.format = *f;
       data_in (&di);
-      lex_get ();
+      lex_get (lexer);
       *x = v.f;
       if (*x == SYSMIS)
         {
@@ -122,9 +122,9 @@
   else 
     {
       if (f != NULL)
-        lex_error (_("expecting number or data string"));
+        lex_error (lexer, _("expecting number or data string"));
       else
-        lex_force_num ();
+        lex_force_num (lexer);
       return false; 
     }
 }
Index: src/language/lexer/range-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/range-parser.h,v
retrieving revision 1.1
diff -b -w -U3 -r1.1 range-parser.h
--- src/language/lexer/range-parser.h	4 Mar 2006 01:11:57 -0000	1.1
+++ src/language/lexer/range-parser.h	11 Nov 2006 00:13:16 -0000
@@ -23,6 +23,7 @@
 #include <stdbool.h>
 
 struct fmt_spec;
-bool parse_num_range (double *x, double *y, const struct fmt_spec *fmt);
+struct lexer;
+bool parse_num_range (struct lexer *, double *, double *, const struct fmt_spec *fmt);
 
 #endif /* range-prs.h */
Index: src/language/lexer/subcommand-list.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/subcommand-list.c,v
retrieving revision 1.1
diff -b -w -U3 -r1.1 subcommand-list.c
--- src/language/lexer/subcommand-list.c	4 Mar 2006 01:11:57 -0000	1.1
+++ src/language/lexer/subcommand-list.c	11 Nov 2006 00:13:16 -0000
@@ -21,6 +21,7 @@
 02110-1301, USA. */
 
 
+#include <config.h>
 #include "subcommand-list.h"
 #include <stdlib.h>
 #include "xalloc.h"
Index: src/language/lexer/variable-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/variable-parser.c,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 variable-parser.c
--- src/language/lexer/variable-parser.c	26 Oct 2006 06:16:36 -0000	1.10
+++ src/language/lexer/variable-parser.c	11 Nov 2006 00:13:17 -0000
@@ -44,23 +44,24 @@
    variable's index and returns true if successful.  On failure
    emits an error message and returns false. */
 static bool
-parse_vs_variable_idx (const struct var_set *vs, size_t *idx)
+parse_vs_variable_idx (struct lexer *lexer, const struct var_set *vs, 
+		size_t *idx)
 {
   assert (idx != NULL);
   
-  if (token != T_ID)
+  if (lex_token (lexer) != T_ID)
     {
-      lex_error (_("expecting variable name"));
+      lex_error (lexer, _("expecting variable name"));
       return false;
     }
-  else if (var_set_lookup_var_idx (vs, tokid, idx)) 
+  else if (var_set_lookup_var_idx (vs, lex_tokid (lexer), idx)) 
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else 
     {
-      msg (SE, _("%s is not a variable name."), tokid);
+      msg (SE, _("%s is not a variable name."), lex_tokid (lexer));
       return false;
     }
 }
@@ -69,20 +70,20 @@
    if successful.  On failure emits an error message and returns
    a null pointer. */
 static struct variable *
-parse_vs_variable (const struct var_set *vs)
+parse_vs_variable (struct lexer *lexer, const struct var_set *vs)
 {
   size_t idx;
-  return parse_vs_variable_idx (vs, &idx) ? var_set_get_var (vs, idx) : NULL;
+  return parse_vs_variable_idx (lexer, vs, &idx) ? var_set_get_var (vs, idx) : NULL;
 }
 
 /* Parses a variable name in dictionary D and returns the
    variable if successful.  On failure emits an error message and
    returns a null pointer. */
 struct variable *
-parse_variable (const struct dictionary *d) 
+parse_variable (struct lexer *lexer, const struct dictionary *d) 
 {
   struct var_set *vs = var_set_create_from_dict (d);
-  struct variable *var = parse_vs_variable (vs);
+  struct variable *var = parse_vs_variable (lexer, vs);
   var_set_destroy (vs);
   return var;
 }
@@ -92,7 +93,8 @@
    number of variables into *CNT.  Returns true only if
    successful. */
 bool
-parse_variables (const struct dictionary *d, struct variable ***var,
+parse_variables (struct lexer *lexer, const struct dictionary *d, 
+			struct variable ***var,
                  size_t *cnt, int opts) 
 {
   struct var_set *vs;
@@ -103,7 +105,7 @@
   assert (cnt != NULL);
 
   vs = var_set_create_from_dict (d);
-  success = parse_var_set_vars (vs, var, cnt, opts);
+  success = parse_var_set_vars (lexer, vs, var, cnt, opts);
   if ( success == 0 )
      free ( *var ) ;
   var_set_destroy (vs);
@@ -116,7 +118,8 @@
    successful.  Same behavior as parse_variables, except that all
    allocations are taken from the given POOL. */
 bool
-parse_variables_pool (struct pool *pool, const struct dictionary *dict,
+parse_variables_pool (struct lexer *lexer, struct pool *pool, 
+		const struct dictionary *dict,
                       struct variable ***vars, size_t *var_cnt, int opts) 
 {
   int retval;
@@ -127,7 +130,7 @@
      later. */
   assert (!(opts & PV_APPEND));
   
-  retval = parse_variables (dict, vars, var_cnt, opts);
+  retval = parse_variables (lexer, dict, vars, var_cnt, opts);
   if (retval)
     pool_register (pool, free, *vars);
   return retval;
@@ -138,10 +141,11 @@
    dictionary class, and returns true.  Returns false on
    failure. */
 static bool
-parse_var_idx_class (const struct var_set *vs, size_t *idx,
+parse_var_idx_class (struct lexer *lexer, const struct var_set *vs, 
+			size_t *idx,
                      enum dict_class *class)
 {
-  if (!parse_vs_variable_idx (vs, idx))
+  if (!parse_vs_variable_idx (lexer, vs, idx))
     return false;
 
   *class = dict_class_from_id (var_set_get_var (vs, *idx)->name);
@@ -212,7 +216,7 @@
    Conversely, if parse_variables() returns true, then *nv is
    nonzero and *v is non-NULL. */
 bool
-parse_var_set_vars (const struct var_set *vs, 
+parse_var_set_vars (struct lexer *lexer, const struct var_set *vs, 
                     struct variable ***v, size_t *nv,
                     int pv_opts)
 {
@@ -254,7 +258,7 @@
 
   do
     {
-      if (lex_match (T_ALL))
+      if (lex_match (lexer, T_ALL))
         add_variables (v, nv, &mv, included, pv_opts,
                        vs, 0, var_set_get_cnt (vs) - 1, DC_ORDINARY);
       else 
@@ -262,10 +266,10 @@
           enum dict_class class;
           size_t first_idx;
 
-          if (!parse_var_idx_class (vs, &first_idx, &class))
+          if (!parse_var_idx_class (lexer, vs, &first_idx, &class))
             goto fail;
 
-          if (!lex_match (T_TO))
+          if (!lex_match (lexer, T_TO))
             add_variable (v, nv, &mv, included, pv_opts, vs, first_idx);
           else 
             {
@@ -273,7 +277,7 @@
               enum dict_class last_class;
               struct variable *first_var, *last_var;
 
-              if (!parse_var_idx_class (vs, &last_idx, &last_class))
+              if (!parse_var_idx_class (lexer, vs, &last_idx, &last_class))
                 goto fail;
 
               first_var = var_set_get_var (vs, first_idx);
@@ -307,10 +311,10 @@
 
       if (pv_opts & PV_SINGLE)
         break;
-      lex_match (',');
+      lex_match (lexer, ',');
     }
-  while (token == T_ALL
-         || (token == T_ID && var_set_lookup_var (vs, tokid) != NULL));
+  while (lex_token (lexer) == T_ALL
+         || (lex_token (lexer) == T_ID && var_set_lookup_var (vs, lex_tokid (lexer)) != NULL));
   
   if (*nv == 0)
     goto fail;
@@ -372,7 +376,7 @@
 /* Parses a list of variable names according to the DATA LIST version
    of the TO convention.  */
 bool
-parse_DATA_LIST_vars (char ***names, size_t *nnames, int pv_opts)
+parse_DATA_LIST_vars (struct lexer *lexer, char ***names, size_t *nnames, int pv_opts)
 {
   int n1, n2;
   int d1, d2;
@@ -398,29 +402,29 @@
 
   do
     {
-      if (token != T_ID)
+      if (lex_token (lexer) != T_ID)
 	{
-	  lex_error ("expecting variable name");
+	  lex_error (lexer, "expecting variable name");
 	  goto fail;
 	}
-      if (dict_class_from_id (tokid) == DC_SCRATCH
+      if (dict_class_from_id (lex_tokid (lexer)) == DC_SCRATCH
           && (pv_opts & PV_NO_SCRATCH))
 	{
 	  msg (SE, _("Scratch variables not allowed here."));
 	  goto fail;
 	}
-      strcpy (name1, tokid);
-      lex_get ();
-      if (token == T_TO)
+      strcpy (name1, lex_tokid (lexer));
+      lex_get (lexer);
+      if (lex_token (lexer) == T_TO)
 	{
-	  lex_get ();
-	  if (token != T_ID)
+	  lex_get (lexer);
+	  if (lex_token (lexer) != T_ID)
 	    {
-	      lex_error ("expecting variable name");
+	      lex_error (lexer, "expecting variable name");
 	      goto fail;
 	    }
-	  strcpy (name2, tokid);
-	  lex_get ();
+	  strcpy (name2, lex_tokid (lexer));
+	  lex_get (lexer);
 
 	  if (!extract_num (name1, root1, &n1, &d1)
 	      || !extract_num (name2, root2, &n2, &d2))
@@ -463,12 +467,12 @@
 	  (*names)[nvar++] = xstrdup (name1);
 	}
 
-      lex_match (',');
+      lex_match (lexer, ',');
 
       if (pv_opts & PV_SINGLE)
 	break;
     }
-  while (token == T_ID);
+  while (lex_token (lexer) == T_ID);
   success = 1;
 
 fail:
@@ -502,7 +506,7 @@
    parse_DATA_LIST_vars(), except that all allocations are taken
    from the given POOL. */
 bool
-parse_DATA_LIST_vars_pool (struct pool *pool,
+parse_DATA_LIST_vars_pool (struct lexer *lexer, struct pool *pool,
                            char ***names, size_t *nnames, int pv_opts)
 {
   int retval;
@@ -513,7 +517,7 @@
      re-free it later. */
   assert (!(pv_opts & PV_APPEND));
   
-  retval = parse_DATA_LIST_vars (names, nnames, pv_opts);
+  retval = parse_DATA_LIST_vars (lexer, names, nnames, pv_opts);
   if (retval)
     register_vars_pool (pool, *names, *nnames);
   return retval;
@@ -523,7 +527,7 @@
    existing and the rest are to be created.  Same args as
    parse_DATA_LIST_vars(). */
 bool
-parse_mixed_vars (const struct dictionary *dict, 
+parse_mixed_vars (struct lexer *lexer, const struct dictionary *dict, 
 		  char ***names, size_t *nnames, int pv_opts)
 {
   size_t i;
@@ -537,14 +541,14 @@
       *names = NULL;
       *nnames = 0;
     }
-  while (token == T_ID || token == T_ALL)
+  while (lex_token (lexer) == T_ID || lex_token (lexer) == T_ALL)
     {
-      if (token == T_ALL || dict_lookup_var (dict, tokid) != NULL)
+      if (lex_token (lexer) == T_ALL || dict_lookup_var (dict, lex_tokid (lexer)) != NULL)
 	{
 	  struct variable **v;
 	  size_t nv;
 
-	  if (!parse_variables (dict, &v, &nv, PV_NONE))
+	  if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
 	    goto fail;
 	  *names = xnrealloc (*names, *nnames + nv, sizeof **names);
 	  for (i = 0; i < nv; i++)
@@ -552,7 +556,7 @@
 	  free (v);
 	  *nnames += nv;
 	}
-      else if (!parse_DATA_LIST_vars (names, nnames, PV_APPEND))
+      else if (!parse_DATA_LIST_vars (lexer, names, nnames, PV_APPEND))
 	goto fail;
     }
   return 1;
@@ -571,7 +575,7 @@
    parse_mixed_vars(), except that all allocations are taken
    from the given POOL. */
 bool
-parse_mixed_vars_pool (const struct dictionary *dict, struct pool *pool,
+parse_mixed_vars_pool (struct lexer *lexer, const struct dictionary *dict, struct pool *pool,
                        char ***names, size_t *nnames, int pv_opts)
 {
   int retval;
@@ -582,7 +586,7 @@
      re-free it later. */
   assert (!(pv_opts & PV_APPEND));
 
-  retval = parse_mixed_vars (dict, names, nnames, pv_opts);
+  retval = parse_mixed_vars (lexer, dict, names, nnames, pv_opts);
   if (retval)
     register_vars_pool (pool, *names, *nnames);
   return retval;
Index: src/language/lexer/variable-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/variable-parser.h,v
retrieving revision 1.4
diff -b -w -U3 -r1.4 variable-parser.h
--- src/language/lexer/variable-parser.h	26 Oct 2006 06:16:36 -0000	1.4
+++ src/language/lexer/variable-parser.h	11 Nov 2006 00:13:17 -0000
@@ -27,6 +27,7 @@
 struct dictionary;
 struct var_set;
 struct variable;
+struct lexer ;
 
 struct var_set *var_set_create_from_dict (const struct dictionary *d);
 struct var_set *var_set_create_from_array (struct variable *const *var,
@@ -55,19 +56,19 @@
     PV_NO_SCRATCH = 00200 	/* Disallow scratch variables. */
   };
 
-struct variable *parse_variable (const struct dictionary *);
-bool parse_variables (const struct dictionary *, struct variable ***, size_t *,
+struct variable *parse_variable (struct lexer *, const struct dictionary *);
+bool parse_variables (struct lexer *, const struct dictionary *, struct variable ***, size_t *,
                      int opts);
-bool parse_variables_pool (struct pool *, const struct dictionary *,
+bool parse_variables_pool (struct lexer *, struct pool *, const struct dictionary *,
                           struct variable ***, size_t *, int opts);
-bool parse_var_set_vars (const struct var_set *, struct variable ***, size_t *,
+bool parse_var_set_vars (struct lexer *, const struct var_set *, struct variable ***, size_t *,
                         int opts);
-bool parse_DATA_LIST_vars (char ***names, size_t *cnt, int opts);
-bool parse_DATA_LIST_vars_pool (struct pool *,
+bool parse_DATA_LIST_vars (struct lexer *, char ***names, size_t *cnt, int opts);
+bool parse_DATA_LIST_vars_pool (struct lexer *, struct pool *,
                                char ***names, size_t *cnt, int opts);
-bool parse_mixed_vars (const struct dictionary *dict, 
+bool parse_mixed_vars (struct lexer *, const struct dictionary *dict, 
 		       char ***names, size_t *cnt, int opts);
-bool parse_mixed_vars_pool (const struct dictionary *dict, 
+bool parse_mixed_vars_pool (struct lexer *, const struct dictionary *dict, 
 			    struct pool *,
                            char ***names, size_t *cnt, int opts);
 
Index: src/language/stats/aggregate.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/aggregate.c,v
retrieving revision 1.18
diff -b -w -U3 -r1.18 aggregate.c
--- src/language/stats/aggregate.c	3 Nov 2006 04:53:51 -0000	1.18
+++ src/language/stats/aggregate.c	11 Nov 2006 00:13:17 -0000
@@ -155,7 +155,7 @@
                                        const struct ccase *);
 
 /* Prototypes. */
-static bool parse_aggregate_functions (const struct dictionary *,
+static bool parse_aggregate_functions (struct lexer *, const struct dictionary *,
 				       struct agr_proc *);
 static void agr_destroy (struct agr_proc *);
 static bool aggregate_single_case (struct agr_proc *agr,
@@ -173,7 +173,7 @@
 
 /* Parses and executes the AGGREGATE procedure. */
 int
-cmd_aggregate (struct dataset *ds)
+cmd_aggregate (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct agr_proc agr;
@@ -193,12 +193,12 @@
   dict_set_documents (agr.dict, dict_get_documents (dict));
 
   /* OUTFILE subcommand must be first. */
-  if (!lex_force_match_id ("OUTFILE"))
+  if (!lex_force_match_id (lexer, "OUTFILE"))
     goto error;
-  lex_match ('=');
-  if (!lex_match ('*'))
+  lex_match (lexer, '=');
+  if (!lex_match (lexer, '*'))
     {
-      out_file = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+      out_file = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
       if (out_file == NULL)
         goto error;
     }
@@ -206,28 +206,28 @@
   /* Read most of the subcommands. */
   for (;;)
     {
-      lex_match ('/');
+      lex_match (lexer, '/');
       
-      if (lex_match_id ("MISSING"))
+      if (lex_match_id (lexer, "MISSING"))
 	{
-	  lex_match ('=');
-	  if (!lex_match_id ("COLUMNWISE"))
+	  lex_match (lexer, '=');
+	  if (!lex_match_id (lexer, "COLUMNWISE"))
 	    {
-	      lex_error (_("while expecting COLUMNWISE"));
+	      lex_error (lexer, _("while expecting COLUMNWISE"));
               goto error;
 	    }
 	  agr.missing = COLUMNWISE;
 	}
-      else if (lex_match_id ("DOCUMENT"))
+      else if (lex_match_id (lexer, "DOCUMENT"))
         copy_documents = true;
-      else if (lex_match_id ("PRESORTED"))
+      else if (lex_match_id (lexer, "PRESORTED"))
         presorted = true;
-      else if (lex_match_id ("BREAK"))
+      else if (lex_match_id (lexer, "BREAK"))
 	{
           int i;
 
-	  lex_match ('=');
-          agr.sort = sort_parse_criteria (dict,
+	  lex_match (lexer, '=');
+          agr.sort = sort_parse_criteria (lexer, dict,
                                           &agr.break_vars, &agr.break_var_cnt,
                                           &saw_direction, NULL);
           if (agr.sort == NULL)
@@ -242,7 +242,7 @@
 	}
       else
         {
-          lex_error (_("expecting BREAK"));
+          lex_error (lexer, _("expecting BREAK"));
           goto error;
         }
     }
@@ -252,8 +252,8 @@
                "the same way as the input data."));
       
   /* Read in the aggregate functions. */
-  lex_match ('/');
-  if (!parse_aggregate_functions (dict, &agr))
+  lex_match (lexer, '/');
+  if (!parse_aggregate_functions (lexer, dict, &agr))
     goto error;
 
   /* Delete documents. */
@@ -359,7 +359,7 @@
 
 /* Parse all the aggregate functions. */
 static bool
-parse_aggregate_functions (const struct dictionary *dict, struct agr_proc *agr)
+parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict, struct agr_proc *agr)
 {
   struct agr_var *tail; /* Tail of linked list starting at agr->vars. */
 
@@ -370,6 +370,7 @@
       char **dest;
       char **dest_label;
       size_t n_dest;
+      struct string function_name;
 
       int include_missing;
       const struct agr_func *function;
@@ -392,11 +393,11 @@
       arg[1].c = NULL;
 
       /* Parse the list of target variables. */
-      while (!lex_match ('='))
+      while (!lex_match (lexer, '='))
 	{
 	  size_t n_dest_prev = n_dest;
 	  
-	  if (!parse_DATA_LIST_vars (&dest, &n_dest,
+	  if (!parse_DATA_LIST_vars (lexer, &dest, &n_dest,
                                      PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
 	    goto error;
 
@@ -409,41 +410,49 @@
 	      dest_label[j] = NULL;
 	  }
 	  
-	  if (token == T_STRING)
+
+	  
+	  if (lex_token (lexer) == T_STRING)
 	    {
-	      ds_truncate (&tokstr, 255);
-	      dest_label[n_dest - 1] = ds_xstrdup (&tokstr);
-	      lex_get ();
+	      struct string label;
+	      ds_init_string (&label, lex_tokstr (lexer));
+
+	      ds_truncate (&label, 255);
+	      dest_label[n_dest - 1] = ds_xstrdup (&label);
+	      lex_get (lexer);
 	    }
 	}
 
       /* Get the name of the aggregation function. */
-      if (token != T_ID)
+      if (lex_token (lexer) != T_ID)
 	{
-	  lex_error (_("expecting aggregation function"));
+	  lex_error (lexer, _("expecting aggregation function"));
 	  goto error;
 	}
 
       include_missing = 0;
-      if (tokid[strlen (tokid) - 1] == '.')
-	{
+
+      ds_init_string (&function_name, lex_tokstr (lexer));
+
+      ds_chomp (&function_name, '.');
+
+      if (lex_tokid(lexer)[strlen (lex_tokid (lexer)) - 1] == '.')
 	  include_missing = 1;
-	  tokid[strlen (tokid) - 1] = 0;
-	}
       
       for (function = agr_func_tab; function->name; function++)
-	if (!strcasecmp (function->name, tokid))
+	if (!strcasecmp (function->name, ds_cstr (&function_name)))
 	  break;
       if (NULL == function->name)
 	{
-	  msg (SE, _("Unknown aggregation function %s."), tokid);
+	  msg (SE, _("Unknown aggregation function %s."), 
+	       ds_cstr (&function_name));
 	  goto error;
 	}
       func_index = function - agr_func_tab;
-      lex_get ();
+      lex_get (lexer);
 
       /* Check for leading lparen. */
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
 	{
 	  if (func_index == N)
 	    func_index = N_NO_VARS;
@@ -451,7 +460,7 @@
 	    func_index = NU_NO_VARS;
 	  else
 	    {
-	      lex_error (_("expecting `('"));
+	      lex_error (lexer, _("expecting `('"));
 	      goto error;
 	    }
 	}
@@ -466,7 +475,7 @@
 	    else if (function->n_args)
 	      pv_opts |= PV_SAME_TYPE;
 
-	    if (!parse_variables (dict, &src, &n_src, pv_opts))
+	    if (!parse_variables (lexer, dict, &src, &n_src, pv_opts))
 	      goto error;
 	  }
 
@@ -477,15 +486,15 @@
 	      {
 		int type;
 	    
-		lex_match (',');
-		if (token == T_STRING)
+		lex_match (lexer, ',');
+		if (lex_token (lexer) == T_STRING)
 		  {
-		    arg[i].c = ds_xstrdup (&tokstr);
+		    arg[i].c = ds_xstrdup (lex_tokstr (lexer));
 		    type = ALPHA;
 		  }
-		else if (lex_is_number ())
+		else if (lex_is_number (lexer))
 		  {
-		    arg[i].f = tokval;
+		    arg[i].f = lex_tokval (lexer);
 		    type = NUMERIC;
 		  } else {
 		    msg (SE, _("Missing argument %d to %s."), i + 1,
@@ -493,7 +502,7 @@
 		    goto error;
 		  }
 	    
-		lex_get ();
+		lex_get (lexer);
 
 		if (type != src[0]->type)
 		  {
@@ -505,9 +514,9 @@
 	      }
 
 	  /* Trailing rparen. */
-	  if (!lex_match(')'))
+	  if (!lex_match (lexer, ')'))
 	    {
-	      lex_error (_("expecting `)'"));
+	      lex_error (lexer, _("expecting `)'"));
 	      goto error;
 	    }
 	  
@@ -649,12 +658,12 @@
       free (dest);
       free (dest_label);
 
-      if (!lex_match ('/'))
+      if (!lex_match (lexer, '/'))
 	{
-	  if (token == '.')
+	  if (lex_token (lexer) == '.')
 	    return true;
 
-	  lex_error ("expecting end of command");
+	  lex_error (lexer, "expecting end of command");
 	  return false;
 	}
       continue;
@@ -1106,7 +1115,8 @@
 /* Aggregate the current case and output it if we passed a
    breakpoint. */
 static bool
-presorted_agr_to_sysfile (const struct ccase *c, void *agr_, const struct dataset *ds UNUSED) 
+presorted_agr_to_sysfile (const struct ccase *c, void *agr_, 
+			  const struct dataset *ds UNUSED) 
 {
   struct agr_proc *agr = agr_;
 
Index: src/language/stats/autorecode.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/autorecode.c,v
retrieving revision 1.13
diff -b -w -U3 -r1.13 autorecode.c
--- src/language/stats/autorecode.c	29 Oct 2006 09:51:36 -0000	1.13
+++ src/language/stats/autorecode.c	11 Nov 2006 00:13:17 -0000
@@ -102,7 +102,7 @@
 
 /* Performs the AUTORECODE procedure. */
 int
-cmd_autorecode (struct dataset *ds)
+cmd_autorecode (struct lexer *lexer, struct dataset *ds)
 {
   struct autorecode_pgm arc;
   size_t dst_cnt;
@@ -119,15 +119,15 @@
   arc.print = 0;
   dst_cnt = 0;
 
-  lex_match_id ("VARIABLES");
-  lex_match ('=');
-  if (!parse_variables (dataset_dict (ds), &arc.src_vars, &arc.var_cnt,
+  lex_match_id (lexer, "VARIABLES");
+  lex_match (lexer, '=');
+  if (!parse_variables (lexer, dataset_dict (ds), &arc.src_vars, &arc.var_cnt,
                         PV_NO_DUPLICATE))
     goto lossage;
-  if (!lex_force_match_id ("INTO"))
+  if (!lex_force_match_id (lexer, "INTO"))
     goto lossage;
-  lex_match ('=');
-  if (!parse_DATA_LIST_vars (&arc.dst_names, &dst_cnt, PV_NONE))
+  lex_match (lexer, '=');
+  if (!parse_DATA_LIST_vars (lexer, &arc.dst_names, &dst_cnt, PV_NONE))
     goto lossage;
   if (dst_cnt != arc.var_cnt)
     {
@@ -144,14 +144,14 @@
 
       goto lossage;
     }
-  while (lex_match ('/'))
-    if (lex_match_id ("DESCENDING"))
+  while (lex_match (lexer, '/'))
+    if (lex_match_id (lexer, "DESCENDING"))
       arc.direction = DESCENDING;
-    else if (lex_match_id ("PRINT"))
+    else if (lex_match_id (lexer, "PRINT"))
       arc.print = 1;
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       goto lossage;
     }
 
Index: src/language/stats/correlations.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/correlations.q,v
retrieving revision 1.13
diff -b -w -U3 -r1.13 correlations.q
--- src/language/stats/correlations.q	26 Oct 2006 06:16:36 -0000	1.13
+++ src/language/stats/correlations.q	11 Nov 2006 00:13:17 -0000
@@ -46,12 +46,12 @@
 static struct file_handle *matrix_file;
 
 static void free_correlations_state (void);
-static int internal_cmd_correlations (struct dataset *ds);
+static int internal_cmd_correlations (struct lexer *lexer, struct dataset *ds);
 
 int
-cmd_correlations (struct dataset *ds)
+cmd_correlations (struct lexer *lexer, struct dataset *ds)
 {
-  int result = internal_cmd_correlations (ds);
+  int result = internal_cmd_correlations (lexer, ds);
   free_correlations_state ();
   return result;
 }
@@ -71,14 +71,14 @@
 /* (functions) */
 
 int
-internal_cmd_correlations (struct dataset *ds)
+internal_cmd_correlations (struct lexer *lexer, struct dataset *ds)
 {
   struct cmd_correlations cmd;
 
   cor_list = cor_last = NULL;
   matrix_file = NULL;
 
-  if (!parse_correlations (ds, &cmd, NULL))
+  if (!parse_correlations (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   free_correlations (&cmd);
@@ -87,26 +87,26 @@
 }
 
 static int
-cor_custom_variables (struct dataset *ds, struct cmd_correlations *cmd UNUSED, void *aux UNUSED)
+cor_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_correlations *cmd UNUSED, void *aux UNUSED)
 {
   struct variable **v1, **v2;
   size_t nv1, nv2;
   struct cor_set *cor;
 
   /* Ensure that this is a VARIABLES subcommand. */
-  if (!lex_match_id ("VARIABLES")
-      && (token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) != NULL)
-      && token != T_ALL)
+  if (!lex_match_id (lexer, "VARIABLES")
+      && (lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match ('=');
+  lex_match (lexer, '=');
 
-  if (!parse_variables (dataset_dict (ds), &v1, &nv1,
+  if (!parse_variables (lexer, dataset_dict (ds), &v1, &nv1,
 			PV_NO_DUPLICATE | PV_NUMERIC))
     return 0;
   
-  if (lex_match (T_WITH))
+  if (lex_match (lexer, T_WITH))
     {
-      if (!parse_variables (dataset_dict (ds), &v2, &nv2,
+      if (!parse_variables (lexer, dataset_dict (ds), &v2, &nv2,
 			    PV_NO_DUPLICATE | PV_NUMERIC))
 	{
 	  free (v1);
@@ -134,21 +134,21 @@
 }
 
 static int
-cor_custom_matrix (struct dataset *ds UNUSED, struct cmd_correlations *cmd UNUSED, void *aux UNUSED)
+cor_custom_matrix (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_correlations *cmd UNUSED, void *aux UNUSED)
 {
-  if (!lex_force_match ('('))
+  if (!lex_force_match (lexer, '('))
     return 0;
   
-  if (lex_match ('*'))
+  if (lex_match (lexer, '*'))
     matrix_file = NULL;
   else 
     {
-      matrix_file = fh_parse (FH_REF_FILE);
+      matrix_file = fh_parse (lexer, FH_REF_FILE);
       if (matrix_file == NULL)
         return 0; 
     }
 
-  if (!lex_force_match (')'))
+  if (!lex_force_match (lexer, ')'))
     return 0;
 
   return 1;
Index: src/language/stats/crosstabs.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/crosstabs.q,v
retrieving revision 1.21
diff -b -w -U3 -r1.21 crosstabs.q
--- src/language/stats/crosstabs.q	5 Nov 2006 05:20:53 -0000	1.21
+++ src/language/stats/crosstabs.q	11 Nov 2006 00:13:18 -0000
@@ -176,7 +176,7 @@
 static struct pool *pl_tc;	/* For table cells. */
 static struct pool *pl_col;	/* For column data. */
 
-static int internal_cmd_crosstabs (struct dataset *ds);
+static int internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds);
 static void precalc (const struct ccase *, void *, const struct dataset *);
 static bool calc_general (const struct ccase *, void *, const struct dataset *);
 static bool calc_integer (const struct ccase *, void *, const struct dataset *);
@@ -188,9 +188,9 @@
 
 /* Parse and execute CROSSTABS, then clean up. */
 int
-cmd_crosstabs (struct dataset *ds)
+cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
 {
-  int result = internal_cmd_crosstabs (ds);
+  int result = internal_cmd_crosstabs (lexer, ds);
 
   free (variables);
   pool_destroy (pl_tc);
@@ -201,7 +201,7 @@
 
 /* Parses and executes the CROSSTABS procedure. */
 static int
-internal_cmd_crosstabs (struct dataset *ds)
+internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
 {
   int i;
   bool ok;
@@ -213,7 +213,7 @@
   pl_tc = pool_create ();
   pl_col = pool_create ();
 
-  if (!parse_crosstabs (ds, &cmd, NULL))
+  if (!parse_crosstabs (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   mode = variables ? INTEGER : GENERAL;
@@ -303,7 +303,7 @@
 
 /* Parses the TABLES subcommand. */
 static int
-crs_custom_tables (struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
+crs_custom_tables (struct lexer *lexer, struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 {
   struct var_set *var_set;
   int n_by;
@@ -313,11 +313,11 @@
   int success = 0;
 
   /* Ensure that this is a TABLES subcommand. */
-  if (!lex_match_id ("TABLES")
-      && (token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == NULL)
-      && token != T_ALL)
+  if (!lex_match_id (lexer, "TABLES")
+      && (lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match ('=');
+  lex_match (lexer, '=');
 
   if (variables != NULL)
     var_set = var_set_create_from_array (variables, variables_cnt);
@@ -329,7 +329,7 @@
     {
       by = xnrealloc (by, n_by + 1, sizeof *by);
       by_nvar = xnrealloc (by_nvar, n_by + 1, sizeof *by_nvar);
-      if (!parse_var_set_vars (var_set, &by[n_by], &by_nvar[n_by],
+      if (!parse_var_set_vars (lexer, var_set, &by[n_by], &by_nvar[n_by],
                                PV_NO_DUPLICATE | PV_NO_SCRATCH))
 	goto done;
       if (xalloc_oversized (nx, by_nvar[n_by])) 
@@ -340,11 +340,11 @@
       nx *= by_nvar[n_by];
       n_by++;
 
-      if (!lex_match (T_BY))
+      if (!lex_match (lexer, T_BY))
 	{
 	  if (n_by < 2)
 	    {
-	      lex_error (_("expecting BY"));
+	      lex_error (lexer, _("expecting BY"));
 	      goto done;
 	    }
 	  else 
@@ -407,7 +407,7 @@
 
 /* Parses the VARIABLES subcommand. */
 static int
-crs_custom_variables (struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
+crs_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 {
   if (nxtab)
     {
@@ -415,7 +415,7 @@
       return 0;
     }
 
-  lex_match ('=');
+  lex_match (lexer, '=');
   
   for (;;)
     {
@@ -424,42 +424,43 @@
 
       long min, max;
       
-      if (!parse_variables (dataset_dict (ds), &variables, &variables_cnt,
+      if (!parse_variables (lexer, dataset_dict (ds), 
+			    &variables, &variables_cnt,
 			    (PV_APPEND | PV_NUMERIC
 			     | PV_NO_DUPLICATE | PV_NO_SCRATCH)))
 	return 0;
 
-      if (token != '(')
+      if (lex_token (lexer) != '(')
 	{
-	  lex_error ("expecting `('");
+	  lex_error (lexer, "expecting `('");
 	  goto lossage;
 	}
-      lex_get ();
+      lex_get (lexer);
 
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	goto lossage;
-      min = lex_integer ();
-      lex_get ();
+      min = lex_integer (lexer);
+      lex_get (lexer);
 
-      lex_match (',');
+      lex_match (lexer, ',');
 
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	goto lossage;
-      max = lex_integer ();
+      max = lex_integer (lexer);
       if (max < min)
 	{
 	  msg (SE, _("Maximum value (%ld) less than minimum value (%ld)."),
 	       max, min);
 	  goto lossage;
 	}
-      lex_get ();
+      lex_get (lexer);
 
-      if (token != ')')
+      if (lex_token (lexer) != ')')
 	{
-	  lex_error ("expecting `)'");
+	  lex_error (lexer, "expecting `)'");
 	  goto lossage;
 	}
-      lex_get ();
+      lex_get (lexer);
       
       for (i = orig_nv; i < variables_cnt; i++) 
         {
@@ -470,7 +471,7 @@
           var_attach_aux (variables[i], vr, var_dtor_free);
 	}
       
-      if (token == '/')
+      if (lex_token (lexer) == '/')
 	break;
     }
   
Index: src/language/stats/descriptives.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/descriptives.c,v
retrieving revision 1.16
diff -b -w -U3 -r1.16 descriptives.c
--- src/language/stats/descriptives.c	5 Nov 2006 00:35:43 -0000	1.16
+++ src/language/stats/descriptives.c	11 Nov 2006 00:13:18 -0000
@@ -169,12 +169,12 @@
   };
 
 /* Parsing. */
-static enum dsc_statistic match_statistic (void);
+static enum dsc_statistic match_statistic (struct lexer *);
 static void free_dsc_proc (struct dsc_proc *);
 
 /* Z-score functions. */
 static bool try_name (const struct dictionary *dict, 
-		      struct dsc_proc *dsc, char *name);
+		      struct dsc_proc *dsc, const char *name);
 static bool generate_z_varname (const struct dictionary *dict, 
 				struct dsc_proc *dsc, char *z_name,
 				const char *name, size_t *z_cnt);
@@ -191,7 +191,7 @@
 
 /* Handles DESCRIPTIVES. */
 int
-cmd_descriptives (struct dataset *ds)
+cmd_descriptives (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct dsc_proc *dsc;
@@ -219,106 +219,106 @@
   dsc->show_stats = dsc->calc_stats = DEFAULT_STATS;
 
   /* Parse DESCRIPTIVES. */
-  while (token != '.') 
+  while (lex_token (lexer) != '.') 
     {
-      if (lex_match_id ("MISSING"))
+      if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match ('=');
-          while (token != '.' && token != '/') 
+          lex_match (lexer, '=');
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
-              if (lex_match_id ("VARIABLE"))
+              if (lex_match_id (lexer, "VARIABLE"))
                 dsc->missing_type = DSC_VARIABLE;
-              else if (lex_match_id ("LISTWISE"))
+              else if (lex_match_id (lexer, "LISTWISE"))
                 dsc->missing_type = DSC_LISTWISE;
-              else if (lex_match_id ("INCLUDE"))
+              else if (lex_match_id (lexer, "INCLUDE"))
                 dsc->include_user_missing = 1;
               else
                 {
-                  lex_error (NULL);
+                  lex_error (lexer, NULL);
                   goto error;
                 }
-              lex_match (',');
+              lex_match (lexer, ',');
             }
         }
-      else if (lex_match_id ("SAVE"))
+      else if (lex_match_id (lexer, "SAVE"))
         save_z_scores = 1;
-      else if (lex_match_id ("FORMAT")) 
+      else if (lex_match_id (lexer, "FORMAT")) 
         {
-          lex_match ('=');
-          while (token != '.' && token != '/') 
+          lex_match (lexer, '=');
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
-              if (lex_match_id ("LABELS"))
+              if (lex_match_id (lexer, "LABELS"))
                 dsc->show_var_labels = 1;
-              else if (lex_match_id ("NOLABELS"))
+              else if (lex_match_id (lexer, "NOLABELS"))
                 dsc->show_var_labels = 0;
-              else if (lex_match_id ("INDEX"))
+              else if (lex_match_id (lexer, "INDEX"))
                 dsc->show_index = 1;
-              else if (lex_match_id ("NOINDEX"))
+              else if (lex_match_id (lexer, "NOINDEX"))
                 dsc->show_index = 0;
-              else if (lex_match_id ("LINE"))
+              else if (lex_match_id (lexer, "LINE"))
                 dsc->format = DSC_LINE;
-              else if (lex_match_id ("SERIAL"))
+              else if (lex_match_id (lexer, "SERIAL"))
                 dsc->format = DSC_SERIAL;
               else
                 {
-                  lex_error (NULL);
+                  lex_error (lexer, NULL);
                   goto error;
                 }
-              lex_match (',');
+              lex_match (lexer, ',');
             }
         }
-      else if (lex_match_id ("STATISTICS")) 
+      else if (lex_match_id (lexer, "STATISTICS")) 
         {
-          lex_match ('=');
+          lex_match (lexer, '=');
           dsc->show_stats = 0;
-          while (token != '.' && token != '/') 
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
-              if (lex_match (T_ALL)) 
+              if (lex_match (lexer, T_ALL)) 
                 dsc->show_stats |= (1ul << DSC_N_STATS) - 1;
-              else if (lex_match_id ("DEFAULT"))
+              else if (lex_match_id (lexer, "DEFAULT"))
                 dsc->show_stats |= DEFAULT_STATS;
               else
-		dsc->show_stats |= 1ul << (match_statistic ());
-              lex_match (',');
+		dsc->show_stats |= 1ul << (match_statistic (lexer));
+              lex_match (lexer, ',');
             }
           if (dsc->show_stats == 0)
             dsc->show_stats = DEFAULT_STATS;
         }
-      else if (lex_match_id ("SORT")) 
+      else if (lex_match_id (lexer, "SORT")) 
         {
-          lex_match ('=');
-          if (lex_match_id ("NAME"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "NAME"))
             dsc->sort_by_stat = DSC_NAME;
           else 
 	    {
-	      dsc->sort_by_stat = match_statistic ();
+	      dsc->sort_by_stat = match_statistic (lexer);
 	      if (dsc->sort_by_stat == DSC_NONE )
 		dsc->sort_by_stat = DSC_MEAN;
 	    }
-          if (lex_match ('(')) 
+          if (lex_match (lexer, '(')) 
             {
-              if (lex_match_id ("A"))
+              if (lex_match_id (lexer, "A"))
                 dsc->sort_ascending = 1;
-              else if (lex_match_id ("D"))
+              else if (lex_match_id (lexer, "D"))
                 dsc->sort_ascending = 0;
               else
-                lex_error (NULL);
-              lex_force_match (')');
+                lex_error (lexer, NULL);
+              lex_force_match (lexer, ')');
             }
         }
       else if (var_cnt == 0)
         {
-          if (lex_look_ahead () == '=') 
+          if (lex_look_ahead (lexer) == '=') 
             {
-              lex_match_id ("VARIABLES");
-              lex_match ('=');
+              lex_match_id (lexer, "VARIABLES");
+              lex_match (lexer, '=');
             }
 
-          while (token != '.' && token != '/') 
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
               int i;
               
-              if (!parse_variables (dataset_dict (ds), &vars, &var_cnt,
+              if (!parse_variables (lexer, dataset_dict (ds), &vars, &var_cnt,
                                     PV_APPEND | PV_NO_DUPLICATE | PV_NUMERIC))
 		goto error;
 
@@ -332,34 +332,34 @@
                 }
               dsc->var_cnt = var_cnt;
 
-              if (lex_match ('(')) 
+              if (lex_match (lexer, '(')) 
                 {
-                  if (token != T_ID) 
+                  if (lex_token (lexer) != T_ID) 
                     {
-                      lex_error (NULL);
+                      lex_error (lexer, NULL);
                       goto error;
                     }
-                  if (try_name (dict, dsc, tokid)) 
+                  if (try_name (dict, dsc, lex_tokid (lexer))) 
                     {
-                      strcpy (dsc->vars[dsc->var_cnt - 1].z_name, tokid);
+                      strcpy (dsc->vars[dsc->var_cnt - 1].z_name, lex_tokid (lexer));
                       z_cnt++;
                     }
                   else
                     msg (SE, _("Z-score variable name %s would be"
-                               " a duplicate variable name."), tokid);
-                  lex_get ();
-                  if (!lex_force_match (')'))
+                               " a duplicate variable name."), lex_tokid (lexer));
+                  lex_get (lexer);
+                  if (!lex_force_match (lexer, ')'))
 		    goto error;
                 }
             }
         }
       else 
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           goto error; 
         }
 
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
   if (var_cnt == 0)
     {
@@ -431,23 +431,23 @@
   return CMD_FAILURE;
 }
 
-/* Returns the statistic named by the current token and skips past the token.
+/* Returns the statistic named by the current lex_token (lexer) and skips past the lex_token (lexer).
    Returns DSC_NONE if no statistic is given (e.g., subcommand with no
-   specifiers). Emits an error if the current token ID does not name a
+   specifiers). Emits an error if the current lex_token (lexer) ID does not name a
    statistic. */
 static enum dsc_statistic
-match_statistic (void) 
+match_statistic (struct lexer *lexer) 
 {
-  if (token == T_ID) 
+  if (lex_token (lexer) == T_ID) 
     {
       enum dsc_statistic stat;
 
       for (stat = 0; stat < DSC_N_STATS; stat++)
-        if (lex_match_id (dsc_info[stat].identifier)) 
+        if (lex_match_id (lexer, dsc_info[stat].identifier)) 
 	  return stat;
 
-      lex_get();
-      lex_error (_("expecting statistic name: reverting to default"));
+      lex_get (lexer);
+      lex_error (lexer, _("expecting statistic name: reverting to default"));
     }
 
   return DSC_NONE;
@@ -473,7 +473,8 @@
 /* Returns false if NAME is a duplicate of any existing variable name or
    of any previously-declared z-var name; otherwise returns true. */
 static bool
-try_name (const struct dictionary *dict, struct dsc_proc *dsc, char *name)
+try_name (const struct dictionary *dict, struct dsc_proc *dsc, 
+	  const char *name)
 {
   size_t i;
 
Index: src/language/stats/examine.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/examine.q,v
retrieving revision 1.14
diff -b -w -U3 -r1.14 examine.q
--- src/language/stats/examine.q	5 Nov 2006 00:35:43 -0000	1.14
+++ src/language/stats/examine.q	11 Nov 2006 00:13:19 -0000
@@ -110,7 +110,7 @@
 static struct metrics *totals=0;
 
 /* Parse the clause specifying the factors */
-static int examine_parse_independent_vars (const struct dictionary *dict, struct cmd_examine *cmd);
+static int examine_parse_independent_vars (struct lexer *lexer, const struct dictionary *dict, struct cmd_examine *cmd);
 
 
 
@@ -191,14 +191,14 @@
 
 
 int
-cmd_examine (struct dataset *ds)
+cmd_examine (struct lexer *lexer, struct dataset *ds)
 {
   bool ok;
 
   subc_list_double_create(&percentile_list);
   percentile_algorithm = PC_HAVERAGE;
 
-  if ( !parse_examine (ds, &cmd, NULL) )
+  if ( !parse_examine (lexer, ds, &cmd, NULL) )
     return CMD_FAILURE;
 
   /* If /MISSING=INCLUDE is set, then user missing values are ignored */
@@ -429,43 +429,43 @@
 
 /* Parse the PERCENTILES subcommand */
 static int
-xmn_custom_percentiles(struct dataset *ds UNUSED, 
+xmn_custom_percentiles(struct lexer *lexer, struct dataset *ds UNUSED, 
 		       struct cmd_examine *p UNUSED, void *aux UNUSED)
 {
   sbc_percentile = 1;
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  lex_match('(');
+  lex_match (lexer, '(');
 
-  while ( lex_is_number() ) 
+  while ( lex_is_number (lexer) ) 
     {
-      subc_list_double_push (&percentile_list, lex_number());
+      subc_list_double_push (&percentile_list, lex_number (lexer));
 
-      lex_get();
+      lex_get (lexer);
 
-      lex_match(',') ;
+      lex_match (lexer, ',') ;
     }
-  lex_match(')');
+  lex_match (lexer, ')');
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ( lex_match_id("HAVERAGE"))
+  if ( lex_match_id (lexer, "HAVERAGE"))
     percentile_algorithm = PC_HAVERAGE; 
 
-  else if ( lex_match_id("WAVERAGE"))
+  else if ( lex_match_id (lexer, "WAVERAGE"))
     percentile_algorithm = PC_WAVERAGE; 
 
-  else if ( lex_match_id("ROUND"))
+  else if ( lex_match_id (lexer, "ROUND"))
     percentile_algorithm = PC_ROUND;
 
-  else if ( lex_match_id("EMPIRICAL"))
+  else if ( lex_match_id (lexer, "EMPIRICAL"))
     percentile_algorithm = PC_EMPIRICAL;
 
-  else if ( lex_match_id("AEMPIRICAL"))
+  else if ( lex_match_id (lexer, "AEMPIRICAL"))
     percentile_algorithm = PC_AEMPIRICAL; 
 
-  else if ( lex_match_id("NONE"))
+  else if ( lex_match_id (lexer, "NONE"))
     percentile_algorithm = PC_NONE; 
 
 
@@ -485,7 +485,7 @@
 
 /* TOTAL and NOTOTAL are simple, mutually exclusive flags */
 static int
-xmn_custom_total (struct dataset *ds UNUSED, struct cmd_examine *p, void *aux UNUSED)
+xmn_custom_total (struct lexer *lexer UNUSED, struct dataset *ds UNUSED, struct cmd_examine *p, void *aux UNUSED)
 {
   if ( p->sbc_nototal ) 
     {
@@ -497,7 +497,7 @@
 }
 
 static int
-xmn_custom_nototal (struct dataset *ds UNUSED, 
+xmn_custom_nototal (struct lexer *lexer UNUSED, struct dataset *ds UNUSED, 
 		    struct cmd_examine *p, void *aux UNUSED)
 {
   if ( p->sbc_total ) 
@@ -514,18 +514,18 @@
 /* Parser for the variables sub command  
    Returns 1 on success */
 static int
-xmn_custom_variables(struct dataset *ds, struct cmd_examine *cmd, void *aux UNUSED)
+xmn_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_examine *cmd, void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     {
       return 2;
     }
   
-  if (!parse_variables (dict, &dependent_vars, &n_dependent_vars,
+  if (!parse_variables (lexer, dict, &dependent_vars, &n_dependent_vars,
 			PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
     {
       free (dependent_vars);
@@ -536,10 +536,10 @@
 
   totals = xnmalloc (n_dependent_vars, sizeof *totals);
 
-  if ( lex_match(T_BY))
+  if ( lex_match (lexer, T_BY))
     {
       int success ; 
-      success =  examine_parse_independent_vars (dict, cmd);
+      success =  examine_parse_independent_vars (lexer, dict, cmd);
       if ( success != 1 ) {
         free (dependent_vars);
       	free (totals) ; 
@@ -554,35 +554,35 @@
 
 /* Parse the clause specifying the factors */
 static int
-examine_parse_independent_vars (const struct dictionary *dict, struct cmd_examine *cmd)
+examine_parse_independent_vars (struct lexer *lexer, const struct dictionary *dict, struct cmd_examine *cmd)
 {
   int success;
   struct factor *sf = xmalloc (sizeof *sf);
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     {
       free ( sf ) ;
       return 2;
     }
 
 
-  sf->indep_var[0] = parse_variable (dict);
+  sf->indep_var[0] = parse_variable (lexer, dict);
   sf->indep_var[1] = 0;
 
-  if ( token == T_BY ) 
+  if ( lex_token (lexer) == T_BY ) 
     {
 
-      lex_match(T_BY);
+      lex_match (lexer, T_BY);
 
-      if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-	  && token != T_ALL)
+      if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+	  && lex_token (lexer) != T_ALL)
 	{
 	  free ( sf ) ;
 	  return 2;
 	}
 
-      sf->indep_var[1] = parse_variable (dict);
+      sf->indep_var[1] = parse_variable (lexer, dict);
 
     }
 
@@ -596,12 +596,12 @@
   sf->next = factors;
   factors = sf;
   
-  lex_match(',');
+  lex_match (lexer, ',');
 
-  if ( token == '.' || token == '/' ) 
+  if ( lex_token (lexer) == '.' || lex_token (lexer) == '/' ) 
     return 1;
 
-  success =  examine_parse_independent_vars (dict, cmd);
+  success =  examine_parse_independent_vars (lexer, dict, cmd);
   
   if ( success != 1 ) 
     free ( sf ) ; 
Index: src/language/stats/flip.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/flip.c,v
retrieving revision 1.13
diff -b -w -U3 -r1.13 flip.c
--- src/language/stats/flip.c	26 Oct 2006 06:16:36 -0000	1.13
+++ src/language/stats/flip.c	11 Nov 2006 00:13:19 -0000
@@ -90,7 +90,7 @@
 
 /* Parses and executes FLIP. */
 int
-cmd_flip (struct dataset *ds)
+cmd_flip (struct lexer *lexer, struct dataset *ds)
 {
   struct flip_pgm *flip;
   struct case_sink *sink;
@@ -112,24 +112,24 @@
   flip->new_names_tail = NULL;
   flip->file = NULL;
 
-  lex_match ('/');
-  if (lex_match_id ("VARIABLES"))
+  lex_match (lexer, '/');
+  if (lex_match_id (lexer, "VARIABLES"))
     {
-      lex_match ('=');
-      if (!parse_variables (dict, &flip->var, &flip->var_cnt,
+      lex_match (lexer, '=');
+      if (!parse_variables (lexer, dict, &flip->var, &flip->var_cnt,
                             PV_NO_DUPLICATE))
 	goto error;
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
   else
     dict_get_vars (dict, &flip->var, &flip->var_cnt, 1u << DC_SYSTEM);
   pool_register (flip->pool, free, flip->var);
 
-  lex_match ('/');
-  if (lex_match_id ("NEWNAMES"))
+  lex_match (lexer, '/');
+  if (lex_match_id (lexer, "NEWNAMES"))
     {
-      lex_match ('=');
-      flip->new_names = parse_variable (dict);
+      lex_match (lexer, '=');
+      flip->new_names = parse_variable (lexer, dict);
       if (!flip->new_names)
         goto error;
     }
@@ -178,7 +178,7 @@
   /* Set up flipped data for reading. */
   proc_set_source (ds, flip_source_create (flip));
 
-  return ok ? lex_end_of_command () : CMD_CASCADING_FAILURE;
+  return ok ? lex_end_of_command (lexer) : CMD_CASCADING_FAILURE;
 
  error:
   destroy_flip_pgm (flip);
Index: src/language/stats/frequencies.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/frequencies.q,v
retrieving revision 1.21
diff -b -w -U3 -r1.21 frequencies.q
--- src/language/stats/frequencies.q	29 Oct 2006 11:16:07 -0000	1.21
+++ src/language/stats/frequencies.q	11 Nov 2006 00:13:20 -0000
@@ -305,15 +305,15 @@
 
 /* Parser and outline. */
 
-static int internal_cmd_frequencies (struct dataset *ds);
+static int internal_cmd_frequencies (struct lexer *lexer, struct dataset *ds);
 
 int
-cmd_frequencies (struct dataset *ds)
+cmd_frequencies (struct lexer *lexer, struct dataset *ds)
 {
   int result;
 
   int_pool = pool_create ();
-  result = internal_cmd_frequencies (ds);
+  result = internal_cmd_frequencies (lexer, ds);
   pool_destroy (int_pool);
   int_pool=0;
   pool_destroy (gen_pool);
@@ -324,7 +324,7 @@
 }
 
 static int
-internal_cmd_frequencies (struct dataset *ds)
+internal_cmd_frequencies (struct lexer *lexer, struct dataset *ds)
 {
   int i;
   bool ok;
@@ -335,7 +335,7 @@
   n_variables = 0;
   v_variables = NULL;
 
-  if (!parse_frequencies (ds, &cmd, NULL))
+  if (!parse_frequencies (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   if (cmd.onepage_limit == NOT_LONG)
@@ -793,7 +793,7 @@
 /* Parses the VARIABLES subcommand, adding to
    {n_variables,v_variables}. */
 static int
-frq_custom_variables (struct dataset *ds, struct cmd_frequencies *cmd UNUSED, void *aux UNUSED)
+frq_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_frequencies *cmd UNUSED, void *aux UNUSED)
 {
   int mode;
   int min = 0, max = 0;
@@ -801,31 +801,31 @@
   size_t old_n_variables = n_variables;
   size_t i;
 
-  lex_match ('=');
-  if (token != T_ALL && (token != T_ID
-                         || dict_lookup_var (dataset_dict (ds), tokid) == NULL))
+  lex_match (lexer, '=');
+  if (lex_token (lexer) != T_ALL && (lex_token (lexer) != T_ID
+                         || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL))
     return 2;
 
-  if (!parse_variables (dataset_dict (ds), &v_variables, &n_variables,
+  if (!parse_variables (lexer, dataset_dict (ds), &v_variables, &n_variables,
 			PV_APPEND | PV_NO_SCRATCH))
     return 0;
 
-  if (!lex_match ('('))
+  if (!lex_match (lexer, '('))
     mode = FRQM_GENERAL;
   else
     {
       mode = FRQM_INTEGER;
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	return 0;
-      min = lex_integer ();
-      lex_get ();
-      if (!lex_force_match (','))
+      min = lex_integer (lexer);
+      lex_get (lexer);
+      if (!lex_force_match (lexer, ','))
 	return 0;
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	return 0;
-      max = lex_integer ();
-      lex_get ();
-      if (!lex_force_match (')'))
+      max = lex_integer (lexer);
+      lex_get (lexer);
+      if (!lex_force_match (lexer, ')'))
 	return 0;
       if (max < min)
 	{
@@ -881,11 +881,11 @@
 /* Parses the GROUPED subcommand, setting the n_grouped, grouped
    fields of specified variables. */
 static int
-frq_custom_grouped (struct dataset *ds, struct cmd_frequencies *cmd UNUSED, void *aux UNUSED)
+frq_custom_grouped (struct lexer *lexer, struct dataset *ds, struct cmd_frequencies *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if ((token == T_ID && dict_lookup_var (dataset_dict (ds), tokid) != NULL)
-      || token == T_ID)
+  lex_match (lexer, '=');
+  if ((lex_token (lexer) == T_ID && dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != NULL)
+      || lex_token (lexer) == T_ID)
     for (;;)
       {
 	size_t i;
@@ -898,27 +898,27 @@
 	size_t n;
 	struct variable **v;
 
-	if (!parse_variables (dataset_dict (ds), &v, &n,
+	if (!parse_variables (lexer, dataset_dict (ds), &v, &n,
                               PV_NO_DUPLICATE | PV_NUMERIC))
 	  return 0;
-	if (lex_match ('('))
+	if (lex_match (lexer, '('))
 	  {
 	    nl = ml = 0;
 	    dl = NULL;
-	    while (lex_integer ())
+	    while (lex_integer (lexer))
 	      {
 		if (nl >= ml)
 		  {
 		    ml += 16;
 		    dl = pool_nrealloc (int_pool, dl, ml, sizeof *dl);
 		  }
-		dl[nl++] = tokval;
-		lex_get ();
-		lex_match (',');
+		dl[nl++] = lex_tokval (lexer);
+		lex_get (lexer);
+		lex_match (lexer, ',');
 	      }
 	    /* Note that nl might still be 0 and dl might still be
 	       NULL.  That's okay. */
-	    if (!lex_match (')'))
+	    if (!lex_match (lexer, ')'))
 	      {
 		free (v);
 		msg (SE, _("`)' expected after GROUPED interval list."));
@@ -949,12 +949,12 @@
                 }
             }
 	free (v);
-	if (!lex_match ('/'))
+	if (!lex_match (lexer, '/'))
 	  break;
-	if ((token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) != NULL)
-            && token != T_ALL)
+	if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != NULL)
+            && lex_token (lexer) != T_ALL)
 	  {
-	    lex_put_back ('/');
+	    lex_put_back (lexer, '/');
 	    break;
 	  }
       }
@@ -979,7 +979,7 @@
 	break;
     }
 
-  if (i >= n_percentiles || tokval != percentiles[i].p)
+  if (i >= n_percentiles || x != percentiles[i].p)
     {
       percentiles = pool_nrealloc (int_pool, percentiles,
                                    n_percentiles + 1, sizeof *percentiles);
Index: src/language/stats/means.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/means.q,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 means.q
--- src/language/stats/means.q	26 Oct 2006 06:16:36 -0000	1.10
+++ src/language/stats/means.q	11 Nov 2006 00:13:20 -0000
@@ -61,7 +61,7 @@
 
 /* Parses and executes the T-TEST procedure. */
 int
-cmd_means (struct dataset *ds)
+cmd_means (struct lexer *lexer, struct dataset *ds)
 {
   struct cmd_means cmd;
   int success = CMD_FAILURE;
@@ -71,7 +71,7 @@
   v_dim = NULL;
   v_var = NULL;
 
-  if (!parse_means (ds, &cmd, NULL))
+  if (!parse_means (lexer, ds, &cmd, NULL))
     goto free;
 
   if (cmd.sbc_cells)
@@ -122,15 +122,15 @@
 
 /* Parses the TABLES subcommand. */
 static int
-mns_custom_tables (struct dataset *ds, struct cmd_means *cmd, void *aux UNUSED)
+mns_custom_tables (struct lexer *lexer, struct dataset *ds, struct cmd_means *cmd, void *aux UNUSED)
 {
   struct var_set *var_set;
   
-  if (!lex_match_id ("TABLES")
-      && (token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == NULL)
-      && token != T_ALL)
+  if (!lex_match_id (lexer, "TABLES")
+      && (lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match ('=');
+  lex_match (lexer, '=');
 
   if (cmd->sbc_tables)
     {
@@ -147,7 +147,7 @@
       size_t nvl;
       struct variable **vl;
 
-      if (!parse_var_set_vars (var_set, &vl, &nvl,
+      if (!parse_var_set_vars (lexer, var_set, &vl, &nvl,
                                PV_NO_DUPLICATE | PV_NO_SCRATCH)) 
         goto lossage;
       
@@ -158,7 +158,7 @@
       nv_dim[n_dim - 1] = nvl;
       v_dim[n_dim - 1] = vl;
     }
-  while (lex_match (T_BY));
+  while (lex_match (lexer, T_BY));
 
   var_set_destroy (var_set);
   return 1;
Index: src/language/stats/oneway.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/oneway.q,v
retrieving revision 1.14
diff -b -w -U3 -r1.14 oneway.q
--- src/language/stats/oneway.q	5 Nov 2006 00:35:44 -0000	1.14
+++ src/language/stats/oneway.q	11 Nov 2006 00:13:20 -0000
@@ -112,12 +112,12 @@
 
 
 int
-cmd_oneway (struct dataset *ds)
+cmd_oneway (struct lexer *lexer, struct dataset *ds)
 {
   int i;
   bool ok;
 
-  if ( !parse_oneway (ds, &cmd, NULL) )
+  if ( !parse_oneway (lexer, ds, &cmd, NULL) )
     return CMD_FAILURE;
 
   /* What statistics were requested */
@@ -213,18 +213,19 @@
 
 /* Parser for the variables sub command */
 static int
-oneway_custom_variables(struct dataset *ds, struct cmd_oneway *cmd UNUSED, 
+oneway_custom_variables (struct lexer *lexer, 
+			struct dataset *ds, struct cmd_oneway *cmd UNUSED, 
 			void *aux UNUSED)
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
 
-  if (!parse_variables (dict, &vars, &n_vars,
+  if (!parse_variables (lexer, dict, &vars, &n_vars,
 			PV_DUPLICATE 
 			| PV_NUMERIC | PV_NO_SCRATCH) )
     {
@@ -234,14 +235,14 @@
 
   assert(n_vars);
 
-  if ( ! lex_match(T_BY))
+  if ( ! lex_match (lexer, T_BY))
     return 2;
 
-  indep_var = parse_variable (dict);
+  indep_var = parse_variable (lexer, dict);
 
   if ( !indep_var ) 
     {
-      msg(SE,_("`%s' is not a variable name"),tokid);
+      msg(SE,_("`%s' is not a variable name"),lex_tokid (lexer));
       return 0;
     }
 
Index: src/language/stats/rank.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/rank.q,v
retrieving revision 1.18
diff -b -w -U3 -r1.18 rank.q
--- src/language/stats/rank.q	5 Nov 2006 00:35:44 -0000	1.18
+++ src/language/stats/rank.q	11 Nov 2006 00:13:20 -0000
@@ -729,7 +729,6 @@
   return var;
 }
 
-int cmd_rank(struct dataset *ds);
 
 static void
 rank_cleanup(void)
@@ -758,14 +757,14 @@
 }
 
 int
-cmd_rank (struct dataset *ds)
+cmd_rank (struct lexer *lexer, struct dataset *ds)
 {
   bool result;
   struct variable *order;
   size_t i;
   n_rank_specs = 0;
 
-  if ( !parse_rank (ds, &cmd, NULL) )
+  if ( !parse_rank (lexer, ds, &cmd, NULL) )
     {
       rank_cleanup ();
     return CMD_FAILURE;
@@ -929,27 +928,28 @@
 /* Parser for the variables sub command  
    Returns 1 on success */
 static int
-rank_custom_variables (struct dataset *ds, struct cmd_rank *cmd UNUSED, void *aux UNUSED)
+rank_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd UNUSED, void *aux UNUSED)
 {
   static const int terminators[2] = {T_BY, 0};
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
       return 2;
 
-  sc = sort_parse_criteria (dataset_dict (ds), 
+  sc = sort_parse_criteria (lexer, dataset_dict (ds), 
 			    &src_vars, &n_src_vars, 0, terminators);
 
-  if ( lex_match(T_BY)  )
+  if ( lex_match (lexer, T_BY)  )
     {
-      if ((token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == NULL))
+      if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL))
 	{
 	  return 2;
 	}
 
-      if (!parse_variables (dataset_dict (ds), &group_vars, &n_group_vars,
+      if (!parse_variables (lexer, dataset_dict (ds), 
+			    &group_vars, &n_group_vars,
 			    PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
 	{
 	  free (group_vars);
@@ -963,7 +963,7 @@
 
 /* Parse the [/rank INTO var1 var2 ... varN ] clause */
 static int
-parse_rank_function(struct dictionary *dict, struct cmd_rank *cmd UNUSED, enum RANK_FUNC f)
+parse_rank_function (struct lexer *lexer, struct dictionary *dict, struct cmd_rank *cmd UNUSED, enum RANK_FUNC f)
 {
   int var_count = 0;
   
@@ -975,16 +975,16 @@
   rank_specs[n_rank_specs - 1].destvars = 
 	    xcalloc (sc->crit_cnt, sizeof (struct variable *));
 	  
-  if (lex_match_id("INTO"))
+  if (lex_match_id (lexer, "INTO"))
     {
       struct variable *destvar;
 
-      while( token == T_ID ) 
+      while( lex_token (lexer) == T_ID ) 
 	{
 
-	  if ( dict_lookup_var (dict, tokid) != NULL )
+	  if ( dict_lookup_var (dict, lex_tokid (lexer)) != NULL )
 	    {
-	      msg(SE, _("Variable %s already exists."), tokid);
+	      msg(SE, _("Variable %s already exists."), lex_tokid (lexer));
 	      return 0;
 	    }
 	  if ( var_count >= sc->crit_cnt ) 
@@ -993,10 +993,10 @@
 	      return 0;
 	    }
 
-	  destvar = create_rank_variable (dict, f, src_vars[var_count], tokid);
+	  destvar = create_rank_variable (dict, f, src_vars[var_count], lex_tokid (lexer));
 	  rank_specs[n_rank_specs - 1].destvars[var_count] = destvar ;
 
-	  lex_get();
+	  lex_get (lexer);
 	  ++var_count;
 	}
     }
@@ -1006,74 +1006,74 @@
 
 
 static int
-rank_custom_rank(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_rank (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, RANK);
+  return parse_rank_function (lexer, dict, cmd, RANK);
 }
 
 static int
-rank_custom_normal(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_normal (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct  dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, NORMAL);
+  return parse_rank_function (lexer, dict, cmd, NORMAL);
 }
 
 static int
-rank_custom_percent(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_percent (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, PERCENT);
+  return parse_rank_function (lexer, dict, cmd, PERCENT);
 }
 
 static int
-rank_custom_rfraction(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_rfraction (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, RFRACTION);
+  return parse_rank_function (lexer, dict, cmd, RFRACTION);
 }
 
 static int
-rank_custom_proportion(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_proportion (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, PROPORTION);
+  return parse_rank_function (lexer, dict, cmd, PROPORTION);
 }
 
 static int
-rank_custom_n (struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_n (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, N);
+  return parse_rank_function (lexer, dict, cmd, N);
 }
 
 static int
-rank_custom_savage(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_savage (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, SAVAGE);
+  return parse_rank_function (lexer, dict, cmd, SAVAGE);
 }
 
 
 static int
-rank_custom_ntiles (struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_ntiles (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  if ( lex_force_match('(') ) 
+  if ( lex_force_match (lexer, '(') ) 
     {
-      if ( lex_force_int() ) 
+      if ( lex_force_int (lexer) ) 
 	{
-	  k_ntiles = lex_integer ();
-	  lex_get();
-	  lex_force_match(')');
+	  k_ntiles = lex_integer (lexer);
+	  lex_get (lexer);
+	  lex_force_match (lexer, ')');
 	}
       else
 	return 0;
@@ -1081,5 +1081,5 @@
   else
     return 0;
 
-  return parse_rank_function(dict, cmd, NTILES);
+  return parse_rank_function (lexer, dict, cmd, NTILES);
 }
Index: src/language/stats/regression.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/regression.q,v
retrieving revision 1.37
diff -b -w -U3 -r1.37 regression.q
--- src/language/stats/regression.q	5 Nov 2006 00:35:44 -0000	1.37
+++ src/language/stats/regression.q	11 Nov 2006 00:13:20 -0000
@@ -916,31 +916,31 @@
 }
 
 static int
-regression_custom_export (struct dataset *ds UNUSED, struct cmd_regression *cmd UNUSED, void *aux UNUSED)
+regression_custom_export (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_regression *cmd UNUSED, void *aux UNUSED)
 {
   /* 0 on failure, 1 on success, 2 on failure that should result in syntax error */
-  if (!lex_force_match ('('))
+  if (!lex_force_match (lexer, '('))
     return 0;
 
-  if (lex_match ('*'))
+  if (lex_match (lexer, '*'))
     model_file = NULL;
   else
     {
-      model_file = fh_parse (FH_REF_FILE);
+      model_file = fh_parse (lexer, FH_REF_FILE);
       if (model_file == NULL)
 	return 0;
     }
 
-  if (!lex_force_match (')'))
+  if (!lex_force_match (lexer, ')'))
     return 0;
 
   return 1;
 }
 
 int
-cmd_regression (struct dataset *ds)
+cmd_regression (struct lexer *lexer, struct dataset *ds)
 {
-  if (!parse_regression (ds, &cmd, NULL))
+  if (!parse_regression (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   models = xnmalloc (cmd.n_dependent, sizeof *models);
@@ -1004,20 +1004,20 @@
 
 /* Parser for the variables sub command */
 static int
-regression_custom_variables (struct dataset *ds, 
+regression_custom_variables (struct lexer *lexer, struct dataset *ds, 
 			     struct cmd_regression *cmd UNUSED,
 			     void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
 
-  lex_match ('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
 
 
-  if (!parse_variables (dict, &v_variables, &n_variables, PV_NONE))
+  if (!parse_variables (lexer, dict, &v_variables, &n_variables, PV_NONE))
     {
       free (v_variables);
       return 0;
Index: src/language/stats/sort-cases.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/sort-cases.c,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 sort-cases.c
--- src/language/stats/sort-cases.c	26 Oct 2006 06:16:36 -0000	1.6
+++ src/language/stats/sort-cases.c	11 Nov 2006 00:13:20 -0000
@@ -40,24 +40,24 @@
 
 /* Performs the SORT CASES procedures. */
 int
-cmd_sort_cases (struct dataset *ds)
+cmd_sort_cases (struct lexer *lexer, struct dataset *ds)
 {
   struct sort_criteria *criteria;
   bool success = false;
 
-  lex_match (T_BY);
+  lex_match (lexer, T_BY);
 
-  criteria = sort_parse_criteria (dataset_dict (ds), NULL, NULL, NULL, NULL);
+  criteria = sort_parse_criteria (lexer, dataset_dict (ds), NULL, NULL, NULL, NULL);
   if (criteria == NULL)
     return CMD_CASCADING_FAILURE;
 
-  if (get_testing_mode () && lex_match ('/')) 
+  if (get_testing_mode () && lex_match (lexer, '/')) 
     {
-      if (!lex_force_match_id ("BUFFERS") || !lex_match ('=')
-          || !lex_force_int ())
+      if (!lex_force_match_id (lexer, "BUFFERS") || !lex_match (lexer, '=')
+          || !lex_force_int (lexer))
         goto done;
 
-      min_buffers = max_buffers = lex_integer ();
+      min_buffers = max_buffers = lex_integer (lexer);
       allow_internal_sort = false;
       if (max_buffers < 2) 
         {
@@ -65,7 +65,7 @@
           goto done;
         }
 
-      lex_get ();
+      lex_get (lexer);
     }
 
   success = sort_active_file_in_place (ds, criteria);
@@ -76,6 +76,6 @@
   allow_internal_sort = true;
   
   sort_destroy_criteria (criteria);
-  return success ? lex_end_of_command () : CMD_CASCADING_FAILURE;
+  return success ? lex_end_of_command (lexer) : CMD_CASCADING_FAILURE;
 }
 
Index: src/language/stats/sort-criteria.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/sort-criteria.c,v
retrieving revision 1.3
diff -b -w -U3 -r1.3 sort-criteria.c
--- src/language/stats/sort-criteria.c	27 Jun 2006 19:09:22 -0000	1.3
+++ src/language/stats/sort-criteria.c	11 Nov 2006 00:13:20 -0000
@@ -50,7 +50,7 @@
    
 */
 struct sort_criteria *
-sort_parse_criteria (const struct dictionary *dict,
+sort_parse_criteria (struct lexer *lexer, const struct dictionary *dict,
                      struct variable ***vars, size_t *var_cnt,
                      bool *saw_direction,
 		     const int *terminators
@@ -82,23 +82,23 @@
       enum sort_direction direction;
 
       /* Variables. */
-      if (!parse_variables (dict, vars, var_cnt,
+      if (!parse_variables (lexer, dict, vars, var_cnt,
 			    PV_NO_DUPLICATE | PV_APPEND | PV_NO_SCRATCH))
         goto error;
 
       /* Sort direction. */
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
 	{
-	  if (lex_match_id ("D") || lex_match_id ("DOWN"))
+	  if (lex_match_id (lexer, "D") || lex_match_id (lexer, "DOWN"))
 	    direction = SRT_DESCEND;
-	  else if (lex_match_id ("A") || lex_match_id ("UP"))
+	  else if (lex_match_id (lexer, "A") || lex_match_id (lexer, "UP"))
             direction = SRT_ASCEND;
           else
 	    {
 	      msg (SE, _("`A' or `D' expected inside parentheses."));
               goto error;
 	    }
-	  if (!lex_match (')'))
+	  if (!lex_match (lexer, ')'))
 	    {
 	      msg (SE, _("`)' expected."));
               goto error;
@@ -120,7 +120,7 @@
           c->dir = direction;
         }
     }
-  while (token != '.' && token != '/' && !is_terminator(token, terminators));
+  while (lex_token (lexer) != '.' && lex_token (lexer) != '/' && !is_terminator(lex_token (lexer), terminators));
 
   free (local_vars);
   return criteria;
Index: src/language/stats/sort-criteria.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/sort-criteria.h,v
retrieving revision 1.2
diff -b -w -U3 -r1.2 sort-criteria.h
--- src/language/stats/sort-criteria.h	16 Apr 2006 01:05:15 -0000	1.2
+++ src/language/stats/sort-criteria.h	11 Nov 2006 00:13:20 -0000
@@ -26,8 +26,9 @@
 
 struct variable;
 struct dictionary;
+struct lexer ;
 
-struct sort_criteria *sort_parse_criteria (const struct dictionary *,
+struct sort_criteria *sort_parse_criteria (struct lexer *, const struct dictionary *,
                                            struct variable ***, size_t *,
                                            bool *saw_direction,
 					   const int *terminators
Index: src/language/stats/t-test.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/t-test.q,v
retrieving revision 1.14
diff -b -w -U3 -r1.14 t-test.q
--- src/language/stats/t-test.q	5 Nov 2006 00:35:44 -0000	1.14
+++ src/language/stats/t-test.q	11 Nov 2006 00:13:21 -0000
@@ -154,7 +154,7 @@
 
 static struct pair *pairs=0;
 
-static int parse_value (union value * v, int type) ;
+static int parse_value (struct lexer *lexer, union value * v, int type) ;
 
 /* Structures and Functions for the Statistics Summary Box */
 struct ssbox;
@@ -258,11 +258,11 @@
 
 
 int
-cmd_t_test (struct dataset *ds)
+cmd_t_test (struct lexer *lexer, struct dataset *ds)
 {
   bool ok;
   
-  if ( !parse_t_test (ds, &cmd, NULL) )
+  if ( !parse_t_test (lexer, ds, &cmd, NULL) )
     return CMD_FAILURE;
 
   if (! cmd.sbc_criteria)
@@ -362,16 +362,16 @@
 }
 
 static int
-tts_custom_groups (struct dataset *ds, struct cmd_t_test *cmd UNUSED, void *aux UNUSED)
+tts_custom_groups (struct lexer *lexer, struct dataset *ds, struct cmd_t_test *cmd UNUSED, void *aux UNUSED)
 {
   int n_group_values=0;
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  indep_var = parse_variable (dataset_dict (ds));
+  indep_var = parse_variable (lexer, dataset_dict (ds));
   if (!indep_var)
     {
-      lex_error ("expecting variable name in GROUPS subcommand");
+      lex_error (lexer, "expecting variable name in GROUPS subcommand");
       return 0;
     }
 
@@ -382,7 +382,7 @@
       return 0;
     }
 
-  if (!lex_match ('('))
+  if (!lex_match (lexer, '('))
     {
       if (indep_var->type == NUMERIC)
 	{
@@ -403,11 +403,11 @@
 	}
     }
 
-  if (!parse_value (&gp.v.g_value[0], indep_var->type))
+  if (!parse_value (lexer, &gp.v.g_value[0], indep_var->type))
       return 0;
 
-  lex_match (',');
-  if (lex_match (')'))
+  lex_match (lexer, ',');
+  if (lex_match (lexer, ')'))
     {
       if (indep_var->type != NUMERIC)
 	{
@@ -423,11 +423,11 @@
       return 1;
     }
 
-  if (!parse_value (&gp.v.g_value[1], indep_var->type))
+  if (!parse_value (lexer, &gp.v.g_value[1], indep_var->type))
     return 0;
 
   n_group_values = 2;
-  if (!lex_force_match (')'))
+  if (!lex_force_match (lexer, ')'))
     return 0;
 
   if ( n_group_values == 2 ) 
@@ -441,7 +441,7 @@
 
 
 static int
-tts_custom_pairs (struct dataset *ds, struct cmd_t_test *cmd UNUSED, void *aux UNUSED)
+tts_custom_pairs (struct lexer *lexer, struct dataset *ds, struct cmd_t_test *cmd UNUSED, void *aux UNUSED)
 {
   struct variable **vars;
   size_t n_vars;
@@ -451,10 +451,10 @@
   size_t n_after_WITH = SIZE_MAX;
   int paired ; /* Was the PAIRED keyword given ? */
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
   n_vars=0;
-  if (!parse_variables (dataset_dict (ds), &vars, &n_vars,
+  if (!parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
 			PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH))
     {
       free (vars);
@@ -463,10 +463,10 @@
   assert (n_vars);
 
   n_before_WITH = 0;
-  if (lex_match (T_WITH))
+  if (lex_match (lexer, T_WITH))
     {
       n_before_WITH = n_vars;
-      if (!parse_variables (dataset_dict (ds), &vars, &n_vars,
+      if (!parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
 			    PV_DUPLICATE | PV_APPEND
 			    | PV_NUMERIC | PV_NO_SCRATCH))
 	{
@@ -476,7 +476,7 @@
       n_after_WITH = n_vars - n_before_WITH;
     }
 
-  paired = (lex_match ('(') && lex_match_id ("PAIRED") && lex_match (')'));
+  paired = (lex_match (lexer, '(') && lex_match_id (lexer, "PAIRED") && lex_match (lexer, ')'));
 
   /* Determine the number of pairs needed */
   if (paired)
@@ -563,25 +563,25 @@
   return 1;
 }
 
-/* Parses the current token (numeric or string, depending on type)
+/* Parses the current lex_token (lexer) (numeric or string, depending on type)
     value v and returns success. */
 static int
-parse_value (union value * v, int type )
+parse_value (struct lexer *lexer, union value * v, int type )
 {
   if (type == NUMERIC)
     {
-      if (!lex_force_num ())
+      if (!lex_force_num (lexer))
 	return 0;
-      v->f = tokval;
+      v->f = lex_tokval (lexer);
     }
   else
     {
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
 	return 0;
-      strncpy (v->s, ds_cstr (&tokstr), ds_length (&tokstr));
+      strncpy (v->s, ds_cstr (lex_tokstr (lexer)), ds_length (lex_tokstr (lexer)));
     }
 
-  lex_get ();
+  lex_get (lexer);
 
   return 1;
 }
Index: src/language/tests/casefile-test.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/casefile-test.c,v
retrieving revision 1.8
diff -b -w -U3 -r1.8 casefile-test.c
--- src/language/tests/casefile-test.c	5 Nov 2006 00:35:44 -0000	1.8
+++ src/language/tests/casefile-test.c	11 Nov 2006 00:13:21 -0000
@@ -45,7 +45,7 @@
 static void fail_test (const char *message, ...);
 
 int
-cmd_debug_casefile (struct dataset *ds UNUSED) 
+cmd_debug_casefile (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   static const size_t sizes[] =
     {
@@ -57,15 +57,15 @@
   int pattern;
 
   size_max = sizeof sizes / sizeof *sizes;
-  if (lex_match_id ("SMALL")) 
+  if (lex_match_id (lexer, "SMALL")) 
     {
       size_max -= 4;
       case_max = 511; 
     }
   else
     case_max = 4095;
-  if (token != '.')
-    return lex_end_of_command ();
+  if (lex_token (lexer) != '.')
+    return lex_end_of_command (lexer);
     
   for (pattern = 0; pattern < 7; pattern++) 
     {
Index: src/language/tests/float-format.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/float-format.c,v
retrieving revision 1.1
diff -b -w -U3 -r1.1 float-format.c
--- src/language/tests/float-format.c	28 Oct 2006 04:01:55 -0000	1.1
+++ src/language/tests/float-format.c	11 Nov 2006 00:13:21 -0000
@@ -69,17 +69,17 @@
 /* Parses a floating-point format name into *FORMAT,
    and returns success. */
 static bool
-parse_float_format (enum float_format *format) 
+parse_float_format (struct lexer *lexer, enum float_format *format) 
 {
   size_t i;
 
   for (i = 0; i < format_cnt; i++)
-    if (lex_match_id (fp_formats[i].name)) 
+    if (lex_match_id (lexer, fp_formats[i].name)) 
       {
         *format = fp_formats[i].format;
         return true;
       }
-  lex_error ("expecting floating-point format identifier");
+  lex_error (lexer, "expecting floating-point format identifier");
   return false;
 }
 
@@ -101,25 +101,25 @@
    representation.  Also supports ordinary floating-point numbers
    written in decimal notation.  Returns success. */
 static bool
-parse_fp (struct fp *fp) 
+parse_fp (struct lexer *lexer, struct fp *fp) 
 {
-  if (lex_is_number ()) 
+  if (lex_is_number (lexer)) 
     {
-      double number = lex_number ();
+      double number = lex_number (lexer);
       fp->format = FLOAT_NATIVE_DOUBLE;
       memcpy (fp->data, &number, sizeof number);
-      lex_get ();
+      lex_get (lexer);
     }
-  else if (token == T_ID)
+  else if (lex_token (lexer) == T_ID)
     {
       size_t length;
       
-      if (!parse_float_format (&fp->format)
-          || !lex_force_match ('(')
-          || !lex_force_string ())
+      if (!parse_float_format (lexer, &fp->format)
+          || !lex_force_match (lexer, '(')
+          || !lex_force_string (lexer))
         return false;
 
-      length = ds_length (&tokstr);
+      length = ds_length (lex_tokstr (lexer));
       if (fp->format != FLOAT_HEX) 
         {
           if (length != float_get_size (fp->format)) 
@@ -129,7 +129,7 @@
               return false;
             }
           assert (length <= sizeof fp->data);
-          memcpy (fp->data, ds_data (&tokstr), length); 
+          memcpy (fp->data, ds_data (lex_tokstr (lexer)), length); 
         }
       else 
         {
@@ -138,16 +138,16 @@
               msg (SE, _("Hexadecimal floating constant too long."));
               return false;
             }
-          strncpy ((char *) fp->data, ds_cstr (&tokstr), sizeof fp->data);
+          strncpy ((char *) fp->data, ds_cstr (lex_tokstr (lexer)), sizeof fp->data);
         }
 
-      lex_get ();
-      if (!lex_force_match (')'))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, ')'))
         return false;
     }
   else
     {
-      lex_error (NULL);
+      lex_error (lexer, NULL);
       return false;
     }
   return true;
@@ -235,7 +235,7 @@
 
 /* Executes the DEBUG FLOAT FORMAT command. */
 int
-cmd_debug_float_format (struct dataset *ds UNUSED) 
+cmd_debug_float_format (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   struct fp fp[16];
   size_t fp_cnt = 0;
@@ -249,30 +249,30 @@
           msg (SE, _("Too many values in single command."));
           return CMD_FAILURE;
         }
-      if (!parse_fp (&fp[fp_cnt++]))
+      if (!parse_fp (lexer, &fp[fp_cnt++]))
         return CMD_FAILURE;
 
-      if (token == '.' && fp_cnt > 1)
+      if (lex_token (lexer) == '.' && fp_cnt > 1)
         break;
-      else if (!lex_force_match ('='))
+      else if (!lex_force_match (lexer, '='))
         return CMD_FAILURE;
       
       if (fp_cnt == 1) 
         {
-          if (lex_match ('='))
+          if (lex_match (lexer, '='))
             bijective = true;
-          else if (lex_match (T_GT))
+          else if (lex_match (lexer, T_GT))
             bijective = false;
           else 
             {
-              lex_error (NULL);
+              lex_error (lexer, NULL);
               return CMD_FAILURE;
             }
         }
       else 
         {
-          if ((bijective && !lex_force_match ('='))
-              || (!bijective && !lex_force_match (T_GT)))
+          if ((bijective && !lex_force_match (lexer, '='))
+              || (!bijective && !lex_force_match (lexer, T_GT)))
             return CMD_FAILURE;
         }
     }
Index: src/language/tests/moments-test.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/moments-test.c,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 moments-test.c
--- src/language/tests/moments-test.c	26 Oct 2006 06:16:36 -0000	1.6
+++ src/language/tests/moments-test.c	11 Nov 2006 00:13:21 -0000
@@ -31,27 +31,27 @@
 #define _(msgid) gettext (msgid)
 
 static bool
-read_values (double **values, double **weights, size_t *cnt) 
+read_values (struct lexer *lexer, double **values, double **weights, size_t *cnt) 
 {
   size_t cap = 0;
 
   *values = NULL;
   *weights = NULL;
   *cnt = 0;
-  while (lex_is_number ())
+  while (lex_is_number (lexer))
     {
-      double value = tokval;
+      double value = lex_tokval (lexer);
       double weight = 1.;
-      lex_get ();
-      if (lex_match ('*'))
+      lex_get (lexer);
+      if (lex_match (lexer, '*'))
         {
-          if (!lex_is_number ())
+          if (!lex_is_number (lexer))
             {
-              lex_error (_("expecting weight value"));
+              lex_error (lexer, _("expecting weight value"));
               return false;
             }
-          weight = tokval;
-          lex_get ();
+          weight = lex_tokval (lexer);
+          lex_get (lexer);
         }
 
       if (*cnt >= cap) 
@@ -70,7 +70,7 @@
 }
 
 int
-cmd_debug_moments (struct dataset *ds UNUSED) 
+cmd_debug_moments (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   int retval = CMD_FAILURE;
   double *values = NULL;
@@ -80,22 +80,22 @@
   size_t cnt;
   size_t i;
 
-  if (lex_match_id ("ONEPASS"))
+  if (lex_match_id (lexer, "ONEPASS"))
     two_pass = 0;
-  if (token != '/') 
+  if (lex_token (lexer) != '/') 
     {
-      lex_force_match ('/');
+      lex_force_match (lexer, '/');
       goto done;
     }
-  fprintf (stderr, "%s => ", lex_rest_of_line (NULL));
-  lex_get ();
+  fprintf (stderr, "%s => ", lex_rest_of_line (lexer, NULL));
+  lex_get (lexer);
 
   if (two_pass) 
     {
       struct moments *m = NULL;
   
       m = moments_create (MOMENT_KURTOSIS);
-      if (!read_values (&values, &weights, &cnt)) 
+      if (!read_values (lexer, &values, &weights, &cnt)) 
         {
           moments_destroy (m);
           goto done; 
@@ -112,7 +112,7 @@
       struct moments1 *m = NULL;
   
       m = moments1_create (MOMENT_KURTOSIS);
-      if (!read_values (&values, &weights, &cnt)) 
+      if (!read_values (lexer, &values, &weights, &cnt)) 
         {
           moments1_destroy (m);
           goto done; 
@@ -136,7 +136,7 @@
     }
   fprintf (stderr, "\n");
 
-  retval = lex_end_of_command ();
+  retval = lex_end_of_command (lexer);
   
  done:
   free (values);
Index: src/language/tests/pool-test.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/pool-test.c,v
retrieving revision 1.3
diff -b -w -U3 -r1.3 pool-test.c
--- src/language/tests/pool-test.c	26 Oct 2006 06:16:36 -0000	1.3
+++ src/language/tests/pool-test.c	11 Nov 2006 00:13:21 -0000
@@ -32,7 +32,7 @@
 /* Self-test routine.
    This is not exhaustive, but it can be useful. */
 int
-cmd_debug_pool (struct dataset *ds UNUSED)
+cmd_debug_pool (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   int seed = time (0) * 257 % 32768;
 
Index: src/language/utilities/date.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/date.c,v
retrieving revision 1.3
diff -b -w -U3 -r1.3 date.c
--- src/language/utilities/date.c	26 Oct 2006 06:16:36 -0000	1.3
+++ src/language/utilities/date.c	11 Nov 2006 00:13:21 -0000
@@ -27,10 +27,10 @@
 
 /* Stub for USE command. */
 int
-cmd_use (struct dataset *ds UNUSED) 
+cmd_use (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
-  if (lex_match (T_ALL))
-    return lex_end_of_command ();
+  if (lex_match (lexer, T_ALL))
+    return lex_end_of_command (lexer);
 
   msg (SW, _("Only USE ALL is currently implemented."));
   return CMD_FAILURE;
Index: src/language/utilities/echo.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/echo.c,v
retrieving revision 1.4
diff -b -w -U3 -r1.4 echo.c
--- src/language/utilities/echo.c	26 Oct 2006 06:16:36 -0000	1.4
+++ src/language/utilities/echo.c	11 Nov 2006 00:13:21 -0000
@@ -29,11 +29,11 @@
 
 /* Echos a string to the output stream */
 int
-cmd_echo (struct dataset *ds UNUSED)
+cmd_echo (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   struct tab_table *tab;
 
-  if (token != T_STRING) 
+  if (lex_token (lexer) != T_STRING) 
     return CMD_FAILURE;
   
   tab = tab_create(1, 1, 0);
@@ -41,7 +41,7 @@
   tab_dim (tab, tab_natural_dimensions);
   tab_flags (tab, SOMF_NO_TITLE );
 
-  tab_text(tab, 0, 0, 0, ds_cstr (&tokstr));
+  tab_text(tab, 0, 0, 0, ds_cstr (lex_tokstr (lexer)));
 
   tab_submit(tab);
 
Index: src/language/utilities/include.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/include.c,v
retrieving revision 1.5
diff -b -w -U3 -r1.5 include.c
--- src/language/utilities/include.c	26 Oct 2006 06:16:36 -0000	1.5
+++ src/language/utilities/include.c	11 Nov 2006 00:13:21 -0000
@@ -31,20 +31,20 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_include (struct dataset *ds UNUSED)
+cmd_include (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   /* Skip optional FILE=. */
-  if (lex_match_id ("FILE"))
-    lex_match ('=');
+  if (lex_match_id (lexer, "FILE"))
+    lex_match (lexer, '=');
 
   /* File name can be identifier or string. */
-  if (token != T_ID && token != T_STRING) 
+  if (lex_token (lexer) != T_ID && lex_token (lexer) != T_STRING) 
     {
-      lex_error (_("expecting file name")); 
+      lex_error (lexer, _("expecting file name")); 
       return CMD_CASCADING_FAILURE;
     }
-  getl_include_syntax_file (ds_cstr (&tokstr));
+  getl_include_syntax_file (ds_cstr (lex_tokstr (lexer)));
 
-  lex_get ();
-  return lex_end_of_command ();
+  lex_get (lexer);
+  return lex_end_of_command (lexer);
 }
Index: src/language/utilities/permissions.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/permissions.c,v
retrieving revision 1.6
diff -b -w -U3 -r1.6 permissions.c
--- src/language/utilities/permissions.c	26 Oct 2006 06:16:36 -0000	1.6
+++ src/language/utilities/permissions.c	11 Nov 2006 00:13:21 -0000
@@ -42,32 +42,32 @@
 
 /* Parses the PERMISSIONS command. */
 int
-cmd_permissions (struct dataset *ds UNUSED)
+cmd_permissions (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   char  *fn = 0;
 
-  lex_match ('/');
+  lex_match (lexer, '/');
 
-  if (lex_match_id ("FILE"))
-    lex_match ('=');
+  if (lex_match_id (lexer, "FILE"))
+    lex_match (lexer, '=');
 
-  fn = ds_xstrdup (&tokstr);
-  lex_force_match(T_STRING);
+  fn = ds_xstrdup (lex_tokstr (lexer));
+  lex_force_match (lexer, T_STRING);
 
 
-  lex_match ('/');
+  lex_match (lexer, '/');
   
-  if ( ! lex_match_id ("PERMISSIONS"))
+  if ( ! lex_match_id (lexer, "PERMISSIONS"))
     goto error;
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ( lex_match_id("READONLY"))
+  if ( lex_match_id (lexer, "READONLY"))
     {
       if ( ! change_permissions(fn, PER_RO ) ) 
 	goto error;
     }
-  else if ( lex_match_id("WRITEABLE"))
+  else if ( lex_match_id (lexer, "WRITEABLE"))
     {
       if ( ! change_permissions(fn, PER_RW ) ) 
 	goto error;
Index: src/language/utilities/set.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/set.q,v
retrieving revision 1.18
diff -b -w -U3 -r1.18 set.q
--- src/language/utilities/set.q	5 Nov 2006 05:20:53 -0000	1.18
+++ src/language/utilities/set.q	11 Nov 2006 00:13:21 -0000
@@ -127,11 +127,11 @@
 static enum float_format stc_to_float_format (int stc);
 
 int
-cmd_set (struct dataset *ds)
+cmd_set (struct lexer *lexer, struct dataset *ds)
 {
   struct cmd_set cmd;
 
-  if (!parse_set (ds, &cmd, NULL))
+  if (!parse_set (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   if (cmd.sbc_cca)
@@ -298,10 +298,10 @@
   return true;
 }
 
-/* Extracts a token from IN into a newly allocated AFFIX.  Tokens
-   are delimited by GROUPING.  The token is truncated to at most
+/* Extracts a lex_token (lexer) from IN into a newly allocated AFFIX.  Tokens
+   are delimited by GROUPING.  The lex_token (lexer) is truncated to at most
    FMT_STYLE_AFFIX_MAX characters.  Returns the first character
-   following the token. */
+   following the lex_token (lexer). */
 static const char *
 extract_cc_token (const char *in, int grouping, struct substring *affix) 
 {
@@ -352,20 +352,22 @@
    completely blank fields in numeric data imply.  X, Wnd: Syntax is
    SYSMIS or a numeric value. */
 static int
-stc_custom_blanks (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
+stc_custom_blanks (struct lexer *lexer, 
+		   struct dataset *ds UNUSED, 
+		   struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if ((token == T_ID && lex_id_match ("SYSMIS", tokid)))
+  lex_match (lexer, '=');
+  if ((lex_token (lexer) == T_ID && lex_id_match ("SYSMIS", lex_tokid (lexer))))
     {
-      lex_get ();
+      lex_get (lexer);
       set_blanks (SYSMIS);
     }
   else
     {
-      if (!lex_force_num ())
+      if (!lex_force_num (lexer))
 	return 0;
-      set_blanks (lex_number ());
-      lex_get ();
+      set_blanks (lex_number (lexer));
+      lex_get (lexer);
     }
   return 1;
 }
@@ -373,15 +375,17 @@
 /* Parses the EPOCH subcommand, which controls the epoch used for
    parsing 2-digit years. */
 static int
-stc_custom_epoch (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED) 
+stc_custom_epoch (struct lexer *lexer, 
+		  struct dataset *ds UNUSED, 
+		  struct cmd_set *cmd UNUSED, void *aux UNUSED) 
 {
-  lex_match ('=');
-  if (lex_match_id ("AUTOMATIC"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "AUTOMATIC"))
     set_epoch (-1);
-  else if (lex_is_integer ()) 
+  else if (lex_is_integer (lexer)) 
     {
-      int new_epoch = lex_integer ();
-      lex_get ();
+      int new_epoch = lex_integer (lexer);
+      lex_get (lexer);
       if (new_epoch < 1500) 
         {
           msg (SE, _("EPOCH must be 1500 or later."));
@@ -391,7 +395,7 @@
     }
   else 
     {
-      lex_error (_("expecting AUTOMATIC or year"));
+      lex_error (lexer, _("expecting AUTOMATIC or year"));
       return 0;
     }
 
@@ -399,24 +403,24 @@
 }
 
 static int
-stc_custom_length (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
+stc_custom_length (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
   int page_length;
 
-  lex_match ('=');
-  if (lex_match_id ("NONE"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "NONE"))
     page_length = -1;
   else
     {
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	return 0;
-      if (lex_integer () < 1)
+      if (lex_integer (lexer) < 1)
 	{
 	  msg (SE, _("LENGTH must be at least 1."));
 	  return 0;
 	}
-      page_length = lex_integer ();
-      lex_get ();
+      page_length = lex_integer (lexer);
+      lex_get (lexer);
     }
 
   if (page_length != -1) 
@@ -426,41 +430,41 @@
 }
 
 static int
-stc_custom_seed (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
+stc_custom_seed (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if (lex_match_id ("RANDOM"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "RANDOM"))
     set_rng (time (0));
   else
     {
-      if (!lex_force_num ())
+      if (!lex_force_num (lexer))
 	return 0;
-      set_rng (lex_number ());
-      lex_get ();
+      set_rng (lex_number (lexer));
+      lex_get (lexer);
     }
 
   return 1;
 }
 
 static int
-stc_custom_width (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
+stc_custom_width (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if (lex_match_id ("NARROW"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "NARROW"))
     set_viewwidth (79);
-  else if (lex_match_id ("WIDE"))
+  else if (lex_match_id (lexer, "WIDE"))
     set_viewwidth (131);
   else
     {
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	return 0;
-      if (lex_integer () < 40)
+      if (lex_integer (lexer) < 40)
 	{
 	  msg (SE, _("WIDTH must be at least 40."));
 	  return 0;
 	}
-      set_viewwidth (lex_integer ());
-      lex_get ();
+      set_viewwidth (lex_integer (lexer));
+      lex_get (lexer);
     }
 
   return 1;
@@ -469,12 +473,12 @@
 /* Parses FORMAT subcommand, which consists of a numeric format
    specifier. */
 static int
-stc_custom_format (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
+stc_custom_format (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
   struct fmt_spec fmt;
 
-  lex_match ('=');
-  if (!parse_format_specifier (&fmt))
+  lex_match (lexer, '=');
+  if (!parse_format_specifier (lexer, &fmt))
     return 0;
   if (fmt_is_string (fmt.type))
     {
@@ -490,16 +494,16 @@
 }
 
 static int
-stc_custom_journal (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
+stc_custom_journal (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if (!lex_match_id ("ON") && !lex_match_id ("OFF")) 
+  lex_match (lexer, '=');
+  if (!lex_match_id (lexer, "ON") && !lex_match_id (lexer, "OFF")) 
     {
-      if (token == T_STRING)
-        lex_get ();
+      if (lex_token (lexer) == T_STRING)
+        lex_get (lexer);
       else
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return 0;
         }
     }
@@ -507,14 +511,14 @@
 }
 
 static int
-stc_custom_listing (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
+stc_custom_listing (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
   bool listing;
 
-  lex_match ('=');
-  if (lex_match_id ("ON") || lex_match_id ("YES"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "ON") || lex_match_id (lexer, "YES"))
     listing = true;
-  else if (lex_match_id ("OFF") || lex_match_id ("NO"))
+  else if (lex_match_id (lexer, "OFF") || lex_match_id (lexer, "NO"))
     listing = false;
   else
     {
@@ -527,9 +531,9 @@
 }
 
 static int
-stc_custom_disk (struct dataset *ds, struct cmd_set *cmd UNUSED, void *aux)
+stc_custom_disk (struct lexer *lexer, struct dataset *ds, struct cmd_set *cmd UNUSED, void *aux)
 {
-  return stc_custom_listing (ds, cmd, aux);
+  return stc_custom_listing (lexer, ds, cmd, aux);
 }
 
 static void
@@ -828,9 +832,9 @@
 }
 
 int
-cmd_show (struct dataset *ds) 
+cmd_show (struct lexer *lexer, struct dataset *ds) 
 {
-  if (token == '.') 
+  if (lex_token (lexer) == '.') 
     {
       show_all (ds);
       return CMD_SUCCESS;
@@ -838,38 +842,38 @@
 
   do 
     {
-      if (lex_match (T_ALL))
+      if (lex_match (lexer, T_ALL))
         show_all (ds);
-      else if (lex_match_id ("CC")) 
+      else if (lex_match_id (lexer, "CC")) 
         show_all_cc ();
-      else if (lex_match_id ("WARRANTY"))
+      else if (lex_match_id (lexer, "WARRANTY"))
         show_warranty (ds);
-      else if (lex_match_id ("COPYING"))
+      else if (lex_match_id (lexer, "COPYING"))
         show_copying (ds);
-      else if (token == T_ID)
+      else if (lex_token (lexer) == T_ID)
         {
           int i;
 
           for (i = 0; i < sizeof show_table / sizeof *show_table; i++)
-            if (lex_match_id (show_table[i].name)) 
+            if (lex_match_id (lexer, show_table[i].name)) 
               {
                 show_table[i].function (ds);
                 goto found;
               }
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return CMD_FAILURE;
 
         found: ;
         }
       else 
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return CMD_FAILURE;
         }
 
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
 
   return CMD_SUCCESS;
 }
Index: src/language/utilities/title.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/title.c,v
retrieving revision 1.7
diff -b -w -U3 -r1.7 title.c
--- src/language/utilities/title.c	26 Oct 2006 06:16:36 -0000	1.7
+++ src/language/utilities/title.c	11 Nov 2006 00:13:21 -0000
@@ -36,36 +36,36 @@
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-static int get_title (const char *cmd, char **title);
+static int get_title (struct lexer *, const char *cmd, char **title);
 
 int
-cmd_title (struct dataset *ds UNUSED)
+cmd_title (struct lexer *lexer, struct dataset *ds UNUSED)
 {
-  return get_title ("TITLE", &outp_title);
+  return get_title (lexer, "TITLE", &outp_title);
 }
 
 int
-cmd_subtitle (struct dataset *ds UNUSED)
+cmd_subtitle (struct lexer *lexer, struct dataset *ds UNUSED)
 {
-  return get_title ("SUBTITLE", &outp_subtitle);
+  return get_title (lexer, "SUBTITLE", &outp_subtitle);
 }
 
 static int
-get_title (const char *cmd, char **title)
+get_title (struct lexer *lexer, const char *cmd, char **title)
 {
   int c;
 
-  c = lex_look_ahead ();
+  c = lex_look_ahead (lexer);
   if (c == '"' || c == '\'')
     {
-      lex_get ();
-      if (!lex_force_string ())
+      lex_get (lexer);
+      if (!lex_force_string (lexer))
 	return CMD_FAILURE;
       if (*title)
 	free (*title);
-      *title = ds_xstrdup (&tokstr);
-      lex_get ();
-      if (token != '.')
+      *title = ds_xstrdup (lex_tokstr (lexer));
+      lex_get (lexer);
+      if (lex_token (lexer) != '.')
 	{
 	  msg (SE, _("%s: `.' expected after string."), cmd);
 	  return CMD_FAILURE;
@@ -77,28 +77,26 @@
 
       if (*title)
 	free (*title);
-      *title = xstrdup (lex_rest_of_line (NULL));
-      lex_discard_line ();
+      *title = xstrdup (lex_rest_of_line (lexer, NULL));
+      lex_discard_line (lexer);
       for (cp = *title; *cp; cp++)
 	*cp = toupper ((unsigned char) (*cp));
-      token = '.';
     }
   return CMD_SUCCESS;
 }
 
 /* Performs the FILE LABEL command. */
 int
-cmd_file_label (struct dataset *ds)
+cmd_file_label (struct lexer *lexer, struct dataset *ds)
 {
   const char *label;
 
-  label = lex_rest_of_line (NULL);
-  lex_discard_line ();
+  label = lex_rest_of_line (lexer, NULL);
+  lex_discard_line (lexer);
   while (isspace ((unsigned char) *label))
     label++;
 
   dict_set_label (dataset_dict (ds), label);
-  token = '.';
 
   return CMD_SUCCESS;
 }
@@ -128,7 +126,7 @@
 
 /* Performs the DOCUMENT command. */
 int
-cmd_document (struct dataset *ds)
+cmd_document (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   /* Add a few header lines for reference. */
@@ -148,8 +146,8 @@
       const char *orig_line;
       char *copy_line;
 
-      orig_line = lex_rest_of_line (&had_dot);
-      lex_discard_line ();
+      orig_line = lex_rest_of_line (lexer, &had_dot);
+      lex_discard_line (lexer);
       while (isspace ((unsigned char) *orig_line))
 	orig_line++;
 
@@ -161,20 +159,19 @@
       add_document_line (dict, copy_line, 3);
       free (copy_line);
 
-      lex_get_line ();
+      lex_get_line (lexer);
       if (had_dot)
 	break;
     }
 
-  token = '.';
   return CMD_SUCCESS;
 }
 
 /* Performs the DROP DOCUMENTS command. */
 int
-cmd_drop_documents (struct dataset *ds)
+cmd_drop_documents (struct lexer *lexer, struct dataset *ds)
 {
   dict_set_documents (dataset_dict (ds), NULL);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
Index: src/language/xforms/compute.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/compute.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 compute.c
--- src/language/xforms/compute.c	26 Oct 2006 06:16:36 -0000	1.9
+++ src/language/xforms/compute.c	11 Nov 2006 00:13:22 -0000
@@ -43,7 +43,7 @@
 
 /* Target of a COMPUTE or IF assignment, either a variable or a
    vector element. */
-static struct lvalue *lvalue_parse (struct dataset *);
+static struct lvalue *lvalue_parse (struct lexer *lexer, struct dataset *);
 static int lvalue_get_type (const struct lvalue *, const struct dictionary *);
 static bool lvalue_is_vector (const struct lvalue *);
 static void lvalue_finalize (struct lvalue *,
@@ -69,7 +69,10 @@
     struct expression *rvalue;	 /* Rvalue expression. */
   };
 
-static struct expression *parse_rvalue (const struct lvalue *, struct dataset *);
+static struct expression *parse_rvalue (struct lexer *lexer, 
+					const struct lvalue *, 
+					struct dataset *);
+
 static struct compute_trns *compute_trns_create (void);
 static trns_proc_func *get_proc_func (const struct lvalue *, const struct dictionary *);
 static trns_free_func compute_trns_free;
@@ -77,7 +80,7 @@
 /* COMPUTE. */
 
 int
-cmd_compute (struct dataset *ds)
+cmd_compute (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct lvalue *lvalue = NULL;
@@ -85,13 +88,13 @@
 
   compute = compute_trns_create ();
 
-  lvalue = lvalue_parse (ds);
+  lvalue = lvalue_parse (lexer, ds);
   if (lvalue == NULL)
     goto fail;
 
-  if (!lex_force_match ('='))
+  if (!lex_force_match (lexer, '='))
     goto fail;
-  compute->rvalue = parse_rvalue (lvalue, ds);
+  compute->rvalue = parse_rvalue (lexer, lvalue, ds);
   if (compute->rvalue == NULL)
     goto fail;
 
@@ -100,7 +103,7 @@
 
   lvalue_finalize (lvalue, compute, dict);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
  fail:
   lvalue_destroy (lvalue);
@@ -213,7 +216,7 @@
 /* IF. */
 
 int
-cmd_if (struct dataset *ds)
+cmd_if (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct compute_trns *compute = NULL;
@@ -222,19 +225,19 @@
   compute = compute_trns_create ();
 
   /* Test expression. */
-  compute->test = expr_parse (ds, EXPR_BOOLEAN);
+  compute->test = expr_parse (lexer, ds, EXPR_BOOLEAN);
   if (compute->test == NULL)
     goto fail;
 
   /* Lvalue variable. */
-  lvalue = lvalue_parse (ds);
+  lvalue = lvalue_parse (lexer, ds);
   if (lvalue == NULL)
     goto fail;
 
   /* Rvalue expression. */
-  if (!lex_force_match ('='))
+  if (!lex_force_match (lexer, '='))
     goto fail;
-  compute->rvalue = parse_rvalue (lvalue, ds);
+  compute->rvalue = parse_rvalue (lexer, lvalue, ds);
   if (compute->rvalue == NULL)
     goto fail;
 
@@ -243,7 +246,7 @@
 
   lvalue_finalize (lvalue, compute, dict);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
  fail:
   lvalue_destroy (lvalue);
@@ -267,12 +270,13 @@
 /* Parses and returns an rvalue expression of the same type as
    LVALUE, or a null pointer on failure. */
 static struct expression *
-parse_rvalue (const struct lvalue *lvalue, struct dataset *ds)
+parse_rvalue (struct lexer *lexer, 
+	      const struct lvalue *lvalue, struct dataset *ds)
 {
   const struct dictionary *dict = dataset_dict (ds);
   bool is_numeric = lvalue_get_type (lvalue, dict) == NUMERIC;
 
-  return expr_parse (ds, is_numeric ? EXPR_NUMBER : EXPR_STRING);
+  return expr_parse (lexer, ds, is_numeric ? EXPR_NUMBER : EXPR_STRING);
 }
 
 /* Returns a new struct compute_trns after initializing its fields. */
@@ -315,7 +319,7 @@
 /* Parses the target variable or vector element into a new
    `struct lvalue', which is returned. */
 static struct lvalue *
-lvalue_parse (struct dataset *ds) 
+lvalue_parse (struct lexer *lexer, struct dataset *ds) 
 {
   struct lvalue *lvalue;
 
@@ -324,34 +328,34 @@
   lvalue->vector = NULL;
   lvalue->element = NULL;
 
-  if (!lex_force_id ())
+  if (!lex_force_id (lexer))
     goto lossage;
   
-  if (lex_look_ahead () == '(')
+  if (lex_look_ahead (lexer) == '(')
     {
       /* Vector. */
-      lvalue->vector = dict_lookup_vector (dataset_dict (ds), tokid);
+      lvalue->vector = dict_lookup_vector (dataset_dict (ds), lex_tokid (lexer));
       if (lvalue->vector == NULL)
 	{
-	  msg (SE, _("There is no vector named %s."), tokid);
+	  msg (SE, _("There is no vector named %s."), lex_tokid (lexer));
           goto lossage;
 	}
 
       /* Vector element. */
-      lex_get ();
-      if (!lex_force_match ('('))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, '('))
 	goto lossage;
-      lvalue->element = expr_parse (ds, EXPR_NUMBER);
+      lvalue->element = expr_parse (lexer, ds, EXPR_NUMBER);
       if (lvalue->element == NULL)
         goto lossage;
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
         goto lossage;
     }
   else
     {
       /* Variable name. */
-      str_copy_trunc (lvalue->var_name, sizeof lvalue->var_name, tokid);
-      lex_get ();
+      str_copy_trunc (lvalue->var_name, sizeof lvalue->var_name, lex_tokid (lexer));
+      lex_get (lexer);
     }
   return lvalue;
 
Index: src/language/xforms/count.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/count.c,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 count.c
--- src/language/xforms/count.c	26 Oct 2006 06:16:36 -0000	1.10
+++ src/language/xforms/count.c	11 Nov 2006 00:13:22 -0000
@@ -93,11 +93,11 @@
 static trns_proc_func count_trns_proc;
 static trns_free_func count_trns_free;
 
-static bool parse_numeric_criteria (struct pool *, struct criteria *);
-static bool parse_string_criteria (struct pool *, struct criteria *);
+static bool parse_numeric_criteria (struct lexer *, struct pool *, struct criteria *);
+static bool parse_string_criteria (struct lexer *, struct pool *, struct criteria *);
 
 int
-cmd_count (struct dataset *ds)
+cmd_count (struct lexer *lexer, struct dataset *ds)
 {
   struct dst_var *dv;           /* Destination var being parsed. */
   struct count_trns *trns;      /* Transformation. */
@@ -115,9 +115,9 @@
       dv->crit = NULL;
 
       /* Get destination variable, or at least its name. */
-      if (!lex_force_id ())
+      if (!lex_force_id (lexer))
 	goto fail;
-      dv->var = dict_lookup_var (dataset_dict (ds), tokid);
+      dv->var = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer));
       if (dv->var != NULL)
         {
           if (dv->var->type == ALPHA)
@@ -127,10 +127,10 @@
             }
         }
       else
-        dv->name = pool_strdup (trns->pool, tokid);
+        dv->name = pool_strdup (trns->pool, lex_tokid (lexer));
 
-      lex_get ();
-      if (!lex_force_match ('='))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, '='))
 	goto fail;
 
       crit = dv->crit = pool_alloc (trns->pool, sizeof *crit);
@@ -140,32 +140,32 @@
           
 	  crit->next = NULL;
 	  crit->vars = NULL;
-	  if (!parse_variables (dataset_dict (ds), &crit->vars, &crit->var_cnt,
+	  if (!parse_variables (lexer, dataset_dict (ds), &crit->vars, &crit->var_cnt,
                                 PV_DUPLICATE | PV_SAME_TYPE))
 	    goto fail;
           pool_register (trns->pool, free, crit->vars);
 
-	  if (!lex_force_match ('('))
+	  if (!lex_force_match (lexer, '('))
 	    goto fail;
 
           crit->value_cnt = 0;
           if (crit->vars[0]->type == NUMERIC)
-            ok = parse_numeric_criteria (trns->pool, crit);
+            ok = parse_numeric_criteria (lexer, trns->pool, crit);
           else
-            ok = parse_string_criteria (trns->pool, crit);
+            ok = parse_string_criteria (lexer, trns->pool, crit);
 	  if (!ok)
 	    goto fail;
 
-	  if (token == '/' || token == '.')
+	  if (lex_token (lexer) == '/' || lex_token (lexer) == '.')
 	    break;
 
 	  crit = crit->next = pool_alloc (trns->pool, sizeof *crit);
 	}
 
-      if (token == '.')
+      if (lex_token (lexer) == '.')
 	break;
 
-      if (!lex_force_match ('/'))
+      if (!lex_force_match (lexer, '/'))
 	goto fail;
       dv = dv->next = pool_alloc (trns->pool, sizeof *dv);
     }
@@ -192,7 +192,7 @@
 
 /* Parses a set of numeric criterion values.  Returns success. */
 static bool
-parse_numeric_criteria (struct pool *pool, struct criteria *crit)
+parse_numeric_criteria (struct lexer *lexer, struct pool *pool, struct criteria *crit)
 {
   size_t allocated = 0;
 
@@ -203,11 +203,11 @@
     {
       double low, high;
       
-      if (lex_match_id ("SYSMIS"))
+      if (lex_match_id (lexer, "SYSMIS"))
         crit->count_system_missing = true;
-      else if (lex_match_id ("MISSING"))
+      else if (lex_match_id (lexer, "MISSING"))
 	crit->count_user_missing = true;
-      else if (parse_num_range (&low, &high, NULL)) 
+      else if (parse_num_range (lexer, &low, &high, NULL)) 
         {
           struct num_value *cur;
 
@@ -223,8 +223,8 @@
       else
         return false;
 
-      lex_match (',');
-      if (lex_match (')'))
+      lex_match (lexer, ',');
+      if (lex_match (lexer, ')'))
 	break;
     }
   return true;
@@ -232,7 +232,7 @@
 
 /* Parses a set of string criteria values.  Returns success. */
 static bool
-parse_string_criteria (struct pool *pool, struct criteria *crit)
+parse_string_criteria (struct lexer *lexer, struct pool *pool, struct criteria *crit)
 {
   int len = 0;
   size_t allocated = 0;
@@ -251,15 +251,15 @@
                                            &allocated,
                                            sizeof *crit->values.str);
 
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
 	return false;
       cur = &crit->values.str[crit->value_cnt++];
       *cur = pool_alloc (pool, len + 1);
-      str_copy_rpad (*cur, len + 1, ds_cstr (&tokstr));
-      lex_get ();
+      str_copy_rpad (*cur, len + 1, ds_cstr (lex_tokstr (lexer)));
+      lex_get (lexer);
 
-      lex_match (',');
-      if (lex_match (')'))
+      lex_match (lexer, ',');
+      if (lex_match (lexer, ')'))
 	break;
     }
 
Index: src/language/xforms/fail.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/fail.c,v
retrieving revision 1.3
diff -b -w -U3 -r1.3 fail.c
--- src/language/xforms/fail.c	26 Oct 2006 06:16:36 -0000	1.3
+++ src/language/xforms/fail.c	11 Nov 2006 00:13:22 -0000
@@ -42,10 +42,10 @@
 
 
 int
-cmd_debug_xform_fail (struct dataset *ds)
+cmd_debug_xform_fail (struct lexer *lexer, struct dataset *ds)
 {
 
   add_transformation (ds, trns_fail, NULL, NULL);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
Index: src/language/xforms/recode.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/recode.c,v
retrieving revision 1.12
diff -b -w -U3 -r1.12 recode.c
--- src/language/xforms/recode.c	26 Oct 2006 06:16:36 -0000	1.12
+++ src/language/xforms/recode.c	11 Nov 2006 00:13:22 -0000
@@ -108,21 +108,21 @@
     size_t map_cnt;             /* Number of mappings. */
   };
 
-static bool parse_src_vars (struct recode_trns *, const struct dictionary *dict);
-static bool parse_mappings (struct recode_trns *);
-static bool parse_dst_vars (struct recode_trns *, const struct dictionary *dict);
+static bool parse_src_vars (struct lexer *, struct recode_trns *, const struct dictionary *dict);
+static bool parse_mappings (struct lexer *, struct recode_trns *);
+static bool parse_dst_vars (struct lexer *, struct recode_trns *, const struct dictionary *dict);
 
 static void add_mapping (struct recode_trns *,
                          size_t *map_allocated, const struct map_in *);
 
-static bool parse_map_in (struct map_in *, struct pool *,
+static bool parse_map_in (struct lexer *lexer, struct map_in *, struct pool *,
                           enum var_type src_type, size_t max_src_width);
 static void set_map_in_generic (struct map_in *, enum map_in_type);
 static void set_map_in_num (struct map_in *, enum map_in_type, double, double);
 static void set_map_in_str (struct map_in *, struct pool *,
                             const struct string *, size_t width);
 
-static bool parse_map_out (struct pool *, struct map_out *);
+static bool parse_map_out (struct lexer *lexer, struct pool *, struct map_out *);
 static void set_map_out_num (struct map_out *, double);
 static void set_map_out_str (struct map_out *, struct pool *,
                              const struct string *);
@@ -137,7 +137,7 @@
 
 /* Parses the RECODE transformation. */
 int
-cmd_recode (struct dataset *ds)
+cmd_recode (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -147,9 +147,9 @@
       /* Parse source variable names,
          then input to output mappings,
          then destintation variable names. */
-      if (!parse_src_vars (trns, dataset_dict (ds) )
-          || !parse_mappings (trns)
-          || !parse_dst_vars (trns, dataset_dict (ds)))
+      if (!parse_src_vars (lexer, trns, dataset_dict (ds) )
+          || !parse_mappings (lexer, trns)
+          || !parse_dst_vars (lexer, trns, dataset_dict (ds)))
         {
           recode_trns_free (trns);
           return CMD_FAILURE;
@@ -170,18 +170,19 @@
       add_transformation (ds, 
 			  recode_trns_proc, recode_trns_free, trns);
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
   
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses a set of variables to recode into TRNS->src_vars and
    TRNS->var_cnt.  Sets TRNS->src_type.  Returns true if
    successful, false on parse error. */
 static bool
-parse_src_vars (struct recode_trns *trns, const struct dictionary *dict) 
+parse_src_vars (struct lexer *lexer, 
+		struct recode_trns *trns, const struct dictionary *dict) 
 {
-  if (!parse_variables (dict, &trns->src_vars, &trns->var_cnt,
+  if (!parse_variables (lexer, dict, &trns->src_vars, &trns->var_cnt,
                         PV_SAME_TYPE))
     return false;
   pool_register (trns->pool, free, trns->src_vars);
@@ -193,7 +194,7 @@
    into TRNS->mappings and TRNS->map_cnt.  Sets TRNS->dst_type.
    Returns true if successful, false on parse error. */
 static bool
-parse_mappings (struct recode_trns *trns) 
+parse_mappings (struct lexer *lexer, struct recode_trns *trns) 
 {
   size_t max_src_width;
   size_t map_allocated;
@@ -214,13 +215,13 @@
   trns->map_cnt = 0;
   map_allocated = 0;
   have_dst_type = false;
-  if (!lex_force_match ('('))
+  if (!lex_force_match (lexer, '('))
     return false;
   do
     {
       enum var_type dst_type;
 
-      if (!lex_match_id ("CONVERT")) 
+      if (!lex_match_id (lexer, "CONVERT")) 
         {
           struct map_out out;
           size_t first_map_idx;
@@ -232,15 +233,15 @@
           do
             {
               struct map_in in;
-              if (!parse_map_in (&in, trns->pool,
+              if (!parse_map_in (lexer, &in, trns->pool,
                                  trns->src_type, max_src_width))
                 return false;
               add_mapping (trns, &map_allocated, &in);
-              lex_match (',');
+              lex_match (lexer, ',');
             }
-          while (!lex_match ('='));
+          while (!lex_match (lexer, '='));
 
-          if (!parse_map_out (trns->pool, &out))
+          if (!parse_map_out (lexer, trns->pool, &out))
             return false;
           dst_type = out.width == 0 ? NUMERIC : ALPHA;
           if (have_dst_type && dst_type != trns->dst_type)
@@ -273,10 +274,10 @@
       trns->dst_type = dst_type;
       have_dst_type = true;
 
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
         return false; 
     }
-  while (lex_match ('('));
+  while (lex_match (lexer, '('));
 
   return true;
 }
@@ -287,31 +288,31 @@
    be provided in MAX_SRC_WIDTH.  Returns true if successful,
    false on parse error. */
 static bool
-parse_map_in (struct map_in *in, struct pool *pool,
+parse_map_in (struct lexer *lexer, struct map_in *in, struct pool *pool,
               enum var_type src_type, size_t max_src_width)
 {
-  if (lex_match_id ("ELSE"))
+  if (lex_match_id (lexer, "ELSE"))
     set_map_in_generic (in, MAP_ELSE);
   else if (src_type == NUMERIC)
     {
-      if (lex_match_id ("MISSING"))
+      if (lex_match_id (lexer, "MISSING"))
         set_map_in_generic (in, MAP_MISSING);
-      else if (lex_match_id ("SYSMIS"))
+      else if (lex_match_id (lexer, "SYSMIS"))
         set_map_in_generic (in, MAP_SYSMIS);
       else 
         {
           double x, y;
-          if (!parse_num_range (&x, &y, NULL))
+          if (!parse_num_range (lexer, &x, &y, NULL))
             return false;
           set_map_in_num (in, x == y ? MAP_SINGLE : MAP_RANGE, x, y);
         }
     }
   else
     {
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
         return false;
-      set_map_in_str (in, pool, &tokstr, max_src_width);
-      lex_get ();
+      set_map_in_str (in, pool, lex_tokstr (lexer), max_src_width);
+      lex_get (lexer);
     }
 
   return true;
@@ -365,25 +366,25 @@
 /* Parses a mapping output value into OUT, allocating memory from
    POOL.  Returns true if successful, false on parse error. */
 static bool
-parse_map_out (struct pool *pool, struct map_out *out)
+parse_map_out (struct lexer *lexer, struct pool *pool, struct map_out *out)
 {
-  if (lex_is_number ())
+  if (lex_is_number (lexer))
     {
-      set_map_out_num (out, lex_number ());
-      lex_get ();
+      set_map_out_num (out, lex_number (lexer));
+      lex_get (lexer);
     }
-  else if (lex_match_id ("SYSMIS"))
+  else if (lex_match_id (lexer, "SYSMIS"))
     set_map_out_num (out, SYSMIS);
-  else if (token == T_STRING)
+  else if (lex_token (lexer) == T_STRING)
     {
-      set_map_out_str (out, pool, &tokstr);
-      lex_get ();
+      set_map_out_str (out, pool, lex_tokstr (lexer));
+      lex_get (lexer);
     }
-  else if (lex_match_id ("COPY"))
+  else if (lex_match_id (lexer, "COPY"))
     out->copy_input = true;
   else 
     {
-      lex_error (_("expecting output value"));
+      lex_error (lexer, _("expecting output value"));
       return false;
     }
   return true; 
@@ -415,16 +416,17 @@
 /* Parses a set of target variables into TRNS->dst_vars and
    TRNS->dst_names. */
 static bool
-parse_dst_vars (struct recode_trns *trns, const struct dictionary *dict) 
+parse_dst_vars (struct lexer *lexer, struct recode_trns *trns, 
+		const struct dictionary *dict) 
 {
   size_t i;
   
-  if (lex_match_id ("INTO"))
+  if (lex_match_id (lexer, "INTO"))
     {
       size_t name_cnt;
       size_t i;
 
-      if (!parse_mixed_vars_pool (dict, trns->pool, 
+      if (!parse_mixed_vars_pool (lexer, dict, trns->pool, 
 				  &trns->dst_names, &name_cnt,
                                   PV_NONE))
         return false;
Index: src/language/xforms/sample.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/sample.c,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 sample.c
--- src/language/xforms/sample.c	26 Oct 2006 06:16:36 -0000	1.9
+++ src/language/xforms/sample.c	11 Nov 2006 00:13:22 -0000
@@ -57,7 +57,7 @@
 static trns_free_func sample_trns_free;
 
 int
-cmd_sample (struct dataset *ds)
+cmd_sample (struct lexer *lexer, struct dataset *ds)
 {
   struct sample_trns *trns;
 
@@ -65,34 +65,34 @@
   int a, b;
   unsigned frac;
 
-  if (!lex_force_num ())
+  if (!lex_force_num (lexer))
     return CMD_FAILURE;
-  if (!lex_is_integer ())
+  if (!lex_is_integer (lexer))
     {
       unsigned long min = gsl_rng_min (get_rng ());
       unsigned long max = gsl_rng_max (get_rng ());
 
       type = TYPE_FRACTION;
-      if (tokval <= 0 || tokval >= 1)
+      if (lex_tokval (lexer) <= 0 || lex_tokval (lexer) >= 1)
 	{
 	  msg (SE, _("The sampling factor must be between 0 and 1 "
 		     "exclusive."));
 	  return CMD_FAILURE;
 	}
 	  
-      frac = tokval * (max - min) + min;
+      frac = lex_tokval (lexer) * (max - min) + min;
       a = b = 0;
     }
   else
     {
       type = TYPE_A_FROM_B;
-      a = lex_integer ();
-      lex_get ();
-      if (!lex_force_match_id ("FROM"))
+      a = lex_integer (lexer);
+      lex_get (lexer);
+      if (!lex_force_match_id (lexer, "FROM"))
 	return CMD_FAILURE;
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
 	return CMD_FAILURE;
-      b = lex_integer ();
+      b = lex_integer (lexer);
       if (a >= b)
 	{
 	  msg (SE, _("Cannot sample %d observations from a population of "
@@ -103,7 +103,7 @@
       
       frac = 0;
     }
-  lex_get ();
+  lex_get (lexer);
 
   trns = xmalloc (sizeof *trns);
   trns->type = type;
@@ -113,7 +113,7 @@
   trns->frac = frac;
   add_transformation (ds, sample_trns_proc, sample_trns_free, trns);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Executes a SAMPLE transformation. */
Index: src/language/xforms/select-if.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/select-if.c,v
retrieving revision 1.11
diff -b -w -U3 -r1.11 select-if.c
--- src/language/xforms/select-if.c	26 Oct 2006 06:16:36 -0000	1.11
+++ src/language/xforms/select-if.c	11 Nov 2006 00:13:22 -0000
@@ -47,19 +47,19 @@
 
 /* Parses the SELECT IF transformation. */
 int
-cmd_select_if (struct dataset *ds)
+cmd_select_if (struct lexer *lexer, struct dataset *ds)
 {
   struct expression *e;
   struct select_if_trns *t;
 
-  e = expr_parse (ds, EXPR_BOOLEAN);
+  e = expr_parse (lexer, ds, EXPR_BOOLEAN);
   if (!e)
     return CMD_CASCADING_FAILURE;
 
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
       expr_free (e);
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       return CMD_CASCADING_FAILURE;
     }
 
@@ -92,12 +92,12 @@
 
 /* Parses the FILTER command. */
 int
-cmd_filter (struct dataset *ds)
+cmd_filter (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
-  if (lex_match_id ("OFF"))
+  if (lex_match_id (lexer, "OFF"))
     dict_set_filter (dataset_dict (ds), NULL);
-  else if (token == '.') 
+  else if (lex_token (lexer) == '.') 
     {
       msg (SW, _("Syntax error expecting OFF or BY.  "
                  "Turning off case filtering."));
@@ -107,8 +107,8 @@
     {
       struct variable *v;
 
-      lex_match (T_BY);
-      v = parse_variable (dict);
+      lex_match (lexer, T_BY);
+      v = parse_variable (lexer, dict);
       if (!v)
 	return CMD_FAILURE;
 
@@ -127,5 +127,5 @@
       dict_set_filter (dict, v);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
Index: src/ui/terminal/main.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/terminal/main.c,v
retrieving revision 1.19
diff -b -w -U3 -r1.19 main.c
--- src/ui/terminal/main.c	7 Nov 2006 12:59:59 -0000	1.19
+++ src/ui/terminal/main.c	11 Nov 2006 00:13:22 -0000
@@ -72,7 +72,7 @@
 void interrupt_handler(int sig);
 static struct dataset * the_dataset = NULL;
 
-
+static struct lexer *the_lexer;
 
 /* Program entry point. */
 int
@@ -102,11 +102,11 @@
     {
       msg_ui_init ();
       outp_read_devices ();
-      lex_init (do_read_line);
+      the_lexer = lex_create (do_read_line);
 
       for (;;)
         {
-          int result = cmd_parse (the_dataset, 
+          int result = cmd_parse (the_lexer, the_dataset, 
 				  proc_has_source (the_dataset)
                                   ? CMD_STATE_DATA : CMD_STATE_INITIAL);
           if (result == CMD_EOF || result == CMD_FINISH)
@@ -188,7 +188,7 @@
       random_done ();
       settings_done ();
       fh_done ();
-      lex_done ();
+      lex_destroy (the_lexer);
       getl_uninitialize ();
       readln_uninitialize ();
 
