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-errorsyck-runtime-errorsyck-argument-errorsyck-parse-errorYAML のパースエラーが発生した時に通知される例外。
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-errorS式の構築中にエラーになった場合に通知される例外です。
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-loadcall-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-filecall-seq:
(syck-load-file filename [options...]) => S expression
YAML ファイルを読み込み S 式に変換します。 最初の YAML ドキュメントのみ返します。
filename に不正な値を指定した場合は以下の例外が通知されます。
syck-load-documentscall-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-optioncall-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-versioncall-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-versioncall-seq:
(syck-version) => "major.minor"
syck 自体のバージョンを返します。
syck-yaml-versioncall-seq:
(syck-yaml-version) => "major.minor"
syck が実装している YAML 仕様のバージョンを文字列で返します。 バージョンは "major.minor" という形式です。
syck-yaml-major-versioncall-seq:
(syck-yaml-major-version) => major version number
syck が実装している YAML 仕様のメジャーバージョンを数値で返します。
syck-yaml-minor-versioncall-seq:
(syck-yaml-minor-version) => minor version number
syck が実装している YAML 仕様のマイナーバージョンを数値で返します。
syck-yaml-domaincall-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 リリース!