Инструменты пользователя
алгол
Различия
Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
алгол [2016/02/01 12:35] stalko [апвпвап] |
алгол [2016/02/01 12:58] stalko [Литература] |
||
---|---|---|---|
Строка 5: | Строка 5: | ||
====История==== | ====История==== | ||
Алгол был разработан в [[1958 год|1958 году]] на недельной конференции в [[Швейцарская высшая техническая школа Цюриха|ETH]] (Цюрих, Швейцария) как универсальный язык программирования для широкого круга применений, а затем доработан комитетом, созданным Международной федерацией по обработке информации (IFIP). В комитет вошёл ряд ведущих европейских и американских учёных и инженеров-разработчиков языков. Среди них были: [[Джон Бэкус]] — один из создателей [[Фортран|Фортрана]], [[Джозеф Уэгстен]] — впоследствии возглавлял комитет по разработке языка [[Кобол]], [[Джон Маккарти]] — автор языка [[Лисп]] разработанного одновременно с Алголом, [[Петер Наур]] — впоследствии доработал «нормальную форму Бэкуса», завершив разработку [[Форма Бэкуса — Наура|БНФ]], [[Эдсгер Дейкстра]] — нидерландский учёный, впоследствии получивший широкую известность как один из создателей структурного программирования и сторонник математического подхода к программированию, будущий лауреат [[Премия Тьюринга|Премии Тьюринга]].\\ | Алгол был разработан в [[1958 год|1958 году]] на недельной конференции в [[Швейцарская высшая техническая школа Цюриха|ETH]] (Цюрих, Швейцария) как универсальный язык программирования для широкого круга применений, а затем доработан комитетом, созданным Международной федерацией по обработке информации (IFIP). В комитет вошёл ряд ведущих европейских и американских учёных и инженеров-разработчиков языков. Среди них были: [[Джон Бэкус]] — один из создателей [[Фортран|Фортрана]], [[Джозеф Уэгстен]] — впоследствии возглавлял комитет по разработке языка [[Кобол]], [[Джон Маккарти]] — автор языка [[Лисп]] разработанного одновременно с Алголом, [[Петер Наур]] — впоследствии доработал «нормальную форму Бэкуса», завершив разработку [[Форма Бэкуса — Наура|БНФ]], [[Эдсгер Дейкстра]] — нидерландский учёный, впоследствии получивший широкую известность как один из создателей структурного программирования и сторонник математического подхода к программированию, будущий лауреат [[Премия Тьюринга|Премии Тьюринга]].\\ | ||
- | ==== апвпвап ==== | ||
- | |||
Сначала работа столкнулась с большими трудностями непринципиального характера. Так, например, один из членов комитета вспоминал «десятичную бурю» — крайне резкую дискуссию между американскими и европейскими участниками по поводу того, какой именно символ использовать в качестве [[Разделитель целой и дробной частей числа|разделителя целой и дробной части числа]]. Американцы стояли за точку, европейцы требовали применять традиционную в Европе запятую, и из-за такой мелочи работа оказалась под реальной угрозой срыва. Чтобы избежать конфликтов по мелким вопросам, было решено, что описание Алгола будет трёхуровневым, включающим уровень описаний, публикаций и реализации. Мелкие вопросы, типа выбора между точкой и запятой или используемого алфавита, были вынесены на второй-третий уровень, что позволило относительно быстро решить принципиальные вопросы. На уровне публикаций, согласованном позже, допускалось использование национальных ключевых слов и стандартов представления данных (в том числе и десятичной точки), уровень реализации определял язык совершенно строго — согласно ему должны были строиться трансляторы.\\ | Сначала работа столкнулась с большими трудностями непринципиального характера. Так, например, один из членов комитета вспоминал «десятичную бурю» — крайне резкую дискуссию между американскими и европейскими участниками по поводу того, какой именно символ использовать в качестве [[Разделитель целой и дробной частей числа|разделителя целой и дробной части числа]]. Американцы стояли за точку, европейцы требовали применять традиционную в Европе запятую, и из-за такой мелочи работа оказалась под реальной угрозой срыва. Чтобы избежать конфликтов по мелким вопросам, было решено, что описание Алгола будет трёхуровневым, включающим уровень описаний, публикаций и реализации. Мелкие вопросы, типа выбора между точкой и запятой или используемого алфавита, были вынесены на второй-третий уровень, что позволило относительно быстро решить принципиальные вопросы. На уровне публикаций, согласованном позже, допускалось использование национальных ключевых слов и стандартов представления данных (в том числе и десятичной точки), уровень реализации определял язык совершенно строго — согласно ему должны были строиться трансляторы.\\ | ||
- | После принятия в 1958 году первой версии описания языка Алгол 58 (первоначально предполагалось назвать язык IAL — International Algebraic Language, но от этого отказались((//A. J. Perlis.// Talk on Computing in the fifties // ACM National Conference. — 1981.)) ) довольно быстро были осознаны проблемы, для решения которых комитет сформировал новый вариант стандарта — Алгол 60; он и стал «классическим» Алголом. В [[1959 год|1959 году]] Джон Бэкус разработал «нормальную форму Бэкуса» (БНФ) — формальный способ описания алгоритмических языков. Первым языком, спецификация которого была записана в БНФ, стал Алгол 58. Впоследствии, после усовершенствований, которые предложил Питер Наур, возникла форма Бэкуса — Наура (аббревиатура та же — БНФ или BNF), которая использовалась для спецификации языка ALGOL 60 уже на этапе её разработки.\\ | + | После принятия в 1958 году первой версии описания языка Алгол 58 (первоначально предполагалось назвать язык IAL — International Algebraic Language, но от этого отказались((//A. J. Perlis.// Talk on Computing in the fifties ACM National Conference. — 1981.)) ) довольно быстро были осознаны проблемы, для решения которых комитет сформировал новый вариант стандарта — Алгол 60; он и стал «классическим» Алголом. В [[1959 год|1959 году]] Джон Бэкус разработал «нормальную форму Бэкуса» (БНФ) — формальный способ описания алгоритмических языков. Первым языком, спецификация которого была записана в БНФ, стал Алгол 58. Впоследствии, после усовершенствований, которые предложил Питер Наур, возникла форма Бэкуса — Наура (аббревиатура та же — БНФ или BNF), которая использовалась для спецификации языка ALGOL 60 уже на этапе её разработки.\\ |
У нового языка нашлись как приверженцы, так и критики. В США Алгол приняли холодно, он был популярен только в академической среде, и то не повсеместно. Те, кто попытался реализовать Алгол, столкнулись с целым рядом сложностей. Так, например, обнаружилось, что ни один из существовавших тогда компьютеров не поддерживал ввод-вывод всех 116 литер, из которых состоял алфавит Алгола.\\ | У нового языка нашлись как приверженцы, так и критики. В США Алгол приняли холодно, он был популярен только в академической среде, и то не повсеместно. Те, кто попытался реализовать Алгол, столкнулись с целым рядом сложностей. Так, например, обнаружилось, что ни один из существовавших тогда компьютеров не поддерживал ввод-вывод всех 116 литер, из которых состоял алфавит Алгола.\\ | ||
SHARE — американская ассоциация пользователей [[IBM System/360|компьютеров IBM]] — потребовала от фирмы реализовать Алгол для своих машин, но появившийся в конце концов компилятор Алгола для IBM [[OS/360]] был крайне неудобен в использовании — вполне естественно, что [[IBM]], вложившая в [[Фортран]] огромные суммы, не имела стимула для создания нового продукта, который лишь конкурировал бы со старым. В то же время, недостатки Фортрана вынудили IBM искать ему замену и привели к разработке [[PL/I]] — языка-наследника Фортрана, в котором влияние Алгола было весьма заметным.\\ | SHARE — американская ассоциация пользователей [[IBM System/360|компьютеров IBM]] — потребовала от фирмы реализовать Алгол для своих машин, но появившийся в конце концов компилятор Алгола для IBM [[OS/360]] был крайне неудобен в использовании — вполне естественно, что [[IBM]], вложившая в [[Фортран]] огромные суммы, не имела стимула для создания нового продукта, который лишь конкурировал бы со старым. В то же время, недостатки Фортрана вынудили IBM искать ему замену и привели к разработке [[PL/I]] — языка-наследника Фортрана, в котором влияние Алгола было весьма заметным.\\ | ||
Строка 14: | Строка 12: | ||
Язык Алгол был принят фирмой [[Burroughs Corporation]] в их моделях, начиная с [[B5000]] — этот язык получил название Elliott ALGOL. На компьютерах [[LGP-30]] (//[[//en.wikipedia.org/wiki/LGP-30|англ.]]//) использовался язык Dartmouth ALGOL 30.\\ | Язык Алгол был принят фирмой [[Burroughs Corporation]] в их моделях, начиная с [[B5000]] — этот язык получил название Elliott ALGOL. На компьютерах [[LGP-30]] (//[[//en.wikipedia.org/wiki/LGP-30|англ.]]//) использовался язык Dartmouth ALGOL 30.\\ | ||
Даже когда язык Алгол почти перестал использоваться для программирования, он ещё долго оставался официальным языком для публикации алгоритмов.\\ | Даже когда язык Алгол почти перестал использоваться для программирования, он ещё долго оставался официальным языком для публикации алгоритмов.\\ | ||
- | ==== 1 ==== | + | Перед текстом описания языка использовался эпиграф из «Логико-философского трактата» [[Витгенштейн, Людвиг|Людвига Витгенштейна]]: «То, что вообще может быть сказано, может быть сказано ясно; а о чём невозможно говорить, о том следует молчать».(([["http:db.chgk.info/question/vladbel/34"|Вопросы Владимира Белкина (Москва). Вопрос 34 | Что? Где? Когда?]]))\\ |
- | Перед текстом описания языка использовался эпиграф из «Логико-философского трактата» [[Витгенштейн, Людвиг|Людвига Витгенштейна]]: «То, что вообще может быть сказано, может быть сказано ясно; а о чём невозможно говорить, о том следует молчать».(([[http://db.chgk.info/question/vladbel/34|Вопросы Владимира Белкина (Москва). Вопрос 34 Что? Где? Когда?]]))\\ | + | ====Свойства языка==== |
- | ==== История ==== | + | |
Особенности языка Алгол стали типичными для большинства императивных языков, созданных позднее него. Именно в Алголе появилось представление о программе не как о свободной последовательности команд, а как о блочной структуре, состоящей из чётко описанных и отделённых друг от друга частей. Основной блок программы на Алголе — это сама главная программа. Она содержит свою исполняемую часть, заключённую в блок, ограниченный парой ключевых слов **''begin''** и **''end''**, а также описания подпрограмм. Каждая подпрограмма — это программа в миниатюре, имеющая собственные, описанные внутри неё данные, однозначно определённый интерфейс в виде имени и списка формальных параметров, и блок кода. При этом в блоке могут выделяться подблоки.\\ | Особенности языка Алгол стали типичными для большинства императивных языков, созданных позднее него. Именно в Алголе появилось представление о программе не как о свободной последовательности команд, а как о блочной структуре, состоящей из чётко описанных и отделённых друг от друга частей. Основной блок программы на Алголе — это сама главная программа. Она содержит свою исполняемую часть, заключённую в блок, ограниченный парой ключевых слов **''begin''** и **''end''**, а также описания подпрограмм. Каждая подпрограмма — это программа в миниатюре, имеющая собственные, описанные внутри неё данные, однозначно определённый интерфейс в виде имени и списка формальных параметров, и блок кода. При этом в блоке могут выделяться подблоки.\\ | ||
Были выделены структурные управляющие конструкции: ветвления, циклы, последовательные участки, исполняющие условно или многократно вложенные наборы операторов, также ограниченные теми же ключевыми словами **''begin''** и **''end''**, что дало возможность описывать логику программы без использования безусловных переходов — печально известного оператора [[Goto|goto]], провоцирующего на создание запутанных и плохо структурированных программ.\\ | Были выделены структурные управляющие конструкции: ветвления, циклы, последовательные участки, исполняющие условно или многократно вложенные наборы операторов, также ограниченные теми же ключевыми словами **''begin''** и **''end''**, что дало возможность описывать логику программы без использования безусловных переходов — печально известного оператора [[Goto|goto]], провоцирующего на создание запутанных и плохо структурированных программ.\\ | ||
Строка 24: | Строка 21: | ||
В Алголе было предложено два способа передачи параметров в подпрограмму — [[Вызов по имени|по имени]] и [[Вызов по значению|по значению]]. Если второй способ возражений не вызывает (он широко используется в абсолютном большинстве языков по сей день), то первый (он предполагает, что в процедуру передаётся имя фактического параметра, и процедура работает так, как будто в точке обращения записан её код, где вместо формального параметра написано имя фактического) приводил к трудностям реализации компиляторов и появлению труднообнаруживаемых ошибок.\\ | В Алголе было предложено два способа передачи параметров в подпрограмму — [[Вызов по имени|по имени]] и [[Вызов по значению|по значению]]. Если второй способ возражений не вызывает (он широко используется в абсолютном большинстве языков по сей день), то первый (он предполагает, что в процедуру передаётся имя фактического параметра, и процедура работает так, как будто в точке обращения записан её код, где вместо формального параметра написано имя фактического) приводил к трудностям реализации компиляторов и появлению труднообнаруживаемых ошибок.\\ | ||
====Пример кода на языке Алгол 60==== | ====Пример кода на языке Алгол 60==== | ||
- | ''**procedure** Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k); **value** n, m; **array** a; **integer** n, m, i, k; **real** y;**comment** Наибольший элемент матрицы a, размера n на m передаётся в виде результата в y, а его индексы — в параметры i и k;**begin** **integer** p, q; y := 0; i := k := 1; **for** p:=1 **step** 1 **until** n **do** **for** q:=1 **step** 1 **until** m **do** **if** abs(a[p, q]) > y **then** **begin** y := abs(a[p, q]); i := p; k := q **end****end** Absmax''Это пример выдачи на печать таблицы в реализации Алгола Elliott 803 ALGOL.\\ | + | ''**procedure** Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k); **value** n, m; **array** a; **integer** n, m, i, k; **real** y;**comment** Наибольший элемент матрицы a, размера n на m передаётся в виде результата в y, а его индексы — в параметры i и k;**begin** **integer** p, q; y := 0; i := k := 1; **for** p:=1 **step** 1 **until** n **do** **for** q:=1 **step** 1 **until** m **do** **if** abs(a[p, q]) > y **then** **begin** y := abs(a[p, q]); i := p; k := q **end****end** Absmax''Это пример выдачи на печать таблицы в реализации Алгола Elliott 803 ALGOL.\\ |
- | ''FLOATING POINT ALGOL TEST'BEGIN REAL A,B,C,D'READ D'FOR A:= 0.0 STEP D UNTIL 6.3 DOBEGIN PRINT PUNCH(3),??L??' B := SIN(A)' C := COS(A)' PRINT PUNCH(3),SAMELINE,ALIGNED(1,6),A,B,C'END'END'''PUNCH(3) посылает текст не на перфоратор, а на удалённый принтер. SAMELINE подавляет возврат каретки. ALIGNED(1,6) указывает формат — 1 знак до и 6 после десятичной точки.\\ | + | ''FLOATING POINT ALGOL TEST'BEGIN REAL A,B,C,D'READ D'FOR A:= 0.0 STEP D UNTIL 6.3 DOBEGIN PRINT PUNCH(3),??L??' B := SIN(A)' C := COS(A)' PRINT PUNCH(3),SAMELINE,ALIGNED(1,6),A,B,C'END'END'''PUNCH(3) посылает текст не на перфоратор, а на удалённый принтер. SAMELINE подавляет возврат каретки. ALIGNED(1,6) указывает формат — 1 знак до и 6 после десятичной точки.\\ |
====Hello, World==== | ====Hello, World==== | ||
- | Это пример программы **Hello, World** для реализации Dartmouth ALGOL 30(([[http://www.engin.umd.umich.edu/CIS/course.des/cis400/algol/hworld.html|Hello world! Example Program]])):\\ | + | Это пример программы **Hello, World** для реализации Dartmouth ALGOL 30(([["http:www.engin.umd.umich.edu/CIS/course.des/cis400/algol/hworld.html"|Hello world! Example Program]])):\\ |
- | ''BEGINFILE F (KIND=REMOTE);EBCDIC ARRAY E [0:11];REPLACE E BY "HELLO, WORLD!";WHILE TRUE DO BEGIN WRITE (F, *, E); END;END.''Это альтернативная реализация для Elliott Algol:\\ | + | ''BEGINFILE F (KIND=REMOTE);EBCDIC ARRAY E [0:11];REPLACE E BY "HELLO, WORLD!";WHILE TRUE DO BEGIN WRITE (F, *, E); END;END.''Это альтернативная реализация для Elliott Algol:\\ |
- | '' **program** HiFolks; **begin** **print** "Hello, world"; **end**;''Реализация для IBM OS/360 ALGOL F:\\ | + | '' **program** HiFolks; **begin** **print** "Hello, world"; **end**;''Реализация для IBM OS/360 ALGOL F:\\ |
- | '''BEGIN' OUTSTRING (1, '('HELLO, WORLD!')');'END'''\\ | + | '''BEGIN' OUTSTRING (1, '('HELLO, WORLD!')');'END'''\\ |
====Трюк Йенсена==== | ====Трюк Йенсена==== | ||
Рассмотрим следующую программу на Алголе:\\ | Рассмотрим следующую программу на Алголе:\\ | ||
- | ''**begin** **procedure** p (a, b); **name** a, b; **integer** a, b; **begin** **for** a:=1 **step** 1 **until** 10 **do** b := 0 **end** p; **integer** i; **integer** **array** s [1:10]; p (i, s[i])**end**''В соответствии с определением способа передачи параметров по имени, вызов процедуры p в данном случае должен приводить к обнулению всех элементов массива s. Такое использование передачи параметра по имени было названо «трюком Йенсена» в честь впервые предложившего его программиста. Функции с такими параметрами легко реализуются с помощью препроцессора (как в языке C), однако, генерация объектного кода для них достаточно сложна: фактически для передачи по имени сложных выражений компилятор должен был создавать специальную неименованную функцию, вычисляющую это выражение в его собственной среде окружения, так называемый //[[Санк|санк]] (//[[//en.wikipedia.org/wiki/Thunk|англ.]]//)//. Ближайшим аналогом санка является замыкание в языке Лисп, однако, санк возникает только в специфическом контексте передачи параметров. Эта особенность языка Алгол 60, в остальном довольно разумно организованного, примечательна удивительным сочетанием полной практической бесполезности с чрезвычайной сложностью и неэффективностью реализации. Поэтому в дальнейшем развитии языков программирования от передачи параметров по имени отказались. В языке PL/I, в целом очень много унаследовавшем от Алгола-60, на этой волне заодно отказались и от передачи параметров по значению, оставив, как и в раннем Фортране, единственный механизм — по ссылке.((Пратт Т. Языки программирования: разработка и реализация. — М.: Мир, 1979. — 576 с.: ил.)) В языке [[Си (язык программирования)|Си]], напротив, осталась только передача параметров по значению (передача по ссылке там может быть смоделирована путём использования параметров типа «указатель»). А для тех случаев, когда передача параметров по имени имеет смысл (она необходима, например, если требуется создать функцию, для которой значения параметров не вычислялись бы в момент вызова), были созданы специальные синтаксические механизмы.\\ | + | ''**begin** **procedure** p (a, b); **name** a, b; **integer** a, b; **begin** **for** a:=1 **step** 1 **until** 10 **do** b := 0 **end** p; **integer** i; **integer** **array** s [1:10]; p (i, s[i])**end**''В соответствии с определением способа передачи параметров по имени, вызов процедуры p в данном случае должен приводить к обнулению всех элементов массива s. Такое использование передачи параметра по имени было названо «трюком Йенсена» в честь впервые предложившего его программиста. Функции с такими параметрами легко реализуются с помощью препроцессора (как в языке C), однако, генерация объектного кода для них достаточно сложна: фактически для передачи по имени сложных выражений компилятор должен был создавать специальную неименованную функцию, вычисляющую это выражение в его собственной среде окружения, так называемый //[[Санк|санк]] (//[[//en.wikipedia.org/wiki/Thunk|англ.]]//)//. Ближайшим аналогом санка является замыкание в языке Лисп, однако, санк возникает только в специфическом контексте передачи параметров. Эта особенность языка Алгол 60, в остальном довольно разумно организованного, примечательна удивительным сочетанием полной практической бесполезности с чрезвычайной сложностью и неэффективностью реализации. Поэтому в дальнейшем развитии языков программирования от передачи параметров по имени отказались. В языке PL/I, в целом очень много унаследовавшем от Алгола-60, на этой волне заодно отказались и от передачи параметров по значению, оставив, как и в раннем Фортране, единственный механизм — по ссылке.((Пратт Т. Языки программирования: разработка и реализация. — М.: Мир, 1979. — 576 с.: ил.)) В языке [[Си (язык программирования)|Си]], напротив, осталась только передача параметров по значению (передача по ссылке там может быть смоделирована путём использования параметров типа «указатель»). А для тех случаев, когда передача параметров по имени имеет смысл (она необходима, например, если требуется создать функцию, для которой значения параметров не вычислялись бы в момент вызова), были созданы специальные синтаксические механизмы.\\ |
====См. также==== | ====См. также==== | ||
- | * [[ALGOL 68]] | + | * [[ALGOL 68]] |
- | * [[JOVIAL]] | + | * [[JOVIAL]] |
\\ | \\ | ||
====Примечания==== | ====Примечания==== | ||
\\ | \\ | ||
====Литература==== | ====Литература==== | ||
- | * [[http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=6126|ISO 1538:1984 Programming languages — ALGOL 60]] | + | * [[http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=6126|ISO 1538:1984 Programming languages — ALGOL 60]] |
- | * //Роберт В Себеста.// 2.5. Первый шаг к совершенствованию: язык ALGOL 60 // Основные концепции языков программирования = Concepts of Programming Languages. — 5-е изд. — М.: [[Вильямс (издательство)|«Вильямс»]], 2001. — С. 672. — [[Служебная:Источники книг/5845901928|ISBN 5-8459-0192-8]]. | + | * //Роберт В Себеста.// 2.5. Первый шаг к совершенствованию: язык ALGOL 60 // Основные концепции языков программирования = Concepts of Programming Languages. — 5-е изд. — М.: [[Вильямс (издательство)|«Вильямс»]], 2001. — С. 672. — [[Служебная:Источники книг/5845901928|ISBN 5-8459-0192-8]]. |
- | \\ | + | |
====Ссылки==== | ====Ссылки==== | ||
- | * [[http://www.computer-museum.ru/histsoft/algolbnf.php|Язык программирования //Алгол 60// (описание в формулах БНФ).]] | + | * [[http://www.computer-museum.ru/histsoft/algolbnf.php|Язык программирования //Алгол 60// (описание в формулах БНФ).]] |
- | * [[http://www.lrz.de/~bernhard/Algol-BNF.html|Синтаксис]] (англ.) //ALGOL 60// в [[Форма Бэкуса — Наура|БНФ]]. | + | * [[http://www.lrz.de/~bernhard/Algol-BNF.html|Синтаксис]] (англ.) //ALGOL 60// в [[Форма Бэкуса — Наура|БНФ]]. |
- | * [[http://web.archive.org/web/20030315091028/http://www.braithwaite-lee.com/opinions/p75-hoare.pdf|«The Emperor’s Old Clothes»]] (англ.) — речь [[Хоар, Чарльз Энтони Ричард|Чарльза Хоара]] с вручения Приза Тьюринга ACM в 1980 об истории //Алгола// и участии Хоара в ней. | + | * [[http://web.archive.org/web/20030315091028/http://www.braithwaite-lee.com/opinions/p75-hoare.pdf|«The Emperor’s Old Clothes»]] (англ.) — речь [[Хоар, Чарльз Энтони Ричард|Чарльза Хоара]] с вручения Приза Тьюринга ACM в 1980 об истории //Алгола// и участии Хоара в ней. |
- | * [[http://www.billp.org/ccs/A104/|//«803 ALGOL»//]] (англ.) — руководство по Elliott //803 ALGOL//. | + | * [[http://www.billp.org/ccs/A104/|//«803 ALGOL»//]] (англ.) — руководство по Elliott //803 ALGOL//. |
- | * [[http://chernykh.net/content/view/209/221/|История появления //Алгола-60//.]] | + | * [[http://chernykh.net/content/view/209/221/|История появления //Алгола-60//.]] |
+ | |||
+ | {{stemplater>!cl=btmsbln;!nodiv>stemplate:btm:bt-Языки программирования}} | ||
Инструменты страницы