|
132 | 132 | ((and (symbolp pattern) (aliased-pattern pattern))
|
133 | 133 | (parse-sub (aliased-pattern pattern)))
|
134 | 134 | ((eq pattern '*) (make-instance 'everything))
|
| 135 | + ((eq pattern :**?) (make-instance 'non-greedy-everything)) |
135 | 136 | ((stringp pattern) (make-instance 'text :text pattern))
|
136 | 137 | ((and (proper-list-p pattern)
|
137 | 138 | (symbolp (first pattern))
|
138 | 139 | (not (eq (first pattern) '*))
|
| 140 | + (not (eq (first pattern) :**?)) |
139 | 141 | (not (variable-p (first pattern)))
|
140 | 142 | (not (aliased-pattern (first pattern))))
|
141 | 143 | (case (first pattern)
|
|
166 | 168 | (:*
|
167 | 169 | (make-instance 'greedy-repetition
|
168 | 170 | :content-pattern (parse-sub (rest pattern))))
|
| 171 | + (:*? |
| 172 | + (make-instance 'non-greedy-repetition |
| 173 | + :content-pattern (parse-sub (rest pattern)))) |
169 | 174 | (:+
|
170 | 175 | (make-instance 'greedy-repetition-no-zero
|
171 | 176 | :content-pattern (parse-sub (rest pattern))))
|
| 177 | + (:+? |
| 178 | + (make-instance 'non-greedy-repetition-no-zero |
| 179 | + :content-pattern (parse-sub (rest pattern)))) |
172 | 180 | ((:+rx :+erx)
|
173 | 181 | (unless (and (stringp (second pattern))
|
174 | 182 | (every #'variable-p (cddr pattern)))
|
|
417 | 425 | (or (funcall next-fn nil bindings)
|
418 | 426 | (funcall next-fn node bindings)))))
|
419 | 427 |
|
| 428 | +(defclass non-greedy-everything (pattern) ()) |
| 429 | + |
| 430 | +(defmethod create-matcher ((pattern non-greedy-everything) next-fn) |
| 431 | + (matcher-closure pattern everything (node bindings) |
| 432 | + (iter (for from-node initially node then (next-sibling from-node)) |
| 433 | + (while from-node) |
| 434 | + (thereis (funcall next-fn from-node bindings))))) |
| 435 | + |
420 | 436 | (defclass bind (compound-pattern)
|
421 | 437 | ((variable :accessor variable-of :initarg :variable)))
|
422 | 438 |
|
|
565 | 581 | (*rep-saved-bindings* bindings))
|
566 | 582 | (funcall inner-closure node bindings)))))
|
567 | 583 |
|
| 584 | +(defclass non-greedy-repetition (compound-pattern) ()) |
| 585 | + |
| 586 | +(defmethod create-matcher ((pattern non-greedy-repetition) next-fn) |
| 587 | + (let* ((content-matcher nil) |
| 588 | + (inner-closure |
| 589 | + (matcher-closure pattern non-greedy-repetition-inner (node bindings) |
| 590 | + (setf *rep-accumulated-bindings* |
| 591 | + (collect-added-bindings bindings *rep-saved-bindings* |
| 592 | + *rep-accumulated-bindings*)) |
| 593 | + (or (funcall next-fn node (append *rep-accumulated-bindings* |
| 594 | + *rep-saved-bindings*)) |
| 595 | + (funcall content-matcher node *rep-saved-bindings*))))) |
| 596 | + (setf content-matcher (create-matcher (content-pattern-of pattern) inner-closure)) |
| 597 | + (matcher-closure pattern greedy-repetition (node bindings) |
| 598 | + (let ((*rep-accumulated-bindings* '()) |
| 599 | + (*rep-saved-bindings* bindings)) |
| 600 | + (funcall inner-closure node bindings))))) |
| 601 | + |
568 | 602 | (defclass greedy-repetition-no-zero (compound-pattern) ())
|
569 | 603 |
|
570 | 604 | (defmethod create-matcher ((pattern greedy-repetition-no-zero) next-fn)
|
|
583 | 617 | (*rep-saved-bindings* bindings))
|
584 | 618 | (funcall content-matcher node bindings)))))
|
585 | 619 |
|
| 620 | +(defclass non-greedy-repetition-no-zero (compound-pattern) ()) |
| 621 | + |
| 622 | +(defmethod create-matcher ((pattern non-greedy-repetition-no-zero) next-fn) |
| 623 | + (let (content-matcher) |
| 624 | + (setf content-matcher |
| 625 | + (create-matcher (content-pattern-of pattern) |
| 626 | + (matcher-closure pattern repetition (node bindings) |
| 627 | + (setf *rep-accumulated-bindings* |
| 628 | + (collect-added-bindings bindings *rep-saved-bindings* |
| 629 | + *rep-accumulated-bindings*)) |
| 630 | + (or (funcall next-fn node (append *rep-accumulated-bindings* |
| 631 | + *rep-saved-bindings*)) |
| 632 | + (funcall content-matcher node *rep-saved-bindings*))))) |
| 633 | + (matcher-closure pattern greedy-repetition (node bindings) |
| 634 | + (let ((*rep-accumulated-bindings* '()) |
| 635 | + (*rep-saved-bindings* bindings)) |
| 636 | + (funcall content-matcher node bindings))))) |
| 637 | + |
586 | 638 | (defclass deep (compound-pattern) ())
|
587 | 639 |
|
588 | 640 | (defmethod create-matcher ((pattern deep) next-fn)
|
|
0 commit comments