c816b8d5 |
(in-package :cl-user)
|
0a47c44b |
(defpackage yaml.scalar
|
c816b8d5 |
(:use :cl)
|
fe998b64 |
(:export :parse-scalar :*yaml-11-integers*)
|
c816b8d5 |
(:documentation "Parser for scalar values."))
|
0a47c44b |
(in-package :yaml.scalar)
|
c816b8d5 |
;;; Constants
(defparameter +null+ nil
"The NULL constant. Nil by default.")
(defparameter +false+ nil
"The falsehood constant. Nil by default.")
;;; Regular expressions or lists of names
|
23d3a77f |
(defparameter +quoted-scalar-styles+
(list :single-quoted-scalar-style :double-quoted-scalar-style))
|
c816b8d5 |
(defparameter +null-names+
(list "null" "Null" "NULL" "~"))
(defparameter +true-names+
(list "true" "True" "TRUE"))
(defparameter +false-names+
(list "false" "False" "FALSE"))
(defparameter +integer-scanner+
|
11d2ae66 |
(ppcre:create-scanner "^([-+]?[0-9]+)$"))
|
c816b8d5 |
(defparameter +octal-integer-scanner+
|
11d2ae66 |
(ppcre:create-scanner "^0o([0-7]+)$"))
|
c816b8d5 |
(defparameter +hex-integer-scanner+
|
11d2ae66 |
(ppcre:create-scanner "^0x([0-9a-fA-F]+)$"))
|
c816b8d5 |
(defparameter +float-scanner+
(ppcre:create-scanner
|
11d2ae66 |
"^[-+]?(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$"))
|
c816b8d5 |
|
eb71ef53 |
(defparameter +nan-names+
(list ".nan" ".NaN" ".NAN"))
|
0a47c44b |
(defparameter +positive-infinity-scanner+
|
11d2ae66 |
(ppcre:create-scanner "^[+]?(\\.inf|\\.Inf|\\.INF)$"))
|
0a47c44b |
(defparameter +negative-infinity-scanner+
|
11d2ae66 |
(ppcre:create-scanner "^-(\\.inf|\\.Inf|\\.INF)$"))
|
c816b8d5 |
;;; The actual parser
|
fe998b64 |
(defvar *yaml-11-integers* nil)
(defun parse-yaml-integer (string)
(if (and *yaml-11-integers*
(eql #\0 (elt string 0)))
(if (every (lambda (it)
(member it '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7)))
string)
(parse-integer string :radix 8)
string)
(parse-integer string)))
|
c816b8d5 |
|
23d3a77f |
(defun parse-scalar (string &optional (style :plain-scalar-style))
|
c816b8d5 |
"Parse a YAML scalar string into a Lisp scalar value."
(cond
|
23d3a77f |
;; Quoted string
((member style +quoted-scalar-styles+)
string)
|
c816b8d5 |
;; Null
((member string +null-names+ :test #'equal)
+null+)
;; Truth and falsehood
((member string +true-names+ :test #'equal)
t)
((member string +false-names+ :test #'equal)
+false+)
;; Integers
|
0a47c44b |
((ppcre:scan +integer-scanner+ string)
|
fe998b64 |
(parse-yaml-integer string))
|
0a47c44b |
((ppcre:scan +octal-integer-scanner+ string)
(parse-integer (subseq string 2) :radix 8))
((ppcre:scan +hex-integer-scanner+ string)
(parse-integer (subseq string 2) :radix 16))
|
c816b8d5 |
;; Floating-point numbers
|
c4b97458 |
((ppcre:scan +float-scanner+ string)
(parse-number:parse-real-number string))
|
0a47c44b |
;; Special floats
|
c816b8d5 |
((member string +nan-names+ :test #'equal)
|
0a47c44b |
(yaml.float:not-a-number))
((ppcre:scan +positive-infinity-scanner+ string)
(yaml.float:positive-infinity))
((ppcre:scan +negative-infinity-scanner+ string)
(yaml.float:negative-infinity))
;; Just a string
|
c816b8d5 |
(t
string)))
|