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)