注釈付きでマークされた文字列の解析 #15

受容する文字列パターンの範囲を広げてみる。

つまり、マークされていない文字列、すなわち<string>において、
右括弧")"にはマークを終了するための特別な意味を持たせる必要はない。
そのため、<string>を構成する文字として扱っても、
今まで受容してきた文字列パターンは変わらず受容され、
エラーとして扱ってきた一部の文字列が新たに受容される文字列集合に加わるだけである。

また、逆に、マークされた文字列やその注釈については、
左括弧"("にマークを開始するための特別な意味を持たせる必要はない。
そこで今までエラーとして扱ってきたマーク中の左括弧を普通の文字として扱っても(以下同様

しかし、マーク外の文字列に左括弧を含めることやマーク中の文字列に右括弧を含めることは、
それぞれマーク開始、終了の役割があるため、そうすることはできない。
また、マークされた文字列中におけるコロンについても同様である。

以上の点を考慮して#13の解析器を変更してみる。
変更は規則部のみであり、パターンだけを変更するか、規則を丸ごと削除するかしかしていない。
変更前と変更後とでdiffで差分を取ると、

23c23
< [^()]+ {
---
> [^(]+ {
28c28
< \([^():]+:[^()]+\) {
---
> \([^):]+:[^)]+\) {
38c38
< \([^():]+\) {
---
> \([^):]+\) {
49d48
< \([^):]*\(        { yyerror("illegal left parenthesis"); return 1; }
52d50
< \([^):]+:\(       { yyerror("illegal left parenthesis"); return 1; }
54d51
< \)                { yyerror("illegal right parenthesis"); return 1; }

最初の一行分の変更がマーク外の文字列に対応した規則のパターンについての変更、
次の二行分の変更がマーク中の文字列に関する変更である。
それぞれ右括弧または左括弧を文字列中に含まれてはいけない文字のパターンから除いた。
この変更によって、差分表示の最後の行\)のパターンは現れ得なくなったので削除する。

$ echo -n ")" | ./parser
string [)]

$ echo -n "((:left parenthesis) and )" | ./parser
marked-string [(]: annotation[left parenthesis]
string [ and )]

のような今まで受理されなかった文字列を受理するようになった。
もちろん今までエラーを起こさなかったものは今まで通りに通る。

差分表示中の最後から三、二行目分の変更については、
左括弧がマーク中の文字列で許容されていても、
このパターンはマーク中に文字列が終わっていることを意味するのでエラーにすべきである。
しかし、

$ echo -n ":(m:a)((" | ./parser
string [:]
marked-string [m]: annotation[a]
error: illegal left parenthesis

のようなエラーメッセージは左括弧が許容されている場合には不適当である。
そこで、両者とも削除して、それぞれ\([^):]*\([^):]+:[^)]*のパターンの規則に統合してしまう。
これによって、

$ echo -n ":(m:a)((" | ./parser
string [:]
marked-string [m]: annotation[a]
error: unexpected EOF

のように変更前よりも適切なエラーメッセージを出せるようになった。
この例はマークされた文字列の途中で文字列が尽きた場合だが、

$ echo -n ":(m:a)((:(" | ./parser
string [:]
marked-string [m]: annotation[a]
error: unexpected EOF

のように注釈の途中で尽きる場合も同様である。

しかし、それにしても、ここまでやっておいて何だが、

$ echo -n ":(m:a)((:()" | ./parser
string [:]
marked-string [m]: annotation[a]
marked-string [(]: annotation[(]

こういうのが受理されるようだと気持ち悪いというか……
マーク外とマーク内で特別な意味を持つ文字に統一性がないのは問題がある気がしてきた。
そういう点では、コロンについてもマークされる文字列にだけ使えないのも問題かもしれないが、
左括弧と右括弧という対としてまとまりを見出されるようなものがバランスを欠いているのは、
コロン単独での問題よりも違和感があり過ぎると思う。
この点で、#13の解析器で受容される文字列の集合くらいが適当なのかもしれない。