Project

General

Profile

Sim-nML Translator » History » Version 5

Alexander Kamkin, 03/18/2014 02:12 PM

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