Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Вложенных скобочек не будет.
Просмотрел пункт 6.5. сообщения. Там первой строкой идёт:
Variables of a procedure type T have a procedure (or NIL) as value.
То есть, по сути, излишне сжато, а потому пропускается сознанием. Что, естественно, плохо. Особенно для тех, кто не любит делать шаг, пока досконально не изучит место для шага. С другой стороны, это сообщение а не спецификация как таковая.
С процедурной переменной ничего сделать нельзя, только хранить
в качестве значения процедуру, которую в свою очередь можно только вызвать. А вызов процедуры в сообщении описывается. То же самое касается и случая, когда у процедуры возвращаемое значение имеет процедурный тип.
Теперь, я думаю, понятно, но я на всякий случай объясню. Вот РФБН:
factor = number | string | NIL | TRUE | FALSE |
set | designator [ActualParameters] | "(" expression ")" | "~" factor.
designator = qualident {selector}.
Вот вызов:
GetA()()
Сначала разбирается GetA().
GetA()()
По РФБН - это
designator [ActualParameters]
Смотрится наличие такой процедуры, иначе программа будет синтаксически некорректной. Она возвращает
в качестве значения процедуру. А процедуру можно либо присвоить, либо вызвать (как с ней обойтись зависит от последующих лексем). У нас это так:
GetA()()
А вызов процедуры - это
designator [ActualParameters]
designator в этом случае - GetA().