X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/blobdiff_plain/40d95de71fca4c3b7b145d5ba73d1420e8854673..refs/heads/mdw/progfmt:/src/lexer-proto.lisp diff --git a/src/lexer-proto.lisp b/src/lexer-proto.lisp index d5f25fd..a237a92 100644 --- a/src/lexer-proto.lisp +++ b/src/lexer-proto.lisp @@ -65,6 +65,14 @@ (define-condition syntax-error (parser-error base-syntax-error) (:char "") (:eof "") (:ellipsis "`...'") + (:shl "`<<'") + (:shr "`>>'") + (:eq "`=='") + (:ne "`!='") + (:le "`<='") + (:ge "`>='") + (:and "`&&'") + (:or "`||'") (t (format nil "" type value))))) (show-expected (thing) (acond ((gethash thing *indicator-map*) it) @@ -112,11 +120,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 +137,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 +156,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)