pspp-dev
[Top][All Lists]
Advanced

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

[pre-lexer-2 3/4] lexer: New type enum token_type.


From: Ben Pfaff
Subject: [pre-lexer-2 3/4] lexer: New type enum token_type.
Date: Fri, 24 Sep 2010 21:17:53 -0700

It seems useful to have a type that indicates that a value is a token.
Furthermore, being able to enumerate all of the possible tokens in a
straightforward way seems worthwhile.  It also makes it possible for
GCC to check "switch" statements on token types and to build arrays
indexed by token.
---
 src/data/identifier.c                      |    6 +-
 src/data/identifier.h                      |   23 ++-
 src/language/command.c                     |   10 +-
 src/language/control/loop.c                |    6 +-
 src/language/control/repeat.c              |   16 +-
 src/language/data-io/combine-files.c       |   20 +-
 src/language/data-io/data-list.c           |   34 ++--
 src/language/data-io/data-reader.c         |    2 +-
 src/language/data-io/file-handle.q         |    4 +-
 src/language/data-io/get-data.c            |   56 +++---
 src/language/data-io/get.c                 |   10 +-
 src/language/data-io/inpt-pgm.c            |   12 +-
 src/language/data-io/placement-parser.c    |   22 ++--
 src/language/data-io/print-space.c         |    8 +-
 src/language/data-io/print.c               |   22 ++--
 src/language/data-io/save-translate.c      |   22 ++--
 src/language/data-io/save.c                |   16 +-
 src/language/data-io/trim.c                |   16 +-
 src/language/dictionary/apply-dictionary.c |    4 +-
 src/language/dictionary/attributes.c       |   18 +-
 src/language/dictionary/formats.c          |    8 +-
 src/language/dictionary/missing-values.c   |   16 +-
 src/language/dictionary/modify-variables.c |   34 ++--
 src/language/dictionary/mrsets.c           |   23 ++--
 src/language/dictionary/numeric.c          |   12 +-
 src/language/dictionary/rename-variables.c |    8 +-
 src/language/dictionary/sys-file-info.c    |    8 +-
 src/language/dictionary/value-labels.c     |   16 +-
 src/language/dictionary/variable-display.c |   26 ++--
 src/language/dictionary/variable-label.c   |    6 +-
 src/language/dictionary/vector.c           |   14 +-
 src/language/expressions/evaluate.c        |   10 +-
 src/language/expressions/parse.c           |   36 ++--
 src/language/lexer/lexer.c                 |  266 ++++++++++++++++++++++------
 src/language/lexer/lexer.h                 |   14 +-
 src/language/lexer/q2c.c                   |   30 ++--
 src/language/lexer/variable-parser.c       |    4 +-
 src/language/stats/aggregate.c             |   30 ++--
 src/language/stats/autorecode.c            |    8 +-
 src/language/stats/correlations.c          |   26 ++--
 src/language/stats/crosstabs.q             |   12 +-
 src/language/stats/descriptives.c          |   40 ++--
 src/language/stats/examine.q               |   18 +-
 src/language/stats/factor.c                |   64 ++++----
 src/language/stats/flip.c                  |   10 +-
 src/language/stats/frequencies.q           |   14 +-
 src/language/stats/glm.q                   |   12 +-
 src/language/stats/npar.q                  |   40 ++--
 src/language/stats/oneway.c                |   20 +-
 src/language/stats/rank.q                  |    8 +-
 src/language/stats/regression.q            |    4 +-
 src/language/stats/reliability.c           |   26 ++--
 src/language/stats/roc.c                   |   46 +++---
 src/language/stats/sort-cases.c            |    6 +-
 src/language/stats/sort-criteria.c         |    6 +-
 src/language/stats/t-test.q                |   18 +-
 src/language/tests/float-format.c          |   14 +-
 src/language/tests/moments-test.c          |    6 +-
 src/language/utilities/host.c              |    8 +-
 src/language/utilities/include.c           |   12 +-
 src/language/utilities/permissions.c       |    8 +-
 src/language/utilities/set.q               |   24 ++--
 src/language/utilities/title.c             |    7 +-
 src/language/xforms/compute.c              |   10 +-
 src/language/xforms/count.c                |   20 +-
 src/language/xforms/recode.c               |   12 +-
 src/language/xforms/select-if.c            |    6 +-
 tests/language/expressions/evaluate.at     |    2 +-
 68 files changed, 781 insertions(+), 614 deletions(-)

diff --git a/src/data/identifier.c b/src/data/identifier.c
index 7bd2261..166e8c2 100644
--- a/src/data/identifier.c
+++ b/src/data/identifier.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2005, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2005, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -119,7 +119,7 @@ static const size_t keyword_cnt = sizeof keywords / sizeof 
*keywords;
 
 /* Returns true if TOKEN is representable as a keyword. */
 bool
-lex_is_keyword (int token)
+lex_is_keyword (enum token_type token)
 {
   const struct keyword *kw;
   for (kw = keywords; kw < &keywords[keyword_cnt]; kw++)
@@ -146,7 +146,7 @@ lex_id_to_token (struct substring id)
 
 /* Returns the name for the given keyword token type. */
 const char *
-lex_id_name (int token)
+lex_id_name (enum token_type token)
 {
   const struct keyword *kw;
 
diff --git a/src/data/identifier.h b/src/data/identifier.h
index 352ef2e..2815f38 100644
--- a/src/data/identifier.h
+++ b/src/data/identifier.h
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -23,14 +23,27 @@
 #include <libpspp/str.h>
 
 /* Token types. */
-enum
+enum token_type
   {
-    T_ID = 256, /* Identifier. */
+    T_ID = 1,   /* Identifier. */
     T_POS_NUM, /* Positive number. */
     T_NEG_NUM, /* Negative number. */
     T_STRING,  /* Quoted string. */
     T_STOP,    /* End of input. */
 
+    T_ENDCMD,   /* End of command (e.g. '.'). */
+
+    T_PLUS,     /* + */
+    T_DASH,     /* - */
+    T_ASTERISK, /* * */
+    T_SLASH,    /* / */
+    T_EQUALS,   /* = */
+    T_LPAREN,   /* ( */
+    T_RPAREN,   /* ) */
+    T_LBRACK,   /* [ */
+    T_RBRACK,   /* ] */
+    T_COMMA,    /* , */
+
     T_AND,     /* AND */
     T_OR,      /* OR */
     T_NOT,     /* NOT */
@@ -51,7 +64,7 @@ enum
   };
 
 /* Tokens. */
-bool lex_is_keyword (int token);
+bool lex_is_keyword (enum token_type);
 
 /* Recognizing identifiers. */
 bool lex_is_id1 (char);
@@ -65,6 +78,6 @@ bool lex_id_match_n (struct substring keyword, struct 
substring token,
 int lex_id_to_token (struct substring);
 
 /* Identifier names. */
-const char *lex_id_name (int);
+const char *lex_id_name (enum token_type);
 
 #endif /* !data/identifier.h */
diff --git a/src/language/command.c b/src/language/command.c
index f72755e..3edeae8 100644
--- a/src/language/command.c
+++ b/src/language/command.c
@@ -173,7 +173,7 @@ do_parse_command (struct lexer *lexer,
       result = CMD_EOF;
       goto finish;
     }
-  else if (lex_token (lexer) == '.')
+  else if (lex_token (lexer) == T_ENDCMD)
     {
       /* Null commands can result from extra empty lines. */
       result = CMD_SUCCESS;
@@ -270,8 +270,8 @@ parse_command_name (struct lexer *lexer)
   struct string s;
 
   if (lex_token (lexer) == T_EXP
-      || lex_token (lexer) == '*'
-      || lex_token (lexer) == '[')
+      || lex_token (lexer) == T_ASTERISK
+      || lex_token (lexer) == T_LBRACK)
     {
       static const struct command c = { S_ANY, 0, "COMMENT", cmd_comment };
       return &c;
@@ -282,7 +282,7 @@ parse_command_name (struct lexer *lexer)
   ds_init_empty (&s);
   for (;;)
     {
-      if (lex_token (lexer) == '-')
+      if (lex_token (lexer) == T_DASH)
         ds_put_char (&s, '-');
       else if (lex_token (lexer) == T_ID)
         {
@@ -510,7 +510,7 @@ cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED)
 
   if (!lex_force_match_id (lexer, "FILE"))
     return CMD_FAILURE;
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (!lex_force_string (lexer))
     return CMD_FAILURE;
 
diff --git a/src/language/control/loop.c b/src/language/control/loop.c
index f5d205d..f17542c 100644
--- a/src/language/control/loop.c
+++ b/src/language/control/loop.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -103,7 +103,7 @@ cmd_loop (struct lexer *lexer, struct dataset *ds)
   bool ok = true;
 
   loop = create_loop_trns (ds);
-  while (lex_token (lexer) != '.' && ok)
+  while (lex_token (lexer) != T_ENDCMD && ok)
     {
       if (lex_match_id (lexer, "IF"))
         ok = parse_if_clause (lexer, loop, &loop->loop_condition);
@@ -232,7 +232,7 @@ parse_index_clause (struct dataset *ds, struct lexer *lexer,
     }
   lex_get (lexer);
 
-  if (!lex_force_match (lexer, '='))
+  if (!lex_force_match (lexer, T_EQUALS))
     return false;
 
   loop->first_expr = expr_parse_pool (lexer, loop->pool,
diff --git a/src/language/control/repeat.c b/src/language/control/repeat.c
index d7cc544..e85a5b0 100644
--- a/src/language/control/repeat.c
+++ b/src/language/control/repeat.c
@@ -187,7 +187,7 @@ parse_specification (struct lexer *lexer, struct 
repeat_block *block)
 
       /* Skip equals sign. */
       lex_get (lexer);
-      if (!lex_force_match (lexer, '='))
+      if (!lex_force_match (lexer, T_EQUALS))
        return false;
 
       /* Get the details of the variable's possible values. */
@@ -204,7 +204,7 @@ parse_specification (struct lexer *lexer, struct 
repeat_block *block)
        }
       if (count == 0)
        return false;
-      if (lex_token (lexer) != '/' && lex_token (lexer) != '.')
+      if (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
         {
           lex_error (lexer, NULL);
           return false;
@@ -230,9 +230,9 @@ parse_specification (struct lexer *lexer, struct 
repeat_block *block)
          return false;
        }
 
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
 
   return true;
 }
@@ -455,9 +455,9 @@ parse_numbers (struct lexer *lexer, struct repeat_macro 
*macro,
         add_replacement (ss_cstr (pool_asprintf (pool, "%g", i)),
                          macro, pool, &used, &allocated);
 
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
     }
-  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD);
 
   return used;
 }
@@ -487,9 +487,9 @@ parse_strings (struct lexer *lexer, struct repeat_macro 
*macro, struct pool *poo
       add_replacement (ss_cstr (string), macro, pool, &used, &allocated);
 
       lex_get (lexer);
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
     }
-  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD);
 
   return used;
 }
diff --git a/src/language/data-io/combine-files.c 
b/src/language/data-io/combine-files.c
index fd57bec..66163ee 100644
--- a/src/language/data-io/combine-files.c
+++ b/src/language/data-io/combine-files.c
@@ -170,7 +170,7 @@ combine_files (enum comb_command_type command,
 
   dict_set_case_limit (proc.dict, dict_get_case_limit (dataset_dict (ds)));
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   for (;;)
     {
       struct comb_file *file;
@@ -185,7 +185,7 @@ combine_files (enum comb_command_type command,
         }
       else
         break;
-      lex_match (lexer, '=');
+      lex_match (lexer, T_EQUALS);
 
       if (proc.n_files >= allocated_files)
         proc.files = x2nrealloc (proc.files, &allocated_files,
@@ -203,7 +203,7 @@ combine_files (enum comb_command_type command,
       file->in_name[0] = '\0';
       file->in_var = NULL;
 
-      if (lex_match (lexer, '*'))
+      if (lex_match (lexer, T_ASTERISK))
         {
           if (!proc_has_active_file (ds))
             {
@@ -230,7 +230,7 @@ combine_files (enum comb_command_type command,
             goto error;
         }
 
-      while (lex_match (lexer, '/'))
+      while (lex_match (lexer, T_SLASH))
         if (lex_match_id (lexer, "RENAME"))
           {
             if (!parse_dict_rename (lexer, file->dict))
@@ -238,7 +238,7 @@ combine_files (enum comb_command_type command,
           }
         else if (lex_match_id (lexer, "IN"))
           {
-            lex_match (lexer, '=');
+            lex_match (lexer, T_EQUALS);
             if (lex_token (lexer) != T_ID)
               {
                 lex_error (lexer, NULL);
@@ -263,7 +263,7 @@ combine_files (enum comb_command_type command,
       merge_dictionary (proc.dict, file);
     }
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       if (lex_match (lexer, T_BY))
        {
@@ -278,7 +278,7 @@ combine_files (enum comb_command_type command,
            }
           saw_by = true;
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           if (!parse_sort_criteria (lexer, proc.dict, &proc.by_vars,
                                     &by_vars, NULL))
            goto error;
@@ -322,7 +322,7 @@ combine_files (enum comb_command_type command,
               goto error;
             }
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           if (!lex_force_id (lexer))
             goto error;
           strcpy (first_name, lex_tokid (lexer));
@@ -336,7 +336,7 @@ combine_files (enum comb_command_type command,
               goto error;
             }
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           if (!lex_force_id (lexer))
             goto error;
           strcpy (last_name, lex_tokid (lexer));
@@ -362,7 +362,7 @@ combine_files (enum comb_command_type command,
          goto error;
        }
 
-      if (!lex_match (lexer, '/') && lex_token (lexer) != '.')
+      if (!lex_match (lexer, T_SLASH) && lex_token (lexer) != T_ENDCMD)
         {
           lex_end_of_command (lexer);
           goto error;
diff --git a/src/language/data-io/data-list.c b/src/language/data-io/data-list.c
index 80c9849..96a0c2b 100644
--- a/src/language/data-io/data-list.c
+++ b/src/language/data-io/data-list.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010 Free Software 
Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -92,11 +92,11 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds)
   table = -1;                /* Print table if nonzero, -1=undecided. */
   has_type = false;
 
-  while (lex_token (lexer) != '/')
+  while (lex_token (lexer) != T_SLASH)
     {
       if (lex_match_id (lexer, "FILE"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           fh_unref (fh);
          fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
@@ -104,7 +104,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "ENCODING"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (!lex_force_string (lexer))
            goto error;
 
@@ -114,17 +114,17 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "RECORDS"))
        {
-         lex_match (lexer, '=');
-         lex_match (lexer, '(');
+         lex_match (lexer, T_EQUALS);
+         lex_match (lexer, T_LPAREN);
          if (!lex_force_int (lexer))
            goto error;
           data_parser_set_records (parser, lex_integer (lexer));
          lex_get (lexer);
-         lex_match (lexer, ')');
+         lex_match (lexer, T_RPAREN);
        }
       else if (lex_match_id (lexer, "SKIP"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (!lex_force_int (lexer))
            goto error;
           data_parser_set_skip (parser, lex_integer (lexer));
@@ -144,7 +144,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds)
              goto error;
            }
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (!lex_force_id (lexer))
            goto error;
          end = dict_lookup_var (dict, lex_tokid (lexer));
@@ -186,11 +186,11 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds)
 
           if (data_parser_get_type (parser) == DP_DELIMITED)
             {
-              if (lex_match (lexer, '('))
+              if (lex_match (lexer, T_LPAREN))
                 {
                   struct string delims = DS_EMPTY_INITIALIZER;
 
-                  while (!lex_match (lexer, ')'))
+                  while (!lex_match (lexer, T_RPAREN))
                     {
                       int delim;
 
@@ -210,7 +210,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds)
                         }
                       ds_put_char (&delims, delim);
 
-                      lex_match (lexer, ',');
+                      lex_match (lexer, T_COMMA);
                     }
 
                   data_parser_set_empty_line_has_field (parser, true);
@@ -321,7 +321,7 @@ parse_fixed (struct lexer *lexer, struct dictionary *dict,
   int record = 0;
   int column = 1;
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       char **names;
       size_t name_cnt, name_idx;
@@ -415,7 +415,7 @@ parse_free (struct lexer *lexer, struct dictionary *dict,
             struct pool *tmp_pool, struct data_parser *parser)
 {
   lex_get (lexer);
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       struct fmt_spec input, output;
       char **name;
@@ -426,11 +426,11 @@ parse_free (struct lexer *lexer, struct dictionary *dict,
                                      &name, &name_cnt, PV_NONE))
        return false;
 
-      if (lex_match (lexer, '('))
+      if (lex_match (lexer, T_LPAREN))
        {
          if (!parse_format_specifier (lexer, &input)
               || !fmt_check_input (&input)
-              || !lex_force_match (lexer, ')'))
+              || !lex_force_match (lexer, T_RPAREN))
             return NULL;
 
           /* As a special case, N format is treated as F format
@@ -442,7 +442,7 @@ parse_free (struct lexer *lexer, struct dictionary *dict,
        }
       else
        {
-         lex_match (lexer, '*');
+         lex_match (lexer, T_ASTERISK);
           input = fmt_for_input (FMT_F, 8, 0);
          output = *settings_get_format ();
        }
diff --git a/src/language/data-io/data-reader.c 
b/src/language/data-io/data-reader.c
index 061505f..6c1f9b4 100644
--- a/src/language/data-io/data-reader.c
+++ b/src/language/data-io/data-reader.c
@@ -178,7 +178,7 @@ read_inline_record (struct dfm_reader *r)
     {
       r->flags |= DFM_SAW_BEGIN_DATA;
 
-      while (lex_token (r->lexer) == '.')
+      while (lex_token (r->lexer) == T_ENDCMD)
         lex_get (r->lexer);
       if (!lex_force_match_id (r->lexer, "BEGIN") || !lex_force_match_id 
(r->lexer, "DATA"))
         return false;
diff --git a/src/language/data-io/file-handle.q 
b/src/language/data-io/file-handle.q
index 71081b9..f72d60e 100644
--- a/src/language/data-io/file-handle.q
+++ b/src/language/data-io/file-handle.q
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -69,7 +69,7 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds)
     }
 
   lex_get (lexer);
-  if (!lex_force_match (lexer, '/'))
+  if (!lex_force_match (lexer, T_SLASH))
     return CMD_CASCADING_FAILURE;
 
   if (!parse_file_handle (lexer, ds, &cmd, NULL))
diff --git a/src/language/data-io/get-data.c b/src/language/data-io/get-data.c
index 94fadd6..72598d3 100644
--- a/src/language/data-io/get-data.c
+++ b/src/language/data-io/get-data.c
@@ -47,12 +47,12 @@ static int parse_get_psql (struct lexer *lexer, struct 
dataset *);
 int
 cmd_get_data (struct lexer *lexer, struct dataset *ds)
 {
-  lex_force_match (lexer, '/');
+  lex_force_match (lexer, T_SLASH);
 
   if (!lex_force_match_id (lexer, "TYPE"))
     return CMD_FAILURE;
 
-  lex_force_match (lexer, '=');
+  lex_force_match (lexer, T_EQUALS);
 
   if (lex_match_id (lexer, "GNM"))
     return parse_get_gnm (lexer, ds);
@@ -75,12 +75,12 @@ parse_get_psql (struct lexer *lexer, struct dataset *ds)
   psql.bsize = -1;
   ds_init_empty (&psql.sql);
 
-  lex_force_match (lexer, '/');
+  lex_force_match (lexer, T_SLASH);
 
   if (!lex_force_match_id (lexer, "CONNECT"))
     goto error;
 
-  lex_force_match (lexer, '=');
+  lex_force_match (lexer, T_EQUALS);
 
   if (!lex_force_string (lexer))
     goto error;
@@ -89,17 +89,17 @@ parse_get_psql (struct lexer *lexer, struct dataset *ds)
 
   lex_get (lexer);
 
-  while (lex_match (lexer, '/') )
+  while (lex_match (lexer, T_SLASH) )
     {
       if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          psql.str_width = lex_integer (lexer);
          lex_get (lexer);
        }
       else if ( lex_match_id (lexer, "BSIZE"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          psql.bsize = lex_integer (lexer);
          lex_get (lexer);
        }
@@ -109,7 +109,7 @@ parse_get_psql (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "SQL"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if ( ! lex_force_string (lexer) )
            goto error;
 
@@ -143,12 +143,12 @@ parse_get_gnm (struct lexer *lexer, struct dataset *ds)
 {
   struct gnumeric_read_info gri  = {NULL, NULL, NULL, 1, true, -1};
 
-  lex_force_match (lexer, '/');
+  lex_force_match (lexer, T_SLASH);
 
   if (!lex_force_match_id (lexer, "FILE"))
     goto error;
 
-  lex_force_match (lexer, '=');
+  lex_force_match (lexer, T_EQUALS);
 
   if (!lex_force_string (lexer))
     goto error;
@@ -157,16 +157,16 @@ parse_get_gnm (struct lexer *lexer, struct dataset *ds)
 
   lex_get (lexer);
 
-  while (lex_match (lexer, '/') )
+  while (lex_match (lexer, T_SLASH) )
     {
       if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          gri.asw = lex_integer (lexer);
        }
       else if (lex_match_id (lexer, "SHEET"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (lex_match_id (lexer, "NAME"))
            {
              if ( ! lex_force_string (lexer) )
@@ -184,7 +184,7 @@ parse_get_gnm (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "CELLRANGE"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
          if (lex_match_id (lexer, "FULL"))
            {
@@ -203,7 +203,7 @@ parse_get_gnm (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "READNAMES"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
          if ( lex_match_id (lexer, "ON"))
            {
@@ -278,11 +278,11 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
   enum data_parser_type type;
   bool has_type;
 
-  lex_force_match (lexer, '/');
+  lex_force_match (lexer, T_SLASH);
 
   if (!lex_force_match_id (lexer, "FILE"))
     goto error;
-  lex_force_match (lexer, '=');
+  lex_force_match (lexer, T_EQUALS);
   fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
   if (fh == NULL)
     goto error;
@@ -296,14 +296,14 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
 
   for (;;)
     {
-      if (!lex_force_match (lexer, '/'))
+      if (!lex_force_match (lexer, T_SLASH))
         goto error;
 
       if (lex_match_id (lexer, "ARRANGEMENT"))
         {
           bool ok;
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "FIXED"))
             ok = set_type (parser, "ARRANGEMENT=FIXED", DP_FIXED, &has_type);
           else if (lex_match_id (lexer, "DELIMITED"))
@@ -319,7 +319,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         }
       else if (lex_match_id (lexer, "FIRSTCASE"))
         {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           if (!lex_force_int (lexer))
             goto error;
           if (lex_integer (lexer) < 1)
@@ -334,7 +334,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         {
           if (!set_type (parser, "DELCASE", DP_DELIMITED, &has_type))
             goto error;
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "LINE"))
             data_parser_set_span (parser, false);
           else if (lex_match_id (lexer, "VARIABLES"))
@@ -357,7 +357,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         {
           if (!set_type (parser, "FIXCASE", DP_FIXED, &has_type))
             goto error;
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (!lex_force_int (lexer))
             goto error;
           if (lex_integer (lexer) < 1)
@@ -370,7 +370,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         }
       else if (lex_match_id (lexer, "IMPORTCASES"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match (lexer, T_ALL))
             {
               data_parser_set_case_limit (parser, -1);
@@ -410,7 +410,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
 
           if (!set_type (parser, "DELIMITERS", DP_DELIMITED, &has_type))
             goto error;
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
 
           if (!lex_force_string (lexer))
             goto error;
@@ -435,7 +435,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         {
           if (!set_type (parser, "QUALIFIERS", DP_DELIMITED, &has_type))
             goto error;
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
 
           if (!lex_force_string (lexer))
             goto error;
@@ -462,7 +462,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
           goto error;
         }
     }
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
 
   record = 1;
@@ -474,7 +474,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
       int fc, lc;
       struct variable *v;
 
-      while (type == DP_FIXED && lex_match (lexer, '/'))
+      while (type == DP_FIXED && lex_match (lexer, T_SLASH))
         {
           if (!lex_force_int (lexer))
             goto error;
@@ -539,7 +539,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         data_parser_add_fixed_field (parser, &input, var_get_case_index (v),
                                      name, record, fc);
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
 
   reader = dfm_open_reader (fh, lexer);
   if (reader == NULL)
diff --git a/src/language/data-io/get.c b/src/language/data-io/get.c
index cf59c8e..fea3881 100644
--- a/src/language/data-io/get.c
+++ b/src/language/data-io/get.c
@@ -75,11 +75,11 @@ parse_read_command (struct lexer *lexer, struct dataset 
*ds, enum reader_command
 
   for (;;)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
 
       if (lex_match_id (lexer, "FILE") || lex_is_string (lexer))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
           fh_unref (fh);
          fh = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
@@ -88,7 +88,7 @@ parse_read_command (struct lexer *lexer, struct dataset *ds, 
enum reader_command
        }
       else if (type == IMPORT_CMD && lex_match_id (lexer, "TYPE"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
          if (lex_match_id (lexer, "COMM"))
            type = PFM_COMM;
@@ -116,9 +116,9 @@ parse_read_command (struct lexer *lexer, struct dataset 
*ds, enum reader_command
 
   case_map_prepare_dict (dict);
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
       if (!parse_dict_trim (lexer, dict))
         goto error;
     }
diff --git a/src/language/data-io/inpt-pgm.c b/src/language/data-io/inpt-pgm.c
index 8cadb94..d6083f9 100644
--- a/src/language/data-io/inpt-pgm.c
+++ b/src/language/data-io/inpt-pgm.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -105,7 +105,7 @@ cmd_input_program (struct lexer *lexer, struct dataset *ds)
   bool saw_END_CASE = false;
 
   proc_discard_active_file (ds);
-  if (lex_token (lexer) != '.')
+  if (lex_token (lexer) != T_ENDCMD)
     return lex_end_of_command (lexer);
 
   inp = xmalloc (sizeof *inp);
@@ -245,7 +245,7 @@ int
 cmd_end_case (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   assert (in_input_program ());
-  if (lex_token (lexer) == '.')
+  if (lex_token (lexer) == T_ENDCMD)
     return CMD_END_CASE;
   return lex_end_of_command (lexer);
 }
@@ -277,11 +277,11 @@ cmd_reread (struct lexer *lexer, struct dataset *ds)
 
   fh = fh_get_default_handle ();
   e = NULL;
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       if (lex_match_id (lexer, "COLUMN"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
          if (e)
            {
@@ -296,7 +296,7 @@ cmd_reread (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "FILE"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           fh_unref (fh);
           fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
diff --git a/src/language/data-io/placement-parser.c 
b/src/language/data-io/placement-parser.c
index 4f1d062..e9fe337 100644
--- a/src/language/data-io/placement-parser.c
+++ b/src/language/data-io/placement-parser.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -70,7 +70,7 @@ parse_var_placements (struct lexer *lexer, struct pool *pool, 
size_t var_cnt, bo
   assert (var_cnt > 0);
   if (lex_is_number (lexer))
     return fixed_parse_columns (lexer, pool, var_cnt, for_input, formats, 
format_cnt);
-  else if (lex_match (lexer, '('))
+  else if (lex_match (lexer, T_LPAREN))
     {
       size_t assignment_cnt;
       size_t i;
@@ -123,14 +123,14 @@ fixed_parse_columns (struct lexer *lexer, struct pool 
*pool, size_t var_cnt, boo
     }
 
   /* Format specifier. */
-  if (lex_match (lexer, '('))
+  if (lex_match (lexer, T_LPAREN))
     {
       /* Get format type. */
       if (lex_token (lexer) == T_ID)
        {
          if (!parse_format_specifier_name (lexer, &format.type))
             return false;
-         lex_match (lexer, ',');
+         lex_match (lexer, T_COMMA);
        }
       else
        format.type = FMT_F;
@@ -144,7 +144,7 @@ fixed_parse_columns (struct lexer *lexer, struct pool 
*pool, size_t var_cnt, boo
       else
        format.d = 0;
 
-      if (!lex_force_match (lexer, ')'))
+      if (!lex_force_match (lexer, T_RPAREN))
        return false;
     }
   else
@@ -173,7 +173,7 @@ fixed_parse_fortran (struct lexer *lexer, struct pool 
*pool, bool for_input,
   size_t formats_used = 0;
 
   *formats = NULL;
-  while (!lex_match (lexer, ')'))
+  while (!lex_match (lexer, T_RPAREN))
     {
       struct fmt_spec f;
       struct fmt_spec *new_formats;
@@ -191,7 +191,7 @@ fixed_parse_fortran (struct lexer *lexer, struct pool 
*pool, bool for_input,
        count = 1;
 
       /* Parse format specifier. */
-      if (lex_match (lexer, '('))
+      if (lex_match (lexer, T_LPAREN))
         {
           /* Call ourselves recursively to handle parentheses. */
           if (!fixed_parse_fortran (lexer, pool, for_input,
@@ -202,7 +202,7 @@ fixed_parse_fortran (struct lexer *lexer, struct pool 
*pool, bool for_input,
         {
           new_formats = &f;
           new_format_cnt = 1;
-          if (lex_match (lexer, '/'))
+          if (lex_match (lexer, T_SLASH))
             f.type = PRS_TYPE_NEW_REC;
           else
             {
@@ -253,7 +253,7 @@ fixed_parse_fortran (struct lexer *lexer, struct pool 
*pool, bool for_input,
           formats_used += new_format_cnt;
         }
 
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
     }
 
   *format_cnt = formats_used;
@@ -335,7 +335,7 @@ parse_column_range (struct lexer *lexer, int base,
 
   /* Last column. */
   lex_negative_to_dash (lexer);
-  if (lex_match (lexer, '-'))
+  if (lex_match (lexer, T_DASH))
     {
       if (!parse_column (lexer, base, last_column))
         return false;
@@ -369,7 +369,7 @@ parse_column_range (struct lexer *lexer, int base,
 bool
 parse_record_placement (struct lexer *lexer, int *record, int *column)
 {
-  while (lex_match (lexer, '/'))
+  while (lex_match (lexer, T_SLASH))
     {
       if (lex_is_integer (lexer))
         {
diff --git a/src/language/data-io/print-space.c 
b/src/language/data-io/print-space.c
index 25bcc75..2fc932d 100644
--- a/src/language/data-io/print-space.c
+++ b/src/language/data-io/print-space.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -54,7 +54,7 @@ cmd_print_space (struct lexer *lexer, struct dataset *ds)
 
   if (lex_match_id (lexer, "OUTFILE"))
     {
-      lex_match (lexer, '=');
+      lex_match (lexer, T_EQUALS);
 
       handle = fh_parse (lexer, FH_REF_FILE);
       if (handle == NULL)
@@ -64,10 +64,10 @@ cmd_print_space (struct lexer *lexer, struct dataset *ds)
   else
     handle = NULL;
 
-  if (lex_token (lexer) != '.')
+  if (lex_token (lexer) != T_ENDCMD)
     {
       expr = expr_parse (lexer, ds, EXPR_NUMBER);
-      if (lex_token (lexer) != '.')
+      if (lex_token (lexer) != T_ENDCMD)
        {
          expr_free (expr);
          lex_error (lexer, _("expecting end of command"));
diff --git a/src/language/data-io/print.c b/src/language/data-io/print.c
index 164d992..0137233 100644
--- a/src/language/data-io/print.c
+++ b/src/language/data-io/print.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -150,11 +150,11 @@ internal_cmd_print (struct lexer *lexer, struct dataset 
*ds,
   tmp_pool = pool_create_subpool (trns->pool);
 
   /* Parse the command options. */
-  while (lex_token (lexer) != '/' && lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
     {
       if (lex_match_id (lexer, "OUTFILE"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
          fh = fh_parse (lexer, FH_REF_FILE);
          if (fh == NULL)
@@ -162,13 +162,13 @@ internal_cmd_print (struct lexer *lexer, struct dataset 
*ds,
        }
       else if (lex_match_id (lexer, "RECORDS"))
        {
-         lex_match (lexer, '=');
-         lex_match (lexer, '(');
+         lex_match (lexer, T_EQUALS);
+         lex_match (lexer, T_LPAREN);
          if (!lex_force_int (lexer))
            goto error;
          trns->record_cnt = lex_integer (lexer);
          lex_get (lexer);
-         lex_match (lexer, ')');
+         lex_match (lexer, T_RPAREN);
        }
       else if (lex_match_id (lexer, "TABLE"))
        print_table = true;
@@ -239,13 +239,13 @@ parse_specs (struct lexer *lexer, struct pool *tmp_pool, 
struct print_trns *trns
   int record = 0;
   int column = 1;
 
-  if (lex_token (lexer) == '.')
+  if (lex_token (lexer) == T_ENDCMD)
     {
       trns->record_cnt = 1;
       return true;
     }
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       bool ok;
 
@@ -260,7 +260,7 @@ parse_specs (struct lexer *lexer, struct pool *tmp_pool, 
struct print_trns *trns
       if (!ok)
        return 0;
 
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
     }
 
   if (trns->record_cnt != 0 && trns->record_cnt != record)
@@ -323,7 +323,7 @@ parse_variable_argument (struct lexer *lexer, const struct 
dictionary *dict,
                             &vars, &var_cnt, PV_DUPLICATE))
     return false;
 
-  if (lex_is_number (lexer) || lex_token (lexer) == '(')
+  if (lex_is_number (lexer) || lex_token (lexer) == T_LPAREN)
     {
       if (!parse_var_placements (lexer, tmp_pool, var_cnt, false,
                                  &formats, &format_cnt))
@@ -334,7 +334,7 @@ parse_variable_argument (struct lexer *lexer, const struct 
dictionary *dict,
     {
       size_t i;
 
-      lex_match (lexer, '*');
+      lex_match (lexer, T_ASTERISK);
 
       formats = pool_nmalloc (tmp_pool, var_cnt, sizeof *formats);
       format_cnt = var_cnt;
diff --git a/src/language/data-io/save-translate.c 
b/src/language/data-io/save-translate.c
index 4cf5e71..dcfdb83 100644
--- a/src/language/data-io/save-translate.c
+++ b/src/language/data-io/save-translate.c
@@ -84,7 +84,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
   case_map_prepare_dict (dict);
   dict_delete_scratch_vars (dict);
 
-  while (lex_match (lexer, '/'))
+  while (lex_match (lexer, T_SLASH))
     {
       if (lex_match_id (lexer, "OUTFILE"))
        {
@@ -94,7 +94,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
               goto error;
             }
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
          handle = fh_parse (lexer, FH_REF_FILE);
          if (handle == NULL)
@@ -108,7 +108,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
               goto error;
             }
 
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "CSV"))
             type = CSV_FILE;
           else if (lex_match_id (lexer, "TAB"))
@@ -125,7 +125,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
         include_var_names = true;
       else if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "IGNORE"))
             recode_user_missing = false;
           else if (lex_match_id (lexer, "RECODE"))
@@ -138,7 +138,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
         }
       else if (lex_match_id (lexer, "CELLS"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "VALUES"))
             use_value_labels = false;
           else if (lex_match_id (lexer, "LABELS"))
@@ -151,12 +151,12 @@ cmd_save_translate (struct lexer *lexer, struct dataset 
*ds)
         }
       else if (lex_match_id (lexer, "TEXTOPTIONS"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           for (;;)
             {
               if (lex_match_id (lexer, "DELIMITER"))
                 {
-                  lex_match (lexer, '=');
+                  lex_match (lexer, T_EQUALS);
                   if (!lex_force_string (lexer))
                     goto error;
                   if (ds_length (lex_tokstr (lexer)) != 1)
@@ -170,7 +170,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                 }
               else if (lex_match_id (lexer, "QUALIFIER"))
                 {
-                  lex_match (lexer, '=');
+                  lex_match (lexer, T_EQUALS);
                   if (!lex_force_string (lexer))
                     goto error;
                   if (ds_length (lex_tokstr (lexer)) != 1)
@@ -184,7 +184,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                 }
               else if (lex_match_id (lexer, "DECIMAL"))
                 {
-                  lex_match (lexer, '=');
+                  lex_match (lexer, T_EQUALS);
                   if (lex_match_id (lexer, "DOT"))
                     decimal = '.';
                   else if (lex_match_id (lexer, "COMMA"))
@@ -198,7 +198,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                 }
               else if (lex_match_id (lexer, "FORMAT"))
                 {
-                  lex_match (lexer, '=');
+                  lex_match (lexer, T_EQUALS);
                   if (lex_match_id (lexer, "PLAIN"))
                     use_print_formats = false;
                   else if (lex_match_id (lexer, "VARIABLE"))
@@ -216,7 +216,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
         }
       else if (lex_match_id (lexer, "UNSELECTED"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "RETAIN"))
             retain_unselected = true;
           else if (lex_match_id (lexer, "DELETE"))
diff --git a/src/language/data-io/save.c b/src/language/data-io/save.c
index 91fbc2f..5b51309 100644
--- a/src/language/data-io/save.c
+++ b/src/language/data-io/save.c
@@ -183,7 +183,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
   case_map_prepare_dict (dict);
   dict_delete_scratch_vars (dict);
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   for (;;)
     {
       if (lex_match_id (lexer, "OUTFILE"))
@@ -194,7 +194,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
               goto error;
             }
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
 
          handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
          if (handle == NULL)
@@ -206,7 +206,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
         {
           bool cw;
 
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "READONLY"))
             cw = false;
           else if (lex_match_id (lexer, "WRITEABLE"))
@@ -221,7 +221,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
         }
       else if (command_type == PROC_CMD && lex_match_id (lexer, "UNSELECTED"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "RETAIN"))
             *retain_unselected = true;
           else if (lex_match_id (lexer, "DELETE"))
@@ -241,7 +241,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
       else if (writer_type == SYSFILE_WRITER
                && lex_match_id (lexer, "VERSION"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (!lex_force_int (lexer))
             goto error;
           sysfile_opts.version = lex_integer (lexer);
@@ -249,7 +249,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
        }
       else if (writer_type == PORFILE_WRITER && lex_match_id (lexer, "TYPE"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "COMMUNICATIONS"))
             porfile_opts.type = PFM_COMM;
           else if (lex_match_id (lexer, "TAPE"))
@@ -262,7 +262,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
         }
       else if (writer_type == PORFILE_WRITER && lex_match_id (lexer, "DIGITS"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (!lex_force_int (lexer))
             goto error;
           porfile_opts.digits = lex_integer (lexer);
@@ -271,7 +271,7 @@ parse_write_command (struct lexer *lexer, struct dataset 
*ds,
       else if (!parse_dict_trim (lexer, dict))
         goto error;
 
-      if (!lex_match (lexer, '/'))
+      if (!lex_match (lexer, T_SLASH))
        break;
     }
   if (lex_end_of_command (lexer) != CMD_SUCCESS)
diff --git a/src/language/data-io/trim.c b/src/language/data-io/trim.c
index 5817fd0..be637c4 100644
--- a/src/language/data-io/trim.c
+++ b/src/language/data-io/trim.c
@@ -72,15 +72,15 @@ parse_dict_rename (struct lexer *lexer, struct dictionary 
*dict)
 
   int group;
 
-  lex_match (lexer, '=');
-  if (lex_token (lexer) != '(')
+  lex_match (lexer, T_EQUALS);
+  if (lex_token (lexer) != T_LPAREN)
     {
       struct variable *v;
 
       v = parse_variable (lexer, dict);
       if (v == NULL)
        return 0;
-      if (!lex_force_match (lexer, '=')
+      if (!lex_force_match (lexer, T_EQUALS)
          || !lex_force_id (lexer))
        return 0;
       if (dict_lookup_var (dict, lex_tokid (lexer)) != NULL)
@@ -103,13 +103,13 @@ parse_dict_rename (struct lexer *lexer, struct dictionary 
*dict)
   v = NULL;
   new_names = 0;
   group = 1;
-  while (lex_match (lexer, '('))
+  while (lex_match (lexer, T_LPAREN))
     {
       size_t old_nv = nv;
 
       if (!parse_variables (lexer, dict, &v, &nv, PV_NO_DUPLICATE | PV_APPEND))
        goto done;
-      if (!lex_match (lexer, '='))
+      if (!lex_match (lexer, T_EQUALS))
        {
          msg (SE, _("`=' expected after variable list."));
          goto done;
@@ -125,7 +125,7 @@ parse_dict_rename (struct lexer *lexer, struct dictionary 
*dict)
               nv - old_nv, nn - old_nv, group);
          goto done;
        }
-      if (!lex_force_match (lexer, ')'))
+      if (!lex_force_match (lexer, T_RPAREN))
        goto done;
       group++;
     }
@@ -155,7 +155,7 @@ parse_dict_drop (struct lexer *lexer, struct dictionary 
*dict)
   struct variable **v;
   size_t nv;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
     return false;
   dict_delete_vars (dict, v, nv);
@@ -179,7 +179,7 @@ parse_dict_keep (struct lexer *lexer, struct dictionary 
*dict)
   size_t nv;
   size_t i;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
     return false;
 
diff --git a/src/language/dictionary/apply-dictionary.c 
b/src/language/dictionary/apply-dictionary.c
index 3e1df58..3eb29e7 100644
--- a/src/language/dictionary/apply-dictionary.c
+++ b/src/language/dictionary/apply-dictionary.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -48,7 +48,7 @@ cmd_apply_dictionary (struct lexer *lexer, struct dataset *ds)
   int i;
 
   lex_match_id (lexer, "FROM");
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
   if (!handle)
diff --git a/src/language/dictionary/attributes.c 
b/src/language/dictionary/attributes.c
index ee309ae..35e6954 100644
--- a/src/language/dictionary/attributes.c
+++ b/src/language/dictionary/attributes.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -55,7 +55,7 @@ cmd_variable_attribute (struct lexer *lexer, struct dataset 
*ds)
       bool ok;
 
       if (!lex_force_match_id (lexer, "VARIABLES")
-          || !lex_force_match (lexer, '=')
+          || !lex_force_match (lexer, T_EQUALS)
           || !parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
                                PV_NONE))
         return CMD_FAILURE;
@@ -70,7 +70,7 @@ cmd_variable_attribute (struct lexer *lexer, struct dataset 
*ds)
       if (!ok)
         return CMD_FAILURE;
     }
-  while (lex_match (lexer, '/'));
+  while (lex_match (lexer, T_SLASH));
 
   return lex_end_of_command (lexer);
 }
@@ -80,7 +80,7 @@ match_subcommand (struct lexer *lexer, const char *keyword)
 {
   if (lex_token (lexer) == T_ID
       && lex_id_match (ss_cstr (lex_tokid (lexer)), ss_cstr (keyword))
-      && lex_look_ahead (lexer) == '=') 
+      && lex_look_ahead (lexer) == T_EQUALS)
     {
       lex_get (lexer);          /* Skip keyword. */
       lex_get (lexer);          /* Skip '='. */
@@ -99,7 +99,7 @@ parse_attribute_name (struct lexer *lexer, char 
name[VAR_NAME_LEN + 1],
   strcpy (name, lex_tokid (lexer));
   lex_get (lexer);
 
-  if (lex_match (lexer, '[')) 
+  if (lex_match (lexer, T_LBRACK))
     {
       if (!lex_force_int (lexer))
         return false;
@@ -110,7 +110,7 @@ parse_attribute_name (struct lexer *lexer, char 
name[VAR_NAME_LEN + 1],
         }
       *index = lex_integer (lexer);
       lex_get (lexer);
-      if (!lex_force_match (lexer, ']'))
+      if (!lex_force_match (lexer, T_RBRACK))
         return false;
     }
   else
@@ -126,7 +126,7 @@ add_attribute (struct lexer *lexer, struct attrset **sets, 
size_t n)
   char *value;
 
   if (!parse_attribute_name (lexer, name, &index)
-      || !lex_force_match (lexer, '(')
+      || !lex_force_match (lexer, T_LPAREN)
       || !lex_force_string (lexer))
     return false;
   value = ds_cstr (lex_tokstr (lexer));
@@ -143,7 +143,7 @@ add_attribute (struct lexer *lexer, struct attrset **sets, 
size_t n)
     }
 
   lex_get (lexer);
-  return lex_force_match (lexer, ')');
+  return lex_force_match (lexer, T_RPAREN);
 }
 
 static bool
@@ -195,6 +195,6 @@ parse_attributes (struct lexer *lexer, struct attrset 
**sets, size_t n)
             : delete_attribute (lexer, sets, n)))
         return CMD_FAILURE;
     }
-  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD);
   return CMD_SUCCESS;
 }
diff --git a/src/language/dictionary/formats.c 
b/src/language/dictionary/formats.c
index 640246c..de58615 100644
--- a/src/language/dictionary/formats.c
+++ b/src/language/dictionary/formats.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -78,14 +78,14 @@ internal_cmd_formats (struct lexer *lexer, struct dataset 
*ds, int which)
 
   for (;;)
     {
-      if (lex_token (lexer) == '.')
+      if (lex_token (lexer) == T_ENDCMD)
        break;
 
       if (!parse_variables (lexer, dataset_dict (ds), &v, &cv, PV_NUMERIC))
        return CMD_FAILURE;
       type = var_get_type (v[0]);
 
-      if (!lex_match (lexer, '('))
+      if (!lex_match (lexer, T_LPAREN))
        {
          msg (SE, _("`(' expected after variable list."));
          goto fail;
@@ -95,7 +95,7 @@ internal_cmd_formats (struct lexer *lexer, struct dataset 
*ds, int which)
           || !fmt_check_type_compat (&f, VAL_NUMERIC))
        goto fail;
 
-      if (!lex_match (lexer, ')'))
+      if (!lex_match (lexer, T_RPAREN))
        {
          msg (SE, _("`)' expected after output format."));
          goto fail;
diff --git a/src/language/dictionary/missing-values.c 
b/src/language/dictionary/missing-values.c
index 912c58c..429fefa 100644
--- a/src/language/dictionary/missing-values.c
+++ b/src/language/dictionary/missing-values.c
@@ -44,20 +44,20 @@ cmd_missing_values (struct lexer *lexer, struct dataset *ds)
   int retval = CMD_FAILURE;
   bool deferred_errors = false;
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       size_t i;
 
       if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         goto done;
 
-      if (!lex_force_match (lexer, '('))
+      if (!lex_force_match (lexer, T_LPAREN))
         goto done;
 
       for (i = 0; i < nv; i++)
         var_clear_missing_values (v[i]);
 
-      if (!lex_match (lexer, ')'))
+      if (!lex_match (lexer, T_RPAREN))
         {
           struct missing_values mv;
 
@@ -75,7 +75,7 @@ cmd_missing_values (struct lexer *lexer, struct dataset *ds)
           if (var_is_numeric (v[0]))
             {
               mv_init (&mv, 0);
-              while (!lex_match (lexer, ')'))
+              while (!lex_match (lexer, T_RPAREN))
                 {
                   enum fmt_type type = var_get_print_format (v[0])->type;
                   double x, y;
@@ -90,13 +90,13 @@ cmd_missing_values (struct lexer *lexer, struct dataset *ds)
                   if (!ok)
                     deferred_errors = true;
 
-                  lex_match (lexer, ',');
+                  lex_match (lexer, T_COMMA);
                 }
             }
           else
             {
               mv_init (&mv, MV_MAX_STRING);
-              while (!lex_match (lexer, ')'))
+              while (!lex_match (lexer, T_RPAREN))
                 {
                   uint8_t value[MV_MAX_STRING];
                   size_t length;
@@ -122,7 +122,7 @@ cmd_missing_values (struct lexer *lexer, struct dataset *ds)
                     deferred_errors = true;
 
                   lex_get (lexer);
-                  lex_match (lexer, ',');
+                  lex_match (lexer, T_COMMA);
                 }
             }
 
@@ -142,7 +142,7 @@ cmd_missing_values (struct lexer *lexer, struct dataset *ds)
           mv_destroy (&mv);
         }
 
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
       free (v);
       v = NULL;
     }
diff --git a/src/language/dictionary/modify-variables.c 
b/src/language/dictionary/modify-variables.c
index 8de2ee1..6afd321 100644
--- a/src/language/dictionary/modify-variables.c
+++ b/src/language/dictionary/modify-variables.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -100,7 +100,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
   vm.drop_cnt = 0;
 
   /* Parse each subcommand. */
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   for (;;)
     {
       if (lex_match_id (lexer, "REORDER"))
@@ -115,7 +115,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
            }
          already_encountered |= 1;
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          do
            {
               struct ordering ordering;
@@ -129,7 +129,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
              else if (lex_match_id (lexer, "ALPHA"))
                ordering.positional = 0;
 
-             if (lex_match (lexer, T_ALL) || lex_token (lexer) == '/' || 
lex_token (lexer) == '.')
+             if (lex_match (lexer, T_ALL) || lex_token (lexer) == T_SLASH || 
lex_token (lexer) == T_ENDCMD)
                {
                  if (prev_nv != 0)
                    {
@@ -141,7 +141,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                }
              else
                {
-                 if (!lex_match (lexer, '('))
+                 if (!lex_match (lexer, T_LPAREN))
                    {
                      msg (SE, _("`(' expected on %s subcommand."), "REORDER");
                      free (v);
@@ -153,7 +153,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                      free (v);
                      goto done;
                    }
-                 if (!lex_match (lexer, ')'))
+                 if (!lex_match (lexer, T_RPAREN))
                    {
                      msg (SE, _("`)' expected following variable names on "
                           "REORDER subcommand."));
@@ -164,7 +164,8 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
              sort (&v[prev_nv], nv - prev_nv, sizeof *v,
                     compare_variables_given_ordering, &ordering);
            }
-         while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
+         while (lex_token (lexer) != T_SLASH
+                 && lex_token (lexer) != T_ENDCMD);
 
          vm.reorder_vars = v;
           vm.reorder_cnt = nv;
@@ -178,13 +179,13 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
            }
          already_encountered |= 2;
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          do
            {
              size_t prev_nv_1 = vm.rename_cnt;
              size_t prev_nv_2 = vm.rename_cnt;
 
-             if (!lex_match (lexer, '('))
+             if (!lex_match (lexer, T_LPAREN))
                {
                  msg (SE, _("`(' expected on %s subcommand."), "RENAME");
                  goto done;
@@ -193,7 +194,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                                    &vm.rename_vars, &vm.rename_cnt,
                                    PV_APPEND | PV_NO_DUPLICATE))
                goto done;
-             if (!lex_match (lexer, '='))
+             if (!lex_match (lexer, T_EQUALS))
                {
                  msg (SE, _("`=' expected between lists of new and old 
variable "
                       "names on RENAME subcommand."));
@@ -213,14 +214,15 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                  vm.new_names = NULL;
                  goto done;
                }
-             if (!lex_match (lexer, ')'))
+             if (!lex_match (lexer, T_RPAREN))
                {
                  msg (SE, _("`)' expected after variable lists on RENAME "
                       "subcommand."));
                  goto done;
                }
            }
-         while (lex_token (lexer) != '.' && lex_token (lexer) != '/');
+         while (lex_token (lexer) != T_ENDCMD
+                 && lex_token (lexer) != T_SLASH);
        }
       else if (lex_match_id (lexer, "KEEP"))
        {
@@ -235,7 +237,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
            }
          already_encountered |= 4;
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (!parse_variables (lexer, dataset_dict (ds), &keep_vars, 
&keep_cnt, PV_NONE))
            goto done;
 
@@ -279,7 +281,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
            }
          already_encountered |= 4;
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (!parse_variables (lexer, dataset_dict (ds), &drop_vars, 
&drop_cnt, PV_NONE))
            goto done;
           vm.drop_vars = drop_vars;
@@ -304,9 +306,9 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
          goto done;
        }
 
-      if (lex_token (lexer) == '.')
+      if (lex_token (lexer) == T_ENDCMD)
        break;
-      if (lex_token (lexer) != '/')
+      if (lex_token (lexer) != T_SLASH)
        {
          msg (SE, _("`/' or `.' expected."));
          goto done;
diff --git a/src/language/dictionary/mrsets.c b/src/language/dictionary/mrsets.c
index 96f1a11..0708e89 100644
--- a/src/language/dictionary/mrsets.c
+++ b/src/language/dictionary/mrsets.c
@@ -47,7 +47,7 @@ cmd_mrsets (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  while (lex_match (lexer, '/'))
+  while (lex_match (lexer, T_SLASH))
     {
       bool ok;
 
@@ -87,11 +87,11 @@ parse_group (struct lexer *lexer, struct dictionary *dict,
 
   labelsource_varlabel = false;
   has_value = false;
-  while (lex_token (lexer) != '/' && lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
     {
       if (lex_match_id (lexer, "NAME"))
         {
-          if (!lex_force_match (lexer, '=') || !lex_force_id (lexer))
+          if (!lex_force_match (lexer, T_EQUALS) || !lex_force_id (lexer))
             goto error;
           if (lex_tokid (lexer)[0] != '$')
             {
@@ -107,7 +107,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict,
         }
       else if (lex_match_id (lexer, "VARIABLES"))
         {
-          if (!lex_force_match (lexer, '='))
+          if (!lex_force_match (lexer, T_EQUALS))
             goto error;
 
           free (mrset->vars);
@@ -125,7 +125,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict,
         }
       else if (lex_match_id (lexer, "LABEL"))
         {
-          if (!lex_force_match (lexer, '=') || !lex_force_string (lexer))
+          if (!lex_force_match (lexer, T_EQUALS) || !lex_force_string (lexer))
             goto error;
 
           free (mrset->label);
@@ -134,7 +134,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict,
         }
       else if (type == MRSET_MD && lex_match_id (lexer, "LABELSOURCE"))
         {
-          if (!lex_force_match (lexer, '=')
+          if (!lex_force_match (lexer, T_EQUALS)
               || !lex_force_match_id (lexer, "VARLABEL"))
             goto error;
 
@@ -142,7 +142,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict,
         }
       else if (type == MRSET_MD && lex_match_id (lexer, "VALUE"))
         {
-          if (!lex_force_match (lexer, '='))
+          if (!lex_force_match (lexer, T_EQUALS))
             goto error;
 
           has_value = true;
@@ -182,7 +182,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict,
         }
       else if (type == MRSET_MD && lex_match_id (lexer, "CATEGORYLABELS"))
         {
-          if (!lex_force_match (lexer, '='))
+          if (!lex_force_match (lexer, T_EQUALS))
             goto error;
 
           if (lex_match_id (lexer, "VARLABELS"))
@@ -469,13 +469,14 @@ static bool
 parse_mrset_names (struct lexer *lexer, struct dictionary *dict,
                    struct stringi_set *mrset_names)
 {
-  if (!lex_force_match_id (lexer, "NAME") || !lex_force_match (lexer, '='))
+  if (!lex_force_match_id (lexer, "NAME")
+      || !lex_force_match (lexer, T_EQUALS))
     return false;
 
   stringi_set_init (mrset_names);
-  if (lex_match (lexer, '['))
+  if (lex_match (lexer, T_LBRACK))
     {
-      while (!lex_match (lexer, ']'))
+      while (!lex_match (lexer, T_RBRACK))
         {
           if (!lex_force_id (lexer))
             return false;
diff --git a/src/language/dictionary/numeric.c 
b/src/language/dictionary/numeric.c
index 41f3c79..946c35c 100644
--- a/src/language/dictionary/numeric.c
+++ b/src/language/dictionary/numeric.c
@@ -53,7 +53,7 @@ cmd_numeric (struct lexer *lexer, struct dataset *ds)
        return CMD_FAILURE;
 
       /* Get the optional format specification. */
-      if (lex_match (lexer, '('))
+      if (lex_match (lexer, T_LPAREN))
        {
          if (!parse_format_specifier (lexer, &f))
            goto fail;
@@ -69,7 +69,7 @@ cmd_numeric (struct lexer *lexer, struct dataset *ds)
              goto fail;
            }
 
-         if (!lex_match (lexer, ')'))
+         if (!lex_match (lexer, T_RPAREN))
            {
              msg (SE, _("`)' expected after output format."));
              goto fail;
@@ -96,7 +96,7 @@ cmd_numeric (struct lexer *lexer, struct dataset *ds)
        free (v[i]);
       free (v);
     }
-  while (lex_match (lexer, '/'));
+  while (lex_match (lexer, T_SLASH));
 
   return lex_end_of_command (lexer);
 
@@ -130,9 +130,9 @@ cmd_string (struct lexer *lexer, struct dataset *ds)
       if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NO_DUPLICATE))
        return CMD_FAILURE;
 
-      if (!lex_force_match (lexer, '(')
+      if (!lex_force_match (lexer, T_LPAREN)
           || !parse_format_specifier (lexer, &f)
-          || !lex_force_match (lexer, ')'))
+          || !lex_force_match (lexer, T_RPAREN))
        goto fail;
       if (!fmt_is_string (f.type))
        {
@@ -162,7 +162,7 @@ cmd_string (struct lexer *lexer, struct dataset *ds)
        free (v[i]);
       free (v);
     }
-  while (lex_match (lexer, '/'));
+  while (lex_match (lexer, T_SLASH));
 
   return lex_end_of_command (lexer);
 
diff --git a/src/language/dictionary/rename-variables.c 
b/src/language/dictionary/rename-variables.c
index ecd13aa..79ab997 100644
--- a/src/language/dictionary/rename-variables.c
+++ b/src/language/dictionary/rename-variables.c
@@ -53,7 +53,7 @@ cmd_rename_variables (struct lexer *lexer, struct dataset *ds)
       size_t prev_nv_1 = rename_cnt;
       size_t prev_nv_2 = rename_cnt;
 
-      if (!lex_match (lexer, '('))
+      if (!lex_match (lexer, T_LPAREN))
        {
          msg (SE, _("`(' expected."));
          goto lossage;
@@ -61,7 +61,7 @@ cmd_rename_variables (struct lexer *lexer, struct dataset *ds)
       if (!parse_variables (lexer, dataset_dict (ds), &rename_vars, 
&rename_cnt,
                            PV_APPEND | PV_NO_DUPLICATE))
        goto lossage;
-      if (!lex_match (lexer, '='))
+      if (!lex_match (lexer, T_EQUALS))
        {
          msg (SE, _("`=' expected between lists of new and old variable 
names."));
          goto lossage;
@@ -82,13 +82,13 @@ cmd_rename_variables (struct lexer *lexer, struct dataset 
*ds)
          rename_new_names = NULL;
          goto lossage;
        }
-      if (!lex_match (lexer, ')'))
+      if (!lex_match (lexer, T_RPAREN))
        {
          msg (SE, _("`)' expected after variable names."));
          goto lossage;
        }
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
 
   if (!dict_rename_vars (dataset_dict (ds),
                          rename_vars, rename_new_names, rename_cnt,
diff --git a/src/language/dictionary/sys-file-info.c 
b/src/language/dictionary/sys-file-info.c
index 24130cb..89523e2 100644
--- a/src/language/dictionary/sys-file-info.c
+++ b/src/language/dictionary/sys-file-info.c
@@ -75,7 +75,7 @@ cmd_sysfile_info (struct lexer *lexer, struct dataset *ds 
UNUSED)
   int r, i;
 
   lex_match_id (lexer, "FILE");
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   h = fh_parse (lexer, FH_REF_FILE);
   if (!h)
@@ -247,11 +247,11 @@ cmd_display (struct lexer *lexer, struct dataset *ds)
                 break;
               }
 
-          lex_match (lexer, '/');
+          lex_match (lexer, T_SLASH);
           lex_match_id (lexer, "VARIABLES");
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
 
-          if (lex_token (lexer) != '.')
+          if (lex_token (lexer) != T_ENDCMD)
             {
               if (!parse_variables_const (lexer, dataset_dict (ds), &vl, &n,
                                           PV_NONE))
diff --git a/src/language/dictionary/value-labels.c 
b/src/language/dictionary/value-labels.c
index 226518f..0fdd7a2 100644
--- a/src/language/dictionary/value-labels.c
+++ b/src/language/dictionary/value-labels.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -64,9 +64,9 @@ do_value_labels (struct lexer *lexer, const struct dictionary 
*dict, bool erase)
   size_t var_cnt;         /* Number of variables. */
   int parse_err=0;        /* true if error parsing variables */
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       parse_err = !parse_variables (lexer, dict, &vars, &var_cnt,
                                    PV_SAME_WIDTH);
@@ -77,11 +77,11 @@ do_value_labels (struct lexer *lexer, const struct 
dictionary *dict, bool erase)
        }
       if (erase)
         erase_labels (vars, var_cnt);
-      while (lex_token (lexer) != '/' && lex_token (lexer) != '.')
+      while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
        if (!get_label (lexer, vars, var_cnt))
           goto lossage;
 
-      if (lex_token (lexer) != '/')
+      if (lex_token (lexer) != T_SLASH)
        {
           free (vars);
           break;
@@ -133,7 +133,7 @@ get_label (struct lexer *lexer, struct variable **vars, 
size_t var_cnt)
           value_destroy (&value, width);
           return 0;
         }
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
 
       /* Set label. */
       if (lex_token (lexer) != T_ID && !lex_force_string (lexer))
@@ -157,9 +157,9 @@ get_label (struct lexer *lexer, struct variable **vars, 
size_t var_cnt)
       value_destroy (&value, width);
 
       lex_get (lexer);
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
     }
-  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD);
 
   return 1;
 }
diff --git a/src/language/dictionary/variable-display.c 
b/src/language/dictionary/variable-display.c
index 83df065..8351ff6 100644
--- a/src/language/dictionary/variable-display.c
+++ b/src/language/dictionary/variable-display.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -51,7 +51,7 @@ cmd_variable_alignment (struct lexer *lexer, struct dataset 
*ds)
       if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match (lexer, '(') )
+      if ( lex_force_match (lexer, T_LPAREN) )
        {
          if ( lex_match_id (lexer, "LEFT"))
            align = ALIGN_LEFT;
@@ -65,7 +65,7 @@ cmd_variable_alignment (struct lexer *lexer, struct dataset 
*ds)
               return CMD_FAILURE;
             }
 
-         lex_force_match (lexer, ')');
+         lex_force_match (lexer, T_RPAREN);
        }
       else
         {
@@ -76,12 +76,12 @@ cmd_variable_alignment (struct lexer *lexer, struct dataset 
*ds)
       for( i = 0 ; i < nv ; ++i )
         var_set_alignment (v[i], align);
 
-      while (lex_token (lexer) == '/')
+      while (lex_token (lexer) == T_SLASH)
        lex_get (lexer);
       free (v);
 
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
   return CMD_SUCCESS;
 }
 
@@ -102,14 +102,14 @@ cmd_variable_width (struct lexer *lexer, struct dataset 
*ds)
       if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if (!lex_force_match (lexer, '(') || !lex_force_int (lexer))
+      if (!lex_force_match (lexer, T_LPAREN) || !lex_force_int (lexer))
         {
           free (v);
           return CMD_FAILURE;
         }
       width = lex_integer (lexer);
       lex_get (lexer);
-      if (!lex_force_match (lexer, ')'))
+      if (!lex_force_match (lexer, T_RPAREN))
         {
           free (v);
           return CMD_FAILURE;
@@ -126,12 +126,12 @@ cmd_variable_width (struct lexer *lexer, struct dataset 
*ds)
       for( i = 0 ; i < nv ; ++i )
         var_set_display_width (v[i], width);
 
-      while (lex_token (lexer) == '/')
+      while (lex_token (lexer) == T_SLASH)
        lex_get (lexer);
       free (v);
 
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
   return CMD_SUCCESS;
 }
 
@@ -149,7 +149,7 @@ cmd_variable_level (struct lexer *lexer, struct dataset *ds)
       if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match (lexer, '(') )
+      if ( lex_force_match (lexer, T_LPAREN) )
        {
          if ( lex_match_id (lexer, "SCALE"))
            level = MEASURE_SCALE;
@@ -163,7 +163,7 @@ cmd_variable_level (struct lexer *lexer, struct dataset *ds)
               return CMD_FAILURE;
             }
 
-         lex_force_match (lexer, ')');
+         lex_force_match (lexer, T_RPAREN);
        }
       else
         {
@@ -175,11 +175,11 @@ cmd_variable_level (struct lexer *lexer, struct dataset 
*ds)
        var_set_measure (v[i], level);
 
 
-      while (lex_token (lexer) == '/')
+      while (lex_token (lexer) == T_SLASH)
        lex_get (lexer);
       free (v);
 
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
   return CMD_SUCCESS;
 }
diff --git a/src/language/dictionary/variable-label.c 
b/src/language/dictionary/variable-label.c
index fbf7e20..e6bd622 100644
--- a/src/language/dictionary/variable-label.c
+++ b/src/language/dictionary/variable-label.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -63,11 +63,11 @@ cmd_variable_labels (struct lexer *lexer, struct dataset 
*ds)
       ds_destroy (&label);
 
       lex_get (lexer);
-      while (lex_token (lexer) == '/')
+      while (lex_token (lexer) == T_SLASH)
        lex_get (lexer);
       free (v);
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
   return CMD_SUCCESS;
 }
 
diff --git a/src/language/dictionary/vector.c b/src/language/dictionary/vector.c
index 1a616ab..a884331 100644
--- a/src/language/dictionary/vector.c
+++ b/src/language/dictionary/vector.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -80,12 +80,12 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
           vectors[vector_cnt++] = pool_strdup (pool, lex_tokid (lexer));
 
          lex_get (lexer);
-         lex_match (lexer, ',');
+         lex_match (lexer, T_COMMA);
        }
 
       /* Now that we have the names it's time to check for the short
          or long forms. */
-      if (lex_match (lexer, '='))
+      if (lex_match (lexer, T_EQUALS))
        {
          /* Long form. */
           struct variable **v;
@@ -104,7 +104,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
 
           dict_create_vector (dict, vectors[0], v, nv);
        }
-      else if (lex_match (lexer, '('))
+      else if (lex_match (lexer, T_LPAREN))
        {
           /* Short form. */
           struct fmt_spec format;
@@ -118,7 +118,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
           var_cnt = 0;
           format = fmt_for_output (FMT_F, 8, 2);
           seen_format = false;
-          while (!lex_match (lexer, ')'))
+          while (!lex_match (lexer, T_RPAREN))
             {
               if (lex_is_integer (lexer) && var_cnt == 0)
                 {
@@ -143,7 +143,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
                   lex_error (lexer, NULL);
                   goto fail;
                 }
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
             }
           if (var_cnt == 0)
             {
@@ -195,7 +195,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
          goto fail;
        }
     }
-  while (lex_match (lexer, '/'));
+  while (lex_match (lexer, T_SLASH));
 
   pool_destroy (pool);
   return lex_end_of_command (lexer);
diff --git a/src/language/expressions/evaluate.c 
b/src/language/expressions/evaluate.c
index 65404b4..9bcfe31 100644
--- a/src/language/expressions/evaluate.c
+++ b/src/language/expressions/evaluate.c
@@ -125,7 +125,7 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset 
*dsother UNUSED)
         optimize = 0;
       else if (lex_match_id (lexer, "POSTFIX"))
         dump_postfix = 1;
-      else if (lex_match (lexer, '('))
+      else if (lex_match (lexer, T_LPAREN))
         {
           char name[VAR_NAME_LEN + 1];
           struct variable *v;
@@ -137,7 +137,7 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset 
*dsother UNUSED)
           strcpy (name, lex_tokid (lexer));
 
           lex_get (lexer);
-          if (!lex_force_match (lexer, '='))
+          if (!lex_force_match (lexer, T_EQUALS))
             goto done;
 
           if (lex_is_number (lexer))
@@ -172,15 +172,15 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset 
*dsother UNUSED)
           if (!parse_value (lexer, case_data_rw (c, v), var_get_width (v)))
             NOT_REACHED ();
 
-          if (!lex_force_match (lexer, ')'))
+          if (!lex_force_match (lexer, T_RPAREN))
             goto done;
         }
       else
         break;
     }
-  if (lex_token (lexer) != '/')
+  if (lex_token (lexer) != T_SLASH)
     {
-      lex_force_match (lexer, '/');
+      lex_force_match (lexer, T_SLASH);
       goto done;
     }
 
diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c
index f2b4f1c..90de07f 100644
--- a/src/language/expressions/parse.c
+++ b/src/language/expressions/parse.c
@@ -500,7 +500,7 @@ match_operator (struct lexer *lexer, const struct operator 
ops[], size_t op_cnt,
 
   for (op = ops; op < ops + op_cnt; op++)
     {
-      if (op->token == '-')
+      if (op->token == T_DASH)
         lex_negative_to_dash (lexer);
       if (lex_match (lexer, op->token))
         {
@@ -665,7 +665,7 @@ parse_rel (struct lexer *lexer, struct expression *e)
       {
         static const struct operator ops[] =
           {
-            { '=', OP_EQ, "numeric equality (`=')" },
+            { T_EQUALS, OP_EQ, "numeric equality (`=')" },
             { T_EQ, OP_EQ, "numeric equality (`EQ')" },
             { T_GE, OP_GE, "numeric greater-than-or-equal-to (`>=')" },
             { T_GT, OP_GT, "numeric greater than (`>')" },
@@ -683,7 +683,7 @@ parse_rel (struct lexer *lexer, struct expression *e)
       {
         static const struct operator ops[] =
           {
-            { '=', OP_EQ_STRING, "string equality (`=')" },
+            { T_EQUALS, OP_EQ_STRING, "string equality (`=')" },
             { T_EQ, OP_EQ_STRING, "string equality (`EQ')" },
             { T_GE, OP_GE_STRING, "string greater-than-or-equal-to (`>=')" },
             { T_GT, OP_GT_STRING, "string greater than (`>')" },
@@ -708,8 +708,8 @@ parse_add (struct lexer *lexer, struct expression *e)
 {
   static const struct operator ops[] =
     {
-      { '+', OP_ADD, "addition (`+')" },
-      { '-', OP_SUB, "subtraction (`-')" },
+      { T_PLUS, OP_ADD, "addition (`+')" },
+      { T_DASH, OP_SUB, "subtraction (`-')" },
     };
 
   return parse_binary_operators (lexer, e, parse_mul (lexer, e),
@@ -723,8 +723,8 @@ parse_mul (struct lexer *lexer, struct expression *e)
 {
   static const struct operator ops[] =
     {
-      { '*', OP_MUL, "multiplication (`*')" },
-      { '/', OP_DIV, "division (`/')" },
+      { T_ASTERISK, OP_MUL, "multiplication (`*')" },
+      { T_SLASH, OP_DIV, "division (`/')" },
     };
 
   return parse_binary_operators (lexer, e, parse_neg (lexer, e),
@@ -736,7 +736,7 @@ parse_mul (struct lexer *lexer, struct expression *e)
 static union any_node *
 parse_neg (struct lexer *lexer, struct expression *e)
 {
-  static const struct operator op = { '-', OP_NEG, "negation (`-')" };
+  static const struct operator op = { T_DASH, OP_NEG, "negation (`-')" };
   return parse_inverting_unary_operator (lexer, e, &op, parse_exp);
 }
 
@@ -824,7 +824,7 @@ parse_primary (struct lexer *lexer, struct expression *e)
   switch (lex_token (lexer))
     {
     case T_ID:
-      if (lex_look_ahead (lexer) == '(')
+      if (lex_look_ahead (lexer) == T_LPAREN)
         {
           /* An identifier followed by a left parenthesis may be
              a vector element reference.  If not, it's a function
@@ -881,12 +881,12 @@ parse_primary (struct lexer *lexer, struct expression *e)
        return node;
       }
 
-    case '(':
+    case T_LPAREN:
       {
         union any_node *node;
        lex_get (lexer);
        node = parse_or (lexer, e);
-       if (node != NULL && !lex_force_match (lexer, ')'))
+       if (node != NULL && !lex_force_match (lexer, T_RPAREN))
           return NULL;
         return node;
       }
@@ -913,12 +913,12 @@ parse_vector_element (struct lexer *lexer, struct 
expression *e)
   /* Skip left parenthesis token.
      The caller must have verified that the lookahead is a left
      parenthesis. */
-  assert (lex_token (lexer) == '(');
+  assert (lex_token (lexer) == T_LPAREN);
   lex_get (lexer);
 
   element = parse_or (lexer, e);
   if (!type_coercion (e, OP_number, &element, "vector indexing")
-      || !lex_match (lexer, ')'))
+      || !lex_match (lexer, T_RPAREN))
     return NULL;
 
   return expr_allocate_binary (e, (vector_get_type (vector) == VAL_NUMERIC
@@ -1207,7 +1207,7 @@ parse_function (struct lexer *lexer, struct expression *e)
     }
 
   lex_get (lexer);
-  if (!lex_force_match (lexer, '('))
+  if (!lex_force_match (lexer, T_LPAREN))
     {
       ds_destroy (&func_name);
       return NULL;
@@ -1215,11 +1215,11 @@ parse_function (struct lexer *lexer, struct expression 
*e)
 
   args = NULL;
   arg_cnt = arg_cap = 0;
-  if (lex_token (lexer) != ')')
+  if (lex_token (lexer) != T_RPAREN)
     for (;;)
       {
         if (lex_token (lexer) == T_ID
-            && toupper (lex_look_ahead (lexer)) == 'T')
+            && toupper (lex_look_ahead (lexer)) == T_ID)
           {
             const struct variable **vars;
             size_t var_cnt;
@@ -1240,9 +1240,9 @@ parse_function (struct lexer *lexer, struct expression *e)
 
             add_arg (&args, &arg_cnt, &arg_cap, arg);
           }
-        if (lex_match (lexer, ')'))
+        if (lex_match (lexer, T_RPAREN))
           break;
-        else if (!lex_match (lexer, ','))
+        else if (!lex_match (lexer, T_COMMA))
           {
             lex_error (lexer, _("expecting `,' or `)' invoking %s function"),
                        first->name);
diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c
index aa681c8..6a7e9c6 100644
--- a/src/language/lexer/lexer.c
+++ b/src/language/lexer/lexer.c
@@ -186,7 +186,7 @@ lex_get (struct lexer *lexer)
          if (lexer->dot)
            {
              lexer->dot = 0;
-             lexer->token = '.';
+             lexer->token = T_ENDCMD;
              return;
            }
          else if (!lex_get_line (lexer))
@@ -230,7 +230,7 @@ lex_get (struct lexer *lexer)
 
                if (!c_isdigit ((unsigned char) *lexer->prog) && *lexer->prog 
!= '.')
                  {
-                   lexer->token = '-';
+                   lexer->token = T_DASH;
                    break;
                  }
                 lexer->token = T_NEG_NUM;
@@ -275,10 +275,45 @@ lex_get (struct lexer *lexer)
          lexer->token = parse_string (lexer, CHARACTER_STRING);
          break;
 
-       case '(': case ')': case ',': case '=': case '+': case '/':
-        case '[': case ']':
-         lexer->token = *lexer->prog++;
-         break;
+        case '+':
+          lexer->token = T_PLUS;
+          lexer->prog++;
+          break;
+
+        case '/':
+          lexer->token = T_SLASH;
+          lexer->prog++;
+          break;
+
+        case '=':
+          lexer->token = T_EQUALS;
+          lexer->prog++;
+          break;
+
+       case '(':
+          lexer->token = T_LPAREN;
+          lexer->prog++;
+          break;
+
+       case ')':
+          lexer->token = T_RPAREN;
+          lexer->prog++;
+          break;
+
+       case '[':
+          lexer->token = T_LBRACK;
+          lexer->prog++;
+          break;
+
+       case ']':
+          lexer->token = T_RBRACK;
+          lexer->prog++;
+          break;
+
+        case ',':
+          lexer->token = T_COMMA;
+          lexer->prog++;
+          break;
 
        case '*':
          if (*++lexer->prog == '*')
@@ -287,7 +322,7 @@ lex_get (struct lexer *lexer)
              lexer->token = T_EXP;
            }
          else
-           lexer->token = '*';
+           lexer->token = T_ASTERISK;
          break;
 
        case '<':
@@ -421,7 +456,7 @@ lex_error (struct lexer *lexer, const char *message, ...)
 
   if (lexer->token == T_STOP)
     ds_put_cstr (&s, _("Syntax error at end of file"));
-  else if (lexer->token == '.')
+  else if (lexer->token == T_ENDCMD)
     ds_put_cstr (&s, _("Syntax error at end of command"));
   else
     {
@@ -452,7 +487,7 @@ lex_error (struct lexer *lexer, const char *message, ...)
 int
 lex_end_of_command (struct lexer *lexer)
 {
-  if (lexer->token != '.')
+  if (lexer->token != T_ENDCMD)
     {
       lex_error (lexer, _("expecting end of command"));
       return CMD_FAILURE;
@@ -512,7 +547,7 @@ lex_integer (struct lexer *lexer)
 /* If TOK is the current token, skips it and returns true
    Otherwise, returns false. */
 bool
-lex_match (struct lexer *lexer, int t)
+lex_match (struct lexer *lexer, enum token_type t)
 {
   if (lexer->token == t)
     {
@@ -584,7 +619,7 @@ lex_force_match_id (struct lexer *lexer, const char *s)
 /* 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 (struct lexer *lexer, int t)
+lex_force_match (struct lexer *lexer, enum token_type t)
 {
   if (lexer->token == t)
     {
@@ -652,13 +687,8 @@ lex_force_id (struct lexer *lexer)
 
 /* Weird token functions. */
 
-/* Returns the first character of the next token, except that if the
-   next token is not an identifier, the character returned will not be
-   a character that can begin an identifier.  Specifically, the
-   hexstring lead-in X' causes lookahead() to return '.  Note that an
-   alphanumeric return value doesn't guarantee an ID token, it could
-   also be a reserved-word token. */
-int
+/* Returns the likely type of the next token, or 0 if it's hard to tell. */
+enum token_type
 lex_look_ahead (struct lexer *lexer)
 {
   if (lexer->put_token)
@@ -677,7 +707,7 @@ lex_look_ahead (struct lexer *lexer)
            break;
 
          if (lexer->dot)
-           return '.';
+           return T_ENDCMD;
          else if (!lex_get_line (lexer))
             return 0;
 
@@ -685,20 +715,80 @@ lex_look_ahead (struct lexer *lexer)
            return lexer->put_token;
        }
 
-      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 '\'';
+      switch (toupper ((unsigned char) *lexer->prog))
+        {
+        case 'X': case 'B': case 'O':
+          if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
+            return T_STRING;
+          /* Fall through */
+
+       case '-':
+          return T_DASH;
+
+        case '.':
+       case '0': case '1': case '2': case '3': case '4':
+       case '5': case '6': case '7': case '8': case '9':
+          return T_POS_NUM;
+
+       case '\'': case '"':
+          return T_STRING;
+
+        case '+':
+          return T_PLUS;
+
+        case '/':
+          return T_SLASH;
+
+        case '=':
+          return T_EQUALS;
+
+       case '(':
+          return T_LPAREN;
+
+       case ')':
+          return T_RPAREN;
+
+       case '[':
+          return T_LBRACK;
+
+       case ']':
+          return T_RBRACK;
+
+        case ',':
+          return T_COMMA;
+
+       case '*':
+         return lexer->prog[1] == '*' ? T_EXP : T_ASTERISK;
 
-      return *lexer->prog;
+       case '<':
+          return (lexer->prog[1] == '=' ? T_LE
+                  : lexer->prog[1] == '>' ? T_NE
+                  : T_LT);
+
+       case '>':
+          return lexer->prog[1] == '=' ? T_GE : T_GT;
+
+       case '~':
+          return lexer->prog[1] == '=' ? T_NE : T_NOT;
+
+       case '&':
+         return T_AND;
+
+       case '|':
+         return T_OR;
+
+        default:
+          if (lex_is_id1 (*lexer->prog))
+            return T_ID;
+          return 0;
+        }
     }
 }
 
 /* Makes the current token become the next token to be read; the
    current token is set to T. */
 void
-lex_put_back (struct lexer *lexer, int t)
+lex_put_back (struct lexer *lexer, enum token_type t)
 {
   save_token (lexer);
   lexer->token = t;
@@ -771,7 +861,7 @@ lex_discard_rest_of_command (struct lexer *lexer)
 {
   if (!getl_is_interactive (lexer->ss))
     {
-      while (lexer->token != T_STOP && lexer->token != '.')
+      while (lexer->token != T_STOP && lexer->token != T_ENDCMD)
        lex_get (lexer);
     }
   else
@@ -884,7 +974,7 @@ lex_get_line (struct lexer *lexer)
                        &line_starts_command, &lexer->dot);
 
   if (line_starts_command)
-    lexer->put_token = '.';
+    lexer->put_token = T_ENDCMD;
 
   lexer->prog = ds_cstr (&lexer->line_buffer);
   return true;
@@ -894,20 +984,96 @@ lex_get_line (struct lexer *lexer)
 
 /* Returns the name of a token. */
 const char *
-lex_token_name (int token)
+lex_token_name (enum token_type token)
 {
-  if (lex_is_keyword (token))
-    return lex_id_name (token);
-  else if (token < 256)
+  switch (token)
     {
-      static char t[256][2];
-      char *s = t[token];
-      s[0] = token;
-      s[1] = '\0';
-      return s;
+    case T_ID:
+    case T_POS_NUM:
+    case T_NEG_NUM:
+    case T_STRING:
+      NOT_REACHED ();
+
+    case T_STOP:
+      return "";
+
+    case T_ENDCMD:
+      return ".";
+
+    case T_PLUS:
+      return "+";
+
+    case T_DASH:
+      return "-";
+
+    case T_ASTERISK:
+      return "*";
+
+    case T_SLASH:
+      return "/";
+
+    case T_EQUALS:
+      return "=";
+
+    case T_LPAREN:
+      return "(";
+
+    case T_RPAREN:
+      return ")";
+
+    case T_LBRACK:
+      return "[";
+
+    case T_RBRACK:
+      return "]";
+
+    case T_COMMA:
+      return ",";
+
+    case T_AND:
+      return "AND";
+
+    case T_OR:
+      return "OR";
+
+    case T_NOT:
+      return "NOT";
+
+    case T_EQ:
+      return "EQ";
+
+    case T_GE:
+      return ">=";
+
+    case T_GT:
+      return ">";
+
+    case T_LE:
+      return "<=";
+
+    case T_LT:
+      return "<";
+
+    case T_NE:
+      return "~=";
+
+    case T_ALL:
+      return "ALL";
+
+    case T_BY:
+      return "BY";
+
+    case T_TO:
+      return "TO";
+
+    case T_WITH:
+      return "WITH";
+
+    case T_EXP:
+      return "**";
     }
-  else
-    NOT_REACHED ();
+
+  NOT_REACHED ();
 }
 
 /* Returns an ASCII representation of the current token as a
@@ -923,7 +1089,6 @@ lex_token_representation (struct lexer *lexer)
     case T_POS_NUM:
     case T_NEG_NUM:
       return ds_xstrdup (&lexer->tokstr);
-      break;
 
     case T_STRING:
       {
@@ -962,21 +1127,10 @@ lex_token_representation (struct lexer *lexer)
 
        return token_rep;
       }
-    break;
-
-    case T_STOP:
-      token_rep = xmalloc (1);
-      *token_rep = '\0';
-      return token_rep;
-
-    case T_EXP:
-      return xstrdup ("**");
 
     default:
       return xstrdup (lex_token_name (lexer->token));
     }
-
-  NOT_REACHED ();
 }
 
 /* Really weird functions. */
@@ -994,7 +1148,7 @@ lex_negative_to_dash (struct lexer *lexer)
       lexer->tokval = -lexer->tokval;
       ds_assign_substring (&lexer->tokstr, ds_substr (&lexer->tokstr, 1, 
SIZE_MAX));
       save_token (lexer);
-      lexer->token = '-';
+      lexer->token = T_DASH;
     }
 }
 
@@ -1011,7 +1165,7 @@ lex_skip_comment (struct lexer *lexer)
           return;
         }
 
-      if (lexer->put_token == '.')
+      if (lexer->put_token == T_ENDCMD)
        break;
 
       ds_cstr (&lexer->line_buffer); /* Ensures ds_end will point to a valid 
char */
@@ -1201,7 +1355,7 @@ finish:
 
 /* Token Accessor Functions */
 
-int
+enum token_type
 lex_token (const struct lexer *lexer)
 {
   return lexer->token;
@@ -1238,12 +1392,12 @@ lex_match_hyphenated_word (struct lexer *lexer, const 
char *s)
     return lex_match_id (lexer, s);
   else if (lexer->token != T_ID
           || !lex_id_match (ss_buffer (s, hyphen - s), ss_cstr (lexer->tokid))
-          || lex_look_ahead (lexer) != '-')
+          || lex_look_ahead (lexer) != T_DASH)
     return false;
   else
     {
       lex_get (lexer);
-      lex_force_match (lexer, '-');
+      lex_force_match (lexer, T_DASH);
       lex_force_match_id (lexer, hyphen + 1);
       return true;
     }
diff --git a/src/language/lexer/lexer.h b/src/language/lexer/lexer.h
index 9e5d09a..efdef8a 100644
--- a/src/language/lexer/lexer.h
+++ b/src/language/lexer/lexer.h
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -51,7 +51,7 @@ bool lex_is_string (struct lexer *);
 
 
 /* Token matching functions. */
-bool lex_match (struct lexer *, int);
+bool lex_match (struct lexer *, enum token_type);
 bool lex_match_id (struct lexer *, const char *);
 bool lex_match_id_n (struct lexer *, const char *, size_t n);
 bool lex_match_int (struct lexer *, int);
@@ -59,7 +59,7 @@ bool lex_match_hyphenated_word (struct lexer *lexer, const 
char *s);
 
 
 /* Forcible matching functions. */
-bool lex_force_match (struct lexer *, int);
+bool lex_force_match (struct lexer *, enum token_type);
 bool lex_force_match_id (struct lexer *, const char *);
 bool lex_force_int (struct lexer *);
 bool lex_force_num (struct lexer *);
@@ -67,8 +67,8 @@ bool lex_force_id (struct lexer *);
 bool lex_force_string (struct lexer *);
 
 /* Weird token functions. */
-int lex_look_ahead (struct lexer *);
-void lex_put_back (struct lexer *, int);
+enum token_type lex_look_ahead (struct lexer *);
+void lex_put_back (struct lexer *, enum token_type);
 void lex_put_back_id (struct lexer *, const char *tokid);
 
 /* Weird line processing functions. */
@@ -87,11 +87,11 @@ bool lex_get_line (struct lexer *);
 bool lex_get_line_raw (struct lexer *);
 
 /* Token names. */
-const char *lex_token_name (int);
+const char *lex_token_name (enum token_type);
 char *lex_token_representation (struct lexer *);
 
 /* Token accessors */
-int lex_token (const struct lexer *);
+enum token_type lex_token (const struct lexer *);
 double lex_tokval (const struct lexer *);
 const char *lex_tokid (const struct lexer *);
 const struct string *lex_tokstr (const struct lexer *);
diff --git a/src/language/lexer/q2c.c b/src/language/lexer/q2c.c
index cf8e53e..c03b6b2 100644
--- a/src/language/lexer/q2c.c
+++ b/src/language/lexer/q2c.c
@@ -1491,12 +1491,12 @@ dump_specifier_parse (const specifier *spec, const 
subcommand *sbc)
            {
              if (s->optvalue)
                {
-                 dump (1, "if (lex_match (lexer, '('))");
+                 dump (1, "if (lex_match (lexer, T_LPAREN))");
                  dump (1, "{");
                }
              else
                {
-                 dump (1, "if (!lex_match (lexer, '('))");
+                 dump (1, "if (!lex_match (lexer, T_RPAREN))");
                  dump (1, "{");
                  dump (0, "msg (SE, _(\"`(' expected after %s "
                        "specifier of %s subcommand.\"));",
@@ -1575,7 +1575,7 @@ dump_specifier_parse (const specifier *spec, const 
subcommand *sbc)
 
          if (s->valtype == VT_PAREN)
            {
-             dump (1, "if (!lex_match (lexer, ')'))");
+             dump (1, "if (!lex_match (lexer, T_RPAREN))");
              dump (1, "{");
              dump (0, "msg (SE, _(\"`)' expected after argument for "
                    "%s specifier of %s.\"));",
@@ -1611,7 +1611,7 @@ dump_subcommand (const subcommand *sbc)
     {
       int count;
 
-      dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')");
+      dump (1, "while (lex_token (lexer) != T_SLASH && lex_token (lexer) != 
T_ENDCMD)");
       dump (1, "{");
 
       {
@@ -1669,7 +1669,7 @@ dump_subcommand (const subcommand *sbc)
          }
       }
 
-      dump (0, "lex_match (lexer, ',');");
+      dump (0, "lex_match (lexer, T_COMMA);");
       dump (-1, "}");
       outdent ();
     }
@@ -1755,11 +1755,11 @@ dump_subcommand (const subcommand *sbc)
     }
   else if (sbc->type == SBC_PINT)
     {
-      dump (0, "lex_match (lexer, '(');");
+      dump (0, "lex_match (lexer, T_LPAREN);");
       dump (1, "if (!lex_force_int (lexer))");
       dump (0, "goto lossage;");
       dump (-1, "p->n_%s = lex_integer (lexer);", st_lower (sbc->name));
-      dump (0, "lex_match (lexer, ')');");
+      dump (0, "lex_match (lexer, T_RPAREN);");
     }
   else if (sbc->type == SBC_DBL_LIST || sbc->type == SBC_INT_LIST)
     {
@@ -1769,9 +1769,9 @@ dump_subcommand (const subcommand *sbc)
       dump (0, "goto lossage;");
       dump (-1,"}");
 
-      dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')");
+      dump (1, "while (lex_token (lexer) != T_SLASH && lex_token (lexer) != 
T_ENDCMD)");
       dump (1, "{");
-      dump (0, "lex_match (lexer, ',');");
+      dump (0, "lex_match (lexer, T_COMMA);");
       dump (0, "if (!lex_force_num (lexer))");
       dump (1, "{");
       dump (0, "goto lossage;");
@@ -1834,12 +1834,12 @@ dump_parser (int persistent)
       if (def->type == SBC_VARLIST)
        dump (1, "if (lex_token (lexer) == T_ID "
               "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != 
NULL "
-             "&& lex_look_ahead (lexer) != '=')");
+             "&& lex_look_ahead (lexer) != T_EQUALS)");
       else
        {
          dump (0, "if ((lex_token (lexer) == T_ID "
                 "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) "
-               "&& lex_look_ahead () != '=')");
+               "&& lex_look_ahead () != T_EQUALS)");
          dump (1, "     || token == T_ALL)");
        }
       dump (1, "{");
@@ -1883,7 +1883,7 @@ dump_parser (int persistent)
        f = 1;
        dump (1, "{");
 
-       dump (0, "lex_match (lexer, '=');");
+       dump (0, "lex_match (lexer, T_EQUALS);");
        dump (0, "p->sbc_%s++;", st_lower (sbc->name));
        if (sbc->arity != ARITY_MANY)
          {
@@ -1906,7 +1906,7 @@ dump_parser (int persistent)
   dump(1,"else if ( settings_get_syntax () != COMPATIBLE && 
lex_match_id(lexer, \"ALGORITHM\"))");
   dump(1,"{");
 
-  dump (0, "lex_match (lexer, '=');");
+  dump (0, "lex_match (lexer, T_EQUALS);");
 
   dump(1,"if (lex_match_id(lexer, \"COMPATIBLE\"))");
   dump(0,"settings_set_cmd_algorithm (COMPATIBLE);");
@@ -1919,12 +1919,12 @@ dump_parser (int persistent)
 
 
 
-  dump (1, "if (!lex_match (lexer, '/'))");
+  dump (1, "if (!lex_match (lexer, T_SLASH))");
   dump (0, "break;");
   dump (-2, "}");
   outdent ();
   dump_blank_line (0);
-  dump (1, "if (lex_token (lexer) != '.')");
+  dump (1, "if (lex_token (lexer) != T_ENDCMD)");
   dump (1, "{");
   dump (0, "lex_error (lexer, _(\"expecting end of command\"));");
   dump (0, "goto lossage;");
diff --git a/src/language/lexer/variable-parser.c 
b/src/language/lexer/variable-parser.c
index b9d6752..b05b7ce 100644
--- a/src/language/lexer/variable-parser.c
+++ b/src/language/lexer/variable-parser.c
@@ -336,7 +336,7 @@ parse_var_set_vars (struct lexer *lexer, const struct 
var_set *vs,
 
       if (pv_opts & PV_SINGLE)
         break;
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
     }
   while (lex_token (lexer) == T_ALL
          || (lex_token (lexer) == T_ID && var_set_lookup_var (vs, lex_tokid 
(lexer)) != NULL));
@@ -511,7 +511,7 @@ parse_DATA_LIST_vars (struct lexer *lexer, char ***names,
          (*names)[nvar++] = xstrdup (name1);
        }
 
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
 
       if (pv_opts & PV_SINGLE)
        break;
diff --git a/src/language/stats/aggregate.c b/src/language/stats/aggregate.c
index a8e3f6d..bbe444d 100644
--- a/src/language/stats/aggregate.c
+++ b/src/language/stats/aggregate.c
@@ -175,11 +175,11 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
   subcase_init_empty (&agr.sort);
 
   /* OUTFILE subcommand must be first. */
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   if (!lex_force_match_id (lexer, "OUTFILE"))
     goto error;
-  lex_match (lexer, '=');
-  if (!lex_match (lexer, '*'))
+  lex_match (lexer, T_EQUALS);
+  if (!lex_match (lexer, T_ASTERISK))
     {
       out_file = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
       if (out_file == NULL)
@@ -188,7 +188,7 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
 
   if (out_file == NULL && lex_match_id (lexer, "MODE"))
     {
-      lex_match (lexer, '=');
+      lex_match (lexer, T_EQUALS);
       if (lex_match_id (lexer, "ADDVARIABLES"))
        {
          agr.add_variables = true;
@@ -215,11 +215,11 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
   /* Read most of the subcommands. */
   for (;;)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
 
       if (lex_match_id (lexer, "MISSING"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (!lex_match_id (lexer, "COLUMNWISE"))
            {
              lex_error (lexer, _("expecting %s"), "COLUMNWISE");
@@ -235,7 +235,7 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
        {
           int i;
 
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
           if (!parse_sort_criteria (lexer, dict, &agr.sort, &agr.break_vars,
                                     &saw_direction))
             goto error;
@@ -258,7 +258,7 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
                "the same way as the input data."));
 
   /* Read in the aggregate functions. */
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   if (!parse_aggregate_functions (lexer, dict, &agr))
     goto error;
 
@@ -412,7 +412,7 @@ parse_aggregate_functions (struct lexer *lexer, const 
struct dictionary *dict,
       ds_init_empty (&function_name);
 
       /* Parse the list of target variables. */
-      while (!lex_match (lexer, '='))
+      while (!lex_match (lexer, T_EQUALS))
        {
          size_t n_dest_prev = n_dest;
 
@@ -468,11 +468,11 @@ parse_aggregate_functions (struct lexer *lexer, const 
struct dictionary *dict,
       lex_get (lexer);
 
       /* Check for leading lparen. */
-      if (!lex_match (lexer, '('))
+      if (!lex_match (lexer, T_LPAREN))
        {
          if (function->src_vars == AGR_SV_YES)
            {
-              lex_force_match (lexer, '(');
+              lex_force_match (lexer, T_LPAREN);
              goto error;
            }
        }
@@ -498,7 +498,7 @@ parse_aggregate_functions (struct lexer *lexer, const 
struct dictionary *dict,
              {
                int type;
 
-               lex_match (lexer, ',');
+               lex_match (lexer, T_COMMA);
                if (lex_is_string (lexer))
                  {
                    arg[i].c = ds_xstrdup (lex_tokstr (lexer));
@@ -528,7 +528,7 @@ parse_aggregate_functions (struct lexer *lexer, const 
struct dictionary *dict,
              }
 
          /* Trailing rparen. */
-         if (!lex_force_match (lexer, ')'))
+         if (!lex_force_match (lexer, T_RPAREN))
             goto error;
 
          /* Now check that the number of source variables match
@@ -670,9 +670,9 @@ parse_aggregate_functions (struct lexer *lexer, const 
struct dictionary *dict,
       free (dest);
       free (dest_label);
 
-      if (!lex_match (lexer, '/'))
+      if (!lex_match (lexer, T_SLASH))
        {
-         if (lex_token (lexer) == '.')
+         if (lex_token (lexer) == T_ENDCMD)
            return true;
 
          lex_error (lexer, "expecting end of command");
diff --git a/src/language/stats/autorecode.c b/src/language/stats/autorecode.c
index ce818cf..891cdfb 100644
--- a/src/language/stats/autorecode.c
+++ b/src/language/stats/autorecode.c
@@ -113,13 +113,13 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
 
   /* Parse variable lists. */
   lex_match_id (lexer, "VARIABLES");
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (!parse_variables_const (lexer, dict, &src_vars, &n_srcs,
                               PV_NO_DUPLICATE))
     goto error;
   if (!lex_force_match_id (lexer, "INTO"))
     goto error;
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (!parse_DATA_LIST_vars (lexer, &dst_names, &n_dsts, PV_NO_DUPLICATE))
     goto error;
   if (n_dsts != n_srcs)
@@ -143,7 +143,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
     }
 
   /* Parse options. */
-  while (lex_match (lexer, '/'))
+  while (lex_match (lexer, T_SLASH))
     {
       if (lex_match_id (lexer, "DESCENDING"))
        direction = DESCENDING;
@@ -156,7 +156,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
        }
     }
 
-  if (lex_token (lexer) != '.')
+  if (lex_token (lexer) != T_ENDCMD)
     {
       lex_error (lexer, _("expecting end of command"));
       goto error;
diff --git a/src/language/stats/correlations.c 
b/src/language/stats/correlations.c
index 6af8ba3..d8f1348 100644
--- a/src/language/stats/correlations.c
+++ b/src/language/stats/correlations.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -341,13 +341,13 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds)
   opts.statistics = 0;
 
   /* Parse CORRELATIONS. */
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
       if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
               if (lex_match_id (lexer, "PAIRWISE"))
                 opts.missing_type = CORR_PAIRWISE;
@@ -363,13 +363,13 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds)
                   lex_error (lexer, NULL);
                   goto error;
                 }
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
             }
         }
       else if (lex_match_id (lexer, "PRINT"))
        {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if ( lex_match_id (lexer, "TWOTAIL"))
                opts.tails = 2;
@@ -385,13 +385,13 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds)
                  goto error;
                }
 
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
            }
        }
       else if (lex_match_id (lexer, "STATISTICS"))
        {
-         lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+         lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if ( lex_match_id (lexer, "DESCRIPTIVES"))
                opts.statistics = STATS_DESCRIPTIVES;
@@ -408,14 +408,14 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds)
                  goto error;
                }
 
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
            }
        }
       else
        {
          if (lex_match_id (lexer, "VARIABLES"))
            {
-             lex_match (lexer, '=');
+             lex_match (lexer, T_EQUALS);
            }
 
          corr = xrealloc (corr, sizeof (*corr) * (n_corrs + 1));
diff --git a/src/language/stats/crosstabs.q b/src/language/stats/crosstabs.q
index 341a920..705b46e 100644
--- a/src/language/stats/crosstabs.q
+++ b/src/language/stats/crosstabs.q
@@ -378,7 +378,7 @@ crs_custom_tables (struct lexer *lexer, struct dataset *ds,
          dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL)
       && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if (proc->variables != NULL)
     var_set = const_var_set_create_from_array (proc->variables,
@@ -467,7 +467,7 @@ crs_custom_variables (struct lexer *lexer, struct dataset 
*ds,
       return 0;
     }
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   for (;;)
     {
@@ -482,7 +482,7 @@ crs_custom_variables (struct lexer *lexer, struct dataset 
*ds,
                                    | PV_NO_DUPLICATE | PV_NO_SCRATCH)))
        return 0;
 
-      if (!lex_force_match (lexer, '('))
+      if (!lex_force_match (lexer, T_LPAREN))
          goto lossage;
 
       if (!lex_force_int (lexer))
@@ -490,7 +490,7 @@ crs_custom_variables (struct lexer *lexer, struct dataset 
*ds,
       min = lex_integer (lexer);
       lex_get (lexer);
 
-      lex_match (lexer, ',');
+      lex_match (lexer, T_COMMA);
 
       if (!lex_force_int (lexer))
        goto lossage;
@@ -503,7 +503,7 @@ crs_custom_variables (struct lexer *lexer, struct dataset 
*ds,
        }
       lex_get (lexer);
 
-      if (!lex_force_match (lexer, ')'))
+      if (!lex_force_match (lexer, T_RPAREN))
         goto lossage;
 
       for (i = orig_nv; i < proc->n_variables; i++)
@@ -515,7 +515,7 @@ crs_custom_variables (struct lexer *lexer, struct dataset 
*ds,
           var_attach_aux (proc->variables[i], vr, var_dtor_free);
        }
 
-      if (lex_token (lexer) == '/')
+      if (lex_token (lexer) == T_SLASH)
        break;
     }
 
diff --git a/src/language/stats/descriptives.c 
b/src/language/stats/descriptives.c
index eb04bfa..17eb445 100644
--- a/src/language/stats/descriptives.c
+++ b/src/language/stats/descriptives.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -214,12 +214,12 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
   dsc->show_stats = dsc->calc_stats = DEFAULT_STATS;
 
   /* Parse DESCRIPTIVES. */
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
       if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
               if (lex_match_id (lexer, "VARIABLE"))
                 dsc->missing_type = DSC_VARIABLE;
@@ -232,15 +232,15 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                   lex_error (lexer, NULL);
                   goto error;
                 }
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
             }
         }
       else if (lex_match_id (lexer, "SAVE"))
         save_z_scores = 1;
       else if (lex_match_id (lexer, "FORMAT"))
         {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
               if (lex_match_id (lexer, "LABELS"))
                 dsc->show_var_labels = 1;
@@ -259,14 +259,14 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                   lex_error (lexer, NULL);
                   goto error;
                 }
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
             }
         }
       else if (lex_match_id (lexer, "STATISTICS"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           dsc->show_stats = 0;
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
               if (lex_match (lexer, T_ALL))
                 dsc->show_stats |= (1ul << DSC_N_STATS) - 1;
@@ -274,14 +274,14 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                 dsc->show_stats |= DEFAULT_STATS;
               else
                dsc->show_stats |= 1ul << (match_statistic (lexer));
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
             }
           if (dsc->show_stats == 0)
             dsc->show_stats = DEFAULT_STATS;
         }
       else if (lex_match_id (lexer, "SORT"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
           if (lex_match_id (lexer, "NAME"))
             dsc->sort_by_stat = DSC_NAME;
           else
@@ -290,7 +290,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
              if (dsc->sort_by_stat == DSC_NONE )
                dsc->sort_by_stat = DSC_MEAN;
            }
-          if (lex_match (lexer, '('))
+          if (lex_match (lexer, T_LPAREN))
             {
               if (lex_match_id (lexer, "A"))
                 dsc->sort_ascending = 1;
@@ -298,18 +298,18 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                 dsc->sort_ascending = 0;
               else
                 lex_error (lexer, NULL);
-              lex_force_match (lexer, ')');
+              lex_force_match (lexer, T_RPAREN);
             }
         }
       else if (var_cnt == 0)
         {
-          if (lex_look_ahead (lexer) == '=')
+          if (lex_look_ahead (lexer) == T_EQUALS)
             {
               lex_match_id (lexer, "VARIABLES");
-              lex_match (lexer, '=');
+              lex_match (lexer, T_EQUALS);
             }
 
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
               int i;
 
@@ -327,7 +327,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                 }
               dsc->var_cnt = var_cnt;
 
-              if (lex_match (lexer, '('))
+              if (lex_match (lexer, T_LPAREN))
                 {
                   if (lex_token (lexer) != T_ID)
                     {
@@ -343,7 +343,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                     msg (SE, _("Z-score variable name %s would be"
                                " a duplicate variable name."), lex_tokid 
(lexer));
                   lex_get (lexer);
-                  if (!lex_force_match (lexer, ')'))
+                  if (!lex_force_match (lexer, T_RPAREN))
                    goto error;
                 }
             }
@@ -354,7 +354,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
           goto error;
         }
 
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
     }
   if (var_cnt == 0)
     {
diff --git a/src/language/stats/examine.q b/src/language/stats/examine.q
index e4239fd..452929a 100644
--- a/src/language/stats/examine.q
+++ b/src/language/stats/examine.q
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2008, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -588,9 +588,9 @@ static int
 xmn_custom_percentiles (struct lexer *lexer, struct dataset *ds UNUSED,
                        struct cmd_examine *p UNUSED, void *aux UNUSED)
 {
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
-  lex_match (lexer, '(');
+  lex_match (lexer, T_LPAREN);
 
   while ( lex_is_number (lexer) )
     {
@@ -598,11 +598,11 @@ xmn_custom_percentiles (struct lexer *lexer, struct 
dataset *ds UNUSED,
 
       lex_get (lexer);
 
-      lex_match (lexer, ',') ;
+      lex_match (lexer, T_COMMA) ;
     }
-  lex_match (lexer, ')');
+  lex_match (lexer, T_RPAREN);
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if ( lex_match_id (lexer, "HAVERAGE"))
     percentile_algorithm = PC_HAVERAGE;
@@ -674,7 +674,7 @@ xmn_custom_variables (struct lexer *lexer, struct dataset 
*ds,
                      void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if ( (lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) 
== NULL)
        && lex_token (lexer) != T_ALL)
@@ -749,9 +749,9 @@ examine_parse_independent_vars (struct lexer *lexer,
   else
     ll_push_tail (&factor_list, &sf->ll);
 
-  lex_match (lexer, ',');
+  lex_match (lexer, T_COMMA);
 
-  if ( lex_token (lexer) == '.' || lex_token (lexer) == '/' )
+  if ( lex_token (lexer) == T_ENDCMD || lex_token (lexer) == T_SLASH )
     return 1;
 
   success =  examine_parse_independent_vars (lexer, dict, cmd);
diff --git a/src/language/stats/factor.c b/src/language/stats/factor.c
index d50d6ad..5684bc7 100644
--- a/src/language/stats/factor.c
+++ b/src/language/stats/factor.c
@@ -788,14 +788,14 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
 
   factor.wv = dict_get_weight (dict);
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
 
   if (!lex_force_match_id (lexer, "VARIABLES"))
     {
       goto error;
     }
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if (!parse_variables_const (lexer, dict, &factor.vars, &factor.n_vars,
                              PV_NO_DUPLICATE | PV_NUMERIC))
@@ -804,14 +804,14 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
   if (factor.n_vars < 2)
     msg (MW, _("Factor analysis on a single variable is not useful."));
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
 
       if (lex_match_id (lexer, "PLOT"))
        {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "EIGEN"))
                {
@@ -831,8 +831,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "METHOD"))
        {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "COVARIANCE"))
                {
@@ -851,8 +851,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "ROTATION"))
        {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              /* VARIMAX and DEFAULT are defaults */
              if (lex_match_id (lexer, "VARIMAX") || lex_match_id (lexer, 
"DEFAULT"))
@@ -880,57 +880,57 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "CRITERIA"))
        {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "FACTORS"))
                {
-                 if ( lex_force_match (lexer, '('))
+                 if ( lex_force_match (lexer, T_LPAREN))
                    {
                      lex_force_int (lexer);
                      factor.n_factors = lex_integer (lexer);
                      lex_get (lexer);
-                     lex_force_match (lexer, ')');
+                     lex_force_match (lexer, T_RPAREN);
                    }
                }
              else if (lex_match_id (lexer, "MINEIGEN"))
                {
-                 if ( lex_force_match (lexer, '('))
+                 if ( lex_force_match (lexer, T_LPAREN))
                    {
                      lex_force_num (lexer);
                      factor.min_eigen = lex_number (lexer);
                      lex_get (lexer);
-                     lex_force_match (lexer, ')');
+                     lex_force_match (lexer, T_RPAREN);
                    }
                }
              else if (lex_match_id (lexer, "ECONVERGE"))
                {
-                 if ( lex_force_match (lexer, '('))
+                 if ( lex_force_match (lexer, T_LPAREN))
                    {
                      lex_force_num (lexer);
                      factor.econverge = lex_number (lexer);
                      lex_get (lexer);
-                     lex_force_match (lexer, ')');
+                     lex_force_match (lexer, T_RPAREN);
                    }
                }
              else if (lex_match_id (lexer, "RCONVERGE"))
                {
-                 if ( lex_force_match (lexer, '('))
+                 if ( lex_force_match (lexer, T_LPAREN))
                    {
                      lex_force_num (lexer);
                      factor.rconverge = lex_number (lexer);
                      lex_get (lexer);
-                     lex_force_match (lexer, ')');
+                     lex_force_match (lexer, T_RPAREN);
                    }
                }
              else if (lex_match_id (lexer, "ITERATE"))
                {
-                 if ( lex_force_match (lexer, '('))
+                 if ( lex_force_match (lexer, T_LPAREN))
                    {
                      lex_force_int (lexer);
                      factor.iterations = lex_integer (lexer);
                      lex_get (lexer);
-                     lex_force_match (lexer, ')');
+                     lex_force_match (lexer, T_RPAREN);
                    }
                }
              else if (lex_match_id (lexer, "DEFAULT"))
@@ -949,8 +949,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
       else if (lex_match_id (lexer, "EXTRACTION"))
        {
          extraction_seen = true;
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "PAF"))
                {
@@ -977,8 +977,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "FORMAT"))
        {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "SORT"))
                {
@@ -986,12 +986,12 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
                }
              else if (lex_match_id (lexer, "BLANK"))
                {
-                 if ( lex_force_match (lexer, '('))
+                 if ( lex_force_match (lexer, T_LPAREN))
                    {
                      lex_force_num (lexer);
                      factor.blank = lex_number (lexer);
                      lex_get (lexer);
-                     lex_force_match (lexer, ')');
+                     lex_force_match (lexer, T_RPAREN);
                    }
                }
              else if (lex_match_id (lexer, "DEFAULT"))
@@ -1009,8 +1009,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
       else if (lex_match_id (lexer, "PRINT"))
        {
          factor.print = 0;
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
               if (lex_match_id (lexer, "UNIVARIATE"))
                {
@@ -1083,8 +1083,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
              if (lex_match_id (lexer, "INCLUDE"))
                {
diff --git a/src/language/stats/flip.c b/src/language/stats/flip.c
index 7788186..d08f1b8 100644
--- a/src/language/stats/flip.c
+++ b/src/language/stats/flip.c
@@ -109,23 +109,23 @@ cmd_flip (struct lexer *lexer, struct dataset *ds)
   flip->error = false;
   flip->dict = dict;
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   if (lex_match_id (lexer, "VARIABLES"))
     {
-      lex_match (lexer, '=');
+      lex_match (lexer, T_EQUALS);
       if (!parse_variables_const (lexer, dict, &vars, &flip->n_vars,
                                   PV_NO_DUPLICATE))
        goto error;
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
     }
   else
     dict_get_vars (dict, &vars, &flip->n_vars, DC_SYSTEM);
   pool_register (flip->pool, free, vars);
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   if (lex_match_id (lexer, "NEWNAMES"))
     {
-      lex_match (lexer, '=');
+      lex_match (lexer, T_EQUALS);
       flip->new_names_var = parse_variable (lexer, dict);
       if (!flip->new_names_var)
         goto error;
diff --git a/src/language/stats/frequencies.q b/src/language/stats/frequencies.q
index 723d26e..e397eb8 100644
--- a/src/language/stats/frequencies.q
+++ b/src/language/stats/frequencies.q
@@ -618,7 +618,7 @@ frq_custom_variables (struct lexer *lexer, struct dataset 
*ds,
   size_t n_vars;
   size_t i;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_token (lexer) != T_ALL
       && (lex_token (lexer) != T_ID
           || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL))
@@ -662,7 +662,7 @@ frq_custom_grouped (struct lexer *lexer, struct dataset 
*ds, struct cmd_frequenc
 {
   struct frq_proc *frq = frq_;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if ((lex_token (lexer) == T_ID && dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) != NULL)
       || lex_token (lexer) == T_ID)
     for (;;)
@@ -680,7 +680,7 @@ frq_custom_grouped (struct lexer *lexer, struct dataset 
*ds, struct cmd_frequenc
        if (!parse_variables_const (lexer, dataset_dict (ds), &v, &n,
                               PV_NO_DUPLICATE | PV_NUMERIC))
          return 0;
-       if (lex_match (lexer, '('))
+       if (lex_match (lexer, T_LPAREN))
          {
            nl = ml = 0;
            dl = NULL;
@@ -693,11 +693,11 @@ frq_custom_grouped (struct lexer *lexer, struct dataset 
*ds, struct cmd_frequenc
                  }
                dl[nl++] = lex_tokval (lexer);
                lex_get (lexer);
-               lex_match (lexer, ',');
+               lex_match (lexer, T_COMMA);
              }
            /* Note that nl might still be 0 and dl might still be
               NULL.  That's okay. */
-           if (!lex_match (lexer, ')'))
+           if (!lex_match (lexer, T_RPAREN))
              {
                free (v);
                msg (SE, _("`)' expected after GROUPED interval list."));
@@ -737,12 +737,12 @@ frq_custom_grouped (struct lexer *lexer, struct dataset 
*ds, struct cmd_frequenc
           }
 
        free (v);
-       if (!lex_match (lexer, '/'))
+       if (!lex_match (lexer, T_SLASH))
          break;
        if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) != NULL)
             && lex_token (lexer) != T_ALL)
          {
-           lex_put_back (lexer, '/');
+           lex_put_back (lexer, T_SLASH);
            break;
          }
       }
diff --git a/src/language/stats/glm.q b/src/language/stats/glm.q
index 4de00e3..3ef2249 100644
--- a/src/language/stats/glm.q
+++ b/src/language/stats/glm.q
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -172,7 +172,7 @@ static int
 parse_interactions (struct lexer *lexer, const struct variable 
**interaction_vars, int n_members,
                    int max_members, struct dataset *ds)
 {
-  if (lex_match (lexer, '*'))
+  if (lex_match (lexer, T_ASTERISK))
     {
       if (n_members > max_members)
        {
@@ -196,14 +196,14 @@ glm_custom_design (struct lexer *lexer, struct dataset 
*ds,
 
   interactions = xnmalloc (n_allocated, sizeof (*interactions));
   n_inter = 1;
-  while (lex_token (lexer) != T_STOP && lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_STOP && lex_token (lexer) != T_ENDCMD)
     {
       this_var = parse_variable (lexer, dataset_dict (ds));
-      if (lex_match (lexer, '('))
+      if (lex_match (lexer, T_LPAREN))
        {
-         lex_force_match (lexer, ')');
+         lex_force_match (lexer, T_RPAREN);
        }
-      else if (lex_match (lexer, '*'))
+      else if (lex_match (lexer, T_ASTERISK))
        {
          interaction_vars = xnmalloc (2 * n_inter, sizeof (*interaction_vars));
          n_members = parse_interactions (lexer, interaction_vars, 1, 2 * 
n_inter, ds);
diff --git a/src/language/stats/npar.q b/src/language/stats/npar.q
index 5357972..f88f755 100644
--- a/src/language/stats/npar.q
+++ b/src/language/stats/npar.q
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis. -*-c-*-
-   Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2008, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -241,13 +241,13 @@ npar_custom_chisquare (struct lexer *lexer, struct 
dataset *ds,
 
   cstp->ranged = false;
 
-  if ( lex_match (lexer, '('))
+  if ( lex_match (lexer, T_LPAREN))
     {
       cstp->ranged = true;
       if ( ! lex_force_num (lexer)) return 0;
       cstp->lo = lex_integer (lexer);
       lex_get (lexer);
-      lex_force_match (lexer, ',');
+      lex_force_match (lexer, T_COMMA);
       if (! lex_force_num (lexer) ) return 0;
       cstp->hi = lex_integer (lexer);
       if ( cstp->lo >= cstp->hi )
@@ -259,16 +259,16 @@ npar_custom_chisquare (struct lexer *lexer, struct 
dataset *ds,
          return 0;
        }
       lex_get (lexer);
-      if (! lex_force_match (lexer, ')')) return 0;
+      if (! lex_force_match (lexer, T_RPAREN)) return 0;
     }
 
   cstp->n_expected = 0;
   cstp->expected = NULL;
-  if ( lex_match (lexer, '/') )
+  if ( lex_match (lexer, T_SLASH) )
     {
       if ( lex_match_id (lexer, "EXPECTED") )
        {
-         lex_force_match (lexer, '=');
+         lex_force_match (lexer, T_EQUALS);
          if ( ! lex_match_id (lexer, "EQUAL") )
            {
              double f;
@@ -279,13 +279,13 @@ npar_custom_chisquare (struct lexer *lexer, struct 
dataset *ds,
                  n = 1;
                  f = lex_number (lexer);
                  lex_get (lexer);
-                 if ( lex_match (lexer, '*'))
+                 if ( lex_match (lexer, T_ASTERISK))
                    {
                      n = f;
                      f = lex_number (lexer);
                      lex_get (lexer);
                    }
-                 lex_match (lexer, ',');
+                 lex_match (lexer, T_COMMA);
 
                  cstp->n_expected += n;
                  cstp->expected = pool_realloc (specs->pool,
@@ -301,7 +301,7 @@ npar_custom_chisquare (struct lexer *lexer, struct dataset 
*ds,
            }
        }
       else
-       lex_put_back (lexer, '/');
+       lex_put_back (lexer, T_SLASH);
     }
 
   if ( cstp->ranged && cstp->n_expected > 0 &&
@@ -342,34 +342,34 @@ npar_custom_binomial (struct lexer *lexer, struct dataset 
*ds,
 
   btp->p = 0.5;
 
-  if ( lex_match (lexer, '(') )
+  if ( lex_match (lexer, T_LPAREN) )
     {
       if ( lex_force_num (lexer) )
        {
          btp->p = lex_number (lexer);
          lex_get (lexer);
-         lex_force_match (lexer, ')');
+         lex_force_match (lexer, T_RPAREN);
        }
       else
        return 0;
     }
   else
     /* Kludge: q2c swallows the '=' so put it back here  */
-     lex_put_back (lexer, '=');
+     lex_put_back (lexer, T_EQUALS);
 
 
-  if ( lex_match (lexer, '=') )
+  if ( lex_match (lexer, T_EQUALS) )
     {
       if (parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds),
                                      &tp->vars, &tp->n_vars,
                                      PV_NUMERIC | PV_NO_SCRATCH | 
PV_NO_DUPLICATE) )
        {
-         if ( lex_match (lexer, '('))
+         if ( lex_match (lexer, T_LPAREN))
            {
              lex_force_num (lexer);
              btp->category1 = lex_number (lexer);
              lex_get (lexer);
-             if ( lex_match (lexer, ','))
+             if ( lex_match (lexer, T_COMMA))
                {
                  if ( ! lex_force_num (lexer) ) return 2;
                  btp->category2 = lex_number (lexer);
@@ -380,7 +380,7 @@ npar_custom_binomial (struct lexer *lexer, struct dataset 
*ds,
                  btp->cutpoint = btp->category1;
                }
 
-             lex_force_match (lexer, ')');
+             lex_force_match (lexer, T_RPAREN);
            }
        }
       else
@@ -440,8 +440,8 @@ parse_two_sample_related_test (struct lexer *lexer,
                                        PV_NUMERIC | PV_NO_SCRATCH | 
PV_NO_DUPLICATE) )
        return false;
 
-      paired = (lex_match (lexer, '(') &&
-               lex_match_id (lexer, "PAIRED") && lex_match (lexer, ')'));
+      paired = (lex_match (lexer, T_LPAREN) &&
+               lex_match_id (lexer, "PAIRED") && lex_match (lexer, T_RPAREN));
     }
 
 
@@ -634,14 +634,14 @@ npar_custom_method (struct lexer *lexer, struct dataset 
*ds UNUSED,
        {
          specs->timer = 5.0;
 
-         if ( lex_match (lexer, '('))
+         if ( lex_match (lexer, T_LPAREN))
            {
              if ( lex_force_num (lexer) )
                {
                  specs->timer = lex_number (lexer);
                  lex_get (lexer);
                }
-             lex_force_match (lexer, ')');
+             lex_force_match (lexer, T_RPAREN);
            }
        }
     }
diff --git a/src/language/stats/oneway.c b/src/language/stats/oneway.c
index aa8a255..fb05c49 100644
--- a/src/language/stats/oneway.c
+++ b/src/language/stats/oneway.c
@@ -166,13 +166,13 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
   ll_init (&oneway.contrast_list);
 
   
-  if ( lex_match (lexer, '/'))
+  if ( lex_match (lexer, T_SLASH))
     {
       if (!lex_force_match_id (lexer, "VARIABLES"))
        {
          goto error;
        }
-      lex_match (lexer, '=');
+      lex_match (lexer, T_EQUALS);
     }
 
   if (!parse_variables_const (lexer, dict,
@@ -184,14 +184,14 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
 
   oneway.indep_var = parse_variable_const (lexer, dict);
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
 
       if (lex_match_id (lexer, "STATISTICS"))
        {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "DESCRIPTIVES"))
                {
@@ -213,11 +213,11 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
          struct contrasts_node *cl = xzalloc (sizeof *cl);
 
          struct ll_list *coefficient_list = &cl->coefficient_list;
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
 
          ll_init (coefficient_list);
 
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if ( lex_is_number (lexer))
                {
@@ -238,8 +238,8 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
              if (lex_match_id (lexer, "INCLUDE"))
                {
diff --git a/src/language/stats/rank.q b/src/language/stats/rank.q
index ec3052c..386ef03 100644
--- a/src/language/stats/rank.q
+++ b/src/language/stats/rank.q
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -796,7 +796,7 @@ cmd_rank (struct lexer *lexer, struct dataset *ds)
 static int
 rank_custom_variables (struct lexer *lexer, struct dataset *ds, struct 
cmd_rank *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) == NULL)
       && lex_token (lexer) != T_ALL)
@@ -932,13 +932,13 @@ rank_custom_ntiles (struct lexer *lexer, struct dataset 
*ds, struct cmd_rank *cm
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  if ( lex_force_match (lexer, '(') )
+  if ( lex_force_match (lexer, T_LPAREN) )
     {
       if ( lex_force_int (lexer) )
        {
          k_ntiles = lex_integer (lexer);
          lex_get (lexer);
-         lex_force_match (lexer, ')');
+         lex_force_match (lexer, T_RPAREN);
        }
       else
        return 0;
diff --git a/src/language/stats/regression.q b/src/language/stats/regression.q
index 8f9979a..433ccbd 100644
--- a/src/language/stats/regression.q
+++ b/src/language/stats/regression.q
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2005, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -752,7 +752,7 @@ regression_custom_variables (struct lexer *lexer, struct 
dataset *ds,
 {
   const struct dictionary *dict = dataset_dict (ds);
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if ((lex_token (lexer) != T_ID
        || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
diff --git a/src/language/stats/reliability.c b/src/language/stats/reliability.c
index c737907..1b2f8f0 100644
--- a/src/language/stats/reliability.c
+++ b/src/language/stats/reliability.c
@@ -129,14 +129,14 @@ cmd_reliability (struct lexer *lexer, struct dataset *ds)
 
   reliability.total_start = 0;
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
 
   if (!lex_force_match_id (lexer, "VARIABLES"))
     {
       goto error;
     }
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if (!parse_variables_const (lexer, dict, &reliability.variables, 
&reliability.n_variables,
                              PV_NO_DUPLICATE | PV_NUMERIC))
@@ -166,14 +166,14 @@ cmd_reliability (struct lexer *lexer, struct dataset *ds)
 
 
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
 
       if (lex_match_id (lexer, "SCALE"))
        {
          struct const_var_set *vs;
-         if ( ! lex_force_match (lexer, '('))
+         if ( ! lex_force_match (lexer, T_LPAREN))
            goto error;
 
          if ( ! lex_force_string (lexer) ) 
@@ -183,10 +183,10 @@ cmd_reliability (struct lexer *lexer, struct dataset *ds)
 
          lex_get (lexer);
 
-         if ( ! lex_force_match (lexer, ')'))
+         if ( ! lex_force_match (lexer, T_RPAREN))
            goto error;
 
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
 
          vs = const_var_set_create_from_array (reliability.variables, 
reliability.n_variables);
 
@@ -201,7 +201,7 @@ cmd_reliability (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "MODEL"))
        {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
          if (lex_match_id (lexer, "ALPHA"))
            {
              reliability.model = MODEL_ALPHA;
@@ -211,12 +211,12 @@ cmd_reliability (struct lexer *lexer, struct dataset *ds)
              reliability.model = MODEL_SPLIT;
              reliability.split_point = -1;
 
-             if ( lex_match (lexer, '('))
+             if ( lex_match (lexer, T_LPAREN))
                {
                  lex_force_num (lexer);
                  reliability.split_point = lex_number (lexer);
                  lex_get (lexer);
-                 lex_force_match (lexer, ')');
+                 lex_force_match (lexer, T_RPAREN);
                }
            }
          else
@@ -224,7 +224,7 @@ cmd_reliability (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "SUMMARY"))
         {
-          lex_match (lexer, '=');
+          lex_match (lexer, T_EQUALS);
          if (lex_match_id (lexer, "TOTAL"))
            {
              reliability.summary |= SUMMARY_TOTAL;
@@ -238,8 +238,8 @@ cmd_reliability (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
              if (lex_match_id (lexer, "INCLUDE"))
                {
diff --git a/src/language/stats/roc.c b/src/language/stats/roc.c
index d1461a5..807a381 100644
--- a/src/language/stats/roc.c
+++ b/src/language/stats/roc.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -95,7 +95,7 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
   roc.dict = dataset_dict (ds);
   roc.state_var = NULL;
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
   if (!parse_variables_const (lexer, dict, &roc.vars, &roc.n_vars,
                              PV_APPEND | PV_NO_DUPLICATE | PV_NUMERIC))
     goto error;
@@ -107,7 +107,7 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
 
   roc.state_var = parse_variable (lexer, dict);
 
-  if ( !lex_force_match (lexer, '('))
+  if ( !lex_force_match (lexer, T_LPAREN))
     {
       goto error;
     }
@@ -116,19 +116,19 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
   parse_value (lexer, &roc.state_value, var_get_width (roc.state_var));
 
 
-  if ( !lex_force_match (lexer, ')'))
+  if ( !lex_force_match (lexer, T_RPAREN))
     {
       goto error;
     }
 
 
-  while (lex_token (lexer) != '.')
+  while (lex_token (lexer) != T_ENDCMD)
     {
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
       if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+          lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
             {
              if (lex_match_id (lexer, "INCLUDE"))
                {
@@ -147,15 +147,15 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "PLOT"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if (lex_match_id (lexer, "CURVE"))
            {
              roc.curve = true;
-             if (lex_match (lexer, '('))
+             if (lex_match (lexer, T_LPAREN))
                {
                  roc.reference = true;
                  lex_force_match_id (lexer, "REFERENCE");
-                 lex_force_match (lexer, ')');
+                 lex_force_match (lexer, T_RPAREN);
                }
            }
          else if (lex_match_id (lexer, "NONE"))
@@ -170,8 +170,8 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "PRINT"))
        {
-         lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+         lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "SE"))
                {
@@ -190,12 +190,12 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "CRITERIA"))
        {
-         lex_match (lexer, '=');
-          while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
+         lex_match (lexer, T_EQUALS);
+          while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
              if (lex_match_id (lexer, "CUTOFF"))
                {
-                 lex_force_match (lexer, '(');
+                 lex_force_match (lexer, T_LPAREN);
                  if (lex_match_id (lexer, "INCLUDE"))
                    {
                      roc.exclude = MV_SYSTEM;
@@ -209,11 +209,11 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
                      lex_error (lexer, NULL);
                      goto error;
                    }
-                 lex_force_match (lexer, ')');
+                 lex_force_match (lexer, T_RPAREN);
                }
              else if (lex_match_id (lexer, "TESTPOS"))
                {
-                 lex_force_match (lexer, '(');
+                 lex_force_match (lexer, T_LPAREN);
                  if (lex_match_id (lexer, "LARGE"))
                    {
                      roc.invert = false;
@@ -227,19 +227,19 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
                      lex_error (lexer, NULL);
                      goto error;
                    }
-                 lex_force_match (lexer, ')');
+                 lex_force_match (lexer, T_RPAREN);
                }
              else if (lex_match_id (lexer, "CI"))
                {
-                 lex_force_match (lexer, '(');
+                 lex_force_match (lexer, T_LPAREN);
                  lex_force_num (lexer);
                  roc.ci = lex_number (lexer);
                  lex_get (lexer);
-                 lex_force_match (lexer, ')');
+                 lex_force_match (lexer, T_RPAREN);
                }
              else if (lex_match_id (lexer, "DISTRIBUTION"))
                {
-                 lex_force_match (lexer, '(');
+                 lex_force_match (lexer, T_LPAREN);
                  if (lex_match_id (lexer, "FREE"))
                    {
                      roc.bi_neg_exp = false;
@@ -253,7 +253,7 @@ cmd_roc (struct lexer *lexer, struct dataset *ds)
                      lex_error (lexer, NULL);
                      goto error;
                    }
-                 lex_force_match (lexer, ')');
+                 lex_force_match (lexer, T_RPAREN);
                }
              else
                {
diff --git a/src/language/stats/sort-cases.c b/src/language/stats/sort-cases.c
index deb8b5c..8998120 100644
--- a/src/language/stats/sort-cases.c
+++ b/src/language/stats/sort-cases.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -52,9 +52,9 @@ cmd_sort_cases (struct lexer *lexer, struct dataset *ds)
   if (!parse_sort_criteria (lexer, dataset_dict (ds), &ordering, NULL, NULL))
     return CMD_CASCADING_FAILURE;
 
-  if (settings_get_testing_mode () && lex_match (lexer, '/'))
+  if (settings_get_testing_mode () && lex_match (lexer, T_SLASH))
     {
-      if (!lex_force_match_id (lexer, "BUFFERS") || !lex_match (lexer, '=')
+      if (!lex_force_match_id (lexer, "BUFFERS") || !lex_match (lexer, 
T_EQUALS)
           || !lex_force_int (lexer))
         goto done;
 
diff --git a/src/language/stats/sort-criteria.c 
b/src/language/stats/sort-criteria.c
index 9ae299e..d808d1c 100644
--- a/src/language/stats/sort-criteria.c
+++ b/src/language/stats/sort-criteria.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -63,7 +63,7 @@ parse_sort_criteria (struct lexer *lexer, const struct 
dictionary *dict,
         goto error;
 
       /* Sort direction. */
-      if (lex_match (lexer, '('))
+      if (lex_match (lexer, T_LPAREN))
        {
          if (lex_match_id (lexer, "D") || lex_match_id (lexer, "DOWN"))
            direction = SC_DESCEND;
@@ -74,7 +74,7 @@ parse_sort_criteria (struct lexer *lexer, const struct 
dictionary *dict,
              msg (SE, _("`A' or `D' expected inside parentheses."));
               goto error;
            }
-         if (!lex_match (lexer, ')'))
+         if (!lex_match (lexer, T_RPAREN))
            {
              msg (SE, _("`)' expected."));
               goto error;
diff --git a/src/language/stats/t-test.q b/src/language/stats/t-test.q
index 8aee3b1..47c6af1 100644
--- a/src/language/stats/t-test.q
+++ b/src/language/stats/t-test.q
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -275,7 +275,7 @@ tts_custom_groups (struct lexer *lexer, struct dataset *ds,
   int n_values;
   int width;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   proc->indep_var = parse_variable (lexer, dataset_dict (ds));
   if (proc->indep_var == NULL)
@@ -287,19 +287,19 @@ tts_custom_groups (struct lexer *lexer, struct dataset 
*ds,
   value_init (&proc->g_value[0], width);
   value_init (&proc->g_value[1], width);
 
-  if (!lex_match (lexer, '('))
+  if (!lex_match (lexer, T_LPAREN))
     n_values = 0;
   else
     {
       if (!parse_value (lexer, &proc->g_value[0], width))
         return 0;
-      lex_match (lexer, ',');
-      if (lex_match (lexer, ')'))
+      lex_match (lexer, T_COMMA);
+      if (lex_match (lexer, T_RPAREN))
         n_values = 1;
       else
         {
           if (!parse_value (lexer, &proc->g_value[1], width)
-              || !lex_force_match (lexer, ')'))
+              || !lex_force_match (lexer, T_RPAREN))
             return 0;
           n_values = 2;
         }
@@ -355,7 +355,7 @@ tts_custom_pairs (struct lexer *lexer, struct dataset *ds,
   size_t n_total_pairs;
   size_t i, j;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if (!parse_variables_const (lexer, dataset_dict (ds), &vars1, &n_vars1,
                               PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH))
@@ -370,9 +370,9 @@ tts_custom_pairs (struct lexer *lexer, struct dataset *ds,
           return 0;
         }
 
-      if (lex_match (lexer, '(')
+      if (lex_match (lexer, T_LPAREN)
           && lex_match_id (lexer, "PAIRED")
-          && lex_match (lexer, ')'))
+          && lex_match (lexer, T_RPAREN))
         {
           paired = true;
           if (n_vars1 != n_vars2)
diff --git a/src/language/tests/float-format.c 
b/src/language/tests/float-format.c
index b2d5a16..91e4d9e 100644
--- a/src/language/tests/float-format.c
+++ b/src/language/tests/float-format.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -112,7 +112,7 @@ parse_fp (struct lexer *lexer, struct fp *fp)
       size_t length;
 
       if (!parse_float_format (lexer, &fp->format)
-          || !lex_force_match (lexer, '(')
+          || !lex_force_match (lexer, T_LPAREN)
           || !lex_force_string (lexer))
         return false;
 
@@ -140,7 +140,7 @@ parse_fp (struct lexer *lexer, struct fp *fp)
         }
 
       lex_get (lexer);
-      if (!lex_force_match (lexer, ')'))
+      if (!lex_force_match (lexer, T_RPAREN))
         return false;
     }
   else
@@ -250,14 +250,14 @@ cmd_debug_float_format (struct lexer *lexer, struct 
dataset *ds UNUSED)
       if (!parse_fp (lexer, &fp[fp_cnt++]))
         return CMD_FAILURE;
 
-      if (lex_token (lexer) == '.' && fp_cnt > 1)
+      if (lex_token (lexer) == T_ENDCMD && fp_cnt > 1)
         break;
-      else if (!lex_force_match (lexer, '='))
+      else if (!lex_force_match (lexer, T_EQUALS))
         return CMD_FAILURE;
 
       if (fp_cnt == 1)
         {
-          if (lex_match (lexer, '='))
+          if (lex_match (lexer, T_EQUALS))
             bijective = true;
           else if (lex_match (lexer, T_GT))
             bijective = false;
@@ -269,7 +269,7 @@ cmd_debug_float_format (struct lexer *lexer, struct dataset 
*ds UNUSED)
         }
       else
         {
-          if ((bijective && !lex_force_match (lexer, '='))
+          if ((bijective && !lex_force_match (lexer, T_EQUALS))
               || (!bijective && !lex_force_match (lexer, T_GT)))
             return CMD_FAILURE;
         }
diff --git a/src/language/tests/moments-test.c 
b/src/language/tests/moments-test.c
index 795c729..f5fc858 100644
--- a/src/language/tests/moments-test.c
+++ b/src/language/tests/moments-test.c
@@ -40,7 +40,7 @@ read_values (struct lexer *lexer, double **values, double 
**weights, size_t *cnt
       double value = lex_tokval (lexer);
       double weight = 1.;
       lex_get (lexer);
-      if (lex_match (lexer, '*'))
+      if (lex_match (lexer, T_ASTERISK))
         {
           if (!lex_is_number (lexer))
             {
@@ -79,9 +79,9 @@ cmd_debug_moments (struct lexer *lexer, struct dataset *ds 
UNUSED)
 
   if (lex_match_id (lexer, "ONEPASS"))
     two_pass = 0;
-  if (lex_token (lexer) != '/')
+  if (lex_token (lexer) != T_SLASH)
     {
-      lex_force_match (lexer, '/');
+      lex_force_match (lexer, T_SLASH);
       goto done;
     }
   lex_get (lexer);
diff --git a/src/language/utilities/host.c b/src/language/utilities/host.c
index ac09145..52dfcf1 100644
--- a/src/language/utilities/host.c
+++ b/src/language/utilities/host.c
@@ -129,15 +129,15 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED)
       return CMD_FAILURE;
     }
 
-  if (lex_token (lexer) == '.')
+  if (lex_token (lexer) == T_ENDCMD)
     return shell () ? CMD_SUCCESS : CMD_FAILURE;
   else if (lex_match_id (lexer, "COMMAND"))
     {
       struct string command;
       bool ok;
 
-      lex_match (lexer, '=');
-      if (!lex_force_match (lexer, '['))
+      lex_match (lexer, T_EQUALS);
+      if (!lex_force_match (lexer, T_LBRACK))
         return CMD_FAILURE;
 
       ds_init_empty (&command);
@@ -148,7 +148,7 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED)
           ds_put_substring (&command, ds_ss (lex_tokstr (lexer)));
           lex_get (lexer);
         }
-      if (!lex_force_match (lexer, ']'))
+      if (!lex_force_match (lexer, T_RBRACK))
         {
           ds_destroy (&command);
           return CMD_FAILURE;
diff --git a/src/language/utilities/include.c b/src/language/utilities/include.c
index 52d0e09..d259855 100644
--- a/src/language/utilities/include.c
+++ b/src/language/utilities/include.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -80,11 +80,11 @@ cmd_insert (struct lexer *lexer, struct dataset *ds UNUSED)
 
   lex_get (lexer);
 
-  while ( '.' != lex_token (lexer))
+  while ( T_ENDCMD != lex_token (lexer))
     {
       if (lex_match_id (lexer, "SYNTAX"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if ( lex_match_id (lexer, "INTERACTIVE") )
            syntax_mode = GETL_INTERACTIVE;
          else if ( lex_match_id (lexer, "BATCH"))
@@ -98,7 +98,7 @@ cmd_insert (struct lexer *lexer, struct dataset *ds UNUSED)
        }
       else if (lex_match_id (lexer, "CD"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if ( lex_match_id (lexer, "YES") )
            {
              cd = true;
@@ -116,7 +116,7 @@ cmd_insert (struct lexer *lexer, struct dataset *ds UNUSED)
        }
       else if (lex_match_id (lexer, "ERROR"))
        {
-         lex_match (lexer, '=');
+         lex_match (lexer, T_EQUALS);
          if ( lex_match_id (lexer, "CONTINUE") )
            {
              error_mode = ERRMODE_CONTINUE;
@@ -175,7 +175,7 @@ parse_insert (struct lexer *lexer, char **filename)
 
   /* Skip optional FILE=. */
   if (lex_match_id (lexer, "FILE"))
-    lex_match (lexer, '=');
+    lex_match (lexer, T_EQUALS);
 
   /* File name can be identifier or string. */
   if (lex_token (lexer) != T_ID && !lex_is_string (lexer))
diff --git a/src/language/utilities/permissions.c 
b/src/language/utilities/permissions.c
index 967b1bd..24fdca4 100644
--- a/src/language/utilities/permissions.c
+++ b/src/language/utilities/permissions.c
@@ -42,10 +42,10 @@ cmd_permissions (struct lexer *lexer, struct dataset *ds 
UNUSED)
 {
   char  *fn = 0;
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
 
   if (lex_match_id (lexer, "FILE"))
-    lex_match (lexer, '=');
+    lex_match (lexer, T_EQUALS);
 
   if (!lex_force_string (lexer))
     return CMD_FAILURE;
@@ -54,12 +54,12 @@ cmd_permissions (struct lexer *lexer, struct dataset *ds 
UNUSED)
   lex_force_match (lexer, T_STRING);
 
 
-  lex_match (lexer, '/');
+  lex_match (lexer, T_SLASH);
 
   if ( ! lex_match_id (lexer, "PERMISSIONS"))
     goto error;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if ( lex_match_id (lexer, "READONLY"))
     {
diff --git a/src/language/utilities/set.q b/src/language/utilities/set.q
index 79fe921..e9b6a7d 100644
--- a/src/language/utilities/set.q
+++ b/src/language/utilities/set.q
@@ -271,7 +271,7 @@ set_output_routing (struct lexer *lexer, enum 
settings_output_type type)
 {
   enum settings_output_devices devices;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_match_id (lexer, "ON") || lex_match_id (lexer, "BOTH"))
     devices = SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL;
   else if (lex_match_id (lexer, "TERMINAL"))
@@ -299,7 +299,7 @@ stc_custom_blanks (struct lexer *lexer,
                   struct dataset *ds UNUSED,
                   struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_match_id (lexer, "SYSMIS"))
     {
       lex_get (lexer);
@@ -322,7 +322,7 @@ stc_custom_epoch (struct lexer *lexer,
                  struct dataset *ds UNUSED,
                  struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_match_id (lexer, "AUTOMATIC"))
     settings_set_epoch (-1);
   else if (lex_is_integer (lexer))
@@ -357,7 +357,7 @@ stc_custom_length (struct lexer *lexer, struct dataset *ds 
UNUSED, struct cmd_se
 {
   int page_length;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_match_id (lexer, "NONE"))
     page_length = -1;
   else
@@ -385,7 +385,7 @@ stc_custom_locale (struct lexer *lexer, struct dataset *ds 
UNUSED,
 {
   const struct string *s;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
 
   if ( !lex_force_string (lexer))
     return 0;
@@ -436,7 +436,7 @@ stc_custom_results (struct lexer *lexer, struct dataset *ds 
UNUSED,
 static int
 stc_custom_seed (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_match_id (lexer, "RANDOM"))
     set_rng (time (0));
   else
@@ -453,7 +453,7 @@ stc_custom_seed (struct lexer *lexer, struct dataset *ds 
UNUSED, struct cmd_set
 static int
 stc_custom_width (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_match_id (lexer, "NARROW"))
     settings_set_viewwidth (79);
   else if (lex_match_id (lexer, "WIDE"))
@@ -481,7 +481,7 @@ stc_custom_format (struct lexer *lexer, struct dataset *ds 
UNUSED, struct cmd_se
 {
   struct fmt_spec fmt;
 
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (!parse_format_specifier (lexer, &fmt))
     return 0;
 
@@ -504,7 +504,7 @@ stc_custom_format (struct lexer *lexer, struct dataset *ds 
UNUSED, struct cmd_se
 static int
 stc_custom_journal (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match (lexer, '=');
+  lex_match (lexer, T_EQUALS);
   if (lex_match_id (lexer, "ON") || lex_match_id (lexer, "YES"))
     journal_enable ();
   else if (lex_match_id (lexer, "OFF") || lex_match_id (lexer, "NO"))
@@ -877,7 +877,7 @@ show_copying (const struct dataset *ds UNUSED)
 int
 cmd_show (struct lexer *lexer, struct dataset *ds)
 {
-  if (lex_token (lexer) == '.')
+  if (lex_token (lexer) == T_ENDCMD)
     {
       show_all (ds);
       return CMD_SUCCESS;
@@ -917,9 +917,9 @@ cmd_show (struct lexer *lexer, struct dataset *ds)
           return CMD_FAILURE;
         }
 
-      lex_match (lexer, '/');
+      lex_match (lexer, T_SLASH);
     }
-  while (lex_token (lexer) != '.');
+  while (lex_token (lexer) != T_ENDCMD);
 
   return CMD_SUCCESS;
 }
diff --git a/src/language/utilities/title.c b/src/language/utilities/title.c
index fe826db..966b5a9 100644
--- a/src/language/utilities/title.c
+++ b/src/language/utilities/title.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -52,10 +52,7 @@ cmd_subtitle (struct lexer *lexer, struct dataset *ds UNUSED)
 static int
 parse_title (struct lexer *lexer, enum text_item_type type)
 {
-  int c;
-
-  c = lex_look_ahead (lexer);
-  if (c == '"' || c == '\'')
+  if (lex_look_ahead (lexer) == T_STRING)
     {
       lex_get (lexer);
       if (!lex_force_string (lexer))
diff --git a/src/language/xforms/compute.c b/src/language/xforms/compute.c
index a508933..8245ffe 100644
--- a/src/language/xforms/compute.c
+++ b/src/language/xforms/compute.c
@@ -90,7 +90,7 @@ cmd_compute (struct lexer *lexer, struct dataset *ds)
   if (lvalue == NULL)
     goto fail;
 
-  if (!lex_force_match (lexer, '='))
+  if (!lex_force_match (lexer, T_EQUALS))
     goto fail;
   compute->rvalue = parse_rvalue (lexer, lvalue, ds);
   if (compute->rvalue == NULL)
@@ -246,7 +246,7 @@ cmd_if (struct lexer *lexer, struct dataset *ds)
     goto fail;
 
   /* Rvalue expression. */
-  if (!lex_force_match (lexer, '='))
+  if (!lex_force_match (lexer, T_EQUALS))
     goto fail;
   compute->rvalue = parse_rvalue (lexer, lvalue, ds);
   if (compute->rvalue == NULL)
@@ -346,7 +346,7 @@ lvalue_parse (struct lexer *lexer, struct dataset *ds)
   if (!lex_force_id (lexer))
     goto lossage;
 
-  if (lex_look_ahead (lexer) == '(')
+  if (lex_look_ahead (lexer) == T_LPAREN)
     {
       /* Vector. */
       lvalue->vector = dict_lookup_vector (dict, lex_tokid (lexer));
@@ -358,12 +358,12 @@ lvalue_parse (struct lexer *lexer, struct dataset *ds)
 
       /* Vector element. */
       lex_get (lexer);
-      if (!lex_force_match (lexer, '('))
+      if (!lex_force_match (lexer, T_LPAREN))
        goto lossage;
       lvalue->element = expr_parse (lexer, ds, EXPR_NUMBER);
       if (lvalue->element == NULL)
         goto lossage;
-      if (!lex_force_match (lexer, ')'))
+      if (!lex_force_match (lexer, T_RPAREN))
         goto lossage;
     }
   else
diff --git a/src/language/xforms/count.c b/src/language/xforms/count.c
index 4fb889b..ceead0a 100644
--- a/src/language/xforms/count.c
+++ b/src/language/xforms/count.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -128,7 +128,7 @@ cmd_count (struct lexer *lexer, struct dataset *ds)
         dv->name = pool_strdup (trns->pool, lex_tokid (lexer));
 
       lex_get (lexer);
-      if (!lex_force_match (lexer, '='))
+      if (!lex_force_match (lexer, T_EQUALS))
        goto fail;
 
       crit = dv->crit = pool_alloc (trns->pool, sizeof *crit);
@@ -144,7 +144,7 @@ cmd_count (struct lexer *lexer, struct dataset *ds)
            goto fail;
           pool_register (trns->pool, free, crit->vars);
 
-         if (!lex_force_match (lexer, '('))
+         if (!lex_force_match (lexer, T_LPAREN))
            goto fail;
 
           crit->value_cnt = 0;
@@ -155,16 +155,16 @@ cmd_count (struct lexer *lexer, struct dataset *ds)
          if (!ok)
            goto fail;
 
-         if (lex_token (lexer) == '/' || lex_token (lexer) == '.')
+         if (lex_token (lexer) == T_SLASH || lex_token (lexer) == T_ENDCMD)
            break;
 
          crit = crit->next = pool_alloc (trns->pool, sizeof *crit);
        }
 
-      if (lex_token (lexer) == '.')
+      if (lex_token (lexer) == T_ENDCMD)
        break;
 
-      if (!lex_force_match (lexer, '/'))
+      if (!lex_force_match (lexer, T_SLASH))
        goto fail;
       dv = dv->next = pool_alloc (trns->pool, sizeof *dv);
     }
@@ -222,8 +222,8 @@ parse_numeric_criteria (struct lexer *lexer, struct pool 
*pool, struct criteria
       else
         return false;
 
-      lex_match (lexer, ',');
-      if (lex_match (lexer, ')'))
+      lex_match (lexer, T_COMMA);
+      if (lex_match (lexer, T_RPAREN))
        break;
     }
   return true;
@@ -257,8 +257,8 @@ parse_string_criteria (struct lexer *lexer, struct pool 
*pool, struct criteria *
       str_copy_rpad (*cur, len + 1, ds_cstr (lex_tokstr (lexer)));
       lex_get (lexer);
 
-      lex_match (lexer, ',');
-      if (lex_match (lexer, ')'))
+      lex_match (lexer, T_COMMA);
+      if (lex_match (lexer, T_RPAREN))
        break;
     }
 
diff --git a/src/language/xforms/recode.c b/src/language/xforms/recode.c
index 5cfad0e..12f1eb4 100644
--- a/src/language/xforms/recode.c
+++ b/src/language/xforms/recode.c
@@ -167,7 +167,7 @@ cmd_recode (struct lexer *lexer, struct dataset *ds)
       add_transformation (ds,
                          recode_trns_proc, recode_trns_free, trns);
     }
-  while (lex_match (lexer, '/'));
+  while (lex_match (lexer, T_SLASH));
 
   return lex_end_of_command (lexer);
 }
@@ -211,7 +211,7 @@ parse_mappings (struct lexer *lexer, struct recode_trns 
*trns)
   trns->map_cnt = 0;
   map_allocated = 0;
   have_dst_type = false;
-  if (!lex_force_match (lexer, '('))
+  if (!lex_force_match (lexer, T_LPAREN))
     return false;
   do
     {
@@ -234,9 +234,9 @@ parse_mappings (struct lexer *lexer, struct recode_trns 
*trns)
                                  trns->src_type, trns->max_src_width))
                 return false;
               add_mapping (trns, &map_allocated, &in);
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
             }
-          while (!lex_match (lexer, '='));
+          while (!lex_match (lexer, T_EQUALS));
 
           if (!parse_map_out (lexer, trns->pool, &out))
             return false;
@@ -276,10 +276,10 @@ parse_mappings (struct lexer *lexer, struct recode_trns 
*trns)
       trns->dst_type = dst_type;
       have_dst_type = true;
 
-      if (!lex_force_match (lexer, ')'))
+      if (!lex_force_match (lexer, T_RPAREN))
         return false;
     }
-  while (lex_match (lexer, '('));
+  while (lex_match (lexer, T_LPAREN));
 
   return true;
 }
diff --git a/src/language/xforms/select-if.c b/src/language/xforms/select-if.c
index 85f616d..74edf2d 100644
--- a/src/language/xforms/select-if.c
+++ b/src/language/xforms/select-if.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -54,7 +54,7 @@ cmd_select_if (struct lexer *lexer, struct dataset *ds)
   if (!e)
     return CMD_CASCADING_FAILURE;
 
-  if (lex_token (lexer) != '.')
+  if (lex_token (lexer) != T_ENDCMD)
     {
       expr_free (e);
       lex_error (lexer, _("expecting end of command"));
@@ -95,7 +95,7 @@ cmd_filter (struct lexer *lexer, struct dataset *ds)
   struct dictionary *dict = dataset_dict (ds);
   if (lex_match_id (lexer, "OFF"))
     dict_set_filter (dict, NULL);
-  else if (lex_token (lexer) == '.')
+  else if (lex_token (lexer) == T_ENDCMD)
     {
       msg (SW, _("Syntax error expecting OFF or BY.  "
                  "Turning off case filtering."));
diff --git a/tests/language/expressions/evaluate.at 
b/tests/language/expressions/evaluate.at
index a714422..c6978ab 100644
--- a/tests/language/expressions/evaluate.at
+++ b/tests/language/expressions/evaluate.at
@@ -281,7 +281,7 @@ dnl Make sure >= token can't be split:
   [['asdfj   ' ne 'asdf'], [true]],
 dnl <> token can't be split:
   [[1 < > 1], [error],
-   [error: DEBUG EVALUATE: Syntax error at `GT'.]],
+   [error: DEBUG EVALUATE: Syntax error at `>'.]],
 dnl # ~= token can't be split:
   [[1 ~ = 1], [error],
    [error: DEBUG EVALUATE: Syntax error at `NOT': expecting end of command.]])
-- 
1.7.1




reply via email to

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