X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/239fa5bd3dff0b38b0cebdd3438311f21c24ba4f..678b6c0f7fe1d62abdf249b173a8a922c4e5c1d3:/src/lexer-impl.lisp diff --git a/src/lexer-impl.lisp b/src/lexer-impl.lisp index f474590..7e953ef 100644 --- a/src/lexer-impl.lisp +++ b/src/lexer-impl.lisp @@ -7,7 +7,7 @@ ;;;----- Licensing notice --------------------------------------------------- ;;; -;;; This file is part of the Sensble Object Design, an object system for C. +;;; This file is part of the Sensible Object Design, an object system for C. ;;; ;;; SOD is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by @@ -39,9 +39,6 @@ ;;;-------------------------------------------------------------------------- ;;; Indicators and error messages. -(defvar *indicator-map* (make-hash-table) - "Hash table mapping indicator objects to human-readable descriptions.") - (defun show-char (stream char &optional colonp atsignp) "Format CHAR to STREAM in a readable way. @@ -52,6 +49,45 @@ (format stream "`~C'" char)) (t (format stream "<~(~:C~)>" char)))) +(defun skip-until (scanner token-types &key keep-end) + "This is the implementation of the `skip-until' parser." + (do ((consumedp nil t)) + ((member (token-type scanner) token-types) + (unless keep-end (scanner-step scanner)) + (values nil t (or keep-end consumedp))) + (when (scanner-at-eof-p scanner) + (return (values token-types nil consumedp))) + (scanner-step scanner))) + +(defun parse-error-recover (scanner parser recover &key ignore-unconsumed) + "This is the implementation of the `error' parser." + (multiple-value-bind (result win consumedp) (funcall parser) + (cond ((or win + (and (not consumedp) + (or ignore-unconsumed + (scanner-at-eof-p scanner)))) + ;; If we succeeded, or if we didn't consume any tokens and the + ;; caller's OK with that, then there's nothing for us to do here. + ;; On the other hand, if we failed, didn't consume any tokens, and + ;; we're at end-of-file, then there's not much hope of making + ;; onward progress, so in this case we propagate the failure + ;; rather than trying to recover. And we assume that the + ;; continuation will somehow arrange to report the problem, and + ;; avoid inundating the user with error reports. + (values result win consumedp)) + (t + ;; Now we have to do some kind of sensible error recovery. The + ;; important thing to do here is to make sure that we make some + ;; progress. If we consumed any tokens then we're fine, and we'll + ;; just try the provided recovery strategy. Otherwise, if we're + ;; not at EOF, then we can ensure progress by discarding the + ;; 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)) + (funcall recover))))) + ;;;-------------------------------------------------------------------------- ;;; Token scanning.