%%%----- 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
\begin{describe}{fun}{combine-parser-failures @<failures> @> @<list>}
\end{describe}
+\begin{describe}{fun}{parse-empty \&optional @<value> @> @<function>}
+\end{describe}
+
+\begin{describe}{fun}
+ {parse-fail @<indicator> \&optional @<consumedp> @> @<function>}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Streams} \label{sec:parsing.streams}
+
+\begin{describe*}
+ {\dhead{cls}{position-aware-stream \&key :file :line :column}
+ \dhead{gf}{position-aware-stream-file @<stream> @> @<pathname>}
+ \dhead{gf}{setf (position-aware-stream-file @<stream>) @<pathname>}
+ \dhead{gf}{position-aware-stream-line @<stream> @> @<fixnum>}
+ \dhead{gf}{setf (position-aware-stream-line @<stream>) @<fixnum>}
+ \dhead{gf}{position-aware-stream-column @<stream> @> @<fixnum>}
+ \dhead{gf}{setf (position-aware-stream-column @<stream>) @<fixnum>}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{cls}{position-aware-input-stream \&key :file :line :column}
+ \dhead{cls}{position-aware-output-stream \&key :file :line :column}}
+\end{describe*}
+
+\begin{describe}{gf}{stream-pathname @<stream> @> @<pathname-or-nil>}
+ \begin{describe}{meth}{stream}
+ {stream-pathname (@<stream> stream) @> nil}
+ \end{describe}
+ \begin{describe}{meth}{file-stream}
+ {stream-pathname (@<stream> file-stream) @> @<pathname>}
+ \end{describe}
+ \begin{describe}{meth}{position-aware-stream}
+ {stream-pathname (@<stream> position-aware-stream) @> @<pathname>}
+ \end{describe}
+\end{describe}
+
+\begin{describe}{gf}{stream-line-and-column @<stream> @> @<line> @<column>}
+ \begin{describe}{meth}{stream}
+ {stream-line-and-column (@<stream> stream) @> nil nil}
+ \end{describe}
+ \begin{describe}{meth}{position-aware-stream}
+ {stream-line-and-column (@<stream> position-aware-stream)
+ \nlret @<line> @<column>}
+ \end{describe}
+\end{describe}
+
%%%--------------------------------------------------------------------------
\section{File locations} \label{sec:parsing.floc}
\end{describe*}
\begin{describe}{gf}{file-location @<object> @> @<floc>}
- \begin{describe}{meth}{file-location (@<floc> file-location) @> @<floc>}
+ \begin{describe}{meth}{file-location}
+ {file-location (@<floc> file-location) @> @<floc>}
\end{describe}
- \begin{describe}{meth}{file-location (@<stream> stream) @> @<floc>}
+ \begin{describe}{meth}{stream}
+ {file-location (@<stream> stream) @> @<floc>}
\end{describe}
- \begin{describe}{meth}{file-location (@<any> t) @> @<floc>}
+ \begin{describe}{meth}{t}
+ {file-location (@<any> t) @> @<floc>}
\end{describe}
\end{describe}
\begin{describe}{cls}{condition-with-location (condition) \&key :location}
\end{describe}
-\begin{describe}{meth}
+\begin{describe}{meth}{condition-with-location}
{file-location (@<condition> condition-with-location) @> @<floc>}
\end{describe}
\begin{describe*}
{\quad\=\quad\=\kill
\dhead{cls}
- {error-with-location (condition-with-location error) \\ \>
- \&key :location}
- \dhead{cls}
- {warning-with-location (condition-with-location warning) \\ \>
- \&key :location}
- \dhead{cls}
- {enclosing-error-with-location
- (enclosing-error-with-location error) \\ \>
- \&key :condition :location}
- \dhead{cls}
- {enclosing-warning-with-location
- (enclosing-condition-with-location warning) \\ \>
- \&key :condition :location}
+ {error-with-location (condition-with-location error) \\ \>
+ \&key :location}
+ \dhead{cls}
+ {warning-with-location (condition-with-location warning) \\ \>
+ \&key :location}
+ \dhead{cls}
+ {information-with-location (condition-with-location information) \\ \>
+ \&key :location}
+ \dhead{cls}
+ {enclosing-condition-with-location (condition) \\ \>
+ \&key :location}
+ \dhead{cls}
+ {enclosing-error-with-location
+ (enclosing-error-with-location error) \\ \>
+ \&key :condition :location}
+ \dhead{cls}
+ {enclosing-warning-with-location
+ (enclosing-condition-with-location warning) \\ \>
+ \&key :condition :location}
\dhead{cls}
- {simple-condition-with-location
- (condition-with-location simple-condition) \\ \>
- \&key :format-control :format-arguments :location}
+ {enclosing-information-with-location
+ (enclosing-condition-with-location information) \\ \>
+ \&key :condition :location}
\dhead{cls}
- {simple-error-with-location
- (error-with-location simple-error) \\ \>
- \&key :format-control :format-arguments :location}
- \dhead{cls}
- {simple-warning-with-location
- (warning-with-location simple-warning) \\ \>
- \&key :format-control :format-arguments :location}}
+ {simple-condition-with-location
+ (condition-with-location simple-condition) \\ \>
+ \&key :format-control :format-arguments :location}
+ \dhead{cls}
+ {simple-error-with-location
+ (error-with-location simple-error) \\ \>
+ \&key :format-control :format-arguments :location}
+ \dhead{cls}
+ {simple-warning-with-location
+ (warning-with-location simple-warning) \\ \>
+ \&key :format-control :format-arguments :location}
+ \dhead{cls}
+ {simple-information-with-location
+ (information-with-location simple-information) \\ \>
+ \&key :format-control :format-arguments :location}}
\end{describe*}
+\begin{describe}{gf}
+ {enclosing-condition-with-location-type @<condition> @> @<symbol>}
+\end{describe}
+
\begin{describe}{fun}
{make-condition-with-location @<default-type> @<floc>
@<datum> \&rest @<arguments>
\dhead{fun}{cerror-with-location @<floc> @<continue-string>
@<datum> \&rest @<arguments>}
\dhead{fun}{cerror*-with-location @<floc> @<datum> \&rest @<arguments>}
- \dhead{fun}{warn-with-location @<floc> @<datum> \&rest @<arguments>}}
+ \dhead{fun}{warn-with-location @<floc> @<datum> \&rest @<arguments>}
+ \dhead{fun}{info-with-location @<floc> @<datum> \&rest @<arguments>}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{cls}{parser-error (error) \\ \ind
+ \&key :expected :found \-}
+ \dhead{gf}{parser-error-expected @<condition> @> @<list>}
+ \dhead{gf}{parser-error-found @<condition> @> @<value>}}
+\end{describe*}
+
+\begin{describe}{fun}
+ {report-parser-error @<error> @<stream> @<show-expected> @<show-found>}
+\end{describe}
+
+\begin{describe*}
+ {\quad\=\kill
+ \dhead{cls}{base-lexer-error (error-with-location) \&key :location}
+ \dhead{cls}{simple-lexer-error
+ (base-lexer-error simple-error-with-location) \\\>
+ \&key :format-control :format-arguments :location}
+ \dhead{cls}{base-syntax-error (error-with-location) \&key :location}
+ \dhead{cls}{simple-syntax-error
+ (base-syntax-error simple-error-with-location) \\\>
+ \&key :format-control :format-arguments :location}}
\end{describe*}
\begin{describe}{mac}
- {with-default-error-location (@<floc>) @<body-form>^* @> @<value>^*}
+ {with-default-error-location (@<floc>) @<declaration>^* @<form>^*
+ @> @<value>^*}
+\end{describe}
+
+\begin{describe}{gf}{classify-condition @<condition> @> @<string>}
+ \begin{describe*}
+ {\dhead{meth}{error}
+ {classify-condition (@<condition> error) @> @<string>}
+ \dhead{meth}{warning}
+ {classify-condition (@<condition> warning) @> @<string>}
+ \dhead{meth}{information}
+ {classify-condition (@<condition> information)
+ @> @<string>}
+ \dhead{meth}{base-lexer-error}
+ {classify-condition (@<condition> base-lexer-error)
+ @> @<string>}
+ \dhead{meth}{base-syntax-error}
+ {classify-condition (@<condition> base-syntax-error)
+ @> @<string>}}
+ \end{describe*}
\end{describe}
\begin{describe}{mac}
- {count-and-report-errors () @<body-form>^*
+ {count-and-report-errors () @<declaration>^* @<form>^*
@> @<value> @<n-errors> @<n-warnings>}
\end{describe}
allows rewinding the scanner to an earlier point in the input so that it can
be scanned again.
+
\subsection{Basic scanner protocol} \label{sec:parsing.scanner.basic}
The basic protocol supports stepping the scanner forward through its input
step the scanner.
\end{describe}
+
\subsection{Place-capture scanner protocol} \label{sec:parsing.scanner.place}
The place-capture protocol allows rewinding to an earlier point in the
rewound to the position held in it.
Depending on how the scanner works, holding onto a captured place might
-consume a lot of memory or case poor performance. For example, if the
+consume a lot of memory or cause poor performance. For example, if the
scanner is reading from an input stream, having a captured place means that
data from that point on must be buffered in case the program needs to rewind
the scanner and read that data again. Therefore it's possible to
\end{describe}
\begin{describe}{mac}
- {with-scanner-place (@<place> @<scanner>) @<body-form>^* @> @<value>^*}
- Capture the @<scanner>'s current position as a place, evaluate the
- @<body-form>s as an implicit progn with the variable @<place> bound to the captured
- place. When control leaves the @<body-form>s, the place is released. The return
- values are the values of the final @<body-form>.
+ {with-scanner-place (@<place> @<scanner>) @<declarations>^* @<form>^*
+ @> @<value>^*}
+ Capture the @<scanner>'s current position as a place, evaluate the @<form>s
+ as an implicit progn with the variable @<place> bound to the captured
+ place. When control leaves the @<form>s, the place is released. The
+ return values are the values of the final @<form>.
\end{describe}
+
\subsection{Scanner file-location protocol} \label{sec:parsing.scanner.floc}
Some scanners participate in the file-location protocol
return nil.
\end{describe*}
+
\subsection{Character scanners} \label{sec:parsing.scanner.char}
Character scanners are scanners which read sequences of characters.
\begin{describe}{gf}{scanner-unread @<scanner> @<character>}
Rewind the @<scanner> by one step. The @<chararacter> must be the previous
current character, and becomes the current character again. It is an error
- if: the @<scanner> has reached end-of-file; the @<scanner> is never been
+ if: the @<scanner> has reached end-of-file; the @<scanner> has never been
stepped; or @<character> was not the previous current character.
\end{describe}
character scanner protocols is suitable. See @|make-scanner-stream|.
\end{describe}
+
\subsection{String scanners} \label{sec:parsing.scanner.string}
A \emph{string scanner} is a simple kind of character scanner which reads
to the end of the @<string>).
\end{describe}
+
\subsection{Character buffer scanners} \label{sec:parsing.scanner.charbuf}
A \emph{character buffer scanner}, or \emph{charbuf scanner} for short, is an
the scanner will update the location as it reads its input.
\end{describe}
+\begin{describe}{cls}
+ {charbuf-scanner-stream (character-scanner-stream) \&key :scanner}
+\end{describe}
+
\begin{describe}{cls}{charbuf-scanner-place}
The class of place objects captured by a charbuf scanner.
\end{describe}
\begin{describe}{gf}
{charbuf-scanner-map @<scanner> @<func> \&optional @<fail>
- \nlret @<result> @<successp> @<consumedp>}
+ \nlret @<result> @<success-flag> @<consumed-flag>}
Read characters from the @<scanner>'s buffers.
This is intended to be an efficient and versatile interface for reading
characters from a scanner in bulk. The function @<func> is invoked
repeatedly, as if by
\begin{prog}
- (multiple-value-bind (@<donep> @<used>) \\ \ind\ind
- (funcall @<func> @<buf> @<start> @<end>) \- \\
+ (multiple-value-bind (@<donep> @<used>) \\ \ind\ind
+ (funcall @<func> @<buf> @<start> @<end>) \-\\
\textrm\ldots)
\end{prog}
The argument @<buf> is a simple string; @<start> and @<end> are two
@<start> (inclusive) and @<end> (exclusive) should be processed. If
@<func>'s return value @<donep> is nil then @<used> is ignored: the
function has consumed the entire buffer and wishes to read more. If
- @<donep> is non-nil, then it must be a fixnum such that $@<start> \le
+ @<donep> is non-nil, then @<used> must be a fixnum such that $@<start> \le
@<used> \le @<end>$: the function has consumed the buffer as far as @<used>
(exclusive) and has completed successfully.
fails: the @<fail> function is called with no arguments, and is expected to
return two values. If omitted, @<fail> defaults to
\begin{prog}
- (lambda () \\ \ind
- (values nil nil))%
+ (lambda () \\ \ind
+ (values nil nil))
\end{prog}
The @|charbuf-scanner-map| function returns three values. The first value
at least once, or with $@<used> > @<start>$.
\end{describe}
+
\subsection{Token scanners} \label{sec:parsing.scanner.token}
\begin{describe}{cls}
{token-scanner () \&key :filename (:line 1) (:column 0)}
\end{describe}
+\begin{describe*}
+ {\dhead{gf}{setf (scanner-line @<scanner>) @<fixnum>}
+ \dhead{gf}{setf (scanner-column @<scanner>) @<fixnum>}}
+\end{describe*}
+
\begin{describe}{gf}{token-type @<scanner> @> @<type>}
\end{describe}
{token-scanner-place-p @<value> @> @<generalized-boolean>}
\end{describe}
+
\subsection{List scanners}
\begin{describe}{ty}{list-scanner}
\end{describe}
%%%--------------------------------------------------------------------------
-\section{Parsing syntax}
+\section{Parser contexts and parser syntax} \label{sec:parsing.syntax}
+
+
+\subsection{Parser contexts} \label{sec:parsing.syntax.contexts}
+
+\begin{describe}{mac}
+ {with-parser-context
+ (@<context-class> @{ @<init-keyword> @<value> @}^*) \\ \ind
+ @<declaration>^* \\
+ @<form>^*
+ \-\nlret @<value>^*}
+\end{describe}
\begin{describe}{gf}{expand-parser-spec @<context> @<spec> @> @<form>}
\end{describe}
\begin{describe}{mac}
{defparse @<name> (@[[ :context (@<var> @<context-class>) @]]
- @<destructuring-lambda-list-item>^*) \\ \ind
- @<body-form>^* \-
- \nlret @<name>}
-\end{describe}
-
-\begin{describe}{mac}
- {with-parser-context
- (@<context-class> @{ @<init-keyword> @<value> @}^*) \\ \ind
- @<body-form>^* \-
- \nlret @<value>^*}
+ @<destructuring-lambda-list-item>^*) \\ \ind
+ @[[ @<declaration>^* @! @<doc-string> @]] \\
+ @<form>^*
+ \-\nlret @<name>}
\end{describe}
\begin{describe}{lmac}
{parse @<parser> @> @<result> @<success-flag> @<consumed-flag>}
\end{describe}
-\begin{describe}{gf}{parser-at-eof-p @<context> @> @<form>}
+\begin{describe}{mac}
+ {parser @<lambda-list>
+ @[[ @<declaration>^* @! @<doc-string> @]]
+ @<parser>
+ @> @<function>}
\end{describe}
-\begin{describe}{gf}{parser-step @<context> @> @<form>}
+\begin{describe}{gf}{parser-at-eof-p @<context> @> @<form>}
\end{describe}
-\begin{describe}{sym}{it}
+\begin{describe}{gf}{parser-step @<context> @> @<form>}
\end{describe}
\begin{describe}{mac}
{if-parse (@[[ \=:result @<result-var> @!
- :expected @<expected-var> @! \+ \\
- :consumedp @<consumed-var> @]]) \- \\ \ind\ind
- @<parser> \- \\
- @<consequent> \\
- @[@<alternatve>@] \-
- \nlret @<value>^*}
+ :expected @<expected-var> @! \+\\
+ :consumedp @<consumed-var> @]]) \-\\ \ind\ind
+ @<parser> \-\\
+ @<consequent> \\
+ @[@<alternatve>@]
+ \-\nlret @<value>^*}
\end{describe}
\begin{describe}{mac}
- {when-parse (@[@<result-var>@]) @<parser> \\ \ind
- @<body-form>^* \-
- \nlret @<value>^*}
+ {when-parse (@[@<result-var>@]) @<parser> \\ \ind
+ @<form>^*
+ \-\nlret @<value>^*}
\end{describe}
\begin{describe}{mac}
{cond-parse (@[[ \=:result @<result-var> @!
- :expected @<expected-var> @! \+ \\
- :consumedp @<consumed-var> @]]) \- \\ \ind
- @{ (@<parser> @<form>^*) @}^* \-
- \nlret @<value>^*}
+ :expected @<expected-var> @! \+\\
+ :consumedp @<consumed-var> @]]) \-\\ \ind
+ @{ (@<parser> @<form>^*) @}^*
+ \-\nlret @<value>^*}
\end{describe}
+\begin{describe}{cls}{list-parser () \&key :var}
+\end{describe}
+
+
+\subsection{Basic parser syntax} \label{sec:parsing.syntax.basic}
+
\begin{describe}{parse}{:eof}
\end{describe}
\end{describe}
\begin{describe}{parseform}
- {seq (@{ @<atomic-parser-spec> @! (@[@<var>@] @<parser>) @}^*) \\ \ind
- @<body-form>^*}
+ {seq (@{ @<atomic-parser-spec> @!
+ (@[@<var>@] @<parser>) @}^*) \\ \ind
+ @<form>^*}
\end{describe}
\begin{describe}{parseform}{and @<parser>^*}
\end{describe}
\begin{describe}{parseform}
- {many (\=@<accumulator-var> @<init-form> @<update-form> \+ \\
- @[[ \=:new @<new-var> @! :final @<final-form> @! \+ \\
- :min @<minimum> @! :max @<maximum> @! \\
- :commitp @<commitp> @]]) \-\- \\ \ind
+ {many (\=@<accumulator-var> @<init-form> @<update-form> \+\\
+ @[[ \=:new @<new-var> @! :final @<final-form> @! \+\\
+ :min @<minimum> @! :max @<maximum> @! \\
+ :commitp @<commitp> @]]) \-\-\\ \ind
@<item-parser> @[@<sep-parser>@]}
\end{describe}
\begin{describe}{parseform}
{list (@[[ :min @<minimum> @! :max @<maximum> @!
- :commitp @<commitp> @]])\\ \ind
+ :commitp @<commitp> @]]) \\ \ind
@<item-parser> @[@<sep-parser>@]}
\end{describe}
\begin{describe}{parseform}
{skip-many (@[[ :min @<minimum> @! :max @<maximum> @!
- :commitp @<commitp> @]])\\ \ind
+ :commitp @<commitp> @]]) \\ \ind
@<item-parser> @[@<sep-parser>@]}
\end{describe}
\end{describe}
\begin{describe}{mac}
- {define-pluggable-parser @<symbol> @<tag> @<lambda-list> @<body-form>^*}
+ {define-pluggable-parser @<symbol> @<tag> @<lambda-list>
+ @[[ @<declaration>^* @! @<doc-string> @]]
+ @<form>^*}
\end{describe}
+
+\subsection{Place-capture protocol} \label{sec:parsing.syntax.place}
+
\begin{describe}{gf}{parser-capture-place @<context> @> @<form>}
\end{describe}
\end{describe}
\begin{describe}{gf}
- {parser-places-must-be-released-p @<context> @> @<generalized-boolean>>}
+ {parser-places-must-be-released-p @<context> @> @<generalized-boolean>}
\end{describe}
\begin{describe}{mac}
- {with-parser-place (@<place-var> @<context>) @<body-form>^*}
+ {with-parser-place (@<place-var> @<context>)
+ @[[ @<declaration>^* @! @<doc-string> @]]
+ @<form>^*}
\end{describe}
\begin{describe}{parseform}{peek @<parser>}
\end{describe}
+\begin{describe}{parseform}{commit}
+\end{describe}
+
+
+\subsection{Character parsers} \label{sec:parsing.syntax.character}
+
\begin{describe}{cls}{character-parser-context () \&key}
\end{describe}
\begin{describe}{gf}{parser-current-char @<context> @> @<form>}
\end{describe}
+\begin{describe}{cls}
+ {string-parser (character-parser-context) \&key :string :index :length}
+\end{describe}
+
\begin{describe}{parseform}
{if-char (@[@<result-var>@]) @<condition> @<consequent> @<alternative>}
\end{describe}
\begin{describe}{parseform}{char @<character>}
\end{describe}
-\begin{describe}[char]{parse}{@<character>}
+\begin{describe}{parse}[char]{@<character>}
\end{describe}
-\begin{describe}[string]{parse}{@<string>}
+\begin{describe}{parse}[string]{@<string>}
\end{describe}
\begin{describe}{parse}{:any}
\begin{describe}{parseform}{token @<type> @[@<value>@] @[:peekp @<peek>@]}
\end{describe}
-\begin{describe}[atom]{parse}{@<atom>}
+\begin{describe}{parse}[atom]{@<atom>}
\end{describe}
-\begin{describe}[string]{parse}{@<string>}
-\end{describe}
+
+\subsection{Scanner contexts} \label{sec:parsing.syntax.scanner}
\begin{describe}{cls}{scanner-context () \&key :scanner}
\end{describe}
-\begin{describe}{gf}{parse-scanner @<context> @> @<symbol>}
+\begin{describe}{gf}{parser-scanner @<context> @> @<symbol>}
\end{describe}
\begin{describe}{cls}
\&key :scanner}
\end{describe}
-%% FIXME parser-expr
+
+\subsection{Expression parsing} \label{sec:parsing.syntax.expression}
+
+\begin{describe}{gf}{operator-push-action @<left> @<right>}
+\end{describe}
+
+\begin{describe}{parseform}
+ {expr \=(@[[ :nestedp @<nestedp-var> @]]) \+\\
+ @<operand-parser> @<binop-parser>
+ @<preop-parser> @<postop-parser>}
+\end{describe}
+
+\begin{describe}{gf}{operator-left-precedence @<operator> @> @<prec>}
+\end{describe}
+
+\begin{describe}{gf}{operator-right-precedence @<operator> @> @<prec>}
+\end{describe}
+
+\begin{describe}{gf}{operator-associativity @<operator> @> @<assoc>}
+\end{describe}
+
+\begin{describe}{cls}{prefix-operator () \&key}
+\end{describe}
+
+\begin{describe}{cls}{simple-operator () \&key :name :function}
+\end{describe}
+
+\begin{describe}{cls}
+ {simple-unary-operator (simple-operator) \&key :name :function}
+\end{describe}
+
+\begin{describe*}
+ {\quad\=\kill
+ \dhead{cls}{simple-binary-operator (simple-operator) \\ \>
+ \&key :name :function
+ :lprec :rprec :associativity}
+ \dhead{cls}{simple-postfix-operator (simple-unary-operator) \\ \>
+ \&key :name :function :lprec :rprec}
+ \dhead{cls}{simple-prefix-operator
+ (prefix-operator simple-unary-operator) \\ \>
+ \&key :name :function :rprec}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{mac}{preop @<name> (@<operand-var> @<lprec>)
+ @<declaration>^* @<form>^*
+ @> @<prefix-operator>}
+ \dhead{mac}{postop @<name>
+ (@<operand-var> @<lprec> @[[ :rprec @<rprec> @]])
+ @<declaration>^* @<form>^*
+ \nlret @<postfix-operator>}
+ \dhead{mac}{binop @<name> (@<operand-var> @<lprec> @<rprec> @<assoc>)
+ @<declaration>^*@<form>^*
+ @> @<binary-operator>}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{cls}{open-parenthesis (parenthesis prefix-operator) \&key :tag}
+ \dhead{cls}{close-parenthesis (parenthesis) \&key :tag}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{fun}{lparen @<tag> @> @<open-paren>}
+ \dhead{fun}{rparen @<tag> @> @<close-paren>}}
+\end{describe*}
%%%-------------------------------------------------------------------------
-\section{Lexical analyser}
+\section{Lexical analyser} \label{sec:parsing.lexical}
+
+\begin{describe}{cls}
+ {sod-token-scanner (token-scanner)
+ \&key :filename (:line 1) (:column 0) :char-scanner}
+\end{describe}
+
+\begin{describe}{fun}{define-indicator @<indicator> @<description>}
+\end{describe}
+
+\begin{describe*}
+ {\dhead{cls}{lexer-error (parser-error base-lexer-error) \\ \ind
+ \&key :expected :found :location \-}
+ \dhead{cls}{syntax-error (parser-error base-syntax-error) \\ \ind
+ \&key :expected :found :location \-}}
+\end{describe*}
+
+\begin{describe}{fun}
+ {syntax-error @<scanner> @<expected> \&key :continuep :location}
+\end{describe}
+
+\begin{describe}{fun}
+ {lexer-error @<char-scanner> @<expected> \&key :location}
+\end{describe}
+
+\begin{describe}{parseform}
+ {skip-until (@[[ :keep-end @<keep-end-flag> @]]) @<token-type>^*}
+\end{describe}
+
+\begin{describe}{parseform}
+ {error (@[[ :ignore-unconsumed @<flag> @!
+ :force-process @<flag> @]]) \\ \ind\ind
+ @<sub-parser> @<recover-parser> \-\\
+ @<declaration>^* \\
+ @<form>^*}
+\end{describe}
+
+\begin{describe}{parseform}{must @<sub-parser> @[@<default>@]}
+\end{describe}
+
+\begin{describe}{fun}
+ {scan-comment @<char-scanner>
+ @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
%%%----- That's all, folks --------------------------------------------------