Какой язык программирования мне выбрать?

4.1. Простой контроллер термостата

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

Необходимо распознавать следующие токены: heat, on/off (состояние STATE), target, temperature и числа (NUMBER).

Lex-анализатор выглядит следующим образом (пример 4):

Отметим два важных изменения. Во-первых, мы подключили файл ‘y.tab.h’, во-вторых, мы больше ничего не печатаем, а лишь возвращаем имена токенов

Это изменение нужно потому, что мы будем отдавать поток токенов на вход YACC, которому неважно, что мы выводим на экран. В файле y.tab.h как раз находятся определения этих токенов.

Но откуда же берется файл y.tab.h? Он генерируется самим YACC из файла грамматики, который мы сейчас напишем. Наш язык очень прост, такой же простой будет и его грамматика:

Первая часть, я называю ее «корень». Она означает, что мы имеем «команды» (commands), и эти команды состоят из отдельных «команд» (command). Как нетрудно заметить, это определение рекурсивно, ведь оно содержит в себе само себя. Благодаря рекурсии, программа способна постепенно сокращать набор команд одну за одной. В разделе «Внутреннее устройство Lex и YACC» есть существенные замечания по рекурсии.

Второе правило определяет, что из себя представляет команда. Мы задумываем лишь два типа команд — heat_switch (вкл/выкл обогревателя) и target_set (установка температуры). Здесь используется знак ИЛИ — | . В целом правило означает: «command может быть heat_switch или target_set».

Правило heat_switch состоит из токена HEAT (это просто слово «heat»), после которого идет состояние (оно определено в Lex-файле как «on» или «off»).

Немного более сложным является последнее правило target_set, состоящее из токена TARGET (слово «target»), токена TEMPERATURE (слово «temperature») и числа.

Полный YACC-файл

В предыдущем разделе приведена лишь грамматическая часть YACC-файла, но это еще не все. Мы намеренно опустили этот заголовок:

Функция yyerror() вызывается YACC, когда он обнаруживает ошибку. Здесь мы просто выводим сообщение, что ошибка найдена, но можно выполнять и куда более умные вещи — смотрите раздел «Дополнительные материалы» в конце статьи.

Функция yywrap() может быть использована для продолжения чтения из другого файла. Она вызывается при получении символа EOF, здесь вы можете открыть другой файл, и вернуть 0. Либо можете вернуть значение 1 — это означает, что действительно достигнут конец. Более подробные сведения смотрите в разделе «Внутреннее устройство Lex и YACC».

Далее, есть функция main(), которая не делает ничего, только запускает наш механизм.

В последней строке определены используемые токены. На основе этой строки генерируется файл y.tab.h, если YACC вызван с ключом ‘-d’.

Компилируем и запускаем контроллер термостата

Пример диалога:

Это не совсем то, чего мы хотели достичь, но в интересах понятности объяснения и легкости обучения нельзя показывать все и сразу.

Выработка случайных чисел

В языке PHP применяются два генератора случайных чисел (вызываемых соответственно с помощью функций rand()
и mt_rand()
). С каждым из этих генераторов связаны по три функции одинакового назначения: функция задания начального значения (srand()
и mt_srand()
), сама функция получения случайного числа и функция, осуществляющая выборку наибольшего целого числа, которое может быть возвращено генератором ((getrandmax()
и mt_getrandmax()
)). Функции getrandmax() и mt_getrandmax() возвращают значение наибольшего числа, которое может быть возвращено функцией rand() или mt_rand(), на платформах Windows это значение ограничено величиной 32768.

Выбор конкретной функции выработки псевдослучайных чисел, которая используется в функции rand(), может зависеть от того, с какими именно библиотеками был откомпилирован интерпретатор PHP. В отличие от этого в генераторе mt_rand() всегда используется одна и та же функция выработки псевдослучайных чисел (mt — сокращение от Mersenne Twister), причем автор оперативной документации к функции mt_rand() утверждает, что эта функция к тому же является более быстродействующей и «более случайной» (с точки зрения криптографии), чем rand(). У нас нет оснований сомневаться в истинности этих утверждений, поэтому мы предпочитаем использовать функцию mt_rand(), а не rand().

При использовании некоторых версий PHP для некоторых платформ создается впечатление, что функции rand() и mt_rand() вырабатывают на первый взгляд вполне приемлемые случайные числа, даже без предварительного задания начального значения. Но такому впечатлению не следует доверять. Во-первых, программы, в которых используются функции выработки случайных чисел без задания начального значения, невозможно легко переносить на другие платформы, а, во-вторых, надежная работа указанных функций без задания начального значения не гарантируется.

Типичный способ задания начального значения для любого из генераторов случайных чисел PHP (с использованием функции mt_srand() или srand()) заключается в следующем:

mt_srand((double)microtime()*1000000);

В этом операторе задается начальное значение генератора, равное количеству микросекунд, истекших к данному времени с момента отсчета последней целой секунды. (Приведение типа к типу double в этом операторе действительно необходимо, поскольку функция microtime() возвращает строку, которая рассматривается как целое число в операции умножения, но не в операции передачи параметров в функцию.) Рекомендуем читателю вводить указанный оператор задания начального значения, даже если ему не совсем понятно назначние этого оператора; достаточно просто поместить данный оператор на каждую страницу PHP, всего лишь один раз, перед использованием соответствующей функции mt_rand() или rand(), и этот оператор будет гарантировать, что отправная точка изменится и поэтому каждый раз будут вырабатываться различные случайные последовательности.

Данный конкретный метод задания начального значения был глубоко продуман теми специалистами, которые полностью понимают все нюансы выработки псевдослучайных чисел, поэтому, скорее всего, навсегда останется лучшим по сравнению с любыми попытками какого-то отдельного программиста придумать что-то более «заковыристое».

Очевидно, что указанные функции выработки псевдослучайных чисел возвращают только целые числа, но случайное целое число из заданного диапазона можно легко преобразовать в соответствующее число с плавающей точкой (скажем, в число из диапазона от 0.0 до 1.0 включительно) с помощью выражения наподобие rand() / getrandmax(). После этого указанный диапазон можно масштабировать и сдвигать по мере необходимости. Ниже показан пример:

// Допустим нам нужно сгенерировать случайное число от 100.0 до 120.0
$random = 100.0 + 20.0 * mt_rand() / mt_getrandmax();
echo $random.»»;
// Выработка целых чисел (100 — 120);
echo round($random);

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

Java

Сложность: Сложнее, чем Python, но проще, чем C++. Довольно сильно похож на C# как по синтаксису, так и по сложности освоения. А большое количество обучающих материалов разного уровня доступно бесплатно.

Профессии: Тестировщик ПО / Android-разработчик/ Java-разработчик.

Продукты: архитектура Netflix, Spotify, Uber, веб-приложение Twitter

Java стал вездесущим из-за своей универсальности и надежности. Про него слышали даже те, кто далек от программирования, потому что на языке написаны продукты, которыми мы пользуемся каждый день (Android-приложения, игрушки, десктопные ПО, банковские системы). Он кроссплатформенный, благодаря JVM (Java Virtual Machine) его можно запускать везде. Его чаще используют в компаниях, а не в инди-проектах.

У Java одно из самых мощных сообществ. Вы сможете найти много разных проектов с открытым исходным кодом, обратиться за помощью и использовать готовые решения для своих кодов, развивая и совершенствуя их.

Ку

Java-разработчик

Ваш прямой путь в программирование на самом востребованном языке backend-разработки+ навыки DevOps. Дополнительная скидка 5% по промокоду BLOG.

Узнать больше

Примеры неочевидных по смыслу форм[править]

Рассмотрим, для примера, следующий фрагмент кода, выбирающий из списка (Shanghai, Karachi, Mumbai, Delhi, Ahmedabad) строки, содержащие латинскую букву «b»:

grep { /b/ } ("Shanghai", "Karachi",  "Mumbai",
              "Delhi", "Ahmedabad");

Можно подумать, что следующий фрагмент выведет выбранные таким образом элементы, завершив вывод переводом строки:

print (grep { /b/ }  ("Shanghai", "Karachi",  "Mumbai",
                      "Delhi", "Ahmedabad"),
       "\n");

Однако, на деле перевод строки не будет выведен, поскольку с точки зрения Perl 5, строка является… аргументом функции , — отнюдь не .

Исправить ситуацию в данном случае может дополнительная пара скобок вокруг вызова :

print ((grep { /a/ } ("Shanghai", "Karachi",  "Mumbai",
                      "Delhi", "Ahmedabad")),
       "\n");

6.2. Рекурсия: «правая — это неправильно»

Рекурсия — ключевой аспект работы YACC. Без нее было бы невозможно составление последовательностей из отдельных выражений или команд. Первой точкой входа в рекурсивные правила является первое правило, либо то, которое вы обозначаете как первое, с помощью символа «%start».

Рекурсия в YACC (да и вообще) бывает двух видов: правая и левая. Левая рекурсия, которой можно пользоваться в большинстве случаев, выглядит примерно так:

commands: /* пусто */
        |
        commands command

Сравните такой подход с правой рекурсией, который почему-то на взгляд многих людей выглядит привлекательнее:

commands: /* пусто */
        |
        command commands

Если какой-либо символ завершает (и поэтому разделяет) список ваших команд, правая рекурсия на первый взгляд может выглядеть естественной, но она все такая же дорогая:

commands: /* пусто */
        |
        command SEMICOLON commands

Верным решением будет использование левой рекурсии (не я это изобрел):

commands: /* пусто */
        |
        commands command SEMICOLON

В ранних версиях этого HOW-TO ошибочно использовалась правая рекурсия. Маркус Триска (Markus
Triska) любезно проинформировал меня об этом.

Установка веб сервера Apache

Начинаем установку с самого главного, а именно, c программы Apache, который будет служить вам веб сервером. Основная причина, по которой был выбран Apache, является то, что это кроссплатформенное программное обеспечение, основанное на свободном исходном коде, безопасен и надёжен в работе, гибок в установке и настройке. Более подробную информацию и документацию, вы можете найти на официальном сайте apache.org

Скачиваем файл установки httpd-2.2.25-win32-x86-openssl-0.9.8r. После того, как скачали, приступаем к установке веб сервера. Для бедующего сервера, создайте папку C:\server, а в ней папку с именем Apache2

Запустите файл httpd-2.2.25-win32-x86-openssl-0.9.8y.msi (расширение .msi будет скрыто), после чего появится окно.

Рис.1 Установка веб сервера Apache

Далее кликаем на кнопку «Next», появляется следующее окно с лицензионным соглашением.

Рис.2 Установка веб сервера Apache

Выбираем: «I accept the terms in the agreement», чтобы принять лицензионное соглашение. В следующем шаге должно появиться новое окно с описанием веб серрвера Apache.

Рис.3 Установка веб сервера Apache

Кликаем на кнопку “Next” и продолжаем установку. Далее появляется следующие окно.

Рис.4 Установка веб сервера Apache

Рис.5 Установка веб сервера Apache

После того как вы заполнили все поля, кликаем на кнопку “Next”. Должно появиться новое окно.

Рис.6 Установка веб сервера Apache

В этом окне вам предлагают выбрать тип установки, полную (Typical) и выборочную(Custom). Выбираем “Custom” и продолжаем установку.

Рис.7 Установка веб сервера Apache

В следующем шаге вам нужно выбрать куда устанавливать, а также дополнительные библиотеки. Кликаем на против креcтика “Build Headers and Libraries”, в выпадающем списке выбираем “This features will be installed on local hard drive” Потом выбираем папку, куда устанавливать Apache. Вместо C:\Program Files (X86)\Apache Software Foundation\Apache 2.2 указываем C:\server\Apache2\ и кликаем на сново на кнопк “Next”

Рис.8 Установка веб сервера Apache

Должно появиться заключительное окно.

Рис.9 Установка веб сервера Apache

Кликаем на кнопку “Install”, чтобы начать процесс установки.

Рис.10 Установка веб сервера Apache

Ждем завершения процесса установки, после чего должно появиться окно с сообщение, что процесс установки завершен.

Рис.11 Установка веб сервера Apache

Кликаем на кнопку “Finish” и завершаем установку. Всё, теперь установка веб сервера завершена. Чтобы убедиться в этом, смотрим в правом нижнем углу, вы должны увидеть значок, как показано на рисунке 12.

Рис.12 Установка веб сервера Apache

Если этот так, значит веб сервер запущен как служба. Если по какой-либо причине Apache не был запущен, то возможная из причин, что 80 порт занят другой программой. Решить проблему, можно отключив программу, которая занимает 80 порт. Чтобы это выяснить, набираем в командной строке:

netstat -o -n -a | findstr 0.0:80

Рис.13 Установка веб сервера Apache

Очень часто 80 порт занимает программы Skype Если ’80 порт занимает это так, отключите в настройках использование в качестве альтернативных портов 80 и 443 (Инструменты -> Настройки -> Расширенный настройки -> Соединение -> снимаем галочку (Использовать порты 80 и 443 в качестве альтернативных)

Проверяем работоспособность установленого веб сервера. Открываем браузер и набираем в адресной строке http://localhost или http://127.0.0.1 Если вы видите, тоже самое, что на рисунке 14. Поздравляю, ваш веб сервер установлен удачно!

Рис.14 Установка веб сервера Apache

Swift

Логотип Swift

Теперь перейдем к конкретизированным и мобильным разработкам, каким является язык программирования Swift. Язык Swift используют для разработки приложений под iOS и macOS. Очень популярен среди разработчиков. Учитывая, что Apple владеют значительной частью мобильного рынка, данный язык очень актуален!

Платформа Разработка под iOS и macOS
Обучение Относительно легко
Популярность Популярен. №9 в списке PYPL.
Средняя зарплата (мес) 2000$
Преимущества Относительно лёгок в освоении. Самый популярный язык программирования под iOS. Пока производство Apple живо, язык будет востребован всегда.
Недостатки Отсутствуют.

PHP и HTML-текст

Начав писать PHP-код, вы будете работать с самыми обычными текстовыми файлами, содержащими код PHP и HTML. HTML – это простой язык разметки, позволяющий определить, как должна выглядеть страница в окне браузера, но это всего лишь текст. Сервер никак не обрабатывает HTML-файлы перед их отправкой браузеру пользователя. В отличие от HTML, PHP-код должен быть как-то интерпретирован, прежде чем окончательный вариант страницы будет отправлен браузеру. Иначе такая страница на экране у пользователя превратится в смесь текста и программного кода.

Чтобы выделить PHP-код и тем самым проинформировать веб-сервер о необходимости его обработки, PHP-код размещают между формальными или неформальными тегами (<?php … ?>), смешивая с HTML. В примере ниже демонстрируется это с помощью конструкций echo и print. Конструкции echo и print почти совпадают, за исключением того, что конструкция echo может принимать несколько аргументов и не возвращает никакого значения, тогда как конструкция print способна принимать только один аргумент.

Файл этого примера мы назвали index.php, а вы можете взять любое другое имя, главное чтобы оно имело расширение .php. Это расширение сообщает веб-серверу, что файл нужно обрабатывать как PHP-код:

Конструкции echo и print

Когда браузер запросит этот файл, PHP интерпретирует его и воспроизведет текст в формате HTML:

6.3. Продвинутый yylval: %union

На данный момент нам нужно определять тип переменной yylval. Однако это не всегда приемлемо. Бывают случаи, когда нужно работать с несколькими типами данных. Но вернемся к нашему гипотетическому термостату. Допустим, пользователь хочет выбирать, каким обогревателем он будет управлять, например так:

Необходимо, чтобы yylval представлял собой тип данных union — объединение, которое может хранить как строки, так и целые числа — но не одновременно.

Запомните, что раньше мы указывали тип yylval, определяя YYSTYPE. Мы могли бы объявить YYSTYPE как тип union, но YACC предлагает куда более удобное решение — а именно символ %union.

Пример 7 основан на примере 4. Начнем написание YACC-грамматики:

Мы определяем наш тип union, состоящий лишь из чисел и строк. Затем с помощью расширенного синтаксиса %token, мы объясняем YACC, к какой части union’а каждый токен должен иметь доступ.

В нашем случае токен STATE использует целый тип данных, как и обычно. То же самое относится и к токену NUMBER, который используется для задания температур.

Однако здесь появляется новый токен WORD, которому нужен тип данных «строка».

Lex-файл также слегка изменяется:

Как видно из этого примера, мы больше не обращаемся к yylval напрямую, а вместо этого указываем суффикс, обозначающий тип, к которому хотим получить доступ. И не нужно думать об этом в YACC-грамматике, ведь YACC делает все за нас:

Из-за определения %token, данного выше, YACC автоматически выбирает поле «строка» из нашего union’а

Обратите внимание, что мы храним копию $2, которая далее будет использована нами для определения обогревателя, температурой которого будем управлять:. В файле example7.y вы найдете более подробное описание.

В файле example7.y вы найдете более подробное описание.

Замечания

mod_perl 1 / Windows

Ни в коем случае не используйте Apache 1.3x / mod_perl 1.x под Windows в качестве рабочей конфигурации. Проблема в том, что в этом случае все запросы обрабатывает ровно 1 perl-интерпретатор. Таким образом, задержка в исполнении одного запроса блокирует обслуживание всех остальных. Это совершенно недопустимо.

mod_perl 1 / UNIX

Под UNIX количество Perl-интерпретаторов совпадает с количеством экземпляров процесса Apache (httpd). Теоретически они используют общие области памяти, что позволяет экономить, однако на практике на это полагаться нельзя, поскольку любая страница может оказаться изменённой.

Так что всегда следует быть готовым к тому, что на каждый httpd child придётся, скажем, по 50 Мб памяти. Если Вы не готовы предоставить Apache более 500 Мб (он ведь на сервере, скорее всего, не один), отсюда получаем ограничение которое необходимо прописать в глобальный httpd.conf:

Заметьте: по умолчанию этот параметр установлен в 256. Если у Вас менее 13,5 Гб ОЗУ, это практически гарантирует обвал системы из-за вытеснения ядра в swap — раньше или позже.

Ещё 2 директивы, позволяющие поддерживать объём используемой памяти на низком уровне:

При такой настройке ОЗУ ограничено, однако под большой нагрузкой может начаться перегрев CPU по поводу HTTP-запросов, не требующих mod_perl. Статику вообще лучше обслуживать не Apache, а другим, лёгким сервером.

mod_perl 2

По идее, использование mod_perl 2 должно было бы решить все вышеперечисленные проблемы: на обеих платформах поддерживать множественный пул интерпретаторов, параметры которого:

не связаны с конфигурацией Apache в целом.

К сожалению, в реальности имеют место следующие проблемы, из-за которых Apache 2 / mod_perl 2 нельзя признать оптимальной платформой для Eludia- и вообще Perl-приложений:

  • (вроде пустячок, но тем не менее) error.log невозможно разделить по VirtualHost’ам так, чтобы символы перевода строки не превращались в ‘\n’;

Тем не менее, Apache 2 / mod_perl 2 применяется в нескольких рабочих инсталляциях.

С#

Сложность: C# изначально перенял синтаксические конструкции языков С++ и Java, так как его разработали специально, чтобы упростить последние. У него хороший набор фреймворков (.Net, Xamarin) и библиотек.

Профессии: Разработчик игр / Fullstack-разработчик / Backend-разработчик.

Продукты: Это универсальный язык программирования. На нем можно писать серверную часть сайтов, десктопные приложения, серверные приложения и даже игры. На российском рынке популярен движок Unity 3D, который позволяет на языке C# писать игры для любых платформ: для PC, мобильных устройств, приставок или VR.

На нем удобно писать оконные приложения и веб-приложения или даже корпоративное программное обеспечение (например банковское обслуживание).  Так как язык входит в пятерку самых популярных, он узнаваем, и в целом из-за обширной синтаксической семьи C# его сообщество масштабное и активное. Вы можете быть как инди-разработчиком, так и работать в команде — у вас всегда найдутся единомышленники и помощники.

Курс

Разработчик игр

Научим создавать игры на движке Unity, применять на практике ООП и программировать на C#. Дополнительная скидка 5% по промокоду BLOG.

Узнать больше

Отладка

Отладочные средства всегда полезны, особенно в учебе. К счастью, YACC может дать кое-какую обратную связь в виде отладочной информации. Она, естественно, стоит определенных затрат ресурсов, и по умолчанию эта функция отключена. Чтобы включить, надо вызвать YACC с определенными опциями.

При компиляции вашей грамматики, добавьте ключи —debug и —verbose. Также в заголовок вашей программы добавьте следующую строчку:

Это приведет к созданию файла «y.output», содержащего сведения о том, как именно автомат парсера был создан.

Когда вы запустите полученный бинарный файл, он выведет очень много сведений о том, что в данный момент происходит, в том числе текущие состояния автомата и какие токены были распознаны из потока символов.

Питер Джинкс (Peter Jinks) написал статью об , в ней описаны часто допускаемые ошибки и методы их исправления.

Использование «, ==, != и » со строками

Perl обладает парами операторов логического сравнения. Для строк и для чисел. Вы должны четко представлять какой оператор вам нужен в данный момент. Чтобы понять разницу, рассмотрим пример:

«123» == «123.00» #Истинно«123» eq «123.00» #Ложно

Кроме того, иногда программисты небрежно обращаются с истиной в Perl. Ошибочным может быть такой код:

if ($f) {print $f}

Казалось бы, ну что тут ошибочного? Синтаксически – ничего. Perl не станет ругаться на эту строку. Однако, программист сам мог подложить себе свинью. Дело в том, что если в $f окажется значение «0», то этот ноль не будет выведен, хотя могло подразумеваться иное. Если вы хотите выводить все непустые значения $f, включая ноль, то вам нужно написать:

if ($f ne ») {print $f}

Вот соответствия:

  • < lt меньше
  • > gt больше
  • <= le меньше равно
  • >= ge больше равно
  • == eq равно
  • != ne не равно
  • <=> cmp сравнение

7.2. Конфликты: ‘сдвиг/вывод’, ‘вывод/вывод’

Каждый раз, когда YACC предупреждает вас о конфликтах, у вас могут быть проблемы. Разрешение этих конфликтов в какой-то мере является формой искусства, и может быть, вам самим глубже разобраться в описываемом языке. Иногда даже больше, чем этого хотелось бы.

Проблемы состоят в том, как интерпретировать последовательности токенов. Представим, что мы объявили язык, который принимает следующие команды:

Для него мы описали следующую грамматику:

Вы, пожалуй, уже почуяли неладное. Автомат начинает считывать слово «delete», затем «heater», а затем решает, в какое состояние перейти на основе следующего токена. Следующий токен может быть «mode» (описывающий как именно удалять обогреватели), либо имя обогревателя, которое нужно удалить.

Проблема состоит в том, что для обеих команд следующим токеном является WORD. Поэтому YACC не знает, куда идти дальше. Это приводит к появлению предупреждения типа «вывод/вывод», при этом разбор delete_a_heater никогда не будет достигнут.

В данном конкретном случае конфликт разрешается легко (к примеру, переименованием первой команды в «delete heaters all», либо сделав «all» отдельным токеном), но порой сделать это довольно проблематично. Файл y.output, который создается при указании флага yacc —verbose, может здорово вам помочь.

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Люкс-хост
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: