Разработка транслятора с подмножества языка Node.js на язык PHP для использования в веб-разработке

Описание структуры всевозможных документов, трехмерных виртуальных миров, графических интерфейсов пользователя и многих других объектов, используемых в моделях и в реальном мире. Использование трансляторов, предназначенных для интерпретации текстов.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 02.09.2018
Размер файла 2,5 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Федеральное государственное автономное образовательное учреждение высшего образования

"Высшая Школа Экономики"

Факультет информатики, математики и компьютерных наук

Программа подготовки бакалавров по направлению

Программная инженерия

Выпускная квалификационная работа

Разработка транслятора с подмножества языка Node.js на язык PHP для использования в веб-разработке

Куприянов Алексей Павлович

Нижний Новгород, 2018

Оглавление

Введение

Глава 1. Теоретическая часть. Аналоги разрабатываемого продукта Babel

Глава 2. Практическая часть. Инструменты разработки и методология

Заключение

Список литературы

Приложения

Введение

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

Несмотря на то, что к настоящему времени разработаны тысячи различных языков и их трансляторов, процесс создания новых приложений в этой области не прекращается. Это связно как с развитием технологии производства вычислительных систем, так и с необходимостью решения новых прикладных задач. Разработка новых видов трансляторов может быть обусловлена различными причинами, в частности: функциональными ограничениями, отсутствием локализации, низкой эффективностью. Одним из примеров использования транслятора можно считать инструмент babel. После выхода нового стандарта JS, многие браузеры не поддерживали некоторые его функции и часть синтаксиса. Отчасти, для решения этой проблемы был создан babel - транслятор, предназначенный для перевода программного кода, написанного на ES6 в код, соответствующий стандарту ES5. интерфейс транслятор текст

Ввиду обретения огромной популярности, язык js становится намного более широко-используемым в сфере web-разработки, нежели PHP. Идея создания транспилятора с подмножества языка Java Script на PHP является не только продолжением идеи совмещения работы различного типа программ и оборудования (реализованную в инструменте babel), но также ставит вопрос о возможности унификации языков программирования.

Актуальность выбранной тематики

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

Ввиду обретения огромной популярности, язык js становится намного более широко-используемым в сфере web-разработки, нежели PHP. Но в то же время, огромное количество компаний имеет старое, но надежное оборудование, совместимое только с языком PHP. Чтобы обновить оборудование и иметь возможность работать с исходными кодами программ, написанными на js, требуется огромные финансовые и временные затраты. Отсюда и практическое назначение транслятора - убрать зависимость от возможностей оборудования для клиентов, желающих воспользоваться услугами компании, занимающейся разработками в web-сфере.

Помимо этого, исходный код программ, написанных на PHP, имеет намного меньший объем занимаемой памяти, нежели код на языке js. Поэтому применимо к затратам для хостинга web-сайтов, транспилятор также должен приносить выгоду заказчикам: транспилируя исходники js на PHP, клиент получит менее "тяжелые" файлы на выходе, а соответственно, будет иметь меньшие затраты при желании обратиться за услугами хостинга сайтов.

Разрабатываемый транспилятор уникален тем, что не имеет аналогов в общем доступе и решает достаточно важные практические задачи для компании, занимающейся web-разработками.

Идея создания транслятора c подмножества языка JS является актуальной не только с точки зрения развития столь сложной и нетривиальной идеи унификации языков программирования, но и имеет практическую выгоду для it-компаний и заказчиков.

Постановка задачи

Текущее исследование направлено на разработку транспилятора с подмножества языка JavaScript (ECMAScript 6) на язык PHP для использования в веб-разработке. Реализация данного транслятора осуществляется при помощи абстрактного синтаксического дерева. За счет использования синтаксического дерева исходное подмножество JS систематизируется в структуру данных, которая далее используется для генерации кода на PHP.

Реализация проекта делится на 3 основных этапа: реализация стандартной библиотеки PHP функций на js, построение абстрактного синтаксического дерева, выбор наиболее верного подхода к реализации синхронности js.

Библиотека PHP функций на js. Одной из проблем реализации полноценного транспилятора с языка js на PHP является серьезное различие функций, используемых в стандартных библиотеках каждого из языков: большое количество реализаций функций одного из языков отсутствует в стандартной библиотеке другого. Именно поэтому, одной из задач проекта является создание промежуточной библиотеки, которая позволит использовать аналоги PHP функций при разработке на js, необходимых для применения в сфере web разработок.

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

Реализация синхронности js. Одной из главных трудностей разработки подобного траспилятора является совершенно разный подход к управлению процессами в рассматриваемых языках программирования. Если js является асинхронным, применимо к обработке функций, то PHP является полностью синхронным. Именно поэтому, необходимо рассмотреть возможные варианты решения этой проблемы и выбрать наиболее подходящий и удобный в использовании в текущем проекте.

Глава 1. Теоретическая часть. Аналоги разрабатываемого продукта Babel

Babel.JS - это транспайлер, переписывающий код стандарта ES-2015 в код на предыдущем стандарте ES5, который может работать в любом браузере, даже в старых версиях.

Он делает доступными все синтаксические новинки, которые были добавлены в JavaScript с новой спецификацией ES6, среди которых:

· классы (classes)

· Пример объявления класса в ES6:

· если запустить его через Babel, получаем функцию конструктора:

· стрелочные функции (fat arrows)

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

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

· многострочный вариант определения строки (multiline strings)

· ES6 также имеет новый способ определения строк. Символ "`" (backtick) позволяет создавать многострочный вариант определения строки. Эта функциональность особенно полезна при определении шаблонов в JavaScript:

· данный исходный код преобразуется в:

Babel позволяет использовать синтаксис нового стандарта языка JS в любой нужный момент без потребности ожидания обновления оборудования или программ, работающих с исходным кодом, написанным с использованием нового стандарта. Этот инструмент достаточно популярен в сфере web-разработок, т.к. многие браузеры поддерживают исключительно стандарт ES-5. Идея разработки такого продукта, помогающего использовать любой удобный для разработчика стандарт языка или же абсолютно другой язык программирования была перенесена и на текущий проект.

NET Framework

NET Framework - это программная платформа, выпущенная компанией Microsoft, уникальной особенностью которой является совместимость различных служб, написанных на разных языках программирования.

Спецификация (Common Language Infrastructure specification (CLI)) описывает список функций, которые должен предоставить каждый язык программирования для использования.NET Framework и общеязыковой среды исполнения (Common Language Runtime (CLR)) и взаимодействия с компонентами программ, написанных на других языках программирования. Если язык программирования реализует необходимую функциональность, то он называется.NET-совместимым. Каждый.NET-совместимый язык программирования поддерживает одинаковые типы данных, использует те же.NET Framework классы, компилируется в промежуточный уровень, называемый MSIL (Microsoft Intermediate Language) и использует общеязыковую среду выполнения для управления выполнением. За счет этого разработчики могут сами выбрать наиболее удобный язык программирования для реализации отдельных компонентов, не меняя платформу разработки. Кроме этого, компоненты, написанные на одном языке, могут легко взаимодействовать с компонентами, написанными на другом языке. Например, можно написать класс в C#, который наследует от базового класса, написанного в Visual Basic.

Идея унификации конкретного набора функций в.NET Framework реализована и в текущем проекте - был взят необходимый для решения конкретных практических задач (а именно, для написания серверной части сайтов) набор функций языка PHP, которые необходимо реализовать на языке JS с последующей возможностью транслирования исходного кода на JS в PHP.

Дерево разбора и абстрактное синтаксическое дерево

Одной из главных подзадач проекта является преобразование исходного кода, написанного на языке JS, в структурированный вид с возможностью дальнейшего преобразования полученной структуры в исходный код языка PHP. Иначе описанный набор действий можно назвать задачей "парсинга" исходного кода.

Одним из возможных вариантов представления результата парсинга кода является дерево разбора (derivation tree). Это упорядоченное корневое дерево, представляющее синтаксическую структуру строки в соответствии с некоторой грамматикой языка (объединением синтаксических правил языка программирования). Дерево разбора сохраняет всю информацию, используемую при синтаксическом анализе, включая сведения, в которых нуждается исключительно парсер. С другой стороны, абстрактное синтаксическое дерево (abstract syntax tree) полностью описывает синтаксическую структуру выражения в гораздо более простой форме.

Рассмотрим представление примитивного выражения "7*a - (b + 3)" в дереве разбора (Рис. 1.1) и абстрактном синтаксическом дереве (Рис. 1.2), и сравним достоинства и недостатки их использования:

Рис. 1.1: Дерево разбора для выражения 7*a - (b + 3)

Рис. 1.2: Абстрактные синтаксические деревья для выражения 7*a - (b + 3)

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

Основное отличие представленных на рисунках 1.1 и 1.2 деревьев заключается в том, что в абстрактном синтаксическом дереве удалены не значимые токены - в данном случае скобки. Порядок выполнения действий в выражении в АСД задается за счет структуры дерева (уровня размещения токенов). Также в дереве разбора перед каждым токеном на уровне выше находится его идентификатор ("numeral", "strong op", "identifier", "weak op" и т.д.), чего нет в абстрактном синтаксическом дереве. Это объясняется тем, что данные идентификаторы никак не влияют на семантику программы.

Решающее свойство выражения "7*a - (b + 3)" заключается в том, что это разность произведения и суммы определенных чисел и переменных. Любая другая информация в рамках составления дерева с последующей генерацией кода на другом языке программирования является избыточной. Отсюда и преимущество использования абстрактных синтаксических деревьев - тривиальное структурированное представление исходного кода с последующим минимальным временем обработки.

При преобразовании дерева разбора в абстрактное синтаксическое дерево необходимо сохранить символы, представляющие операции и команды, в виде корневых узлов поддеревьев, оставляя операнды их дочерними. Второе дерево на рисунке 1.17 немного отличается от этого принципа: выражение можно рассматривать как бинарную операцию, и два подвыражения. Выбор левого поддерева для бинарной операции произвольный; он предполагает префиксную нотацию следующего вида "-(*(5,a),+(b,1))", что выглядит менее интуитивно понятным, чем первое дерево. Но в рамках построения абстрактного синтаксического дерева, разработчика интересует абстрактное представление языковых конструкций, а не конкретный синтаксис. Разработчик в праве выбрать любое представление, пока существует возможность адекватно описать конструкции языка и поддерживать последовательность.

Управление процессами

Одной из главных трудностей разработки траспилятора является совершенно разный подход к управлению процессами в рассматриваемых языках программирования. Если js является асинхронным, применимо к обработке функций, то PHP является полностью синхронным. Поэтому, необходимо рассмотреть возможные варианты решения этой особенности и выбрать наиболее подходящий и удобный в использовании способ в текущем проекте.

Существует несколько способов управления асинхронными функциями.

Callback

В JS функциях одним из аргументов можно передавать другую функцию. Это необходимо делать для того, чтобы вызвать переданную функцию сразу после завершения какого-то процесса, который может занять некоторое время. Callback-функции позволяют разработчику быть уверенным в последовательности исполняемого кода, другими словами, управлять асинхронными функциями - определенная часть кода не начнет исполнятся до того момента, пока другой код не завершит исполнение. Пример использования callback-функции:

результатом выполнения данного фрагмента кода будет два оповещения, в последовательности один за другим, о том, что выполнение тренировки началось ("Starting my running training") и что тренировка закончилась ("Finished my train").

Основная проблема, связанная с использованием callback-функций ("Callback hell"), заключается в отсутствии возможности читать и поддерживать исходный код, переполненный функциями данного типа (которые образуют длинные лестницы тяжело отслеживаемых последовательностей).

Promise

Используя специальную конструкцию Promise можно улучшить структурированность кода, а как следствие, его восприятие разработчиками. Конструкция создания promise:

Promise инициализируется с помощью функции, в которой есть вызовы методов "resolve" и "reject". Асинхронный код помещают внутри функции, созданной с помощью конструктора Promise. Если код будет выполнен успешно, вызывают метод "resolve", если нет - "reject". Если функция вызовет "resolve", будет исполнен метод ".then" для объекта Promise, аналогично, если будет вызван reject, будет исполнен метод ".catch".

Всего существует 3 возможных состояния для промисов:

· Pending - состояние ожидания вызова "resolve" или "reject": асинхронная операция выполняется

· Resolved - успешное выполнение? асинхронной операции, завершение работы Promise Promise

· Rejected - во время выполнения операции произошла ошибка, завершение работы Promise

В том случае если состояние Promise не находится в состоянии "pending", то Promise считается выполненным окончательно: его состояние не может меняться.

Async/await

Другим методом управления асинхронными операциями и решения проблемы "Callback hell", является async/await - функция JavaScript, которая делает работу с асинхронными функциями более приятной с точки зрения восприятия кода. Она построена поверх Promise и совместима со всеми существующими API-интерфейсами на основе Promise.

Ключевое слово "async" указывает на функцию, которую предполагается выполнять асинхронно. "await" сообщает системе о том, какая часть кода должна ждать разрешения соответствующего Promise. Сравним использование методов управления асинхронными функциями на примере чтения из файла с последующей записью (Приложение 1).

Выделенные серой подсветкой участки кода наглядно демонстрируют применение callback-функций, конструкции Promise и конструкции async/await. Очевидно, что при имеющейся реализации функции в библиотеке (в данном примере потребовалось писать реализацию функций вручную), конструкции Promises и async/await являются намного понятнее и удобнее в использовании, нежели callback-функции. А работа с конструкцией async/await становится сравнимой с написанием кода на синхронном языке программирования:

Интуитивно понятная структура кода, читабельность, отсутствие "лестниц вложенности" - эти преимущества являются определяющими факторами использования async/await в текущем проекте.

Глава 2. Практическая часть. Инструменты разработки и методология

Программная платформа Node.js

Текущий проект планируется использовать в целях изменения исходного кода серверной части web-сайтов: на данный момент серверная часть сайтов пишется не только на PHP, но и на JavaScript - используется платформа Node.js. Это программная платформа, основанная на движке V8, превращает JavaScript из узкоспециализированного языка в язык общего назначения. Платформа Node.js современнее PHP, обладает более лаконичным и удобным синтаксисом, исходный код реализуемых программ легко оптимизировать для новых версий платформы. Сегодня, огромное количество программистов постепенно переходит к использованию данной платформы для разработки web-приложений и не только, ввиду следующих преимуществ: Node.js добавляет возможность JavaScript взаимодействовать с устройствами ввода-вывода через свой API, подключать другие внешние библиотеки, написанные на разных языках, обеспечивая вызовы к ним из JavaScript-кода. Текущее исследование лишний раз подчеркивает важность использования данной платформы в современном программировании, учитывает и разрабатывает метод взаимодействия с PHP, другим значимым и популярным языком программирования.

Модель разработки

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

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

· Waterfall

· Итеративная модель

Waterfall

Модель Waterfall является одной из самых старых и классических с точки зрения понимания разработки программного обеспечения. Рассмотрим структуру данной методологии (Приложение 2, Рис 3.1). Весь процесс разработки ПО является линейным и строгим. Для каждого этапа модели формируются четкие цели, каждая из которых начинается сразу после того, как предыдущая полностью завершена, без возможности откатиться на предыдущий этап. Одним из главных преимуществ модели является стабильность выполняемых задач: они точно сформулированы и задокументированы, остаются неизменными на всем процессе разработки. Модель удобна для прогнозирования необходимых финансовых, временных и человеческих ресурсов, необходимых для реализации проекта.

Основной недостаток Waterfall-модели заключается в невозможности обрабатывать динамические изменения проекта: очень сложно откатить один из процессов на шаг назад и заложить функции, не учтенные на стадии разработки требований.

Строгость Waterfall-модели к временным срокам, неизменяемость поставленных требований, отсутствие возможности варьировать последовательность действий в разработке послужили определяющим фактором отказа от данной модели в текущем проекте.

Iterative Model

В данном проекте использующейся методологией разработки является итеративная модель (Приложение 2, Рис. 3.2). Итеративная модель включает в себя 4 основные фазы жизненного цикла разработки ПО (начало, исследование, построение и внедрение. На каждой фазе проект проходит множество итераций, приводящих к созданию работоспособных версий: на начальных создаются прототипы, уточняются требования, прорабатываются наиболее сложные проблемы; конечные приводят к созданию продукта, его совершенствованию и расширению функциональности. Преимуществом данной модели является увеличение шансов успешного создания сложной системы, т.к. она реализуется в серии небольших шагов и каждый шаг заключает в себе четко определенный результат.

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

Библиотека acorn.js и парсинг исходного кода

Библиотека acorn, расположенная в репозитории сайта GitHub, включает в себя описание методов реализации парсинга кода и построения абстрактного синтаксического дерева. Данная разработка описывает прототипы используемых для парсинга функций с последующей генерацией объекта абстрактного синтаксического дерева, описывает методы его обхода, включает список совместимых с библиотекой плагинов. Данная разработка является основным источником, применяемым в проекте. Методы библиотеки берутся за основу и перерабатываются для достижения необходимых результатов: непосредственно для транспилирования исходного кода js в необходимую структуру данных, далее генерируемую в результирующий код на языке PHP.

Рассмотрим возможность парсинга исходного кода, написанного на языке JS, в структуру, представляющую абстрактное синтаксическое дерево на примере следующего фрагмента кода:

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

Основные атрибуты структурного представления, генерируемого абстрактного синтаксического дерева:

Название атрибута + описание

Пример

type - тип / название выделенной лексемы

variable declaration, identifier, call expression, literal

body - содержание основных синтаксических единиц кода

Тело программы, функции, блока

start / end - расположение взятой лексемы (номера первого и последнего значащих символов лексемы)

"start": 0,

"end": 78

name - название функций, переменных

"name": "factorial"

"name": "n"

left, right, operator - обработка выражений

левая часть выражения, оператор, правая часть выражения (n == 1)

argument - аргумент при вызове функции

Может быть несколько - в данном примере аргументом при вызове функции factorial является выражение n - 1

В парсере текущего проекта следует выделить следующие основные особенности:

· tokenizer - создает массив лексем (последовательности символов, имеющих смысл для транслятора), необходимых для последующей обработки

· parser - работает с лексемами, выделенными tokenizer-ом. Первым узлом (node), или корнем, каждой программы, созданным парсером является узел "Program". Каждый узел дерева, который определяется парсером, как лист, вызывает рекурсивную функцию, которая возвращает парсер в предыдущий узел дерева до тех пор, пока не найдет возможность дальнейшего построения дерева посредством создания нового узла.

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

Отображаемая структура абстрактного синтаксического дерева достаточно понятно и наглядно представляет содержимое программы - опираясь на структуру, изображенную в Приложении 3 легко создать древовидную структуру текущего дерева (Приложение 4). В данном приложении представлены основные элементы, при помощи которых можно однозначно определить структуру и порядок расположения синтаксических единиц, описанных в предложенном фрагменте кода, что говорит о правильности работы парсера и подтверждает возможность последующей обработки полученной структуры.

Работа Генератора

После создания абстрактного синтаксического дерева в виде структуры, перед траспилятором ставится задача генерации соответствующего кода на языке PHP.

Рассмотрим основной фрагмент кода транспилятора, реализующий генерацию кода на PHP (Приложение 6).

Обход синтаксического дерева выполняется следующим образом:

1. Создается метод code, который в качестве аргументов принимает node (текущий узел дерева - для каждого нового дерева первым узлом всегда будет узел типа Program) и src (представление транслируемого кода в виде строки - с целью вычисления позиции лексемы в зависимости от атрибутов "start" и "end") - данный метод будет применяться при необходимости сгенерировать PHP код из полученной структуры после парсинга кода.

2. Внутри данной функции создается экземпляр класса Code, который будет содержать сгенерированный PHP код.

3. Создается функция "c", которая принимает в качестве аргументов текущий узел, экземпляр класса code, и тип узла (type).

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

5. Таким образом, функция "с" будет рекурсивно вызываться в каждой из функций обработки структуры для перемещения по узлам дерева. Запись обработанного результата будет осуществляться в code, также являющимся аргументом генератора.

Алгоритм обхода в значительной степени реализует паттерн

Visitor - класс-visitor (в данном случае Generate), содержит методы для работы с каждой из конкретных реализаций нашей абстракции (методов реализаций PHP кода в зависимости от типа обрабатываемого узла). А каждая конкретная реализация содержит метод (функцию "с"), который делает одну единственную вещь - передаёт себя соответствующему методу класса Visitor (в данном случае методу generator класса Generate). Схематичное представление описанной реализации:

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

На фрагменте кода (Приложение 6) в строках 160-180 можно наблюдать отдельную обработку комментариев. Идея состоит в том, что при составлении структуры абстрактного синтаксического дерева, не обрабатываются блоки комментариев - поэтому, для полной генерации кода на PHP, необходимо делать это отдельно. Использование библиотеки estraverse позволяет присоединять найденные при парсинге кода на JS конструкции комментариев в качестве аргументов к созданной структуре, представляющей абстрактное синтаксическое дерево. В рассматриваемом фрагменте кода (Приложение 6) можно заметить разделение комментариев на три типа:

· Leading comments - однострочный тип комментария, обозначающийся символами "// *текст комментария", идущий до исходного кода соответствующего узла дерева.

· Block - многострочный тип комментария, обозначающийся символами "/* текст комментария */".

· Trailing comments - однострочный тип комментария, обозначающийся символами "// *текст комментария", идущий после исходного кода соответствующего узла дерева.

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

Метод ln() отвечает за перенос каретки на следующую строку без изменения текущей табуляции. При использовании числового аргумента для метода ln() (например, ln(+1) или ln(-1)), при переносе каретки на следующую строку, будет изменена табуляция на 1 уровень вправо или влево, соответственно знаку аргумента.

Метод un уменьшает уровень табуляции на 1 в текущей строке. В представленном фрагменте кода не обходим для постановки символа "{", использующегося для обозначения окончания тела функции, на необходимое место.

Реализованные функции:

Библиотека PHP функций, реализованных на JS, необходима в данном проекте по причине их отсутствия в транспилируемом языке программирования, что делает невозможным использование некоторых особенностей языка PHP в целях создания серверной части web-сайтов.

Полный листинг функций можно наблюдать в Приложении 5. Рассмотрим некоторые из них более подробно:

Данная функция кодирует данные специальным алгоритмом base64. Это кодирование разработано для корректной передачи бинарных данных по протоколам, не поддерживающим 8-битную передачу, например, для отправки бинарных файлов в теле письма.

Функции json_encode и json_decode служат для преобразования в формат json переменной, массива или объекта и, наоборот, для для расшифровки полученной строки. JSON (Java Script Object Notation) - объект, представляющий собой строку для передачи данных, состоящих из пар атрибут-значение и имеющий определенный формат. Формат JSON часто используются в разработке сайтов при передачи данных между клиентом и сервером.

Использование в web-разработке

Примеры использования траспилятора рассматриваются в рамках серверной части Системы управления Сайт PRO (свидетельство о регистрации №2017610125). Общий процент успешно-транслированных функций равняется ~86%. Транспилятор был использован на 61 файле, в которых определено 1029 функций. Из них успешно реализованных функций - 883. Примеры транслирования файлов Системы управления, написанных на языке JS, в код на язык PHP рассмотрены в Приложении 7.

Исходя из приведенных примеров, можно сделать вывод, что PHP версия кода, полученная при помощи транспилятора, полностью сохраняет функциональные возможности исходного кода, написанного на JS, при этом поддерживая его структуру и синтаксис.

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

Сравнение с существующими реализациями

Существующие реализации транспиляторов с языка программирования JS на язык PHP, находящиеся в открытом доступе, рассматривают возможность траслирования лишь части функционала, реализованного в текущем проекте. Помимо этого, даже в самых успешных версиях реализации подобного инструмента не упомянуты ярко выраженные отличия выбранных языков программирования, в частности, их синхронность / асинхронность.

Рассмотрим транслирование кода в одной из существующих реализаций в Приложении 8 (http://endel.me/js2php/). В представленных примерах можно наблюдать, что автор реализации рассматривает создание подобного инструмента на уровне "теоретически возможно", при этом:

· не затрагивает обработку callback-функций

· количество реализуемых функций минимально

· транспилятор не обрабатывает структуру написанного кода: теряются отступы, код становится нечитаемым

· отсутствует перенос комментариев - в коде на PHP они отсутствуют

Заключение

Результатом выполнения данной работы является полноценный инструмент web-разработчика - транспилятор с подмножества языка JavaScript (ECMAScript 6) на язык PHP. Данный транспилятор является актуальным не только с теоретической точки зрения - решения проблемы унификации языков программирования, но также имеет реальную практическую значимость - может быть использован компаниями в сфере web-разработки в целях уменьшения финансовых затрат на услуги хостинга сайтов и в решении проблем, связанных с зависимостью от типа оборудования, работающего с исходными файлами серверной части программ.

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

В практической части проекта были рассмотрены основные методы создания абстрактного синтаксического дерева в виде структуры данных, подробно проанализирована сама структура данных с выделением ее основных аргументов. В качестве преобразования полученной структуры в код на языке PHP, был создан генератор, работа которого достаточно подробно изложена и подкреплена примерами.

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

Список литературы

1. GitHub. (б.д.). Acorn/acornjs. https://github.com/acornjs/acorn.

2. Haverbeke, M. (2015). Eloquent JavaScript.

3. Ira D. Baxter, A. Y. (б.д.). Clone Detection Using Abstract Syntax Trees.

4. Kenneth Slonneger, B. L. (б.д.). Formal Syntax and Semantics of Programming Languages.

5. Lindley, C. (2013). Javascript Enlightenment.

6. Web-documentation. (б.д.). MDN web docs. https://developer.mozilla.org/ru/.

7. Библиотека estavers. (б.д.). Получено из GitHub.com: https://github.com/estools/estraverse

8. В.А. Пласковицкий, П.У. (2014). Труды БГТУ.

9. Маршалов, А. (б.д.). Создание языка программирования с использованием LLVM.

10. Нямтиу, Ю. (б.д.). Исследование эволюции кода с использованием сравнения абстрактных синтаксических деревьев.

11. Реализация PHP функций на языке JS. (б.д.). Получено из locutus.io: http://locutus.io/

12. Статья "Ещё раз про семь основных методологий разработки". (б.д.). Получено из habr.com: https://habr.com/company/edison/blog/269789/

13. Статья JavaScript: методы асинхронного программирования. (б.д.). Получено из habr.com: https://habr.com/company/ruvds/blog/337662/

Приложение 1

методы управления асинхронными функциями (callbacks + Promise)

методы управления асинхронными функциями async/await

Приложение 2

Рис 3.1: Waterfall-модель разработки ПО

Рис 3.2: Итеративная модель разработки ПО

Приложение 3

Представление функции нахождения факториала в виде АСД при помощи acorn.js (порядок чтения - по столбцам, слева-направо)

{

"type": "Program",

"start": 0,

"end": 79,

"body": [

{

"type": "FunctionDeclaration",

"start": 0,

"end": 78,

"id": {

"type": "Identifier",

"start": 9,

"end": 18,

"name": "factorial"

},

"generator": false,

"expression": false,

"async": false,

"params": [

{

"type": "Identifier",

"start": 19,

"end": 20,

"name": "n"

}

],

"body": {

"type": "BlockStatement",

"start": 22,

"end": 78,

"body": [

{

"type": "IfStatement",

"start": 25,

"end": 46,

"test": {

"type": "BinaryExpression",

"start": 29,

"end": 35,

"left": {

"type": "Identifier",

"start": 29,

"end": 30,

"name": "n"

},

"operator": "==",

"right": {

"type": "Literal",

"start": 34,

"end": 35,

"value": 1,

"raw": "1"

}

},

"consequent": {

"type": "ReturnStatement",

"start": 37,

"end": 46,

"argument": {

"type": "Literal",

"start": 44,

"end": 45,

"value": 1,

"raw": "1"

}

},

"alternate": null

},

{

"type": "ReturnStatement",

"start": 48,

"end": 76,

"argument": {

"type": "BinaryExpression",

"start": 55,

"end": 75,

"left": {

"type": "Identifier",

"start": 55,

"end": 56,

"name": "n"

},

"operator": "*",

"right": {

"type": "CallExpression",

"start": 59,

"end": 75,

"callee": {

"type": "Identifier",

"start": 59,

"end": 68,

"name": "factorial"

},

"arguments": [

{

"type": "BinaryExpression",

"start": 69,

"end": 74,

"left": {

"type": "Identifier",

"start": 69,

"end": 70,

"name": "n"

},

"operator": "-",

"right": {

"type": "Literal",

"start": 73,

"end": 74,

"value": 1,

"raw": "1"

}

}

]

}

}

}

]

}

}

],

"sourceType": "script"

}

Приложение 4

Древовидная структура АСД, представленного в приложении 3

Приложение 5

Листинг реализованных на JS функций языка PHP, необходимых для написания серверной части приложений

Приложение 6

фрагмент функции, отвечающий за генерацию PHP кода из структуры, представляющей абстрактное синтаксическое дерево

Приложение 7

Пример работы транспилятора

Фрагмент файла config.js

Транспилированный фрагмент кода в файле config.js

Фрагмент содержимого файла data.js

Транспилированный фрагмент кода в файле data.js

Приложение 8

примеры работы одного из вариантов реализации транспилятора с JS на PHP

Размещено на Allbest.ru

...

Подобные документы

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

    курсовая работа [580,5 K], добавлен 06.08.2013

  • Методы грамматического разбора при разработке учебного транслятора. Проектирование лексического анализатора и магазинного автомата. Программная реализация синтаксического анализатора текстового языка высокого уровня. Разработка модуля интерпретации.

    курсовая работа [697,2 K], добавлен 06.01.2013

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

    курсовая работа [423,3 K], добавлен 24.08.2009

  • Методика разработки и частичная реализация транслятора для языка "С" с использованием языка "С++", производящего разбиение на минимальные неделимые конструкции языка исходной цепочки символов основываясь на лексике языка. Анализ работы программы.

    курсовая работа [841,3 K], добавлен 19.03.2012

  • Запуск Node-серверов на этапе инициализации системы. Использование процессорных ядер в многоядерной системе. Хранение и выборка данных. Практический пример на основе продолжительных вычислений (числа Фибоначчи). Движки сохранения данных для Node.

    курсовая работа [901,2 K], добавлен 07.04.2014

  • Практическое усвоение технологии вставки в текст документа разных графических объектов, созданных средствами Word и других дополнений MS Office. Схема алгоритма вычисления функции вида X=f(X)*E. Диалоговое окно. Вставка диаграммы.

    лабораторная работа [162,8 K], добавлен 22.05.2007

  • Изучение устройства и механизма процессов в компиляторах и интерпретаторах. Понятие трансляции как процедуры перевода программного кода с языка Паскаль на язык С++. Описание интерфейса программы и автоматизация процесса построения диаграммы классов.

    курсовая работа [536,2 K], добавлен 03.07.2011

  • Разработка консольного приложения, которое обрабатывает входной файл с расширением .pas и транслирует в выходной файл с расширением .cpp или .txt (по выбору пользователя). Синонимичные операторы языков Паскаль и С. Разработка алгоритма решения задачи.

    курсовая работа [329,6 K], добавлен 04.06.2013

  • Изучение особенностей растровых и векторных графических редакторов. Создание графического редактора: выбор языка программирования, разработка структуры программы и алгоритма работы. Описание интерфейса программы. Руководство программиста и пользователя.

    курсовая работа [1,3 M], добавлен 28.07.2013

  • Обоснование языка программирования Object Pascal и среды разработки Delphi. Создание интерфейса пользователя. Проектирование структуры и описание компонентов, использованных при разработке программного продукта. Составление инструкции пользователя.

    курсовая работа [888,7 K], добавлен 20.05.2015

  • Web-сервис как программная система, идентифицируемая с помощью некоторого URI, общедоступный интерфейс и связывания которого определяются и описываются с помощью языка описания интерфейсов WSDL. История, коммерческие предпосылки использования сервисов.

    контрольная работа [169,1 K], добавлен 19.01.2012

  • Использование хеширования для поиска данных. Хеширование и хеш-таблицы. Способы разрешения конфликтов. Использование средств языка программирования в работе с хеш-таблицами. Описание разработанного приложения. Структура программы. Инструкция пользователя.

    курсовая работа [1,1 M], добавлен 19.08.2016

  • Понятие "компьютерная графика". Изучение графических редакторов в школьном курсе для 8-го класса. Способы создания цифровых графических объектов. Представление о цветовых моделях. Анализ программы Inkscape. Копирование файла в папку установки приложения.

    курсовая работа [1,5 M], добавлен 17.05.2014

  • Создание инструмента проектирования и прототипирования графических пользовательских интерфейсов сложных информационных систем. Интерфейс пользователя и командной строки. Средства прототипирования и их характеристики. Создание интерактивных прототипов.

    дипломная работа [2,4 M], добавлен 04.07.2011

  • Характеристика языка программирования С++. Описание классов и методов. Выполнение решения вычислительных процессов по заданным формулам. Создание диалогового приложения. Разработка инструкции пользователя. Операции над одномерными и двумерными массивами.

    дипломная работа [2,0 M], добавлен 16.04.2017

  • Общая характеристика и оценка возможностей языка программирования си-шарп, его сходные и отличительные черты от С++ и Java. Разработка с помощью данного языка программирования лексического и синтаксического анализатора. Составление таблиц разбора.

    курсовая работа [111,6 K], добавлен 11.06.2010

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

    дипломная работа [2,0 M], добавлен 23.12.2016

  • Проектирование лексического и синтаксического анализаторов учебного языка. Правила преобразования логических выражений в ПОЛИЗ. Формирование триад, оптимизация их списка. Логическая структура программы. Тестирование модулей транслятора-интерпретатора.

    курсовая работа [1,3 M], добавлен 28.05.2013

  • Целесообразность выбора языка программирования. Основные структуры языка программирования. Кодирование по методу четности/нечетности, по методу Хэмминга. Машина Поста. Инструкция программиста и пользователя. Использование программы StudyProgram.

    курсовая работа [294,7 K], добавлен 27.02.2009

  • Основы программирования на языке VB.NET. Область применения трехмерных изображений. Форматы хранения пакетов инженерной графики. Преимущества трехмерного моделирования. Разработка программы по вращению трехмерных изображений на языках VB.NET и VRML.

    курсовая работа [195,1 K], добавлен 11.03.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.