lexer: Add support for macro identifiers (that begin with '!').
[pspp] / src / language / lexer / segment.c
index 93eb1e8f8594b564d768737f5e84057da8085009..cfe3de522fca5c912d8d5da8ec37d75d1c3fcbf6 100644 (file)
@@ -286,20 +286,23 @@ segmenter_parse_number__ (struct segmenter *s, const char *input, size_t n,
       if (!eof)
         return -1;
       goto number;
-    };
+    }
   if (input[ofs] == '.')
     {
+      if (ofs + 1 >= n)
+        {
+          if (!eof)
+            return -1;
+          goto number;
+        }
+
       ofs = skip_digits (input, n, eof, ofs + 1);
       if (ofs < 0)
         return -1;
+      else if (ofs >= n)
+        goto number;
     }
 
-  if (ofs >= n)
-    {
-      if (!eof)
-        return -1;
-      goto number;
-    }
   if (input[ofs] == 'e' || input[ofs] == 'E')
     {
       ofs++;
@@ -648,6 +651,7 @@ next_id_in_command (const struct segmenter *s, const char *input, size_t n,
             }
           /* fall through */
 
+        case SEG_MACRO_ID:
         case SEG_NUMBER:
         case SEG_QUOTED_STRING:
         case SEG_HEX_STRING:
@@ -716,10 +720,9 @@ segmenter_parse_id__ (struct segmenter *s, const char *input, size_t n,
         ofs--;
     }
 
-  if (is_reserved_word (input, ofs))
-    *type = SEG_RESERVED_WORD;
-  else
-    *type = SEG_IDENTIFIER;
+  *type = (is_reserved_word (input, ofs) ? SEG_RESERVED_WORD
+           : input[0] == '!' ? SEG_MACRO_ID
+           : SEG_IDENTIFIER);
 
   if (s->substate & SS_START_OF_COMMAND)
     {
@@ -986,6 +989,9 @@ segmenter_parse_mid_command__ (struct segmenter *s,
       return segmenter_parse_string__ (SEG_QUOTED_STRING, 0,
                                        s, input, n, eof, type);
 
+    case '!':
+      return segmenter_parse_id__ (s, input, n, eof, type);
+
     default:
       if (lex_uc_is_space (uc))
         {