branch: externals/lex
commit ccbfa1da2d773e07c9f1e0451b70b23f721fa7d5
Author: Stefan Monnier <[email protected]>
Commit: Stefan Monnier <[email protected]>

    lex.el (lex--nfa): Fix mis-parse of (not-char ...)
    
    Reported by Taylor R Campbell <[email protected]>
    who provided a slightly different patch along with the following
    test case:
    
    Without this patch, (not-char X Y Z ...) ignores X as a character to
    exclude, and matches X.  In contrast, (char not X Y Z ...) correctly
    excludes X.
    
    Test case:
    
    (let ((lex1
           (lex-compile
            '(((+ (char not ?\; ?\.)) . content) (?\; . semi) (?\. . dot))))
          (lex2
           (lex-compile
            '(((+ (not-char ?\; ?\.)) . content) (?\; . semi) (?\. . dot)))))
      (dolist (lex (list lex1 lex2))
        (message "%S" (lex--tokenizer lex "xy;."))))
    
    Expected outcome:
    
    ((content . "xy") (semi . ";") (dot . "."))
    ((content . "xy") (semi . ";") (dot . "."))
    
    Actual outcome, without the patch:
    
    ((content . "xy") (semi . ";") (dot . "."))
    ((content . "xy;") (dot . "."))
---
 lex.el | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/lex.el b/lex.el
index a211c61859..d27591b1bf 100644
--- a/lex.el
+++ b/lex.el
@@ -1,10 +1,10 @@
 ;;; lex.el --- Lexical analyser construction  -*- lexical-binding:t -*-
 
-;; Copyright (C) 2008-2024  Free Software Foundation, Inc.
+;; Copyright (C) 2008-2026  Free Software Foundation, Inc.
 
 ;; Author: Stefan Monnier <[email protected]>
 ;; Keywords:
-;; Version: 1.2
+;; Version: 1.3
 
 ;; 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
@@ -73,6 +73,10 @@
 
 ;;; News:
 
+;; Since 1.2:
+
+;; - Bug fix for `not-char'.
+
 ;;; Notes
 
 ;; Search
@@ -598,13 +602,14 @@ or (check (not (PREDICATE . ARG))).")
          (setq state (lex--nfa elem state)))
        state)
       ((or `char `in `not-char)
-       (let ((chars (cdr re))
-             (checks nil)
-             (fail nil)
-             (char nil)  ;The char seen, or nil if none, or t if more than one.
-             (ct (make-char-table 'lexer)))
-         (when (or (eq 'not (car chars)) (eq 'not-char (car re)))
-           (setq chars (cdr chars))
+       (let* ((chars (cdr re))
+              (checks nil)
+              (fail nil)
+              (char nil) ;The char seen, or nil if none, or t if more than one.
+              (ct (make-char-table 'lexer))
+              (has-not (eq 'not (car chars))))
+         (when (or has-not (eq 'not-char (car re)))
+           (when has-not (setq chars (cdr chars)))
            (set-char-table-range ct t state)
            (setq fail state)
            (setq state nil))

Reply via email to