[2] [[URI雛形]]の[DFN[[RUBYB[式]@en[expression]]]]は、 [CODE[{]] と [CODE[}]]
で囲まれた部分と [CODE[{]]、[CODE[}]] です [SRC[>>1]]。

* 仕様書

[REFS[
- [1] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-1.1>
- [3] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-1.2>
- [82] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-1.6>
- [11] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-2>
-- [13] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-2.2>
-- [24] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-2.3>
-- [81] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-2.4.2>
- [17] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-3.2>
-- [16] [CITE@en[RFC 6570 - URI Template]] ([TIME[2014-10-27 23:08:55 +09:00]] 版) <http://tools.ietf.org/html/rfc6570#section-3.2.1>
]REFS]

* 式

[14] [DFN[[RUBYB[[[式]]]@en[expression]]]]は、 [CODE[[[{]]]]、[[演算子]]、[[変数リスト]]、[CODE[[[}]]]]
で構成されます。ただし[[演算子]]は省略できます。 [SRC[>>13]]

[FIG(railroad)[
= [CODE(URI)[[[{]]]]
= ?
== [[演算子]]
= [[変数リスト]]
= [CODE(URI)[[[}]]]]
]FIG]

* 演算子と式型

[4] [[式]]の[[展開]]の過程は、[DFN[[RUBYB[式型]@en[expression type]]]]により決まります
[SRC[>>3, >>13]]。[[式型]]は[[演算子]]によって表されます [SRC[>>13]]。

[5] [[演算子]]が省略された場合の[[式型]]は[DFN[[RUBYB[[[単純文字列展開]]]@en[simple string expansion]]]]です [SRC[>>3, >>13]]。
[[未予約文字]]以外をすべて[[パーセント符号化]]して展開することを表しています。
区切り文字に [CODE[[[,]]]] を使います。

[15] [[演算子]]には次のものがあります。
[FIG(list)[
- [DFN[[CODE[[[+]]]]]] ([DFN[[RUBYB[予約展開]@en[reserved expansion]]]]) は、
[[未予約文字]]、[[予約文字]]、[[パーセント符号化]]はそのままで、
それ以外を[[パーセント符号化]]して展開することを表しています。
区切り文字に [CODE[[[,]]]] を使います。
- [CODE[[[''#'']]]] は、 [CODE[[[+]]]] と同じですが、先頭に [CODE[[[''#'']]]] を付与します。
- [CODE[[[.]]]] は、[[単純文字列展開]]と同じですが、先頭や区切り文字に
[CODE[[[.]]]] を使います。
- [CODE[[[/]]]] は、[[単純文字列展開]]と同じですが、先頭や区切り文字に
[CODE[[[/]]]] を使います。
- [CODE[[[;]]]] は、値の前に変数名と [CODE[[[=]]]] を付与し、先頭や区切り文字に
[CODE[[[;]]]] を使います。
- [CODE[[[?]]]] は、値の前に変数名と [CODE[[[=]]]] を付与し、先頭に [CODE[[[?]]]]、区切り文字に
[CODE[[[&]]]] を使います。
- [CODE[[[&]]]] は、値の前に変数名と [CODE[[[=]]]] を付与し、先頭や区切り文字に
[CODE[[[&]]]] を使います。
]FIG]

[49] 次の[[演算子]]は予約されています [SRC[>>13]]。
[FIG(short list)[
- [CODE[[[=]]]]
- [CODE[[[,]]]]
- [CODE[[[!]]]]
- [CODE[[[@]]]]
- [CODE[[[|]]]]
]FIG]

* 変数リスト

[25] [[雛形式]]に指定する[DFN[[RUBYB[[[変数リスト]]]@en[variable-list]]]]は、
1つ[[以上]]の[[変数指定子]]の[[コンマ]]区切りリストです。 [SRC[>>24]]

[FIG(railroad)[
= [[変数指定子]]
= *
== [CODE[[[,]]]]
== [[変数指定子]]
]FIG]

[26] [DFN[[RUBYB[変数指定子]@en[variable specifier]]]]
([DFN[[[varspec]]]]) は、[[変数名]]と省略可能な[[値修飾子]]です。 [SRC[>>24]]

[FIG(railroad)[
= [[変数名]]
= ?
== [[値修飾子]]
]FIG]

[27] [DFN[[RUBYB[[[値修飾子]]]@en[value modifier]]]]には、
[[接頭辞修飾子]] ([CODE[[[:]]]]) と[[爆発修飾子]] ([CODE[[[*]]]]) があります [SRC[>>24]]。

* 変数

[28] 変数名は、
[FIG(list)[
- [29] どのような種類の値が期待されるかを[[文書化]]したもの
- [30] [[雛形処理器]]での値の関連付けのための[[識別子]]
- [31] 名前=値の形で[[展開]]するときの名前に使う文字列
]FIG]
... という役割を持ちます [SRC[>>24]]。

[32] [[変数名]]は、[[ASCIIラテン文字]]、[[ASCII数字]]、 [CODE[[[_]]]]、
[[パーセント符号化]]、[CODE[[[.]]]] の1つ以上の列です。ただし
[CODE[[[.]]]] は最初と最後には使えません。 [SRC[>>24]]

[FIG(railroad)[
= |
== [[ASCIIラテン文字]]
== [[ASCII数字]]
== [CODE[[[_]]]]
== [[パーセント符号化]]
= *
== ?
=== [CODE[[[.]]]]
== |
=== [[ASCIIラテン文字]]
=== [[ASCII数字]]
=== [CODE[[[_]]]]
=== [[パーセント符号化]]
]FIG]

[33] [[変数名]]は、[[大文字・小文字を区別します]] [SRC[>>24]]。

[34] [[パーセント符号化]]は[[変数名]]の一部として扱い、
[[復号]]はしません。[[パーセント符号化]]された[[変数名]]とそれを[[復号]]した[[変数名]]は、
異なるものとします。 [SRC[>>24]]

* 値

[83] [[RFC 6570]] は、変数に割り当てられる値のデータモデルを明確に規定していません。

[84] 仕様書本文全般では、[[文字列]]、[[リスト]]、[[連想配列]]の3つの[[データ型]]を扱っています。
また、[[未定義]]なる状態を設けています。

[52] [RUBYB[[[文字列]]]@en[string]]は、[[Unicode符号位置]]の0個以上の列であるようです。
[[空文字列]]と[[未定義]]は異なります [SRC[>>24]]。

;; [85] [[利用者]]の入力は [[NFC]] で[[正規化]]する[['''べき''']] [SRC[>>82]]
と規定されていますが、一般にはそのような制約は設けられていません。

[86] [RUBYB[[[リスト]]]@en[list]]は、[[文字列]]の0個以上の列であるようです。
順序を持つか否かは明記されていませんが、常識的には順序を持つと解されます。

[87] [RUBYB[[[連想配列]]]@en[associative array]]は、[RUBYB[名前]@en[name]]と[RUBYB[値]@en[value]]の組の0個以上の列であるようです。
附属書Aのアルゴリズム例には「連想配列その他名前と値の[RUBYB[組]@en[pair]]」
などといった表現もあり、統一されていません。順序を持つか否かは明記されていません。

[90] [[連想配列]]の名前は、[[文字列]]であるようです。重複に関する制約は明記されていません。

[91] [[連想配列]]の値は、[[文字列]]または[[未定義]]であるようです。

[88] [RUBYB[[[構造体]]]@en[structure]]は、[[連想配列]]であるものとして扱います。
ただし階層は [CODE[[[.]]]] によって名前を連結することで表現します。
一部の値が定義されない場合には、値が定義された組のみ含めます。 [SRC[>>81]]

;; [89] [[構造体]]は仕様書中1箇所のみで唐突に登場し、
附属書Aのアルゴリズム例にも挙げられていません。

[92] [[変数]]や[[連想配列]]の値は、定義されているか、[[未定義]]かのいずれかであるようです。
[[未定義]]は、 [[null]] や [[undef]] で表す特別な値です [SRC[>>24]]。

[53] [[リスト]]に含まれる個数が0個の時や、[[連想配列]]の名前と値の組の個数が0個の時や、
名前がすべて未定義に関連付けられている時には、未定義とします。 [SRC[>>24]]

[94] [[雛形式]]は、[[雛形処理器]]が知らない[[変数]]や、
[[未定義]]値に設定された[[変数]]を参照しても構いません [SRC[>>24]]。
[[展開]]の過程で無視されますが、[[誤り]]ではありません。

* 実装水準

[6] [[URI雛形]]では[[式型]]の[[集合]]を[DFN[[RUBYB[水準]@en[level]]]]と呼んでいます。
[[水準1]]から[[水準4]]までがあります。
[FIG(list short)[
- [7] [DFN[[RUBYB[水準1]@en[Level 1]]]]
-- [[単純文字列展開]]
- [8] [DFN[[RUBYB[水準2]@en[Level 2]]]]
-- [[水準1]]
-- [CODE[[[+]]]]
-- [CODE[[[''#'']]]]
- [9] [DFN[[RUBYB[水準3]@en[Level 3]]]]
-- [[水準2]]
-- [CODE[[[.]]]]
-- [CODE[[[/]]]]
-- [CODE[[[;]]]]
-- [CODE[[[?]]]]
-- [CODE[[[&]]]]
-- [CODE[[[,]]]]
- [10] [DFN[[RUBYB[水準3]@en[Level 4]]]]
-- [[水準3]]
-- [CODE[[[:]]]]
-- [CODE[[[*]]]]
]FIG]

[12] 低水準の実装は、より高水準の構文に対応しなくても構いませんが、
対応して[[利用者]]に未対応である旨を伝える[['''べきです''']] [SRC[>>11]]。

* 展開

[18] [[式]]は、次のように[[展開]]します。
[FIG(steps)[
= [19] 先頭の [CODE[[[{]]]] と末尾の [CODE[[[}]]]] を除去します。
= [20] 最初の文字が[[演算子]]なら、これにより[[式型]]を決定します。
その文字は除去します。 [SRC[>>17]]
= [21] それ以外なら、[[単純文字列展開]]を[[式型]]とします [SRC[>>17]]。
= [23] 未対応の[[式型]]なら、[[誤り]]を返します。
= [95] 残った文字列が構文的に正しくないなら、[[誤り]]を返します。
= [22] 残った文字列を[[式型]]依存の方法で処理します。
]FIG]

;; [93] [[URI雛形]]全体の[[展開]]の処理も参照。

[50] 1つの [[URI雛形]]では、同名の[[変数]]はすべて同じ値として処理しなければ[['''なりません''']] [SRC[>>16]]。

;; [51] これは入力として用いられる値が同じであるだけであり、
出力として得られる[[展開]]は異なることがあります。

[71] [[式型]]に依存した[[式]]の[[展開]]は、次のように求めます。
[FIG(steps)[
= [72] [[式]]の[[変数リスト]]に含まれる[[変数]]のリストを用意します。
= [54] リストから、値が未定義のものを除去します [SRC[>>16]]。
= [55] その結果リストが空になった場合は、[[空文字列]]を返し、ここで停止します [SRC[>>16]]。
= [73] リストの値それぞれの[[展開]]を求めます。
= [76] [[演算子]]が [CODE[[[.]]]] や [CODE[[[/]]]] や [CODE[[[;]]]] や [CODE[[[&]]]] なら、
[[演算子]]と同じ[[文字]]の後にリストの各値を[[演算子]]と同じ[[文字]]で連結した値を返します [SRC[>>17]]。
= [77] [[演算子]]が [CODE[[[?]]]] なら、 [CODE[[[?]]]] の後にリストの各値を
[CODE[[[&]]]] で連結した値を返します [SRC[>>17]]。
= [75] [[演算子]]が [CODE[[[''#'']]]] なら、[[演算子]]と同じ[[文字]]の後にリストの各値を [CODE[[[,]]]] で連結した値を返します [SRC[>>17]]。
= [74] [[式型]]がそれ以外なら、リストの各値を [CODE[[[,]]]] で連結した値を返します [SRC[>>17]]。
]FIG]

[56] 値の[[展開]]は、次のように求めます。
[FIG(steps)[
= [58] 値が単純な[[文字列]]なら、
== [59] [[接頭辞修飾子]]があれば、適用します [SRC[>>16]]。
== [78] [[演算子]]が [CODE[[[;]]]] か [CODE[[[?]]]] か [CODE[[[&]]]] なら、
[[変数名]]を[[雛形リテラル]]同様に[[符号化]]したもの [SRC[>>17]]、
[CODE[[[=]]]]、 >>57 により[[符号化]] [SRC[>>16]] したものを連結し、返します。
ただし[[演算子]]が [CODE[[[;]]]] で [CODE[[[=]]]] の後が[[空文字列]]になる時は、 [CODE[[[=]]]] を含めません [SRC[>>17]]。
== [60] そうでなければ、 >>57 により[[符号化]] [SRC[>>16]] したものを返します。
=- [61] [[爆発修飾子]]は無視します [SRC[>>16]]。
= [62] 値が[[連想配列]]なら、
== [63] [[爆発修飾子]]がなければ、
=== [64] 含まれる名前と値の組のうち、値が定義されているものを使って [SRC[>>16]]、
(名前[SUB[1]]、値[SUB[1]]、名前[SUB[2]]、値[SUB[2]]、...) のようなリストを作成します。
=== [65] リストの要素それぞれに >>57 の[[符号化]]を適用します。
=== [79] [[演算子]]が [CODE[[[;]]]] か [CODE[[[?]]]] か [CODE[[[&]]]] なら、
[[変数名]]を[[雛形リテラル]]同様に[[符号化]]したもの [SRC[>>17]]、
[CODE[[[=]]]]、リストの要素を [CODE[[[,]]]] で連結 [SRC[>>16]] したものを連結し、返します。
ただし[[演算子]]が [CODE[[[;]]]] で [CODE[[[=]]]] の後が[[空文字列]]になる時は、 [CODE[[[=]]]] を含めません [SRC[>>17]]。
=== [35] そうでなければ、リストの要素を [CODE[[[,]]]] で連結 [SRC[>>16]] したものを返します。
== [36] [[爆発修飾子]]があれば、
=== [66] 含まれる名前と値の組のうち、値が定義されているものについて [SRC[>>16]]、
==== [37] 値が[[空文字列]]で、[[演算子]]が [CODE[[[?]]]] でも [CODE[[[&]]]]
でもなければ、名前に >>57 の[[符号化]]を適用します [SRC[>>16]]。
==== [38] それ以外なら、名前に >>57 の[[符号化]]を適用したものと値に >>57
の[[符号化]]を適用したものを [CODE[[[=]]]] で連結します [SRC[>>16]]。
=== [39] 得られた値を連結します。この時、[[演算子]]が [CODE[[[?]]]] か [CODE[[[&]]]]
なら [CODE[[[&]]]] を、 [CODE[[[;]]]]、[CODE[[[/]]]]、[CODE[[[.]]]]
なら[[演算子]]と同じ[[文字]]を、それ以外なら [CODE[[[,]]]] を区切りに使います。 [SRC[>>16]]
=- [40] [[接頭辞修飾子]]は無視します。
= [41] 値が[[リスト]]なら、
== [42] 構成要素それぞれに >>57 の[[符号化]]を適用します。
== [44] [[爆発修飾子]]がなければ、
=== [80] [[演算子]]が [CODE[[[;]]]] か [CODE[[[?]]]] か [CODE[[[&]]]] なら、
[[変数名]]を[[雛形リテラル]]同様に[[符号化]]したもの [SRC[>>17]]、
[CODE[[[=]]]]、各値を [CODE[[[,]]]] で連結 [SRC[>>16]] したものを連結し、返します。
ただし[[演算子]]が [CODE[[[;]]]] で [CODE[[[=]]]] の後が[[空文字列]]になる時は、 [CODE[[[=]]]] を含めません [SRC[>>17]]。
=== [43] そうでなければ、各値を [CODE[[[,]]]] で連結 [SRC[>>16]] したものを返します。
== [48] [[爆発修飾子]]があれば、
=== [45] [[演算子]]が [CODE[[[;]]]], [CODE[[[?]]]], [CODE[[[&]]]] なら、
各値の前に[[変数名]]と [CODE[[[=]]]] を連結します [SRC[>>16]]。
ただし[[変数名]]は[[雛形リテラル]]と同じ方法で[[符号化]]します。
=== [46] 各値を >>39 と同じ文字で区切って連結します [SRC[>>16]]。
=- [96] [[接頭辞修飾子]]は無視します。
]FIG]

[57] 文字列値の[[符号化]]は次のように行います [SRC[>>16]]。
[FIG(steps)[
= [47] [[UTF-8]] で[[符号化]]します。
= [67] [[演算子]]が [CODE[[[+]]]] や [CODE[[[''#'']]]] なら、
[[RFC 3986]] [CODE(ABNF)@en[[[unreserved]]]] と [[RFC 3986]] [CODE(ABNF)@en[[[reserved]]]]
と[[パーセント符号化]]以外は、[[パーセント符号化]]します。
= [68] それ以外なら、[[RFC 3986]] [CODE(ABNF)@en[[[unreserved]]]]
以外は、[[パーセント符号化]]します。
]FIG]

;; [69] [CODE[[[+]]]] や [CODE[[[''#'']]]] では、
入力中の[[パーセント符号化]]以外の [CODE[[[%]]]] は、[[パーセント符号化]]が必要です。
入力中の[[パーセント符号化]]はそのまま出力されます。
なおこれは[[雛形リテラル]]に適用されるのと同じ[[符号化]]です。

;; [70] それ以外では、入力中の[[パーセント符号化]]は認識されず、すべての [CODE[[[%]]]]
は[[パーセント符号化]]が必要です。