Project

General

Profile

Sim-nML Translator » History » Version 3

Alexander Kamkin, 03/07/2013 08:00 AM

1 2 Alexander Kamkin
h1. Sim-nML Translator
2
3 3 Alexander Kamkin
h2. Under Construction
4 1 Alexander Kamkin
5
Данный документ содержит описание схемы трансляции спецификаций микропроцессоров на языке Sim-nML в набор Java классов, которые могут быть использованы инструментом MicroTESK для автоматизированной генерации тестовых программ.
6
7
h2. Язык Sim-nML
8
9
Язык Sim-nML является расширением языка nML.
10
11
h2. Java классы, создаваемые при трансляции
12
13
Список Java классов, которые создаются при трансляции:
14
15
# Класс @ProcessorName@, который наследуется от класса @Processor@. Содержит большую часть информации о специфицируемом процессоре.
16
17
>> *TODO:* уточнить, каким образом формируется имя этого класса. Возможен вариант получаеть это имя из имени файла со спецификацией на Sim-nML, или же можно требовать задавания этого имени от пользователя в качестве одного из параметров метода, который осуществляет трансляцию, или же можно использовать какие-то специальные аннотации в самой спецификации.
18
19
h2. Правила грамматики для «общих» нетерминальных символов
20
21
h3. Бинарная операция
22
23
<pre>
24
BinOp : ''+''
25
      | ''-''
26
      | ''*''
27
      | ''/''
28
      | ''%''
29
      | DOUBLE_STAR
30
      | LEFT_SHIFT
31
      | RIGHT_SHIFT
32
      | ROTATE_LEFT
33
      | ROTATE_LEFT
34
      | ROTATE_RIGHT
35
      | ''<''
36
      | ''>''
37
      | LEQ
38
      | GEQ
39
      | EQ
40
      | NEQ
41
      | ''&''
42
      | ''^''
43
      | ''|''
44
      | AND
45
      | OR
46
</pre>
47
48
h3. Числовая константа
49
50
<pre>
51
ConstNumExpr : ConstExprVal
52
             | ConstNumExpr BinOp ConstExprVal
53
54
ConstExprVal : CARD_CONST
55
             | FIXED_CONST
56
             | HEX_CONST
57
             | ''!'' ConstNumExpr
58
             | ''~'' ConstNumExpr
59
             | ''+'' ConstNumExpr %prec ''~''
60
             | ''-'' ConstNumExpr %prec ''~''
61
             | ''('' ConstNumExpr '')''
62
</pre>
63
64
>> *TODO:* предлагается все числовые константные выражения сразу вычислять, в оттранслированный Java код вставлять уже только значения выражений.
65
66
h3. Выражение
67
68
<pre>
69
Bit_Expr : ID
70
         | Bit_Expr ''+'' Bit_Expr
71
         | Bit_Expr ''-'' Bit_Expr
72
         | Bit_Expr ''*'' Bit_Expr
73
         | Bit_Expr ''/'' Bit_Expr
74
         | Bit_Expr ''%'' Bit_Expr
75
         | Bit_Expr DOUBLE_STAR Bit_Expr
76
         | ''('' Bit_Expr '')''
77
         | FIXED_CONST
78
         | CARD_CONST
79
         | STRING_CONST
80
         | BINARY_CONST
81
         | HEX_CONST
82
</pre>
83
84
h3. OR правило
85
86
<pre>
87
OrRule             : Identifier_Or_List
88
89
Identifier_Or_List : ID
90
                   | Identifier_Or_List ''|'' ID
91
</pre>
92
93
h3. AND правило
94
95
<pre>
96
AndRule       : ''('' ParamList '')''
97
98
ParamList     :
99
              | ParamListPart
100
              | ParamList '','' ParamListPart
101
102
ParamListPart : ID '':'' TypeExpr
103
              | ID '':'' ID
104
</pre>
105
106
h3. Атрибуты
107
108
В языке Sim-nML атрибуты используются для описания свойств инструкций и режимов адресации. Описание каждого такого объекта может содержать произвольное число атрибутов. Атрибуты можно разделить на два класса: предопределенные атрибуты и пользовательские атрибуты. Описание предопределенных атрибутов приведено ниже.
109
110
<pre>
111
AttrDefList :
112
            | AttrDefList AttrDef
113
114
AttrDef     : ID ''='' AttrDefPart
115
            | SYNTAX ''='' ID ''.'' SYNTAX
116
            | SYNTAX ''='' AttrExpr
117
            | IMAGE ''='' ID ''.'' IMAGE
118
            | IMAGE ''='' AttrExpr
119
            | ACTION ''='' ID ''.'' ACTION
120
            | ACTION ''='' ''{'' Sequence ''}''
121
            | USES ''='' UsesDef
122
123
AttrDefPart : Expr
124
            | ''{'' Sequence ''}''
125
</pre>
126
127
h4. Атрибут syntax
128
129
Атрибут syntax используется для описания ассемблерного кодирования инструкции или режима адресации. Значения данного атрибута должны иметь строковый тип. Можно выделить следующие основные варианты определения атрибута syntax:
130
131
# Строковая константа — значение определяется посредством строковой константы. Например, “nop”.
132
# Атрибут параметра — значение атрибута определяется как значение этого же атрибута syntax у одного из параметров описываемого объекта. Например, x.syntax.
133
# Форматированная строка — значение атрибута определяется с помощью специальной конструкции format. Данная конструкция является аналогом оператора printf в языке программирования С. Например, format(“%5b”, r).
134
135
>> *TODO:* добавить полное формальное описание конструкции format + описание транслчции данной конструкции в строковое выражение Java.
136
137
h5. Трансляция
138
139
При трансляции данного атрибута в классе, соответствующем описываемому объекту создается метод со следующей сигнатурой:
140
141
<pre>
142
public String syntax()
143
</pre>
144
145
Для случая 1 из приведенного выше списка тело метода просто возвращает данную строковую константу. Для случая 2 метод возвращает результат вызова метода syntax соответствующего аргумента данного объекта. Такой аргумент должен содержаться в качестве поля в классе, соответствующем описываемому объекту. Для случая 3 метод возвращает результат трансляции конструкции format в строковое выражение языка Java.
146
147
h4. Атрибут image
148
149
Атрибут image используется для описания бинарного кодирования описываемого объекта. Значения данного атрибута должны иметь строковый тип, причем допустимы только строки, содержащие символы «0», «1» и пробел. Пробелы используются для улучшения читаемости. Варианты определения атрибута image совпадают с вариантами определения атрибута syntax.
150
151
h5. Трансляция:
152
153
Полностью аналогична трансляции атрибута syntax.
154
155
h4. Атрибут action
156
157
Атрибут action используется для описания семантики выполнения инструкций. 
158
159
h5. Трансляция:
160
161
>> *TODO:* при трансляции атрибута action обратить внимание на то, что в некоторых спецификациях данные между соседними в дереве инструкциями передают с использованием переменных (var). Это надо корректно учитывать, так как по умолчанию при трансляции таких объектов предлагается создавать локальные переменные соответствующих методов. С другой стороны, использование переменных для передачи данных между операциями противоречит описанию языка, в котором сказано, что состояние переменных не сохраняется при переходе от одной инструкции к другой.
162
163
h4. Атрибут uses
164
165
В текущей версии инструмента данный атрибут не рассматриваем.
166
167
h2. Основные конструкции языка
168
169
h3. Конструкция let
170
171
Конструкция let используется для объявления констант. Константы обладают следующими свойствами:
172
173
# Константы получают глобальную область видимости.
174
# Константа может быть определена только один раз.
175
176
<pre>
177
LetDef              : LET ID ''='' LetExpr
178
179
LetExpr             : ConstNumExpr
180
                    | STRING_CONST
181
                    | IF ConstNumExpr THEN LetExpr OptionalElseLetExpr ENDIF
182
                    | SWITCH ''('' ConstNumExpr '')'' ''{'' CaseLetExprList ''}''
183
184
OptionalElseLetExpr :
185
                    | ELSE LetExpr
186
187
CaseLetExprList     : CaseLetExprList1
188
                    | CaseLetExprList1 DEFAULT '':'' LetExpr
189
190
CaseLetExprList1    : CaseLetExprStat
191
                    | CaseLetExprList1 CaseLetExprStat
192
193
CaseLetExprStat     : CASE ConstNumExpr '':'' LetExpr
194
</pre>
195
196
h4. Примеры
197
198
<pre>
199
let REGS = 5
200
let byte_order = “big”
201
let PC = “NIA”
202
let SP = “GPR[29]”
203
</pre>
204
205
h4. Проблемы
206
207
Не ясна семантика if и switch в том случае, когда определяемая величина не получает никакого значения, например
208
209
<pre>
210
let c = if 0 then 0 endif
211
</pre>
212
213
h4. Ограничения
214
215
На первом этапе разработки прототипа предлагается ограничить поддержку конструкции let только простыми вариантами (без if и switch). Сложные вариаты let практически не используются на практике (ни один из примеров спецификаций представленных на сайте языка не содержал таких конструкций), их ценность представляется сомнительной.
216
217
h4. Трансляция
218
219
Если LetExpr является ConstNumExpr, то вычисляется значение этого выражения. Для каждой определенной в спецификации константы определяется поле к классе ProcessorName следующего вида
220
221
<pre>
222
public static final <type> ID = LetExpr;
223
</pre>
224
225
где <type> может принимать следующие значения:
226
227
* String – в случае, если LetExpr является STRING_CONST
228
* int – в случае, если LetExpr является числовым выражением и вычисленное  значение есть целое.число, убирающееся в int.
229
* long – в случае, если LetExpr является числовым выражением и вычисленное  значение есть целое.число, не убирающееся в int.
230
* float – в случае, если  LetExpr является числовым выражением и его вычисленное значение есть число с фиксированной или плавающей точкой, убирающееся в тип float.
231
* double – в случае, если  LetExpr является числовым выражением и его вычисленное значение есть число с фиксированной или плавающей точкой, не убирающееся в тип float.
232
233
h4. Ошибочные ситуации:
234
235
* наличие целых чисел, которые «не убираются» в long
236
* наличие чисел с плавающей точкой, которые «не убираются» в double
237
238
h3. Конструкция type
239
240
Конструкция type используется для определения синонимов новых типов. Синонимы определяются на основе существующих стандартных типов:
241
242
* bool: определяет булевский тип, имеющий два предопределенных значений false и true. При применении преобразования типов (смотри coerces) false отображается в 0, true – в 1. При обратном преобразовании 0 отображается в false, любое ненулевое значение отображается в true.
243
* int(n): определяет сегмент целых чисел @[-2^(n-1), 2^(n-1)-1]@
244
* card(n): определяет сегмент целых чисел @[0, 2^n-1]@
245
* float: определяет число с плавающей точкой согласно стандарту IEEE 754
246
>> *TODO:* несоответствие грамматики и описания
247
* fix(n, m): определяет число с фиксированной точкой, в котором n бит отводятся под мантису и m бит под экспоненту
248
>> *TODO:* уточнить, что описано в документации
249
* [n..m]: определяет интервал натуральных чисел (ограничение @n <= m@)
250
* enum(id1, id2, ..., id(n-1)): определяет перечислимый тип, где именованные константы принимают значения от 0 до n-1. Будет совпадать с типом @card(ceiling(log2(i)))@
251
252
<pre>
253
TypeSpec       : TYPE ID ''='' TypeExpr
254
255
TypeExpr       : BOOL
256
               | INT ''('' ConstNumExpr '')''
257
               | CARD ''('' ConstNumExpr '')''
258
               | FIX ''('' ConstNumExpr '','' ConstNumExpr '')''
259
               | FLOAT ''('' ConstNumExpr '','' ConstNumExpr'')''
260
               | ''['' ConstNumExpr DOUBLE_DOT ConstNumExpr '']''
261
               | ENUM ''('' IdentifierList '')''
262
263
IdentifierList : ID
264
               | ID ''='' CARD_CONST
265
               | IdentifierList '','' ID
266
               | IdentifierList '','' ID ''='' CARD_CONST
267
</pre>
268
269
h4. Примеры
270
271
<pre>
272
type bit = card ( 1 )
273
type byte = card ( 8 )
274
type address = card ( REGS )
275
type breakcode = card ( 20 )
276
</pre>
277
278
h4. Проблемы
279
280
Моделирование чисел с фиксированной точкой.
281
282
h4. Ограничения
283
284
В текущей реализации не рассматриваем случаи, когда определяется интервал, по мощности превосходящий максимальный соответствующий стандартный тип а Java. Например, исключаем из рассмотрения card (128).
285
286
h4. Трансляция: 
287
288
Для каждого такого типа-синонима создается новый класс с именем ID, единственным полем которого будет переменная объемлющего типа, а методы будут обеспечивать корректность работы с этой переменной, контролируя невыход их множества допустимых значений. В случае нарушения данных ограничений метод должен выбрасывать исключение.
289
290
Необходимо учесть, что при трансляции операторов присваивания таким переменным, надо использовать методы set из соответствующих классов. Причем эти методы set должны в качестве параметров принимать так же номер строки и позицию в nml файле, по которой находится данный оператор присваивания. Эти данные используются отладки спецификаций в случае ошибок.
291
292
Перечисления транслируются в стандартные Java перечисления. Например, пусть есть перечисление:
293
294
<pre>
295
type <name> = enum(id1 = val1, id2 = val2, ..., idn = valn)
296
</pre>
297
298
Оно транслируется в отдельный файл <name>.java, который содержит Java перечисление следующего вида:
299
300
<pre>
301
public enum <name> {
302
    id1(val1), id2(val2), ..., idn(valn)
303
}
304
</pre>
305
306
h4. Ошибочные ситуации
307
308
h3. Конструкция mem
309
310
Конструкция mem используется для описания памяти моделируемого микропроцессора. Общий вид такого определения представлен ниже:
311
312
<pre>
313
mem M [N, type] [optional-properties]
314
</pre>
315
316
В этом определении, M – имя данного объекта памяти, N – количество ячеек памяти, и type – тип каждой такой ячейки памяти. Если тип не указан, то по умолчанию тип полагается равным card(8). Доступ к данным ячейкам памяти осуществляется по средствам оператора индексирования: M[0], M[1], ..., M[n-1]. Опциональные параметры могут быть следующими:
317
318
# alias – описывает новую память как синоним какойто части уже описанной памяти. В этом случае оба имени будут ссылать на одни и те же ячейки памяти, но могут интерпретировать их по разному. Например:
319
320
<pre>
321
mem A[6, int(32)]
322
mem M[3, card(32)] alias = A[3]
323
</pre>
324
325
В этом случае ячейки памяти, доступные по обращениям A[3], A[4], A[5], теперь могут быть доступны и по обращениям M[0], M[1], M[2] соответственно. Отличие заключается в том, что в случае обращений с использованием имени A содержимое ячейки интерпретируется как 32-ух разрядное знаковое число, в случае же, когда обращение идет по имени M, содержимое интерпретируется, как беззнаковое число.
326
327
<pre>
328
Bit_Optr           : BIT_LEFT Bit_Expr DOUBLE_DOT Bit_Expr BIT_RIGHT
329
330
MemorySpec         : MEM ID ''['' SizeType '']'' OptionalMemVarAttr
331
332
SizeType           : TypeExpr
333
                   | ConstNumExpr
334
                   | ConstNumExpr '','' TypeExpr
335
336
OptionalMemVarAttr :
337
                   | ALIAS ''='' MemLocation
338
339
MemLocation        : ID Opt_Bit_Optr
340
                   | ID ''['' NumExpr '']'' Opt_Bit_Optr
341
342
Opt_Bit_Optr       :
343
                   | Bit_Optr
344
345
Bit_Optr           : BIT_LEFT Bit_Expr DOUBLE_DOT Bit_Expr BIT_RIGHT
346
</pre>
347
348
>> *TODO:* не ясна семантика Opt_Bit_Expr в грамматики для конструкции mem, в примерах использование именно такой формы тоже не было встречено.
349
350
h4. Примеры
351
352
<pre>
353
mem A[6, int(32)]
354
mem M[3, card(32)] alias = A[3] 
355
</pre>
356
357
h4. Проблемы
358
359
h4. Ограничения
360
361
h4. Трансляция
362
363
Анализ спецификаций на языке Sim-nML позволил выявить, что конструкция mem может быть использована для двух различных целей. Во-первых, она может использоваться для описания памяти моделируемого микропроцессора. В этом случае число ячеек памяти в описании довольно большое (N >> 1). Необходимо найти описание с максимальным числом ячеек, именно оно будет транслироваться в класс, моделирующий память. При трансляции данного описания создается класс ProcessorNameMemory, который является наследником абстрактного класса Memory из библиотеки поддержки трансляции. Класс ProcessorNameMemory имеет следующий вид:
364
365
<pre>
366
class ProcessorNameMemory {
367
    public static final SIZE = <N>;
368
    protected HashMap(Long, <type>) memoryHashMap = new HashMap(Long, <type>)();
369
}
370
</pre>
371
372
Для всех других описаний памяти, которые являются синонимами основной памяти (используют alias <имя основной памяти>), в атрибутах action для операций необходимо изменять обращения по этим именам на обращения по имени основной памяти.
373
Второй класс описаний памяти составляют описания, которые имеют небольшое число ячеек (обычно 1 или 2). Такие описания используются в качестве локальных переменных при описании атрибутов action для инструкций. Все 
374
такие описания при трансляции запоминаются. Затем при трансляции атрибутов action в методы инструкций, для каждой запомненной памяти, по которой присутствует обращение в данном атрибуте, вводится локальная переменная соответствующего типа. Все обращения по данным элементам памяти заменяются при трансляции на обращения к данной переменной. Например,
375
376
<pre>
377
    mem tmp_signed_byte [ 1 , int (32) ]
378
    ...
379
    action = {
380
        tmp_signed_byte = 31
381
        ...
382
    }
383
</pre>
384
385
При трансляции атрибута action получаем получим:
386
387
<pre>
388
    public void execute(...) {
389
        int tmp_signed_byte
390
        ...
391
    }
392
</pre>
393
394
>> *TODO:* определить абстрактный класс Memory
395
396
h4. Ошибочные ситуации
397
398
h3. Конструкция reg
399
400
Конструкция reg используется для описания регистров микропроцессора. Общая форма описания регистров представлена ниже:
401
402
<pre>
403
reg R [N, type] [optional-properties]
404
</pre>
405
406
В представленном определении R – имя регистрового файла, N – опциональный параметр, показывающий количество регистров в регистровом файле и type – тип каждого регистра. Если параметр N не указан, то по умолчанию он полагается равным 1.Доступ к регистрам данного регистрового файла осуществляется посредством оператора индексирования — R[0], R[1], …, R[N-1]. Определение регистров может иметь следующие опциональные атрибуты:
407
Ports: позволяет указать число портов чтения и записи для данного регистрового файла. Например:
408
409
<pre>
410
reg R[16, int(8)] port = 3, 2
411
</pre>
412
413
В представленном примере регистровый файл R имеет 3 порта для записи и 2 порта для чтения. Кроме того, каждый регистр в данном регистровом файле имеет 2 порта для чтения, так же как и весь регистровый файл, и один порт для записи. Порты чтения и записи для регистров рассматриваются в качестве ресурсов и используются для определения зависимостей между инструкциями.
414
Initial: позволяет указать начальное значение для описанных регистров. Например:
415
416
<pre>
417
reg R[1, card(32)] initial = 100
418
</pre>
419
420
<pre>
421
RegisterSpec    : REG ID ''['' SizeType '']'' OptionalRegAttr
422
423
OptionalRegAttr :
424
                | PortsDef
425
                | InitialDef
426
                | PortsDef InitialDef
427
                | InitialDef PortsDef
428
429
PortsDef        : PORTS ''='' CARD_CONST '','' CARD_CONST
430
431
InitialDef      : INITIALA ''='' ConstNumExpr
432
</pre>
433
434
h4. Примеры
435
436
<pre>
437
reg GPR [2 ** REGS, signed_long]
438
reg LO [1, signed_long]
439
reg NIA [1, long]
440
</pre>
441
442
h4. Проблемы
443
444
h4. Ограничения
445
446
h4. Трансляция
447
448
Для каждого описанного регистрового файла создается класс RegisterFileName, который является наследником абстрактного класса библиотеки поддержки трансляции Register. Класс Register содержит следующие поля и методы:
449
450
<pre>
451
class Register {
452
    public static final int WRITE_PORTS = 1;
453
    public static final int READ_PORTS = 1;
454
    ...
455
}
456
</pre>
457
458
Класс RegisterFileName содержит следующие поля и методы:
459
460
<pre>
461
class RegisterFileName {
462
    public static final int READ_PORTS = <read_ports>;
463
    protected <type> value = <init_value>;
464
    ...
465
}
466
</pre>
467
468
Так же в класс ProcessorName добавляются следующие поля и методы:
469
470
<pre>
471
public static final int RegisterFileName_WRITE_PORTS = <write_ports>;
472
473
protected RegisterFileName <some_uniq_name> [] = {
474
    new RegisterFileName(),
475
    ...
476
}
477
</pre>
478
479
Причем количество элементов в массиве RegisterFileName равно N.
480
481
h4. Ошибочные ситуации
482
483
h3. Конструкция var
484
485
Конструкция var используется для определения временных переменных. Типичная конструкция определения временной переменной выглядит следующим образом:
486
487
<pre>
488
var TEMP[N, type]
489
</pre>
490
491
В приведенном выше определении TEMP – имя массива временных переменных, N – количество переменных в определенном массиве и type – тип каждой переменной в массиве. Если параметр N не определен, то по умолчанию он полагается равным 1. Доступ к переменным осуществляется посредством оператора индексирования — TEMP[0], TEMP[1], …, TEMP[N-1]. Важно отметить, что значения временных переменных не сохраняются при переходе от одной инструкции к другой.
492
493
>> *COMMENT:* по всей видимости переменные были введены в язык для прекращения нецелевого использования конструкций определения памяти для введения временных данных. Смотри второй класс конструкций определения памяти в разделе «трансляция» описания конструкции mem
494
495
>> *TODO:* противоречие между текстовым описанием и грамматикой
496
497
<pre>
498
VarSpec : VAR ID ''['' SizeType '']'' OptionalMemVarAttr
499
</pre>
500
501
h4. Примеры
502
503
<pre>
504
var amod[1, card(8)]
505
var carry[1, card(1)]
506
var op1[1, int(32)]
507
</pre>
508
509
h4. Проблемы
510
511
h4. Ограничения
512
513
h4. Трансляция
514
515
Трансляция выполняется аналогично второму классу конструкций определения памяти. Описание приводится в разделе «трансляция» описания конструкции mem.
516
517
h4. Ошибочные ситуации
518
519
h3. Конструкция mode
520
521
Конструкция mode используется для спецификации механизмов адресации. Основу данного описания этих механизмов составляют два вида конструкций: «И»-правила и «ИЛИ»-правила.
522
«ИЛИ»-правила используются для описания логически связанной группы механизмов адресации. С помощью «ИЛИ»-правила можно задать группе таких механизмов общие атрибуты. Общий вид «ИЛИ»-правила следующий:
523
524
<pre>
525
mode n0 = n1 divides n2 divides ... divides nk
526
a1 = e1 a2 = e2 ...
527
</pre>
528
529
«И»-правила используются для описания листовых элементов в дереве механизмов адресации. Общий вид «И»-правила следующий:
530
531
<pre>
532
mode n0(p1: t1, p2: t2, p3: t3 ...) = value assign
533
a1 = e1 a2 = e2 ...
534
</pre>
535
536
<pre>
537
ModeRuleSpec     : MODE ID ModeSpecPart
538
539
ModeSpecPart     : AndRule OptionalModeExpr AttrDefList
540
                 | OrRule
541
542
OptionalModeExpr :
543
                 | ''='' Expr
544
</pre>
545
546
h4. Примеры
547
548
h4. Проблемы
549
550
h4. Ограничения
551
552
h4. Трансляция
553
554
Трансляция дерева «И»-«ИЛИ» правил проводится идентично как для инструкций, так и для режимов адресации. Подробные описания общих концепций трансляции приведены в разделе «Трансляция» описания конструкции op. Эти положения верны и при описании режимов адресации. Специфические моменты при трансляции этих описаний отражены ниже.
555
556
У и правил конструкции mode может присутствовать дополнительный опциональный элемент, который вычисляет значение параметра, передающегося данным способом адресации. Для каждого правила, обладающего таким элементом, в соответствующем классе создается тело метода getValue() на основе описания данного элемента. Метод возвращает оттранслированное выражение записанное в правиле после знака равенства.
557
558
h4. Ошибочные ситуации
559
560
h3. Конструкция op
561
562
Конструкция op используется для описания системы команд моделируемого процессора.
563
564
<pre>
565
OpRuleSpec : OP ID OpRulePart
566
OpRulePart : AndRule AttrDefList
567
           | OrRule
568
</pre>
569
570
h4. Примеры
571
572
h4. Проблемы
573
574
h4. Ограничения
575
576
h4. Трансляция
577
578
Общие положения при трансляции древовидной структуры «И»-«ИЛИ» правил заключаются в следующем. Для каждого правила создается класс. Классы, соответствующие элементам из правых частей «ИЛИ» правил связываются с классом, соответствующим элементу в левой части, отношением наследования. Каждый класс, соответствующий элементу из списка параметров в «И»-правиле, связывается с классом, соответствующим элементу из левой части правила, отношением агрегации. На примере ниже продемонстрированы данные принципы с использованием нотации UML для отображения зависимостей между классами.
579
580
<pre>
581
op instruction(inst alu_op)
582
op alu_instruction = add | sub
583
</pre>
584
585
!uml.png!
586
587
В каждом из этих классов создаются методы, соответствующие атрибутам. Механизм трансляции атрибутов подробно описан в разделе «Атрибуты». Имена создаваемых классов должны содержать некоторый служебный суффикс, что будет говорить о служебном внутреннем использовании данных классов. 
588
589
Для каждого элемента из списка параметров «И» правила в соответствующем классе создаются поле. Для класса также создается конструктор с сигнатурой, соответствующей данному правилу, который инициализирует эти поля.
590
591
>> *TODO:* посмотреть информацию про модификаторы доступа классов, пакетов для защиты служебных классов от некорректного использования
592
593
Далее, для каждого листового элемента в дереве инструкций создается еще один класс, который наследуется от класса Instruction (соответствует корню дерева). Эти классы распределяются по пакетам в соответствии со структурой дерева. Для каждого не листового узла дерева создается отдельный пакет, куда вложены все пакеты и классы, соответствующие потомкам данного узла.
594
595
h4. Ошибочные ситуации