本家「@IT」にはない内容をエンジニアライフで技術紹介するコラム。広く議論する場になることを目指します。

第049回_markupdecl

»
今回はmarkupdeclについて議論しますが、特に実装はありません。

markupdeclのW3Cの勧告内容

----W3C勧告----
2.8 Prolog and Document Type Declaration
・・・
[Definition: A markup declaration is an element type declaration, an attribute-list declaration, an entity declaration, or a notation declaration.] These declarations may be contained in whole or in part within parameter entities, as described in the well-formedness and validity constraints below. For further information, see 4 Physical Structures.
・・・
[29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment [VC: Proper Declaration/PE Nesting]
[WFC: PEs in Internal Subset]
・・・
The markup declarations may be made up in whole or in part of the replacement text of parameter entities. The productions later in this specification for individual nonterminals (elementdecl, AttlistDecl, and so on) describe the declarations after all the parameter entities have been included.

Parameter entity references are recognized anywhere in the DTD (internal and external subsets and external parameter entities), except in literals, processing instructions, comments, and the contents of ignored conditional sections (see 3.4 Conditional Sections). They are also recognized in entity value literals. The use of parameter entities in the internal subset is restricted as described below.
・・・
Validity constraint: Proper Declaration/PE Nesting

Parameter-entity replacement text must be properly nested with markup declarations. That is to say, if either the first character or the last character of a markup declaration (markupdecl above) is contained in the replacement text for a parameter-entity reference, both must be contained in the same replacement text.
----W3C勧告----
----日本語訳----
2.8 プロローグと文書型宣言
・・・
[定義: マークアップ宣言は要素型宣言、属性リスト宣言、実体宣言、記法宣言からなる。]これらの宣言は、後述する整形式性制約や妥当性制約で説明するように、宣言の全部あるいは一部にパラメータ実体を含む
ことができる。更なる情報は4 物理構造 参照。
・・・
[29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment [妥当性制約: 宣言とPEの適切なネスト]
[整形式性制約: 内部サブセットの中のパラメータ実体]
・・・
マークアップ宣言は、全部または一部がパラメータ実体の置換テキストで作られても良い。後述する各非終端(要素型宣言、属性リスト宣言など)の仕様書の生成規則は、すべてのパラメータ実体をインクルードした後
の構文を記述する。

パラメータ実体の参照は
リテラル、処理命令、コメント、条件付セクション(3.4 条件付セクションを参照)で無視するものを除いた、DTDの中で、
どこでも認識する。実体値リテラルの中でも認識する。内部サブセットの中におけるパラメータ実体の使用は、後述するように制限がある。
・・・
妥当性制約: 宣言とPEの適切なネスト

パラメータ実体の置換テキストはマークアップ宣言の中で適切なネストになっていなければならない。つまり、マークアップ宣言(上述したmarkupdecl)にて、最初の文字または最後の文字がパラメータ実体の参照先の置換文字列に含まれるなら、同じ置換テキストに両方が含まれていなければいけない。
----日本語訳----

markupdeclの仕様整理

呼び方
markup declarationは、日本語ではマークアップ宣言と呼びます。

生成規則
生成規則は、
markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment
です。

マークアップ宣言の種類
W3Cの勧告では、--既にスタンドアロン文書宣言で説明した通り--、外部マークアップ宣言とマークアップ宣言があります。

しかし、"外部"マークアップ宣言はintSubset("内部"サブセット)上のDeclSepがパラメータ実体の参照を置換した場合も含むので"外部"と言いながら理解しにくい部分を持ちます。
また、マークアップ宣言はintSubset/extSubsetDecl内のmarkupdeclを示しつつも、extSubsetDecl上のmarkupdeclは特定条件でパラメータ実体を記載できるという異なる性質を持つため仕様が混乱します。

そこで次のように考えると良いと思います。
1.intマークアップ宣言(intSubset上の直接のmarkupdecl)
2.DeclSepマークアップ宣言(intSubset/extSubset上のDeclSepが示すmarkupdecl)
3.extマークアップ宣言(extSubset上のmarkupdecl)
1と3を内部/外部マークアップ宣言と命名しても良いのですが、外部マークアップ宣言という用語は既に使われていてさらに混乱するかもしれないので使わないようにしています。

マークアップ宣言の役割とその問題点
 1.マークアップ宣言の役割はDTDの本体を体現すること

 2.妥当性・整形式性制約の対象となる範囲を作ること
です。

1については、intSubset/extSubsetDeclの構文を考えると
 サブセットに記載できるモノの内、宣言間のパラメータ宣言と条件付セクションを除いたモノ
と表現しても良いでしょう。

2については少し問題があります。マークアップ宣言という範囲を定義しておきながら、
 整形式性制約:内部サブセットの中のパラメータ実体

 整形式性制約以外の外部マークアップ宣言(DeclSep/extマークアップ宣言)の中のパラメータ実体
における仕様の違いを定義してしまっているからです。このようなことをするならintMarkupdeclとextMarkupdeclを別途定義すべきであったと思います。
※実装では別の生成規則として扱います。

定義の修正/役割の変化
W3C勧告では、
 「マークアップ宣言は要素型宣言、属性リスト宣言、実体宣言、記法宣言からなる。」
とありますが、生成規則から
 「マークアップ宣言は要素型宣言、属性リスト宣言、実体宣言、記法宣言、処理命令、コメントからなる。」
と読み取れます。そこで、このコラムでは、
 「DTDは要素型宣言、属性リスト宣言、実体宣言、記法宣言からなる。」
 「マークアップ宣言は要素型宣言、属性リスト宣言、実体宣言、記法宣言、処理命令、コメントからなる。」
と定義します。

このことは、本コラム上でマークアップ宣言の役割が
マークアップ宣言はDTDを含む一方で、マークアップ宣言は概念の定義としてはDTDを示すものとはしないマークアップ宣言が示すのは構文としての範囲のみとする
になることを示しています。

構文の再定義
先の定義の修正から構文は次のように変更します。
markupdecl ::= DTD | PI | Comment
DTD ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl

DeclSepマークアップ宣言とextマークアップ宣言で記載できるパラメータ実体の条件(位置)
W3Cの勧告は、
"マークアップ宣言(上述したmarkupdecl)にて、最初の文字または最後の文字がパラメータ実体の参照先の置換文字列に含まれるなら、同じ置換テキストに両方が含まれていなければいけない。"
と説明しています。

この文面を直接実装することはおそらく難しいので、もう少し実装よりの仕様に変換します。

第一に、「最初の文字」「最後の文字」と文字単位になっているのは、XMLのEBNFが1文字単位であるからであって、
字句解析の後に構文解析があることを考慮すると、
パラメータ実体参照の置換テキストが
'<!ELEMENT' を含む場合は、同じ置換テキスト内に '>' を含まなければならない
'<!ATTLIST' を含む場合は、同じ置換テキスト内に '>' を含まなければならない
'<!ENTITY' を含む場合は、同じ置換テキスト内に '>' を含まなければならない
'<!NOTATION'を含む場合は、同じ置換テキスト内に '>' を含まなければならない
'<?' を含む場合は、同じ置換テキスト内に '>' を含まなければならない
'<!--' を含む場合は、同じ置換テキスト内に '>' を含まなければならない
#
# 補足
# W3Cの勧告にて、マークアップ宣言はおそらくこのコラムで言うところの
# DTDを示していますが、ここの文面は、マークアップ宣言
# (上述したdeclmarkupdecl) と括弧書きがあり、このコラムにおける
# マークアップ宣言と同一であることが推測できます。つまり、
# この特定条件は処理命令とコメントを含みます。
#
# なぜこのように解釈するか?というと、そうしないと実装もXMLファイル
# の記述も難しくなるからです。もう少し説明すると、
#  PIやCommentもマークアップ言語の文法の中で定義していますから、
#  パラメータ実体で表現するとき、
#  最初のトークンと最後のトークンが異なるパラメータ実体に含まれて良い
# と解釈すると
#  置換テキスト内で構文が完結しない
#  XMLファイルを人間の目で見てどことどこのタグが対応しているかが判らない
# となってしまうからです。
#

第二に、宣言の全部をパラメータ実体の参照で示す場合について考えます。この場合は、構文解析器はDeclSepマークアップ宣言のパラメータ実体と解釈しますから、記載位置はマークアップ宣言の間となります。
その置換文字列は
 完全なDTD
 完全なコメント
 完全な処理命令
のいずれかでなければならないことを示します。
例えば、
 <!ENTITY % xx '<!ENTITY tricky "error-prone"' >
 %xx; >
のように %xxが不完全なマークアップ宣言の置換文字列の場合、(同じ置換テキストに最初と最後が含まれていないので)エラーとします。実現方法についてはDeclSepにて検討します。

第三に、宣言の一部をパラメータ実体の参照で示す場合について考えます。
まず状況について考えます。
「整形式性制約: 内部サブセットの中のパラメータ実体」のため、内部サブセット内のDTDは該当しません。extSubsetDecl上でDeclSepマークアップ宣言と認識しなかった、--パラメータ実体の参照ではなかった--
場合が該当します。

さらに、DeclSepマークアップ宣言として認識しなかったとは、extSubsetDeclから
elementdecl、AttlistDecl、EntityDecl、NotationDeclのいずれかの先頭トークンを発見し、各構文として認識した
状況になります。
#
# W3Cの勧告に「リテラルの中, PI命令, コメント, IGNOREの場合の
# 条件セクションの内容」ではパラメータ実体の参照を
# 認識しないとあるのでコメントと処理命令は含みません。
#

この状況において仕様は
パラメータ実体の参照がその構文の末尾より前までを含むことを許しますが、構文の末尾を含んではいけない
という制限として作用します。よって記載位置は、
各マークアップ宣言の先頭トークンの後ろから(第2トークンから)末尾のトークンの前まで
となります。

例えば、DeclSep/extマークアップ宣言にて
例1
 <!ENTITY % aa "'hoge'" >
 <!ENTITY bb %aa; >

 <!ENTITY % xx "'hoge' >" >
 <!ENTITY yy %xx;
がある場合に、%aa;は正常に作用し、%xx;は実体宣言の末尾までを含むのでエラーにします。実現方法については要素宣言、属性リスト宣言、実体宣言、記法宣言にて検討します。
Comment(0)

コメント

コメントを投稿する