Fix operator parsing

This commit is contained in:
Alexander Rosenberg 2024-09-16 03:08:29 -07:00
parent 6f8135238b
commit 53388e6d56
Signed by: Zander671
GPG Key ID: 5FD0394ADBD72730

View File

@ -86,6 +86,20 @@ proposition."))
(iff "<->" "<>" "<=>" "⇔" "↔" "≡" "iff" "=" "==" "xnor" "⊙")) (iff "<->" "<>" "<=>" "⇔" "↔" "≡" "iff" "=" "==" "xnor" "⊙"))
"Alist table of operator symbols and their possible string representations.") "Alist table of operator symbols and their possible string representations.")
(defun alpha-string-p (str)
"Return t if STR is only alphabetical characters."
(not (find-if-not 'alpha-char-p str)))
(defparameter *longest-non-alpha-operator*
(apply 'max (mapcar
(lambda (entry)
(apply 'max
(mapcar 'length
(remove-if 'alpha-string-p (cdr entry)))))
*operator-symbol-table*))
"The longest operator in `*operator-symbol-table*' such that `alpha-string-p'
returns t.")
(defparameter *operator-descriptions* ;; noindent 30 (defparameter *operator-descriptions* ;; noindent 30
`((open-paren ("open parenthesis") `((open-paren ("open parenthesis")
,(format nil "Used in combination with a close parenthesis to denote ~ ,(format nil "Used in combination with a close parenthesis to denote ~
@ -202,6 +216,18 @@ a variable."
(unless (zerop (length str)) (unless (zerop (length str))
(elt str 0))) (elt str 0)))
(defun try-find-operator-for-token (token)
"Return the operator symbol for TOKEN, if it is an operator. As a second
value, return the matched portion of TOKEN. If no match is found, return
(values nil nil)."
(loop for len downfrom (min *longest-non-alpha-operator* (length token)) to 1
for cur-test = (subseq token 0 len)
for oper-sym = (operator-symbol cur-test)
when oper-sym do
(return-from try-find-operator-for-token
(values oper-sym cur-test)))
(values nil nil))
(defun next-symbol-token (str &key multi-char-names) (defun next-symbol-token (str &key multi-char-names)
"Return the next token from STR that is not a paren. If MULTI-CHAR-NAMES is "Return the next token from STR that is not a paren. If MULTI-CHAR-NAMES is
non-nil, allow names to be more than one character long." non-nil, allow names to be more than one character long."
@ -219,13 +245,13 @@ non-nil, allow names to be more than one character long."
(return (return
(string (string
(cond (cond
;; single character unary operand ;; operator
((let ((val (operator-symbol (string (first token))))) ((multiple-value-bind (sym match)
(and (symbolp val) (unary-p val))) (try-find-operator-for-token str)
(first token)) (declare (ignorable sym))
;; multi-char variable, constant (true or false), or operator match))
;; multi-char variable, constant (true or false)
((or multi-char-names ((or multi-char-names
(operator-symbol str)
(symbolp (interpret-operand str))) (symbolp (interpret-operand str)))
str) str)
;; single letter variable (multi-char-names is off) ;; single letter variable (multi-char-names is off)