r1/packrat.scm
author Tony Garnock-Jones <tonygarnockjones@gmail.com>
Wed, 16 Jan 2019 17:15:58 +0000
changeset 438 1fe179d53161
parent 3 d6dba34d7b01
permissions -rw-r--r--
Add missing primitive implementation for the plain interpreter.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     1
;; Packrat Parser Library
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     2
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     3
(require 'srfi-1)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     4
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     5
(define-record-type parse-result
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     6
  (make-parse-result successful? semantic-value next error)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     7
  parse-result?
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     8
  (successful? parse-result-successful?)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
     9
  (semantic-value parse-result-semantic-value)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    10
  (next parse-result-next) ;; #f, if eof or error; otherwise a parse-results
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    11
  (error parse-result-error)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    12
  ;; ^^ #f if none, but usually a parse-error structure
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    13
  )
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    14
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    15
(define-record-type parse-results
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    16
  (make-parse-results position base next map)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    17
  parse-results?
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    18
  (position parse-results-position) ;; a parse-position or #f if unknown
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    19
  (base parse-results-base) ;; a value, #f indicating 'none' or 'eof'
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    20
  (next parse-results-next* set-parse-results-next!)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    21
  ;; ^^ a parse-results, or a nullary function delivering same, or #f for nothing next (eof)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    22
  (map parse-results-map set-parse-results-map!)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    23
  ;; ^^ an alist mapping a nonterminal to a parse-result
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    24
  )
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    25
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    26
(define-record-type parse-error
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    27
  (make-parse-error position expected-strings messages)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    28
  parse-error?
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    29
  (position parse-error-position) ;; a parse-position or #f if unknown
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    30
  (expected-strings parse-error-expected-strings) ;; set of strings (lset)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    31
  (messages parse-error-messages) ;; list of strings
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    32
  )
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    33
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    34
(define-record-type parse-position
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    35
  (make-parse-position file line column)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    36
  parse-position?
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    37
  (file parse-position-file)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    38
  (line parse-position-line)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    39
  (column parse-position-column))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    40
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    41
(define (top-parse-position filename)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    42
  (make-parse-position filename 1 0))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    43
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    44
(define (update-parse-position pos ch)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    45
  (if (not pos)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    46
      #f
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    47
      (let ((file (parse-position-file pos))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    48
	    (line (parse-position-line pos))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    49
	    (column (parse-position-column pos)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    50
	(cond
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    51
	 ((eq? ch #\return) (make-parse-position file line 0))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    52
	 ((eq? ch #\newline) (make-parse-position file (+ line 1) 0))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    53
	 ((eq? ch #\tab) (make-parse-position file line (* (quotient (+ column 8) 8) 8)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    54
	 (else (make-parse-position file line (+ column 1)))))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    55
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    56
(define (parse-position->string pos)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    57
  (if (not pos)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    58
      "<??>"
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    59
      (string-append (parse-position-file pos) ":"
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    60
		     (number->string (parse-position-line pos)) ":"
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    61
		     (number->string (parse-position-column pos)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    62
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    63
(define (empty-results pos)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    64
  (make-parse-results pos #f #f '()))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    65
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    66
(define (make-results pos base next-generator)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    67
  (make-parse-results pos base next-generator '()))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    68
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    69
(define (make-error-expected pos str)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    70
  (make-parse-error pos (list str) '()))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    71
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    72
(define (make-error-message pos msg)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    73
  (make-parse-error pos '() (list msg)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    74
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    75
(define (make-result semantic-value next)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    76
  (make-parse-result #t semantic-value next #f))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    77
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    78
(define (make-expected-result pos str)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    79
  (make-parse-result #f #f #f (make-error-expected pos str)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    80
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    81
(define (make-message-result pos msg)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    82
  (make-parse-result #f #f #f (make-error-message pos msg)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    83
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    84
(define (prepend-base pos base next)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    85
  (make-parse-results pos base next '()))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    86
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    87
(define (prepend-semantic-value pos key result next)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    88
  (make-parse-results pos #f #f
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    89
		      (list (cons key (make-result result next)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    90
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    91
(define (base-generator->results generator)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    92
  ;; Note: applies first next-generator, to get first result
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    93
  (define (results-generator)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    94
    (let-values (((pos base) (generator)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    95
      (if (not base)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    96
	  (empty-results pos)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    97
	  (make-results pos base results-generator))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    98
  (results-generator))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
    99
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   100
(define (parse-results-next results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   101
  (let ((next (parse-results-next* results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   102
    (if (procedure? next)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   103
	(let ((next-value (next)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   104
	  (set-parse-results-next! results next-value)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   105
	  next-value)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   106
	next)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   107
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   108
(define (results->result results key fn)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   109
  (let ((results-map (parse-results-map results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   110
    (cond
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   111
     ((assq key results-map) => cdr)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   112
     (else (let ((result (fn)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   113
	     (set-parse-results-map! results (cons (cons key result) results-map))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   114
	     result)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   115
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   116
(define (parse-position>? a b)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   117
  (cond
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   118
   ((not a) #f)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   119
   ((not b) #t)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   120
   (else (let ((la (parse-position-line a)) (lb (parse-position-line b)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   121
	   (or (> la lb)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   122
	       (and (= la lb)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   123
		    (> (parse-position-column a) (parse-position-column b))))))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   124
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   125
(define (parse-error-empty? e)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   126
  (and (null? (parse-error-expected-strings e))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   127
       (null? (parse-error-messages e))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   128
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   129
(define (merge-parse-errors e1 e2)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   130
  (cond
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   131
   ((not e1) e2)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   132
   ((not e2) e1)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   133
   (else
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   134
    (let ((p1 (parse-error-position e1))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   135
	  (p2 (parse-error-position e2)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   136
      (cond
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   137
       ((or (parse-position>? p1 p2) (parse-error-empty? e2)) e1)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   138
       ((or (parse-position>? p2 p1) (parse-error-empty? e1)) e2)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   139
       (else (make-parse-error p1
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   140
			       (lset-union string=?
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   141
					   (parse-error-expected-strings e1)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   142
					   (parse-error-expected-strings e2))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   143
			       (append (parse-error-messages e1) (parse-error-messages e2)))))))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   144
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   145
(define (merge-result-errors result errs)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   146
  (make-parse-result (parse-result-successful? result)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   147
		     (parse-result-semantic-value result)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   148
		     (parse-result-next result)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   149
		     (merge-parse-errors (parse-result-error result) errs)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   150
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   151
;---------------------------------------------------------------------------
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   152
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   153
(define (parse-results-token-kind results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   154
  (let ((base (parse-results-base results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   155
    (and base (car base))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   156
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   157
(define (parse-results-token-value results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   158
  (let ((base (parse-results-base results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   159
    (and base (cdr base))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   160
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   161
(define (packrat-check-base token-kind k)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   162
  (lambda (results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   163
    (let ((base (parse-results-base results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   164
      (if (eq? (and base (car base)) token-kind)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   165
	  ((k (and base (cdr base))) (parse-results-next results))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   166
	  (make-expected-result (parse-results-position results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   167
				(if (not token-kind)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   168
				    "end-of-file"
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   169
				    (symbol->string token-kind)))))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   170
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   171
(define (packrat-check parser k)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   172
  (lambda (results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   173
    (let ((result (parser results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   174
      (if (parse-result-successful? result)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   175
	  (merge-result-errors ((k (parse-result-semantic-value result))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   176
				(parse-result-next result))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   177
			       (parse-result-error result))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   178
	  result))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   179
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   180
(define (packrat-or p1 p2)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   181
  (lambda (results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   182
    (let ((result (p1 results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   183
      (if (parse-result-successful? result)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   184
	  result
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   185
	  (merge-result-errors (p2 results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   186
			       (parse-result-error result))))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   187
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   188
(define (packrat-unless explanation p1 p2)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   189
  (lambda (results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   190
    (let ((result (p1 results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   191
      (if (parse-result-successful? result)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   192
	  (make-message-result (parse-results-position results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   193
			       explanation)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   194
	  (p2 results)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   195
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   196
;---------------------------------------------------------------------------
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   197
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   198
(define (object->external-representation o)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   199
  (let ((s (open-output-string)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   200
    (write o s)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   201
    (get-output-string s)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   202
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   203
(define-syntax packrat-parser
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   204
  (syntax-rules (<- quote ! @ /)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   205
    ((_ start (nonterminal (alternative body0 body ...) ...) ...)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   206
     (let ()
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   207
       (define nonterminal
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   208
	 (lambda (results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   209
	   (results->result results 'nonterminal
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   210
			    (lambda ()
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   211
			      ((packrat-parser #f "alts" nonterminal
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   212
					       ((begin body0 body ...) alternative) ...)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   213
			       results)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   214
       ...
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   215
       start))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   216
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   217
    ((_ #f "alts" nt (body alternative))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   218
     (packrat-parser #f "altD" nt body alternative))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   219
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   220
    ((_ #f "alts" nt (body alternative) rest0 rest ...)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   221
     (packrat-or (packrat-parser #f "altD" nt body alternative)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   222
		 (packrat-parser #f "alts" nt rest0 rest ...)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   223
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   224
    ((_ #f "altD" nt body alternative)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   225
     (lambda (results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   226
       ;;(write (list (parse-position->string (parse-results-position results))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   227
       ;;'trying- 'nt 'alternative))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   228
       ;;(newline)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   229
       (let ((result ((packrat-parser #f "alt" nt body alternative) results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   230
	 ;;(write (list (parse-position->string
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   231
	 ;;(parse-results-position results))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   232
	 ;;(if (parse-result-successful? result)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   233
	 ;;'success
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   234
	 ;;'failing)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   235
	 ;;'nt 'alternative))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   236
	 ;;(newline)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   237
	 result)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   238
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   239
    ((_ #f "alt" nt body ())
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   240
     (lambda (results) (make-result body results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   241
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   242
    ((_ #f "alt" nt body ((! fails ...) rest ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   243
     (packrat-unless (string-append "Nonterminal " (symbol->string 'nt)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   244
				    " expected to fail "
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   245
				    (object->external-representation '(fails ...)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   246
		     (packrat-parser #f "alt" nt #t (fails ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   247
		     (packrat-parser #f "alt" nt body (rest ...))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   248
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   249
    ((_ #f "alt" nt body ((/ alternative ...) rest ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   250
     (packrat-check (packrat-parser #f "alts" nt (#t alternative) ...)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   251
		    (lambda (result) (packrat-parser #f "alt" nt body (rest ...)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   252
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   253
    ((_ #f "alt" nt body (var <- 'val rest ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   254
     (packrat-check-base 'val
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   255
			 (lambda (var)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   256
			   (packrat-parser #f "alt" nt body (rest ...)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   257
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   258
    ((_ #f "alt" nt body (var <- @ rest ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   259
     (lambda (results)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   260
       (let ((var (parse-results-position results)))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   261
	 ((packrat-parser #f "alt" nt body (rest ...)) results))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   262
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   263
    ((_ #f "alt" nt body (var <- val rest ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   264
     (packrat-check val
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   265
		    (lambda (var)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   266
		      (packrat-parser #f "alt" nt body (rest ...)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   267
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   268
    ((_ #f "alt" nt body ('val rest ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   269
     (packrat-check-base 'val
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   270
			 (lambda (dummy)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   271
			   (packrat-parser #f "alt" nt body (rest ...)))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   272
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   273
    ((_ #f "alt" nt body (val rest ...))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   274
     (packrat-check val
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   275
		    (lambda (dummy)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   276
		      (packrat-parser #f "alt" nt body (rest ...)))))))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   277
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   278
'(define (x)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   279
  (sc-expand
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   280
   '(packrat-parser expr
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   281
		    (expr ((a <- 'num '+ b <- 'num)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   282
			   (+ a b))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   283
			  ((a <- mulexp) a))
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   284
		    (mulexp ((a <- 'num '* b <- 'num)
d6dba34d7b01 Avoid polluting toplevel namespace with example code.
Tony Garnock-Jones <tonyg@lshift.net>
parents:
diff changeset
   285
			     (* a b))))))