token-value generic
with-scanner-place macro
-streams-impl.lisp
+streams-proto.lisp
position-aware-input-stream class
position-aware-output-stream class
position-aware-stream class
position-aware-stream-column generic setf
position-aware-stream-line generic setf
-
-streams-proto.lisp
+ stream-line-and-column generic
stream-pathname generic
Classes:
charbuf-scanner t [:after]
simple-binary-operator t [:after]
token-scanner t [:after]
+stream-line-and-column
+ cl:stream
+ position-aware-stream
sb-gray:stream-line-column
position-aware-output-stream
stream-pathname
\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}{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}
\begin{describe}{cls}{file-location}
;; Base class.
-(export '(position-aware-stream
- position-aware-stream-line position-aware-stream-column))
-(defclass position-aware-stream (proxy-stream)
- ((file :initarg :file :initform nil
- :type (or pathname null) :accessor position-aware-stream-file)
- (line :initarg :line :initform 1
- :type fixnum :accessor position-aware-stream-line)
- (column :initarg :column :initform 0
- :type fixnum :accessor position-aware-stream-column))
- (:documentation
- "Character stream which keeps track of the line and column position.
-
- A position-aware-stream wraps an existing character stream and tracks the
- line and column position of the current stream position. A newline
- character increases the line number by one and resets the column number to
- zero; most characters advance the column number by one, but tab advances
- to the next multiple of eight. (This is consistent with Emacs, at least.)
- The position can be read using `stream-line-and-column'.
-
- This is a base class; you probably want `position-aware-input-stream' or
- `position-aware-output-stream'."))
-
-(defgeneric stream-line-and-column (stream)
- (:documentation
- "Returns the current stream position of STREAM as line/column numbers.
-
- Returns two values: the line and column numbers of STREAM's input
- position.")
- (:method ((stream stream))
- (values nil nil))
- (:method ((stream position-aware-stream))
- (with-slots (line column) stream
- (values line column))))
+(defmethod stream-line-and-column ((stream position-aware-stream))
+ (with-slots (line column) stream
+ (values line column)))
(defmethod stream-pathname ((stream position-aware-stream))
"Return the pathname corresponding to a `position-aware-stream'.
;; Input stream.
-(export 'position-aware-input-stream)
-(defclass position-aware-input-stream
- (position-aware-stream proxy-character-input-stream)
- ()
- (:documentation
- "A character input stream which tracks the input position.
-
- This is particularly useful for parsers and suchlike, which want to
- produce accurate error-location information."))
-
(defmethod stream-unread-char ((stream position-aware-input-stream) char)
;; I could have written this as a :before or :after method, but I think
;; Output stream.
-(export 'position-aware-output-stream)
-(defclass position-aware-output-stream
- (position-aware-stream proxy-character-output-stream)
- ()
- (:documentation
- "A character output stream which tracks the output position.
-
- This is particularly useful when generating C code: the position can be
- used to generate `#line' directives referring to the generated code after
- insertion of some user code."))
-
(defmethod stream-write-sequence
((stream position-aware-output-stream) seq
#+clisp &key #-clisp &optional (start 0) end)
(cl:in-package #:sod-parser)
;;;--------------------------------------------------------------------------
-;;; Discovery of file names.
+;;; Discovery of file names and stream positions.
(export 'stream-pathname)
(defgeneric stream-pathname (stream)
(:method ((stream stream)) nil)
(:method ((stream file-stream)) (pathname stream)))
+(export 'stream-line-and-column)
+(defgeneric stream-line-and-column (stream)
+ (:documentation
+ "Returns the current stream position of STREAM as line/column numbers.
+
+ Returns two values: the line and column numbers of STREAM's input
+ position, or nil if the stream isn't capable of tracking these things.")
+ (:method ((stream stream))
+ (values nil nil)))
+
+;;;--------------------------------------------------------------------------
+;;; Enhanced stream classes.
+
+(export '(position-aware-stream
+ position-aware-stream-line position-aware-stream-column))
+(defclass position-aware-stream (proxy-stream)
+ ((file :initarg :file :initform nil
+ :type (or pathname null) :accessor position-aware-stream-file)
+ (line :initarg :line :initform 1
+ :type fixnum :accessor position-aware-stream-line)
+ (column :initarg :column :initform 0
+ :type fixnum :accessor position-aware-stream-column))
+ (:documentation
+ "Character stream which keeps track of the line and column position.
+
+ A position-aware-stream wraps an existing character stream and tracks the
+ line and column position of the current stream position. A newline
+ character increases the line number by one and resets the column number to
+ zero; most characters advance the column number by one, but tab advances
+ to the next multiple of eight. (This is consistent with Emacs, at least.)
+ The position can be read using `stream-line-and-column'.
+
+ This is a base class; you probably want `position-aware-input-stream' or
+ `position-aware-output-stream'."))
+
+(export 'position-aware-input-stream)
+(defclass position-aware-input-stream
+ (position-aware-stream proxy-character-input-stream)
+ ()
+ (:documentation
+ "A character input stream which tracks the input position.
+
+ This is particularly useful for parsers and suchlike, which want to
+ produce accurate error-location information."))
+
+(export 'position-aware-output-stream)
+(defclass position-aware-output-stream
+ (position-aware-stream proxy-character-output-stream)
+ ()
+ (:documentation
+ "A character output stream which tracks the output position.
+
+ This is particularly useful when generating C code: the position can be
+ used to generate `#line' directives referring to the generated code after
+ insertion of some user code."))
+
;;;----- That's all, folks --------------------------------------------------