История конечной запятой в грамматике языка программирования

Многие языки программирования допускают запятые в их грамматике после последнего элемента в списке. Предположительно, это было сделано для упрощения автоматической генерации кода, что понятно.

В качестве примера, следующая инициализация совершенно законного массива в Java (JLS 10.6 Инициализаторы массива):

int[] a = { 1, 2, 3, };

Мне интересно, если кто-нибудь знает, какой язык должен был сначала разрешать такие запятые, как эти. По-видимому, C уже еще в 1985 году.

Кроме того, если кто-то знает другие грамматические "особенности" современных языков программирования, мне было бы очень интересно узнать о них. Я читал, что Perl и Python, например, еще более либеральны в разрешении запятых в других частях их грамматики.

Ответ 1

Я не эксперт по запятым, но я знаю, что стандартный Паскаль был очень вежлив в том, что полуколоны являются разделителями операторов, а не терминаторами. Это означало, что вы должны очень осторожно относиться к тому, где вы его наложили, если вы не хотите кричать от компилятора.

Позже языки Pascal-esque (C, Modula-2, Ada и т.д.) имели свои стандарты, написанные, чтобы принять нечетную дополнительную точку с запятой, не ведя себя так, как вы только что оценили смесь пирога.

Ответ 2

Я только узнал, что компилятор g77 от Fortran имеет флаг -fugly-comma Ugly Null Arguments, хотя он немного отличается (и как название подразумевает, довольно уродливое).

Параметр -fugly-comma позволяет использовать одну конечную запятую для обозначения "передать дополнительный конечный нулевой аргумент" в списке фактических аргументов внешней процедуре и использовать пустой список аргументов для такой процедуры, чтобы означать msgstr "передать один пустой аргумент" .

Например, CALL FOO(,) означает "передать два нулевых аргумента", а не "передать один пустой аргумент" . Кроме того, CALL BAR() означает "передать один пустой аргумент" .

Я не уверен, какая версия языка, в которой он впервые появился.

Ответ 3

[Кто-нибудь знает] другие грамматические "особенности" современных языков программирования?

Один из моих фаворитов, Modula-3, был разработан в 1990 году с благословением Никлауса Вирта как последний тогдашний язык в "Паскале" семья". Кто-нибудь еще помнит те ужасные бои о том, где точка с запятой должна быть разделителем или терминатором? В Modula-3 выбор за вами! EBNF для последовательности выражений

stmt ::= BEGIN [stmt {; stmt} [;]] END

Аналогично, при написании альтернатив в выражении CASE Modula-3 позволяет использовать вертикальную панель < t22 как разделитель или префикс. Поэтому вы можете написать

CASE c OF
| 'a', 'e', 'i', 'o', 'u' => RETURN Char.Vowel
| 'y' => RETURN Char.Semivowel
ELSE RETURN Char.Consonant
END

или вы можете оставить начальную строку, возможно, потому, что вы предпочитаете писать OF в этой позиции.

Я думаю, что мне понравилось так же, как сам дизайн, было понимание дизайнеров, что идет религиозная война и их настойчивость в поиске способа поддержать обе стороны. Пусть программист выбирает!


P.S. Objective Caml позволяет разрешать использование | в случае выражений, тогда как более ранний и тесно связанный диалект Standard ML не делает. В результате выражения case часто становятся более уродливыми в стандартном коде ML.


EDIT: После просмотра T.E.D. Ответ: Я проверил грамматику Modula-2 и он исправил, Modula-2 также поддерживал точку с запятой как терминатор, но через устройство пустой инструкции, которая делает материал вроде

x := x + 1;;;;;; RETURN x

легальным. Полагаю, это не плохо. Однако Modula-2 не допускает гибкого использования сепаратора корпуса |; похоже, возникла с Modula-3.

Ответ 4

Что-то, что всегда беспокоило меня о C, состоит в том, что, хотя он позволяет добавить дополнительную запятую в список intializer, она не позволяет добавить дополнительную запятую в список перечислителей (для определения литералов типа перечисления). Эта небольшая несогласованность укусила меня в заднице больше раз, чем я хочу признать. И без причины!