История конечной запятой в грамматике языка программирования
Многие языки программирования допускают запятые в их грамматике после последнего элемента в списке. Предположительно, это было сделано для упрощения автоматической генерации кода, что понятно.
В качестве примера, следующая инициализация совершенно законного массива в 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, она не позволяет добавить дополнительную запятую в список перечислителей (для определения литералов типа перечисления). Эта небольшая несогласованность укусила меня в заднице больше раз, чем я хочу признать. И без причины!