For Development HEAD DRAFTSearch (procedure/syntax/module):

4.1 字句構造

GaucheはR7RS Schemeのパーザをいくつかの点で拡張しています。 また、歴史的経緯から、デフォルトの字句構文の中に、R7RSの仕様と相反するものが いくつかあります。リーダのモードを設定することで、 R7RS互換にすることもできます。

hash-bang指示子

#!で始まるトークンはリーダに特別な影響を与えます。 R7RSではそういった指示子がふたつ定義されています。 シンボルのリード時に大文字小文字を無視するかしないかを 切り替える、#!fold-case#!no-fold-caseです。

Gaucheで使える指示子の一覧については、下のHash-bangトークンを参照してください。

角括弧

Gaucheは、R6RSの[]()と同様に扱う構文規則を採用しています。 どちらの括弧も全く等価ですが、それぞれの開き括弧と閉じ括弧は対応していなければなりません。 括弧を混ぜることに眉をひそめる熟練のLisperもいますが、 括弧の種類を使い分けるのは、括弧の役割を視覚的に識別するのに役に立ちます。

一般的な慣習は、関数とマクロ呼び出し以外のグルーピングには[]を使う、 というものです。ただしそのようなグルーピングがネストする場合は、外側には()を 使います。例:

(cond [(test1 x) (y z)]
      [(test2 x) (s t)]
      [else (u v)])

(let ([x (foo a b)]
      [y (bar c d)])
  (baz x y))

この記法は、必ず従わなければいけないというものではありません。 R7RSではこの構文を採用せず、[]は言語拡張用に取ってあるので、 ポータブルなR7RSプログラムを書く場合は()だけを使うのが良いでしょう。 (リーダがstrict-r7モードの時は、[]が使われていたら エラーが通知されます。詳しくはリーダー字句モード参照。)

エディタのSchemeモードの中には、)をタイプするとそれがどちらの 種類の括弧を閉じるかに応じて自動的に])を選んで挿入してくれる ものがあります (EmacsのQuackなど)。この記法を使うときは そういったモードを活用すると良いでしょう。

シンボル名

シンボル名はデフォルトで大文字小文字を区別します (大文字小文字の区別参照)。 数字や’+’, ’-’ で始まるシンボル名も、 トークンが有効な数値リテラルを構成しない限り許されます。 また、他の変な文字も ’|’ でシンボルを囲むことによってシンボル名に含めることが できます (例:’|this is a symbol|’)。 シンボルも参照して下さい。

数値リテラル

非正確な実数の整数部または小数部のいずれかが0の場合、それを省略することが できます。例:30., .25, -.4。 数値のリーダは、パディングの’#’を認識します。 複素数表記は直交座標形 (例:1+0.3i) でも極座標形 (例:3.0@1.57) でも 認識されます。 非正確な実数は、正の無限大、負の無限大、非数(NaN)を含み、 それらはそれぞれ+inf.0-inf.0、および+nan.0と 表記されます。(-nan.0も非数(NaN)として読まれます)。

Gaucheはまた、SRFI-169 (数値中のアンダースコア)構文をサポートしています。 読みやすくするために、数値中に_を挿入することができます (例: #b1100_1010_1111_1110)。 ただし、各アンダースコアは数字に囲まれていなければなりません。 1_2_3はokですが、_123123_12__3は 有効な数値リテラルではありません。

Gaucheはまた、Common Lisp風の基数を明示した数値リテラルも認識します。 例えば3進数の120は#3r120と書けます(10進数で15)。2進数から36進数まで 認識されます。10進数より上ではa-zA-Zのアルファベットを使えます。

複素数の極座標記法において、Gaucheではサフィックスpiをつけることにより 偏角をπの係数で表すことができます。Schemeの構文では偏角はラジアンですが、 πは浮動小数点数では近似値でしか扱えないので、偏角ゼロ以外で切りの良い数値を 表現することができません。

gosh> 2@3.141592653589793
-2.0+2.4492935982947064e-16i

piサフィックスを使うと切りの良い数値が書けます。

gosh> 2@1pi
-2.0
gosh> 2@0.5pi
0.0+2.0i
gosh> 2@-0.5pi
0.0-2.0i
16進数文字エスケープ

いくつかのリテラル中では、文字をその文字コードの16進数表記で記入できます。 具体的には、文字、文字集合、文字列、シンボル、正規表現リテラルです。

R7RSは文字列および縦棒で囲まれたシンボル中では\xNNNN;、文字単独では #\xNNNNというエスケープ構文を採用しました。16進数の桁数は可変で、 文字コードはUnicodeコードポイントです。

Gaucheは歴史的に2種類のエスケープを使ってきました。 \u\xです。 uはUnicodeコードポイントに、xは内部エンコーディングによる 文字コードに使っていました。また、文字リテラル以外では 16進数の桁数は固定で、したがってR7RSのような終端文字(;)を必要としませんでした。

0.9.4からは、\xエスケープはそれが正しいR7RSの16進エスケープと解釈できる 限りはそう読まれます。R7RSの構文に合致しない場合は、以前のGaucheの構文とみなされます。

滅多にないことですが、R7RSとも以前のGauche構文ともみなすことができて、しかし解釈に違いが 生じるような場合というのが存在します。そのようなリテラルを含む昔のソースを 現在のGaucheで読むと、予想外の動作が起きるかもしれません。 その場合は、リーダのモードを以前との互換モードに変更できます。 詳細はリーダー字句モードを参照してください。

拡張された#構文

#’ で始まる特殊構文がたくさん定義されています。 下の表を参照して下さい。


4.1.1 #構文

以下の表はシャープ構文のリストです。

#![R6RS][R7RS][SRFI-22] これは、スクリプトのインタプリタ指定行(shebang)の 開始を示すか、リーダのモードに影響を与える特別なトークンとして読まれます。 下の‘hash-bang token’の節を参照してください。
#"補間された文字列を先導します。文字列の補間参照。
##, #$, #%, #&, #'未使用。
#([R7RS] リテラルベクタ表記の開始です。
#)未使用。
#*ビットベクタあるいは不完全な文字列。文字列参照。
#+未使用。
#,[SRFI-10] リーダ構築子構文を開始します。
#-, #.未使用。
#/リテラルの正規表現を先導します。正規表現参照。
#0#9#n#, #n=: [SRFI-38] 共有サブストラクチャの定義と参照。
#nR, #nr: 基数を明示した数値リテラル。
#:インターンされていないシンボル。シンボル参照。
#;[SRFI-62] S式コメント。続くS式をひとつ読んで捨てます。
#<読み取り不可能オブジェクトを先導します。
#=, #>未使用。
#?デバッグマクロを先導します。デバッグ参照。
#@未使用。
#a未使用。
#b[R7RS] 2進数接頭辞。
#c未使用。
#d[R7RS] 10進数接頭辞。
#e[R7RS] 正確数接頭辞。
#f[R7RS] 真理値の偽、あるいは R7RS のユニフォームベクタを先導します。ユニフォームベクタ参照。 R7RSでは真理値の偽として#f#falseが使えます。
#g, #h未使用。
#i[R7RS] 非正確数接頭辞。
#j, #k, #l, #m, #n未使用。
#o[R7RS] 8進数接頭辞。
#p, #q, #r未使用。
#s[R7RS vector.@] R7RSのユニフォームベクタを先導します。ユニフォームベクタ参照。
#t[R7RS] 真理値の真。R7RSでは真理値の真として#t#trueが使えます。
#u[R7RS vector.@] R7RS のユニフォームベクタを先導します。ユニフォームベクタ参照。 R7RSもバイトベクタに#u8のプリフィクスを使いますが、これは u8ユニフォームベクタと互換です。
#v, #w未使用。
#x[R7RS] 16進数接頭辞
#y, #z未使用。
#[リテラルの文字集合を先導します。文字集合参照
#\[R7RS] リテラルの文字を先導します。文字参照。
#], #^, #_未使用。
#`文字列補間の古い構文です。新しいコードでは#"を使ってください。
#{未使用。
#|[SRFI-30] ブロックコメントを先導します。コメントは対応する ’|#’ で終ります。
#}, #~未使用。

4.1.2 Hash-bangトークン

文字シーケンス#!は、どこでどのように現れるかによって2つの全く異なる 意味を持ちます。

ファイルが#!/もしくは#! (ハッシュ、バング、空白) から始 まっている場合、読み込みルーチンはそれをスクリプトのインタプリタ指定行 (shebang) とみなし、最初の行末までを無視します。 (実際は、ソースはファイルでなくても構いません。リーダはポートの先頭かどうかで 判断します。)

その場合以外では、#!identifierがひとつのトークンとして読ま れ、特別な意味を持ちます。この種のトークンはデータとして読まれるのでは なく、リーダに対して特別な指定を与えることもあります。

デフォルトでは、以下のトークンが認識されます。

#!fold-case
#!no-fold-case

リーダが大文字小文字を区別するかどうかを切り替えます。 #!fold-caseに出会うとリーダは大文字小 文字を区別しないモードになり、#!no-fold-caseに出会うとその逆にな ります。(大文字小文字の区別も参照してください。)

#!r6rs

このトークンはR6RSで導入され、プログラムがR6RSに準拠しているこ とを示します。GaucheはR6RSに準拠していませんが、今のところこのトー クンに出会っても警告を出すだけで読み込みは継続します。

#!r7rs

リーダをR7RSに準拠したstrict-r7モードにします。 詳細はリーダー字句モードを参照してください。

#!gauche-legacy

リーダをGauche 0.9.3およびそれ以前のものと互換なlegacyモードにします。 詳細はリーダー字句モードを参照してください。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT