branch: externals/peg
commit 3eef8aa9e5f6f22a67e65d65a4db9efa2c1c5a0a
Author: Stefan Monnier <[email protected]>
Commit: Stefan Monnier <[email protected]>

    (peg-parse): Fix bug#78884
    
    Backport of Emacs commit 68100ca656ad:
    
    * lisp/progmodes/peg.el (peg-parse): Be more careful when
    testing if a symbol is the name of an existing rule.  Improve docstring.
    
    * test/lisp/progmodes/peg-tests.el (peg-tests--peg-parse): New test.
---
 peg-tests.el |  7 +++++++
 peg.el       | 16 +++++++++++-----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/peg-tests.el b/peg-tests.el
index 518721c105..717cec2b05 100644
--- a/peg-tests.el
+++ b/peg-tests.el
@@ -363,5 +363,12 @@ resp. succeeded instead of signaling an error."
 ;; (peg-ex-last-digit2 (make-string 500000 ?-))
 ;; (peg-ex-last-digit2 (make-string 500000 ?5))
 
+(ert-deftest peg-tests--peg-parse ()
+  (with-temp-buffer
+    (insert "abc")
+    (goto-char (point-min))
+    (peg-parse (bob) "ab")
+    (should (looking-at "c"))))
+
 (provide 'peg-tests)
 ;;; peg-tests.el ends here
diff --git a/peg.el b/peg.el
index de571b1226..cbc84077bd 100644
--- a/peg.el
+++ b/peg.el
@@ -1,6 +1,6 @@
 ;;; peg.el --- Parsing Expression Grammars in Emacs Lisp  -*- 
lexical-binding:t -*-
 
-;; Copyright (C) 2008-2022  Free Software Foundation, Inc.
+;; Copyright (C) 2008-2025  Free Software Foundation, Inc.
 ;;
 ;; Author: Helmut Eller <[email protected]>
 ;; Maintainer: Stefan Monnier <[email protected]>
@@ -318,12 +318,18 @@ EXPS is a list of rules/expressions that failed.")
 PEXS is a sequence of PEG expressions, implicitly combined with `and'.
 Returns STACK if the match succeed and signals an error on failure,
 moving point along the way.
-PEXS can also be a list of PEG rules, in which case the first rule is used."
+For backward compatibility (and convenience) PEXS can also be a list of
+RULES in which case we run the first such rule.  In case of ambiguity,
+prefix PEXS with \"\" so it doesn't look like a list of rules."
   (if (and (consp (car pexs))
            (symbolp (caar pexs))
-           (not (ignore-errors (peg-normalize (car pexs)))))
-      ;; `pexs' is a list of rules: use the first rule as entry point.
-      `(with-peg-rules ,pexs (peg-run (peg ,(caar pexs)) #'peg-signal-failure))
+           (not (or (get (peg--rule-id (caar pexs)) 'peg--rule-definition)
+                    (ignore-errors
+                      (not (eq 'call (car (peg-normalize (car pexs)))))))))
+      ;; The first of `pexs' has not been defined as a rule, so assume
+      ;; that none of them have been and they should be fed to
+      ;; `with-peg-rules'
+      `(with-peg-rules ,pexs (peg-parse ,(caar pexs)))
     `(peg-run (peg ,@pexs) #'peg-signal-failure)))
 
 (defmacro peg (&rest pexs)

Reply via email to