with-default-error-location macro
parser-expr-proto.lisp
- apply-operator generic
binop macro
close-parenthesis class
expr parser-form
postop macro
prefix-operator class
preop macro
- push-operator generic
- push-value generic
rparen function
simple-binary-operator class
simple-operator class
position-aware-input-stream [position-aware-stream]
Methods:
-apply-operator
- open-parenthesis sod-parser::expression-parse-state
- simple-binary-operator sod-parser::expression-parse-state
- simple-unary-operator sod-parser::expression-parse-state
charbuf-scanner-map
charbuf-scanner t
classify-condition
cl:print-object
file-location t
simple-operator t
-push-operator
- t sod-parser::expression-parse-state
- close-parenthesis sod-parser::expression-parse-state
- open-parenthesis sod-parser::expression-parse-state [:after]
- prefix-operator sod-parser::expression-parse-state
-push-value
- t sod-parser::expression-parse-state
scanner-at-eof-p
charbuf-scanner
list-scanner
\subsection{Expression parsing} \label{sec:parsing.syntax.expression}
-\begin{describe}{gf}{push-operator @<operator> @<state>}
-\end{describe}
-
-\begin{describe}{gf}{push-value @<value> @<state>}
-\end{describe}
-
-\begin{describe}{gf}{apply-operator @<operator> @<state>}
-\end{describe}
-
\begin{describe}{gf}{operator-push-action @<left> @<right>}
\end{describe}
(cl:in-package #:sod-parser)
;;;--------------------------------------------------------------------------
-;;; Basic protocol implementation.
+;;; Basic protocol.
(defclass expression-parse-state ()
((opstack :initform nil :type list)
(:documentation
"State for the expression parser. Largely passive."))
-(defmethod push-value (value (state expression-parse-state))
- (with-slots (valstack) state
- (push value valstack)))
+(defgeneric push-operator (operator state)
+ (:documentation
+ "Push an OPERATOR onto the STATE's operator stack.
+
+ This should apply existing stacked operators as necessary to obey the
+ language's precedence rules."))
+
+(defgeneric apply-operator (operator state)
+ (:documentation
+ "Apply the OPERATOR to arguments on the STATE's value stack.
+
+ This should pop any necessary arguments, and push the result."))
(defmethod push-operator (operator (state expression-parse-state))
(with-slots (opstack) state
(push-operator value state)))
(multiple-value-bind (value winp) (parse p-operand)
(unless winp (fail value))
- (push-value value state))
+ (push value (slot-value state 'valstack)))
(loop (multiple-value-bind (value winp) (parse p-postop)
(unless winp (return))
(push-operator value state)))))
;;;--------------------------------------------------------------------------
;;; Basic protocol.
-(export 'push-operator)
-(defgeneric push-operator (operator state)
- (:documentation
- "Push an OPERATOR onto the STATE's operator stack.
-
- This should apply existing stacked operators as necessary to obey the
- language's precedence rules."))
-
-(export 'push-value)
-(defgeneric push-value (value state)
- (:documentation
- "Push VALUE onto the STATE's value stack.
-
- The default method just does that without any fuss. It's unlikely that
- this will need changing unless you invent some really weird values."))
-
-(export 'apply-operator)
-(defgeneric apply-operator (operator state)
- (:documentation
- "Apply the OPERATOR to argument on the STATE's value stack.
-
- This should pop any necessary arguments, and push the result."))
-
(export 'operator-push-action)
(defgeneric operator-push-action (left right)
(:documentation
Prefix operators are special because they are pushed at a time when the
existing topmost operator on the stack may not have its operand
available. It is therefore incorrect to attempt to apply any existing
- operators without careful checking. This class provides a method on
- `push-operator' which immediately pushes the new operator without
- inspecting the existing stack."))
+ operators without careful checking."))
(export 'simple-operator)
(defclass simple-operator ()