chiark / gitweb /
src/lexer-{proto,impl}.lisp: Add explicit recovery action to `error'.
[sod] / src / lexer-proto.lisp
index d5f25fd5d9c5df5100895f546cfe5871d6b25978..a811298759a08868bdb4c8c2be3ef2093f0a7fe5 100644 (file)
@@ -112,11 +112,16 @@ (defparse skip-until (:context (context token-scanner-context)
                      &rest token-types)
   "Discard tokens until we find one listed in TOKEN-TYPES.
 
+   Each of the TOKEN-TYPES is an expression which evaluates to either a
+   two-item list (TYPE VALUE), or a singleton TYPE; the latter is equivalent
+   to a list (TYPE t).  Such a pair matches a token with the corresponding
+   TYPE and VALUE, except that a VALUE of `t' matches any token value.
+
    If KEEP-END is true then retain the found token for later; otherwise
    discard it.  KEEP-END defaults to true if multiple TOKEN-TYPES are given;
    otherwise false.  If end-of-file is encountered then the indicator list is
    simply the list of TOKEN-TYPES; otherwise the result is `nil'."
-  `(skip-until ,(parser-scanner context)
+  `(%skip-until ,(parser-scanner context)
               (list ,@token-types)
               :keep-end ,(if keep-end-p keep-end
                              (> (length token-types) 1))))
@@ -124,7 +129,7 @@ (defparse skip-until (:context (context token-scanner-context)
 (export 'error)
 (defparse error (:context (context token-scanner-context)
                 (&key ignore-unconsumed force-progress)
-                sub &optional (recover t))
+                sub &optional (recover t) &body body)
   "Try to parse SUB; if it fails then report an error, and parse RECOVER.
 
    This is the main way to recover from errors and continue parsing.  Even
@@ -143,7 +148,8 @@ (defparse error (:context (context token-scanner-context)
                        (parser () ,sub)
                        (parser () ,recover)
                        :ignore-unconsumed ,ignore-unconsumed
-                       :force-progress ,force-progress))
+                       :force-progress ,force-progress
+                       :action ,(and body `(lambda () ,@body))))
 
 (export 'must)
 (defparse must (:context (context token-scanner-context)