PascalはLL(1)じゃないよね

http://d.hatena.ne.jp/kmaebashi/20071203#p1
手続き名をlexerが認識するとかどこのBASICでしょうか。Pascalはそんな事してないと思……いやまてよ。

WriteLn(x: 10);

↑こんな、Write/WriteLn中でしか使えない特殊構文がある以上、手続き名をlexerが認識してるのか?
いや、決してlexerでは無いはず。
何故ならvar WriteLn: Integer;とすればSystem.WriteLnを隠蔽できます。その場合でもSystem.WriteLnと書けば上記構文が使えます。
ですので、手続き名をparserが認識している、が正解かな……
……みずしまさんが例示されたBNFの中のPascalは、formal-parameter-sectionにprocedureやfunctionが入っているあたり、実はクロージャが使えるいにしえの教科書のPascalっぽく、unitの仕様が入ってないため当然Systemユニットも無いはずで、こんな例は該当しないのでした。そもそもWrite/WriteLnのフォーマット構文が定義されてない。これって後の拡張でしたっけ?
むしろ、1トークン読んだ時点で手続き呼び出しか代入か区別つける必要あるのかが疑問。まず関数呼び出しもありえる左辺値っぽい式として読んで、後に:=が続いていたらその時点で代入文とすればいいのでは。実際問題Pascalではこんな風に書けます。

nanika^ := 100;

ここでnanikaは「^Integer」と「引数の無い^Integerを返す関数」の両方の可能性があり、後者なら関数呼び出しが発生……
……BNFにははっきりとこうかかれているのでした。

variable := expression  

variable:  
   identifier  
   variable [ subscript-list ]  
   variable . fieldid  
   variable ^  

先生、左辺に関数呼び出しが来れないです。
むむ教科書Pascalは手ごわいな。
まぁ、正直なところを言えば、私の知っているPascalについて言えば、真面目にやるならLL(1)では無いです。断言します。
手続き呼び出しも代入もとりあえず式として読めば一緒くたに扱えるのでこちらは問題ではないです。私の知っているPascalでは関数呼び出しの結果に代入できますから。
問題なのはラベル。

name:

nameを読んだ時点ではラベルか式なのかわかりません。そして、とりあえず式として読む方法ですと、ラベル名のところに左辺値が来れてしまいますからpointer^:なんて書けてしまうことに。え?とりあえず式として読む方法ではラベルを持ちだすまでもなく代入文として明らかに不正なproc(1) := 10;と書けてしまうって?それは現在のPascalにたまたま参照型が無いだけですよ。例えばfunc(1).field := 10;は合法ですし、この手のものはparserではなく意味解析でエラーにすべきかと。
閑話休題、ラベルと式の区別でした。
教科書Pascalではラベル名を数字に限定することでこれを回避しています。
ちなみにAdaではgoto用のラベルは<>ですがブロックに名前を付けるときはname: loopのように書きますので同じ問題があります。
で、これに関しては私の中で有名な(……どこで読んだか忘れましたごめんなさい……)解決方法があって、lexerをちょっと弄って、identifierと、identifierの後ろに(空白やコメントは読み飛ばして)コロンが付いたものを別扱いにしてしまえば、すっきり解決します。

identifier [A-Za-z_][A-Za-z_0-9]*
label_identifier [A-Za-z_][A-Za-z_0-9]*(\(\*.*\*\)|\{.*\}|\x20\t\r\n)*:

こうしてPascalは無理矢理にLL(1)になったのでした。めでたしめでたし。
DelphiやFreePascalはname{$IFDEF X}:と書げふんげふん。……実際のところは少なくともFreePascalはlexerもparserも手書きですので……
http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/compiler/pstatmnt.pas?view=markup
……いったん式として読んで、読んだ式が単体のidentifierで後にコロンが続いていたらラベルにしてるなあ。うーん、手書きparserは好きにif文挟んで文法捻じ曲げられるのが強みだなあ。
ま、これもLL(1)には間違いありますまい!?別に構文解析表が静的でなければならないなんてルールも無いことですし。(←屁理屈)

- LL(2)とかLALR(1)というのは「構文定義」の性質であって、「言語」の性質じゃないので、
 ・「PascalはLL(1)じゃない」という言い方は厳密にはおかしい。
 ・「Pascalの言語仕様に書いてあるBNFはLL(1)じゃない」とかいう言い方なら正しい。
参照もとより引用(リンク自粛)

ごめんなさい。