Разработка транслятора в среде Java и С+
Разработка транслятора в среде Java и С+
Разработка транслятора в среде Java и С+
Введение
Тема, цель, актуальность работы
Анализ проектов, реализованных на языках программирования Java и C# на предмет взаимодействия между классами.
Результат работы программы необходимо вывести в файл *.xml.
Актуальность работы заключается в том, что на сегодняшний день нет известных аналогов программы. Не стоит сравнивать данный проект с такими программными продуктами как Telelogic Rapsody или Rational – он является полной противоположностью названных выше программ, так как анализирует уже «готовый», написанный проект, в то время как Telelogic Rapsody (Rational) генерирует код по диаграммам.
Данный проект может использоваться для углубленного изучения языков программирования Java и C# в рамках программы университета, анализа проектов на предмет взаимодействия классов.
Проект может существовать как автономное приложение, а также может быть дополнен и доработан функционально.
Исследовательская часть
C# и Java– два очень похожих между собой современных языка программирования со сборкой мусора и компиляцией при выполнении. Оба языка – объектно-ориентированные, с синтаксисом, унаследованным от C++, но значительно переработанным.
Java – объектно-ориентированный язык программирования, разрабатываемый компанией Sun Microsystems и официально выпущенный 23 мая 1995 года. Java – так называют не только сам язык, но и платформу для создания приложений уровня предприятий на основе данного языка.
Изначально язык программирования назывался Oak (русск. Дуб) и разрабатывался Джеймсом Гослингом для бытовой электроники, но впоследствии был переименован в Java и стал использоваться для написания клиентских приложений и серверного программного обеспечения. Программы на Java транслируются в байт-код, выполняемый виртуальной java-машиной (JVM) – программой, обрабатывающей байтовый код и передающей инструкции оборудованию как интерпретатор, но с тем отличием, что байтовый код, в отличие от текста, обрабатывается значительно быстрее. Достоинство подобного способа выполнения программ – в полной независимости байт-кода от ОС и оборудования, что позволяет выполнять Java-приложения на любом устройстве, которое поддерживает виртуальную машину. Другой важной особенностью технологии Java является гибкая система безопасности благодаря тому, что исполнение программы полностью контролируется виртуальной машиной.
Длины и диапазоны значений примитивных типов определяются стандартом. Такая жёсткая стандартизация была необходима, чтобы сделать язык платформенно-независимым, что является одним из идеологических требований к Java и одной из причин её успеха. Тем не менее, одна небольшая проблема с платформенной независимостью всё же осталась. Некоторые процессоры используют для промежуточного хранения результатов 10-байтовые регистры или другими способами улучшают точность вычислений.
В языке Java имеются только динамически создаваемые объекты. Причем переменные объектного типа и объекты в Java – совершенно разные сущности. Переменные объектного типа являются ссылками, то есть неявными указателями на динамически создаваемые объекты. Это подчёркивается синтаксисом описания переменных.
C# (произносится си-шарп) – язык программирования, сочетающий объектно-ориентированные и аспектно-ориентированные концепции. Разработан в 1998–2001 годах группой инженеров под руководством Андерса Хейлсберга в компании Microsoft как основной язык разработки приложений для платформы Microsoft.NET. C# относится к семье языков с C-подобным синтаксисом, из них его синтаксис наиболее близок к С++ и Java. Язык имеет строгую статическую типизацию, поддерживает полиморфизм, перегрузку операторов, указатели на функции-члены классов, атрибуты, события, свойства, исключения, комментарии в формате XML. Переняв многое от своих предшественников – языков С++, Java, Delphi, Модула и Smalltalk – С#, опираясь на практику их использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем так, C# не поддерживает множественное наследование классов (в отличие от C++).
В Java модификатор protected в описании, помимо доступа из классов-потомков, разрешает доступ из всех классов, входящих в тот же пакет, что и класс-владелец.
В C# для объектов, которые должны быть видны в пределах сборки (примерный аналог пакета Java) введён отдельный модификатор internal, а protected сохраняет свой изначальный смысл, взятый из C++ – доступ только из классов-потомков. Допускается комбинировать internal и protected – тогда получится область доступа, соответствующая protected в Java.
Внутренние классы в C# имеют доступ только к статическим членам внешнего класса, а для доступа к нестатическим членам нужно явно указывать экземпляр внешнего класса. Локальные внутренние классы в C# не поддерживаются, обработка событий в нём не требует таких классов, поскольку строится на других механизмах. В обоих языках методы, по аналогии с C++ – функции, определённые в классе. Тело метода располагается внутри описания класса. Поддерживаются статические методы, абстрактные методы. В C# также есть явная реализация методов интерфейса, что позволяет классу реализовывать методы интерфейса отдельно от собственных методов или давать разные реализации одноимённых методов, принадлежащих двум разным интерфейсам. C# также поддерживает явное описание передачи параметров по ссылке (ключевые слова ref и out). При использовании out компилятор контролирует наличие в методе присваивания значения. C# позволяет создавать пользовательские типы-значения, используя ключевое слово struct. Это прямое наследие языка С++ от которого создатели Java сознательно отказались.
Java поддерживает импорт статических имён (import static) из классов, позволяющий отдельно импортировать некоторые или все статические методы и переменные класса и использовать их имена без квалификации в импортирующем модуле. В C# импортируется только сборка и при каждом использовании импортируемых статических имён требуется указывать класс.
В Java константы в операторы switch должны относиться либо к целочисленному, либо к перечислимому типу. В C# в switch можно использовать текстовые строки.
Java содержит конструкцию strictfp, гарантирующую одинаковые результаты операций с плавающей точкой на всех платформах.
C# содержит конструкции checked и unchecked, позволяющие локально включать и выключать динамическую проверку арифметического переполнения.
C# поддерживает оператор перехода goto. Обычное использование – передача управления на разные метки case в операторе switch и выход из вложенного цикла. В Java от использования goto сознательно отказались.
Java поддерживает метки в циклах и позволяет использовать их в командах break и continue, благодаря чему исключается такой повод использования goto, как выход из вложенного цикла.
C# поддерживает отдельное понятие именованной типизированной константы и ключевое слово const. В Java констант как таковых нет, вместо них используются статические переменные класса с модификатором final – эффект от их использования точно такой же.
Разработка транслятора
Разработка лексического анализатора
Алфавит языка
Большие и малые буквы английского алфавита a..z, A..Z
Цифры 0,1,2,3,4,5,6,7,8,9.
Другие символы ‘<’, ‘>’, ‘ ’, ‘, ’, ‘’’, ‘;’, ‘{», ‘}’, ‘(», ‘)’
Классы лексем
— зарезервированные слова;
— знаки операций и разделители;
— литералы;
— идентификаторы
Лексика языков
1. Класс идентификаторы к этому классу относятся все наборы цепочек, кроме зарезервированных слов
2. Класс зарезервированных слов
2.1 Для C#
using, class, int, float, char, public, protected, private, return, namespace
2.2 Для Java
using, class, int, float, char, public, protected, private, return
3. Класс знаков операций и разделителей
() {} ; = -> . , ‘ *
4. Класс литералов
Литерал – целочисленная или текстовая константа.
Структура таблицы идентификаторов
имя
номер в классе
тип
Структура таблицы литералов
имя
тип
Разработка синтаксического анализатора
Грамматика языков
В данном проекте исследуется лишь малая часть возможностей и особенностей вышеуказанных языков. В связи с этим спроектированные грамматики для этих языков будут включать лишь те структуры языка, которые нам необходимы
Грамматика С#
1 <программа> = 2 <предпроцессор> 3 namespace 4 {5 <операторы> 6}
7 <предпроцессор> = 9 using 10 <предпроцессор>
8 <предпроцессор> = 11 е
12 <операторы> = 16 <класс> 17 <операторы>
13 <операторы> = 18 идентификатор 19 <продолжение1>
20 <операторы>
14 <операторы> = 21 е
15 <операторы> = 22 <декларация> 23 <операторы>
24 <класс> = 25 class 26 идентификатор 27 <наследование> 28 {29 <операторы> 30} 31;
32<наследование> = 34 35 идентификатор
33<наследование> = 36е
37<продолжение1> = 40. 41 идентификатор 42 <продолжение2> 43;
38<продолжение1> = 44 <продолжение2> 45;
39<продолжение1> = 46;
47 <продолжение2> = 49 (50)
48 <продолжение2> = 80 е
51 <декларация> = 52 <тип> 53 идентификатор 55 <продолжение3>
56<продолжение3> = 58 (59) 60 (61 <операторы> 62 return 63 литерал 64; 81)
57<продолжение3> = 65<продолжение4>
66 <продолжение4> = 68, 69 идентификатор 70 <продолжение4>
67 <продолжение4> = 71;
72 <тип> = 76 int
73 <тип> = 77 float
74 <тип> = 78 char
75 <тип> = 79 идентификатор
Грамматика java
1 <программа> = 2 <предпроцессор> 3 <операторы>
7 <предпроцессор> = 9 using 10 <предпроцессор>
8 <предпроцессор> = 11 е
12 <операторы> = 16 <класс> 17 <операторы>
13 <операторы> = 18 идентификатор 19 <продолжение1>
20 <операторы>
14 <операторы> = 21 е
15 <операторы> = 22 <декларация> 23 <операторы>
24 <класс> = 25 class 26 идентификатор 27 <наследование> 28 {29 <операторы> 30} 31;
32<наследование> = 34 35 идентификатор
33<наследование> = 36е
37<продолжение1> = 40 -> 41 идентификатор 42 <продолжение2> 43;
38<продолжение1> = 44 <продолжение2> 45;
39<продолжение1> = 46;
47 <продолжение2> = 49 (50)
48 <продолжение2> = 80 е
51 <декларация> = 52 <тип> 53 <ссылка> 54 идентификатор 55 <продолжение3>
56<продолжение3> = 58 (59) 60 (61 <операторы> 62 return 63 литерал 64; 81)
57<продолжение3> = 65<продолжение4>
66 <продолжение4> = 68, 69 идентификатор 70 <продолжение4>
67 <продолжение4> = 71;
72 <тип> = 76 int
73 <тип> = 77 float
74 <тип> = 78 char
75 <тип> = 79 идентификатор
82<ссылка> = 84 *
83<ссылка> = 85 e
Доказательство принадлежности к LL(1) – грамматике
С#
<предпроцессор>={using | namespace}
<операторы>={class | идентификатор |} | int | float | char}
<наследование>={ | {}
<продолжение1>={. | (|;)
<продолжение2>={(|;)
<продолжение3>={(|, |;)
<продолжение4>={, |;}
<тип >={int | float | char | идентификатор}
Грамматика java
<предпроцессор>={using | class | идентификатор | int | float | char}
<операторы>={class | идентификатор | int | float | char}
<наследование>={ | {}
<продолжение1>={-> | (|;)
<продолжение2>={(|;)
<продолжение3>={(|, |;)
<продолжение4>={, |;}
<тип >={int | float | char | идентификатор}
<ссылка>={* | идентификатор}
Таблицы разбора
Таблица разбора С#
№
Ожидаемый терминал
Переход
Принять
В стек
Из стека
Ошибка
1.
~
2
—
—
—
—
2.
~
7
—
—
—
—
3.
namespace
4
+
—
—
+
4.
{
5
+
—
—
+
5.
~
12
—
+
—
—
6.
}
0
+
—
+
+
7.
using
9
—
—
—
—
8.
~
11
—
—
—
—
9.
using
10
+
—
—
+
10.
~
7
—
—
—
—
11.
~
3
—
—
—
—
12.
class
16
—
—
—
—
13.
идентификатор
18
—
—
—
—
14.
}
21
—
—
—
—
15.
~
22
—
—
—
—
16.
~
24
—
+
—
—
17.
~
12
—
—
—
—
18.
идентификатор
19
+
—
—
+
19.
~
37
—
+
—
—
20.
~
12
—
—
—
—
21.
~
0
—
—
+
—
22.
~
51
—
+
—
—
23
~
12
—
—
—
—
24
~
25
—
—
—
—
25
class
26
+
—
—
+
26
идентификатор
27
+
—
—
+
27
~
32
—
+
—
—
28
{
29
+
—
—
+
29
~
12
—
+
—
—
30
)
31
+
—
—
+
31
;
0
+
—
+
+
32
34
—
—
—
—
33
~
36
—
—
—
—
34
35
+
—
—
+
35
идентификатор
0
+
—
+
+
36
~
0
—
—
+
—
37
.
40
—
—
—
—
38
(
44
—
—
—
—
39
;
46
—
—
—
+
40
.
41
+
—
—
+
41
идентификатор
42
+
—
—
+
42
~
47
—
+
—
—
43
;
0
+
—
+
+
44
~
47
—
+
—
—
45
;
0
+
—
+
+
46
;
0
+
—
+
+
47
(
49
—
—
—
—
48
~
80
—
—
—
—
49
(
50
+
—
—
+
50
)
0
+
—
+
+
51
~
52
—
—
—
—
52
~
72
—
+
—
—
53
идентификатор
55
+
—
—
+
54
55
~
56
—
—
—
—
56
(
58
—
—
—
—
57
~
65
—
—
—
—
58
(
59
+
—
—
+
59
)
60
+
—
—
+
60
{
61
+
—
—
+
61
~
12
—
+
—
—
62
return
63
+
—
—
+
63
литерал
64
+
—
—
+
64
;
81
+
—
—
+
65
~
66
—
—
—
—
66
,
68
—
—
—
—
67
;
71
—
—
—
+
68
,
69
+
—
—
+
69
идентификатор
70
+
—
—
+
70
~
66
—
—
—
—
71
;
0
+
—
+
+
72
int
76
—
—
—
—
73
float
77
—
—
—
—
74
char
78
—
—
—
—
75
идентификатор
79
—
—
—
+
76
int
0
+
—
+
+
77
float
0
+
—
+
+
78
char
0
+
—
+
+
79
идентификатор
0
+
—
+
+
80
~
0
—
—
+
—
81
}
0
+
—
+
+
Таблица разбора java
№
Ожидаемый терминал
Переход
Принять
В стек
Из стека
Ошибка
1.
~
2
—
—
—
—
2.
~
7
—
—
—
—
3.
~
12
—
—
—
—
7.
using
9
—
—
—
—
8.
~
11
—
—
—
—
9.
using
10
+
—
—
+
10.
~
7
—
—
—
—
11.
~
3
—
—
—
—
12.
class
16
—
—
—
—
13.
идентификатор
18
—
—
—
—
14.
}
21
—
—
—
—
15.
~
22
—
—
—
—
16.
~
24
—
+
—
—
17.
~
12
—
—
—
—
18.
идентификатор
19
+
—
—
+
19.
~
37
—
+
—
—
20.
~
12
—
—
—
—
21.
~
0
—
—
+
—
22.
~
51
—
+
—
—
23
~
12
—
—
—
—
24
~
25
—
—
—
—
25
class
26
+
—
—
+
26
идентификатор
27
+
—
—
+
27
~
32
—
+
—
—
28
{
29
+
—
—
+
29
~
12
—
+
—
—
30
)
31
+
—
—
+
31
;
0
+
—
+
+
32
34
—
—
—
—
33
~
36
—
—
—
—
34
35
+
—
—
+
35
идентификатор
0
+
—
+
+
36
~
0
—
—
+
—
37
->
40
—
—
—
—
38
(
44
—
—
—
—
39
;
46
—
—
—
+
40
->
41
+
—
—
+
41
идентификатор
42
+
—
—
+
42
~
47
—
+
—
—
43
;
0
+
—
+
+
44
~
47
—
+
—
—
45
;
0
+
—
+
+
46
;
0
+
—
+
+
47
(
49
—
—
—
—
48
~
80
—
—
—
—
49
(
50
+
—
—
+
50
)
0
+
—
+
+
51
~
52
—
—
—
—
52
~
72
—
+
—
—
53
~
82
—
—
+
—
54
идентификатор
55
+
—
—
+
55
~
56
—
—
—
—
56
(
58
—
—
—
—
57
~
65
—
—
—
—
58
(
59
+
—
—
+
59
)
60
+
—
—
+
60
{
61
+
—
—
+
61
~
12
—
+
—
—
62
return
63
+
—
—
+
63
литерал
64
+
—
—
+
64
;
81
+
—
—
+
65
~
66
—
—
—
—
66
,
68
—
—
—
—
67
;
71
—
—
—
+
68
,
69
+
—
—
+
69
идентификатор
70
+
—
—
+
70
~
66
—
—
—
—
71
;
0
+
—
+
+
72
int
76
—
—
—
—
73
float
77
—
—
—
—
74
char
78
—
—
—
—
75
идентификатор
79
—
—
—
+
76
int
0
+
—
+
+
77
float
0
+
—
+
+
78
char
0
+
—
+
+
79
идентификатор
0
+
—
+
+
80
~
0
—
—
+
—
81
}
0
+
—
+
+
82
*
84
—
—
—
—
83
~
85
—
—
—
—
84
*
0
+
—
+
+
85
~
0
—
—
+
—
Разработка программы
Классовая модель
Диаграмма прецедентов
Диаграмма классов
Анализ результатов работы программы и выводы
Оба анализируемых языка – объектно-ориентированные, с синтаксисом, унаследованным от C++, но значительно переработанным. Следовательно, они имеют много общего, например, при анализе проектов, мы используем один общий класс разделителей и знаков операций.
Классы зарезервированных слов для каждого языка отличаются. В данном проекте исследуется лишь малая часть возможностей и особенностей вышеуказанных языков. В связи с этим, классы зарезервированных слов для этих языков будут включать лишь те ключевые слова и операторы, которые нам необходимы.
Проект позволяет проанализировать взаимодействие между классами и вывести результат в файл *.xml. Достаточно много времени было потрачено именно на вывод результата в *.xml, так как ранее с подобными задачами не сталкивались.
При реализации были выполнены критерии ООП и модульности, расставлены комментарии (по атрибутам, методам, по параметрам методов, классам).
Проект может существовать как автономное приложение, однако, на мой взгляд, его можно дополнить и доработать функционально, расширить классы зарезервированных слов, внести изменения в LL(1) – грамматику и т.д.
На данном этапе разработки программа работает корректно, четко выполняет поставленные требования.
Список используемой литературы
1. Р. Хантер Проектирование и конструирование компиляторов
2. http //www.linuxcenter.ru/lib/articles/programming
3. Джеффри Рихтер CLR via C# // М., Издательство «Русская редакция», 2007
4. http //javaportal.ru/
5. Конспект лекций по ТОПТ