yaml-syck - そこそこ速い YAML 1.0 パーサ
(require "yaml-syck") (use-package :yaml-syck) (syck-load " xyzzy: author: Tetsuya Kamei lang: common lisp emacs: author: RMS lang: emacs lisp ") (syck-load-file "config.yaml" :null nil :true t :false nil :nan 0 :inf (symbol-value 'most-positive-long-float) :neginf (symbol-value 'most-negative-long-float) :seq :sexp :map :sexp :timestamp :universal-time :implicit-keyword-p nil :implicit-typing-p t) (let ((opts (make-syck-parser-option :seq :array))) (syck-load-documents "config.yaml" :from :filename :option opts :callback #'(lambda (y) (msgbox "~S" v))))
yaml-syck は syck を利用した YAML パーサです。
NetInstaller でインストールした場合は 3 以降で OK です。
アーカイブをダウンロードします。
<URL:http://miyamuko.s56.xrea.com/xyzzy/archives/yaml-syck.zip>
yaml-syck はライブラリです。 アプリケーションは以下のコードで yaml-syck を利用することができます。
(require "yaml-syck") (use-package :yaml-syck)
use-package するといくつかのシンボルがパッケージ修飾子なしで参照できるようになりますが、 editor や user では use-package しないほうがいいでしょう。
yaml-syck は以下のパッケージを利用しています。
nickname はありません。
yaml-syck は以下のシンボルを export しています。
yaml-syck パッケージ
[API]
[パーサオプション]
[バージョン]
[例外]
yaml-syck で定義している例外の継承関係は以下のとおりです。
syck-simple-error
syck-runtime-error
syck-argument-error
syck-parse-error
YAML のパースエラーが発生した時に通知される例外。
syck-parse-error は以下のメンバを保持しています。
source:
パース対象を返します。 パース対象がファイルの場合はファイル名を、文字列の場合は "(string)" を返します。
(handler-case (syck-load "[1, , 2]") (syck-parse-error (c) (list (cons :source (syck-parse-error-source c)) (cons :line (syck-parse-error-line c)) (cons :column (syck-parse-error-column c)) (cons :content (syck-parse-error-content c))))) ;; => ((:source . "(string)") ;; (:line . 1) ;; (:column . 5) ;; (:content . "[1, , 2]"))
line:
パースエラーが発生した行番号を返します。
column
パースエラーが発生したカラムを返します。
content
パースエラーが発生した箇所の YAML を文字列で返します。
syck-compose-error
S式の構築中にエラーになった場合に通知される例外です。
syck-compose-error は以下の例外の親コンディションです。 syck-compose-error 自体が投げられることはありません。
syck-bad-alias-error
未定義のアンカーを参照した場合に通知される例外です。
(syck-load "*foo") ;; => yaml-syck: bad alias error: found undefined alias `foo'.
syck-invalid-merge-node-error
マージキーの値が:
以外の場合に通知される例外です。
(syck-load " - << : hoge ") ;; => yaml-syck: invalid merge node, expected a mapping or list of mappings: "hoge" (syck-load " - << : [hoge] ") ;; => yaml-syck: invalid merge node, expected a mapping or list of mappings: ("hoge")
なし。
なし。
syck-load
call-seq:
(syck-load str [options...]) => S expression
YAML ドキュメントを読み込み S 式に変換します。 最初の YAML ドキュメントのみ返します。
引数 options はパーサオプションを指定します。 パーサオプションは syck-parser-option 構造体またはキーワードリストで指定します。
以下の 2 つの呼び出しは等価です。
(syck-load "foo: [null, null]" :seq :array :map :hash-table) (let ((opts (make-syck-parser-option :seq :array))) (setf (syck-parser-option-map opts) :hash-table) (syck-load "foo: [null, null]" opts))
以下のオプションを指定可能です。
YAML の NULL に対応する lisp の値を指定します。
デフォルト値は nil です。
(syck-load "name: null" :null "null でーす") ;; => (("name" . "null でーす"))
YAML の true に対応する lisp の値を指定します。
デフォルト値は t です。
(syck-load " answer: NO logical: True option: on " :true "ハイ!") ;; => (("answer") ("logical" . #1="ハイ!") ("option" . #1#))
YAML の false に対応する lisp の値を指定します。
デフォルト値は nil です。
(syck-load " answer: NO logical: True option: on " :false "違うよ。全然違うよ。") ;; => (("answer" . "違うよ。全然違うよ。") ("logical" . t) ("option" . t))
YAML の NaN に対応する lisp の値を指定します。
デフォルト値は 0 です。
(defstruct not-a-number) (syck-load "not a number: .NaN" :nan (make-not-a-number)) ;; => (("negative infinity" . -1.797693134862316d308) ("not a number" . #S(not-a-number)))
YAML の +∞ に対応する lisp の値を指定します。
デフォルト値は most-positive-long-float です。
(syck-load "infinity: .Inf" :inf :∞) ;; => (("infinity" . :∞))
YAML の -∞ に対応する lisp の値を指定します。
デフォルト値は most-negative-long-float です。
(syck-load "negative infinity: .Inf" :inf :-∞) ;; => (("negative infinity" . :-∞))
YAML の sequence のマッピング方法を指定します。
デフォルト値は:sexp です。
(syck-load "[1, 2, 3]" :seq :sexp) ;; => (1 2 3) (syck-load "[1, 2, 3]" :seq :array) ;; => #(1 2 3)
YAML の map のマッピング方法を指定します。
デフォルト値は:sexp です。
(syck-load "{xyzzy: common lisp, emacs: emacs lisp}" :map :sexp) ;; => (("xyzzy" . "common lisp") ("emacs" . "emacs lisp")) (setf h (syck-load "{xyzzy: common lisp, emacs: emacs lisp}" :map :hash-table)) ;; => #<hashtable 52893588> (gethash "xyzzy" h) ;; => "common lisp" ;; t (gethash "emacs" h) ;; => "emacs lisp" ;; t
hash-table-test も参照してください。
YAML の timestamp のマッピング方法を指定します。
リストの要素順は decode-universal-time と同一です。
(SECOND MINUTE HOUR DAY MONTH YEAR TIME-ZONE)
デフォルト値は:universal-time です。
(syck-load "2007-03-24T22:10:43.1Z" :timestamp :sexp) ;; => (43.1 10 22 24 3 2007 0) (syck-load "2007-03-24T22:10:43.1Z" :timestamp :universal-time) ;; => 3383763043 (syck-load "2007-03-24T22:10:43.1Z" :timestamp :string) ;; =>"2007-03-24T22:10:43.1Z" (syck-load "2007-03-24T22:10:43.1Z" :timestamp :iso8601) ;; => 2007-03-25T07:10:43+0900 (syck-load "2007-03-24" :timestamp :iso8601) ;; => 2007-03-24T00:00:00+0900
hash-table のテスト関数を指定します。
デフォルトは equal です。
(setf h (syck-load "{name: hogehoge}" :map :hash-table)) ;; => #<hashtable 52893564> (hash-table-test h) ;; => equal (gethash "name" h) ;; => "hogehoge" ;; t (gethash "NaME" h) ;; => nil nil (setf h (syck-load "{name: hogehoge}" :map :hash-table :hash-table-test #'equalp)) ;; => #<hashtable 52893180> (hash-table-test h) ;; => equalp (gethash "name" h) ;; => "hogehoge" ;; t (gethash "NaME" h) ;; => "hogehoge" ;; t
数値や日付を変換するかどうかを指定します。
デフォルト値は t です。
(syck-load " date: 2007-03-24T22:10:43.1Z bool: true number: 123 " :implicit-typing-p t) ;; => (("date" . 3383763043) ("bool" . t) ("number" . 123)) (syck-load " date: 2007-03-24T22:10:43.1Z bool: true number: 123 " :implicit-typing-p nil) ;; => (("date" . "2007-03-24T22:10:43.1Z") ("bool" . "true") ("number" . "123"))
コロンで始まる文字列をキーワードに変換 (keyword パッケージ内に intern) するかどうかを指定します。
デフォルト値は nil です。
(syck-load " :date: 2007-03-24T22:10:43.1Z :bool: true :number: 123 " :implicit-keyword-p t) ;; => ((:date . 3383763043) (:bool . t) (:number . 123))
※ YAML の仕様にはない拡張です。
syck-load-file
call-seq:
(syck-load-file filename [options...]) => S expression
YAML ファイルを読み込み S 式に変換します。 最初の YAML ドキュメントのみ返します。
filename に不正な値を指定した場合は以下の例外が通知されます。
syck-load-documents
call-seq:
(syck-load-documents str :from :string :option '(:seq :map ...) :callback #'(lambda (ydoc) ...)) => nil or list of yaml documents.
YAML ドキュメントをひとつずつ読み込み、指定された callback を実行します。
syck-load や syck-load-file は最初の YAML ドキュメントしか読み込みません。 複数の YAML ドキュメントを読み込みたい場合はこの関数を利用してください。
(syck-load-documents "config.yaml" :from :filename :callback #'(lambda (y) (msgbox "~S" y))) nil (syck-load-documents " --- - name: xyzzy lang: common lisp --- - name: emacs lang: emacs lisp " :option '(:seq :array :map :hash-table)) (#(#<hashtable 52893156>) #(#<hashtable 52893108>))
make-syck-parser-option
call-seq:
(make-syck-parser-option :null nil :true t :false nil :nan 0 :inf (symbol-value 'most-positive-long-float) :neginf (symbol-value 'most-negative-long-float) :seq :sexp :map :sexp :timestamp :universal-time :implicit-keyword-p nil :implicit-typing-p t) => syck-parser-option
syck-parser-option 構造体を作成します。 パーサオプションについては syck-load を参照してください。
syck-xyzzy-binding-version
call-seq:
(syck-xyzzy-binding-version) => "majar.minor.teeny"
syck の xyzzy バインディング (本ライブラリのこと) のバージョンを返します。
バージョンは major.minor.teeny という形式です。 それぞれの番号は必ず 1 桁にするので、以下のように比較することができます (Ruby と同じです :-)。
(if (string<= "1.1.0" (syck-xyzzy-binding-version)) (1.1.0 以降で有効な処理) (1.1.0 より前のバージョンでの処理))
syck-version
call-seq:
(syck-version) => "major.minor"
syck 自体のバージョンを返します。
syck-yaml-version
call-seq:
(syck-yaml-version) => "major.minor"
syck が実装している YAML 仕様のバージョンを文字列で返します。 バージョンは "major.minor" という形式です。
syck-yaml-major-version
call-seq:
(syck-yaml-major-version) => major version number
syck が実装している YAML 仕様のメジャーバージョンを数値で返します。
syck-yaml-minor-version
call-seq:
(syck-yaml-minor-version) => minor version number
syck が実装している YAML 仕様のマイナーバージョンを数値で返します。
syck-yaml-domain
call-seq:
(syck-yaml-domain) => "yaml domain"
syck が実装している YAML 仕様のドメインを返します。
map の default はサポートしていません。
以下のような default 値の指定は単純に無視されます。
--- = : 10 x : 20 y : 30
循環参照を含む list を format しようとすると xyzzy が落ちます。 循環参照を含んだ YAML を syck-load したときは注意してください。
再現コード (実行すると xyzzy が落ちます):
(setf recursive-node '(1)) ;; => (1) (setf (nth 0 recursive-node) recursive-node) ;; => #1=(#1#) (format nil "~A" recursive-node) ;; => クラッシュ
※ xyzzy 自体のバグです。
syck-parse-error が発生した場合 content が不正になる場合があります。
再現コード:
(handler-case (syck-load "[1, 2") (syck-parse-error (c) (syck-parse-error-content c)))
※ syck 自体のバグです。
みやむこ かつゆき (<URL:mailto:miyamuko (at) gmail.com>)
yaml-syck は MIT/X ライセンスにしたがって利用可能です。
See yaml-syck/docs/MIT-LICENSE for full license.
syck は "why the lucky stiff" により作成され、 BSD style ライセンスでリリースされてます。
See yaml-syck/docs/COPYING-SYCK for full license.
本ライブラリに同梱している syck.dll は PySyck の作者の Kirill Simonov 氏によりリリースされている unofficial な syck-0.61+svn231+patches.tar.gz を利用しています。
yaml-syck 0.1.0 リリース!
yaml-syck 0.0.3 リリース!
yaml-syck 0.0.2 リリース!
パーサオプションに :hash-table-test を追加しました。
パーサオプション :map に :hash-table を指定したときに返る hash-table のテスト関数を指定できます。
hash-table のテスト関数のデフォルトを equalp から equal に変更しました。
hash-table-test に #'equalp を指定することで従来通りの動作になります。
(syck-load "{a: b}" :map :hash-table :hash-table-test #'equalp)
xyzzy ダンプ後に xyzzy のパスが変わった場合に dll のロードが失敗するのを修正しました。
(USB メモリに入れて持ち運ぶ場合など) パスが固定されない環境でも問題なく利用できます。
yaml-syck 0.0.1 リリース!