Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add macro to name generated parser, so it can call itself, and rewrit…

…e nested? to use it.
  • Loading branch information...
commit 989108cfb29902143181970e43126ec2952e9a08 1 parent 23e5c5e
Jakub Higersberger authored

Showing 2 changed files with 24 additions and 12 deletions. Show diff stats Hide diff stats

  1. 1  package.lisp
  2. 35  parsers.lisp
1  package.lisp
@@ -70,6 +70,7 @@
70 70
            #:find-after-collect*
71 71
            #:breadth?
72 72
            #:nested?
  73
+           #:named?
73 74
            #:expression?
74 75
            #:expression*
75 76
            #:context-interval
35  parsers.lisp
@@ -422,6 +422,29 @@ parsers."
422 422
   "Parser: result of p or nil"
423 423
   (choice p (result nil)))
424 424
 
  425
+(defmacro named? (name &body body)
  426
+  "Parser macro: give BODY a NAME, so it can refer to itself without causing generator recursion."
  427
+  (with-unique-names (parser wrapped inp)
  428
+    `(let ((,wrapped (zero)))
  429
+       (let ((,name
  430
+              #'(lambda (,inp)
  431
+                  (funcall ,wrapped ,inp))))
  432
+         (let ((,parser
  433
+                ,@body))
  434
+           (setf ,wrapped ,parser)
  435
+           ,parser)))))
  436
+
  437
+(defun nested? (p &key (min nil) (max nil) (result-type 'list) (bracket-left #\() (bracket-right #\)))
  438
+  "Parser: parse a sequence of p, like between?, but with p possibly nested in brackets."
  439
+  (if (and bracket-left bracket-right)
  440
+      (named? nested-parser
  441
+        (between? (choice (bracket? bracket-left nested-parser bracket-right)
  442
+                          p)
  443
+                  min
  444
+                  max
  445
+                  result-type))
  446
+      (between? p min max result-type)))
  447
+
425 448
 (defun expression? (term operators &optional (bracket-left nil) (bracket-right nil))
426 449
   "Parser: Reduce a sequence of terms with unary/binary operators with precedence.
427 450
  OPERATORS is a list of (op-parser :left/:right/:unary), where OP-PARSER is a parser consuming
@@ -446,15 +469,3 @@ parsers."
446 469
             (setf wrapped-term (choice (bracket? bracket-left expr-parser bracket-right)
447 470
                                        term)))
448 471
           expr-parser)))))
449  
-
450  
-(defun nested? (p &key (min nil) (max nil) (result-type 'list) (bracket-left #\() (bracket-right #\)))
451  
-  "Parser: parse a sequence of p, like between?, but with p possibly nested in brackets."
452  
-  (with-parsers (p bracket-left bracket-right)
453  
-    (let ((wrapped-term p))
454  
-      (labels ((term-wrapper (inp)
455  
-                 (funcall wrapped-term inp)))
456  
-        (let ((nested-parser (between? #'term-wrapper min max result-type)))
457  
-          (when (and bracket-left bracket-right)
458  
-            (setf wrapped-term (choice (bracket? bracket-left nested-parser bracket-right)
459  
-                                       wrapped-term)))
460  
-          nested-parser)))))

0 notes on commit 989108c

Please sign in to comment.
Something went wrong with that request. Please try again.