emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[elpa] externals/peg 26703e8695 2/2: * peg.el: Add named rulesets


From: Stefan Monnier
Subject: [elpa] externals/peg 26703e8695 2/2: * peg.el: Add named rulesets
Date: Sun, 11 Dec 2022 11:55:07 -0500 (EST)

branch: externals/peg
commit 26703e869548d233effabc98a537707a3a8ce8e9
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * peg.el: Add named rulesets
    
    (define-peg-ruleset): New macro.
    (with-peg-rules): Allow reference to a ruleset.
---
 peg.el | 57 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 49 insertions(+), 8 deletions(-)

diff --git a/peg.el b/peg.el
index 0d0cab8ca1..0eedca89f3 100644
--- a/peg.el
+++ b/peg.el
@@ -86,6 +86,26 @@
 ;; buffer text.  Rules can be recursive or mutually referential,
 ;; though care must be taken not to create infinite loops.
 ;;
+;;;; Named rulesets:
+;;
+;; You can define a set of rules for later use with:
+;;
+;;     (define-peg-ruleset myrules
+;;       (sign  () (or "+" "-" ""))
+;;       (digit () [0-9])
+;;       (nat   () digit (* digit))
+;;       (int   () sign digit (* digit))
+;;       (float () int "." nat))
+;;
+;; and later refer to it:
+;;
+;;     (with-peg-rules
+;;         (myrules
+;;          (complex float "+i" float))
+;;       ... (peg-parse nat "," nat "," complex) ...)
+;;
+;;;; Parsing actions:
+;;
 ;; PEXs also support parsing actions, i.e. Lisp snippets which are
 ;; executed when a pex matches.  This can be used to construct syntax
 ;; trees or for similar tasks.  The most basic form of action is
@@ -144,7 +164,7 @@
 ;; pushes values to the stack without consuming any, and the latter
 ;; pops values from the stack and discards them.
 ;;
-;; Derived Operators:
+;;;; Derived Operators:
 ;;
 ;; The following operators are implemented as combinations of
 ;; primitive expressions:
@@ -195,7 +215,7 @@
 ;;
 ;; See ";;; Examples" in `peg-tests.el' for other examples.
 ;;
-;; References:
+;;;; References:
 ;;
 ;; [Ford] Bryan Ford. Parsing Expression Grammars: a Recognition-Based
 ;; Syntactic Foundation. In POPL'04: Proceedings of the 31st ACM
@@ -221,6 +241,7 @@
 ;; - Use OClosures to represent PEG rules when available, and let cl-print
 ;;   display their source code.
 ;; - New PEX form (with RULES PEX...).
+;; - Named rulesets.
 
 ;; Version 1.0:
 ;; - New official entry points `peg` and `peg-run`.
@@ -359,16 +380,36 @@ sequencing `and' operator of PEG grammars."
                  ,(byte-run--set-speed id nil -1)
                  (put ',id 'byte-optimizer #'byte-compile-inline-expand))))))))
 
+(defmacro define-peg-ruleset (name &rest rules)
+  "Define a set of PEG rules for later use, e.g., in `with-peg-rules'."
+  (declare (indent 1))
+  (let ((defs ())
+        (aliases ()))
+    (dolist (rule rules)
+      (let* ((rname (car rule))
+             (full-rname (format "%s %s" name rname)))
+        (push `(define-peg-rule ,full-rname . ,(cdr rule)) defs)
+        (push `(,(peg--rule-id rname) #',(peg--rule-id full-rname)) aliases)))
+    `(cl-flet ,aliases
+       ,@defs
+       (eval-and-compile (put ',name 'peg--rules ',aliases)))))
+
 (defmacro with-peg-rules (rules &rest body)
   "Make PEG rules RULES available within the scope of BODY.
 RULES is a list of rules of the form (NAME . PEXS), where PEXS is a sequence
-of PEG expressions, implicitly combined with `and'."
+of PEG expressions, implicitly combined with `and'.
+RULES can also contain symbols in which case these must name
+rulesets defined previously with `define-peg-ruleset'."
   (declare (indent 1) (debug (sexp form))) ;FIXME: `sexp' is not good enough!
-  (let ((rules
-         ;; First, macroexpand the rules.
-         (mapcar (lambda (rule)
-                   (cons (car rule) (peg-normalize `(and . ,(cdr rule)))))
-                 rules))
+  (let* ((rulesets nil)
+         (rules
+          ;; First, macroexpand the rules.
+          (delq nil
+                (mapcar (lambda (rule)
+                          (if (symbolp rule)
+                              (progn (push rule rulesets) nil)
+                            (cons (car rule) (peg-normalize `(and . ,(cdr 
rule))))))
+                        rules)))
         (ctx (assq :peg-rules macroexpand-all-environment)))
     (macroexpand-all
      `(cl-labels



reply via email to

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