It's usually, or at least often, the wrong thing to do. Consider, for
example, how to recover from trying to parse
( list[x] )
when presented with
( )
Instead, add a `:force-progress' argument to the `error' parser. The
default is /not/ to consume a token; I think this is right.
\end{describe}
\begin{describe}{parseform}
\end{describe}
\begin{describe}{parseform}
- {error (@[[ :ignore-unconsumed @<flag> @]]) \\ \ind
+ {error (@[[ :ignore-unconsumed @<flag> @!
+ :force-process @<flag> @]]) \\ \ind
@<sub-parser> @<recover-parser>}
\end{describe}
@<sub-parser> @<recover-parser>}
\end{describe}
(return (values token-types nil consumedp)))
(scanner-step scanner)))
(return (values token-types nil consumedp)))
(scanner-step scanner)))
-(defun parse-error-recover (scanner parser recover &key ignore-unconsumed)
+(defun parse-error-recover (scanner parser recover
+ &key ignore-unconsumed force-progress)
"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
;; current token. Finally, if we are at EOF then our best bet is
;; simply to propagate the current failure back to the caller, but
;; we handled that case above.
;; current token. Finally, if we are at EOF then our best bet is
;; simply to propagate the current failure back to the caller, but
;; we handled that case above.
- (syntax-error scanner result :continuep t)
- (unless consumedp (scanner-step scanner))
+ (syntax-error scanner result)
+ (when (and force-progress (not consumedp)) (scanner-step scanner))
(funcall recover)))))
;;;--------------------------------------------------------------------------
(funcall recover)))))
;;;--------------------------------------------------------------------------
(export 'error)
(defparse error (:context (context token-scanner-context)
(export 'error)
(defparse error (:context (context token-scanner-context)
- (&key ignore-unconsumed)
+ (&key ignore-unconsumed force-progress)
sub &optional (recover t))
"Try to parse SUB; if it fails then report an error, and parse RECOVER.
sub &optional (recover t))
"Try to parse SUB; if it fails then report an error, and parse RECOVER.
`(parse-error-recover ,(parser-scanner context)
(parser () ,sub)
(parser () ,recover)
`(parse-error-recover ,(parser-scanner context)
(parser () ,sub)
(parser () ,recover)
- :ignore-unconsumed ,ignore-unconsumed))
+ :ignore-unconsumed ,ignore-unconsumed
+ :force-progress ,force-progress))
;;;--------------------------------------------------------------------------
;;; Lexical analysis utilities.
;;;--------------------------------------------------------------------------
;;; Lexical analysis utilities.