This ends up being an `:action' keyword argument to
`parse-error-recover', and a macro body to the `error' parser macro.
\begin{describe}{parseform}
{error (@[[ :ignore-unconsumed @<flag> @!
\begin{describe}{parseform}
{error (@[[ :ignore-unconsumed @<flag> @!
- :force-process @<flag> @]]) \\ \ind
- @<sub-parser> @<recover-parser>}
+ :force-process @<flag> @]]) \\ \ind\ind
+ @<sub-parser> @<recover-parser> \-\\
+ @<declaration>^* \\
+ @<form>^*}
\end{describe}
\begin{describe}{parseform}{must @<sub-parser> @[@<default>@]}
\end{describe}
\begin{describe}{parseform}{must @<sub-parser> @[@<default>@]}
(scanner-step scanner)))
(defun parse-error-recover (scanner parser recover
(scanner-step scanner)))
(defun parse-error-recover (scanner parser recover
- &key ignore-unconsumed force-progress)
+ &key ignore-unconsumed force-progress action)
"This is the implementation of the `error' parser."
(multiple-value-bind (result win consumedp) (funcall parser)
(cond ((or win
"This is the implementation of the `error' parser."
(multiple-value-bind (result win consumedp) (funcall parser)
(cond ((or win
;; simply to propagate the current failure back to the caller, but
;; we handled that case above.
(syntax-error scanner result)
;; simply to propagate the current failure back to the caller, but
;; we handled that case above.
(syntax-error scanner result)
+ (when action (funcall action))
(when (and force-progress (not consumedp)) (scanner-step scanner))
(funcall recover)))))
(when (and force-progress (not consumedp)) (scanner-step scanner))
(funcall recover)))))
(export 'error)
(defparse error (:context (context token-scanner-context)
(&key ignore-unconsumed force-progress)
(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
"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
(parser () ,sub)
(parser () ,recover)
:ignore-unconsumed ,ignore-unconsumed
(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)
(export 'must)
(defparse must (:context (context token-scanner-context)