Создателями стандарта ставится цель создания унифицированного формата текстового представления синтаксических деревьев, генерируемых front-end-компиляторами при распознавании файлов программ на различных высокоуровневых языках.
В тексте стандарта используются следующие сокращения
- ЯВУ - язык программирования высокого уровня
Создаваемые ЯВУ должны уметь решать каждую из нижеприведённых задач:
- Вычисление факториала небольшого (не превышающего 12) целого числа при помощи рекурсивного алгоритма.
- Нахождение действительных корней квадратного трёхчлена.
- Вывод изображения при помощи записи в видеопамять.
При создании стандарта были выдвинуты следующие требования:
- Универсальность. Программа, написанная написанная на целевом ЯВУ должна быть корректно представима в формате, регламентируемом стандартом.
- Ориентированность на задачу. Стандарт должен учитывать специфику проблем, решаемых при помощи программ на целевых ЯВУ.
- Простота в реализации. Стандарт должен быть достаточно естественным, чтобы создатели компиляторов для целевых ЯВУ не испытывали чрезмерных сложностей при следовании ему.
- Синтаксические деревья представляются в виде текстового файла, использующего кодировку ASCII.
- Символы, не входящие в набор ASCII являются недопустимыми.
- Пробельные символы, не находящиеся внутри лексемы, являются незначимыми и игнорируются.
- Числа могут записываться как в формате с десятичной точкой, так и без неё. При записи в формате с десятичной точкой после неё может быть указано не более трёх десятичных разрядов.
- Любое синтаксическое дерево программы на целевом ЯВУ обязано содержать определение функции
main()
, не принимающей аргументов. Функцияmain()
считается точкой входа в программу. - Любая объявленная функция обязана содержать узел типа
RET
(см. Типы узлов), лежащий в поддереве правого сына узла объявления функции, но не в поддереве никакого другого узла типаBLOCK
. - Все функции и переменные должны быть объявлены до своего использования. Порядок объявлений определяется "post-order" обходом дерева.
- Поддерево узла типа
BLOCK
(см. Типы узлов) задаёт область видимости. Не допускается использование переменной вне её области видимости. Глобальные переменные (т.е переменные, объявленные вне какого либо блока) имеют глобальную область видимости и доступны из любой точки программы.
Каждый узел дерева записывается в фигурных скобках ('{' и '}'). Внутри фигурных скобок через запятую записываются тип узла, хранимое значение, левый дочерний узел, правый дочерний узел. Пустой узел обозначается пустой парой фигурных скобок ("{ }").
Если правый дочерний узел пуст, пустым обязан быть и левый дочерний узел (т.е. если узел унарный, то его единственный ребёнок - правый).
Далее приведено формальное описание грамматики записи синтаксического дерева.
G ::= Node '\0'
Node ::= ('{' _ '}') | ('{' _ Type _ ',' _ ',' Val _ ',' _ Node _ ',' _ Node _ '}')
_ ::= [' ', '\n', '\t', '\v', '\f', '\r']*
Type ::= "DEFS" | "NVAR" | "NFUN" | "BLOCK" | "ARG" | "OP" | "SEQ" |
"ASS" | "WHILE" | "IF" | "BRANCH" | "CALL" | "PAR" | "RET" |
"CONST" | "VAR"
Val ::= Num | Name | Op | "NULL"
Num ::= [0-9]+ ('.'[0-9]? [0-9]? [0-9]? )?
Name ::= [A-Za-z_]+ [A-Za-z0-9_]*
Op ::= "ADD" | "SUB" | "MUL" | "DIV" | "NEG" |
"AND" | "OR" | "NOT" |
"GEQ" | "LEQ" | "GT" | "LT" | "EQ" | "NEQ"
Список глобальных определений функций и переменных.
- Значение:
NULL
- Левый сын:
NVAR
илиNFUN
- Правый сын:
DEFS
или пустой узел
Определение и инициализация глобальной либо локальной переменной.
- Значение: имя переменной
- Левый сын: пустой узел
- Правый сын:
OP
,CONST
,VAR
илиCALL
Определение новой функции.
- Значение: имя функции
- Левый сын:
ARG
- Правый сын:
BLOCK
Арифметическая, логическая операция или операция сравнения.
- Значение: тип операции (см. раздел Типы операторов)
- Левый сын:
OP
,CONST
,VAR
,CALL
или пустой узел - Правый сын:
OP
,CONST
,VAR
илиCALL
Список формальных аргументов функции.
- Значение: имя аргумента
- Левый сын: пустой узел
- Правый сын:
ARG
или пустой узел
Блок кода с собственной областью видимости.
- Значение:
NULL
- Левый сын: пустой узел
- Правый сын:
SEQ
Последовательность команд и объявлений.
- Значение:
NULL
- Левый сын:
BLOCK
NVAR
,ASS
,IF
,WHILE
,RET
илиCALL
- Правый сын:
SEQ
или пустой узел
Изменение значения переменной.
- Значение: имя переменной
- Левый сын: пустой узел
- Правый сын:
OP
,CONST
,VAR
илиCALL
Цикл с предусловием.
- Значение:
NULL
- Левый сын:
OP
,CONST
,VAR
илиCALL
- Правый сын:
BLOCK
,ASS
,IF
,WHILE
,RET
илиCALL
Конструкция условного выполнения кода.
- Значение:
NULL
- Левый сын:
OP
,CONST
,VAR
илиCALL
- Правый сын:
BRANCH
Ветви кода при условной конструкции.
- Значение:
NULL
- Левый сын:
BLOCK
,ASS
,IF
,WHILE
,RET
илиCALL
- Правый сын:
BLOCK
,ASS
,IF
,WHILE
,RET
,CALL
или пустой узел
Вызов функции с передачей параметров.
- Значение: имя функции
- Левый сын: пустой узел
- Правый сын:
PAR
Фактические аргументы функции, передаваемые при вызове.
- Значение:
NULL
- Левый сын:
OP
,CONST
,VAR
илиCALL
- Правый сын:
PAR
или пустой узел
Завершение выполнения функции с возвращением значения.
- Значение:
NULL
- Левый сын: пустой узел
- Правый сын:
OP
,CONST
,VAR
илиCALL
Действительная численная константа с фиксированной точностью.
- Значение: число с фиксированной точкой (не более трёх знаков после десятичной точки)
- Левый сын: пустой узел
- Правый сын: пустой узел
Обращение к объявленной ранее локальной или глобальной переменной.
- Значение: имя переменной
- Левый сын: пустой узел
- Правый сын: пустой узел
Узлы типа OP
в качестве значения содержат одно из следующих значений:
- Бинарные операции
ADD
арифметическое сложениеSUB
арифметическое вычитаниеMUL
арифметическое умножение с фиксированной точностьюDIV
арифметическое деление с фиксированной точностьюAND
логическая конъюнкцияOR
логическая дизъюнкцияLT
меньшеGT
большеLEQ
меньше или равноGEQ
больше или равноEQ
равноNEQ
не равно
- Унарные операции
NEG
арифметический унарный минусNOT
логическое отрицание
Для решения поставленных перед стандартом задач, авторами стандарта было принято решение, о создании набора функций, не требующих явного объявления в коде на целевом ЯВУ, но при этом всегда доступных для использования. В целях предотвращения конфликтов имён, в дереве не должны встречаться узлы объявления функций с именами, совпадающих с именами функций стандартной библиотеки.
В стандартную библиотеку входят следующие функции:
sqrt(x)
- возвращает значение квадратного корня изx
, вычисленное с фиксированной точностью.abs(x)
- возвращает абсолютную величинуx
.read()
- возвращает число, считанное из стандартного потока ввода.print(x)
- выводит числоx
в стандартный поток вывода и возвращает значениеx
.set_pixel(x, y, ch)
- записывает символch
в видеопамять, используя числаx
иy
в качестве его относительных координат.ch
интерпретируется как код символа в таблице ASCII, дробная часть числа отбрасывается.x
иy
- числа от -1 до 1, интерпретируются как относительные координаты пикселя на экране относительно центра экрана.x
- координата по горизонтали,y
- координата по вертикали. Возвращает значениеch
flush()
- обновляет экран, выводя содержимое видеопамяти. Возвращает число 1.
Если ну ооочень захочется, стандарт можно не соблюдать т.к. он - общепризнанное г**но.
Ну оплату за стандарт занесёшь в комнату №123, там дверь может упасть и не бойся ведра тараканов в углу, но там брось пачку на верхнюю полку косого шкафа в место, где там почище.