Содержание:
В процессе трансляции, Rex выполняет следующие оптимизации кода:
-
Примитивы в математических выражениях вычисляются на этапе трансляции. Например,
3 * 2 - 4
заменяется на2
-
Повторяющиеся унарные операции упрощаются. Например,
--1
заменяется на1
, а---1
на-1
-
Неиспользованные переменные и функции - игнорируются и не выводятся в транслируемый код.
Например, следующий код на языке Ruby:
a = 10 b = 20 def foo() return a end c = a + b puts(a)
В результате трансляции на язык R примет следующий вид:
a <- 10 print(a)
Так как функция
foo
и переменнаяc
хоть и были объявлены, но нигде в дальнейшем не были использованы. А переменнаяb
была использована один раз в расчете переменнойc
, однако т.к. последняя была убрана в ходе оптимизации, то и переменнаяb
теперь больше не используется, поэтому тоже не подлежит трансляции. -
Все операции, расположенные после
return
- игнорируются и не выводятся в транслируемый код. Если на верхнем уровне встречен операторreturn
, то процесс парсинга завершается, т.к. нижеследующие операторы уже не имеют смысла. -
Содержимое
return
верхнего уровня - игнорируется, т.к. не имеет смысла. -
Ненужные скобки игнорируются на этапе трансляции.
Например, следующий код на языке Ruby:
a = (((((((((((10 + 20))))))))))) b = (((((a)) + (10))) * 20) puts(a + b)
В результате трансляции на язык R примет следующий вид:
a <- 10 + 20 b = (a + 10) * 20 print(a + b)
Задача теста, проверить, что лексер правильно распознает токены числовых операторов.
В качестве входных данных рассматривается следующий код на языке Ruby:
x = 10 + 5 - 5 * 2 / 2 % 10
x += 1
x -= 1
x *= 1
x /= 1
x %= 1
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
x = 10 + 5 - 5 * 2 / 2 % 10 | Special.ID Operators.EQUALS Special.INTEGER Operators.PLUS Special.INTEGER Operators.MINUS Special.INTEGER Operators.ASTERISK Special.INTEGER Operators.SLASH Special.INTEGER Operators.MOD Special.INTEGER Special.NEWLINE |
Special.ID Operators.EQUALS Special.INTEGER Operators.PLUS Special.INTEGER Operators.MINUS Special.INTEGER Operators.ASTERISK Special.INTEGER Operators.SLASH Special.INTEGER Operators.MOD Special.INTEGER Special.NEWLINE |
x += 1 | Special.ID Operators.PLUS_EQUALS Special.INTEGER Special.NEWLINE |
Special.ID Operators.PLUS_EQUALS Special.INTEGER Special.NEWLINE |
x -= 1 | Special.ID Operators.MINUS_EQUALS Special.INTEGER Special.NEWLINE |
Special.ID Operators.MINUS_EQUALS Special.INTEGER Special.NEWLINE |
x *= 1 | Special.ID Special.ASTERISK_EQUALS Special.INTEGER Special.NEWLINE |
Special.ID Special.ASTERISK_EQUALS Special.INTEGER Special.NEWLINE |
x /= 1 | Special.ID Operators.SLASH_EQUALS Special.INTEGER Special.NEWLINE |
Special.ID Operators.SLASH_EQUALS Special.INTEGER Special.NEWLINE |
x %= 1 | Special.ID Operators.MOD_EQUALS Special.INTEGER |
Special.ID Operators.MOD_EQUALS Special.INTEGER |
End Of File | Special.EOF | Special.EOF |
Задача теста, проверить, что лексер правильно распознает токены и значения чисел.
В качестве входных данных рассматривается следующий код на языке Ruby:
0
1
10
100
0.1
0.01e4
-100
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
0 | (Special.INTEGER, '0') Special.NEWLINE |
(Special.INTEGER, '0') Special.NEWLINE |
1 | (Special.INTEGER, '1') Special.NEWLINE |
(Special.INTEGER, '1') Special.NEWLINE |
10 | (Special.INTEGER, '10') Special.NEWLINE |
(Special.INTEGER, '10') Special.NEWLINE |
100 | (Special.INTEGER, '100') Special.NEWLINE |
(Special.INTEGER, '100') Special.NEWLINE |
0.1 | (Special.FLOAT, '0.1') Special.NEWLINE |
(Special.FLOAT, '0.1') Special.NEWLINE |
0.01e4 | (Special.FLOAT, '0.01e4') Special.NEWLINE |
(Special.FLOAT, '0.01e4') Special.NEWLINE |
-100 | Operators.MINUS (Special.INTEGER, '100') |
Operators.MINUS (Special.INTEGER, '100') |
End Of File | Special.EOF | Special.EOF |
Задача теста, проверить, что лексер правильно распознает токены ключевых слов языка Ruby.
В качестве входных данных рассматривается следующий код на языке Ruby:
def return end while do for until next break if elsif else in case when or and not true false nil
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
def | KeyWords.FUNCTION | KeyWords.FUNCTION |
return | KeyWords.RETURN | KeyWords.RETURN |
end | KeyWords.END | KeyWords.END |
while | KeyWords.WHILE | KeyWords.WHILE |
do | KeyWords.DO | KeyWords.DO |
for | KeyWords.FOR | KeyWords.FOR |
until | KeyWords.UNTIL | KeyWords.UNTIL |
next | KeyWords.NEXT | KeyWords.NEXT |
break | KeyWords.BREAK | KeyWords.BREAK |
if | KeyWords.IF | KeyWords.IF |
elsif | KeyWords.ELSIF | KeyWords.ELSIF |
else | KeyWords.ELSE | KeyWords.ELSE |
in | KeyWords.IN | KeyWords.IN |
case | KeyWords.CASE | KeyWords.CASE |
when | KeyWords.WHEN | KeyWords.WHEN |
or | KeyWords.OR | KeyWords.OR |
and | KeyWords.AND | KeyWords.AND |
not | KeyWords.NOT | KeyWords.NOT |
true | Reserved.TRUE | Reserved.TRUE |
false | Reserved.FALSE | Reserved.FALSE |
nil | Reserved.NIL | Reserved.NIL |
End Of File | Special.EOF | Special.EOF |
Задача теста, проверить, что лексер правильно распознает токены скобок языка Ruby.
В качестве входных данных рассматривается следующий код на языке Ruby:
( ) [ ] { }\
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
( ) [ ] { } | Special.LPAR Special.RPAR Special.LBR Special.RBR Special.LFBR Special.RFBR Special.VBR Special.EOF |
Special.LPAR Special.RPAR Special.LBR Special.RBR Special.LFBR Special.RFBR Special.VBR Special.EOF |
Задача теста, проверить, что лексер правильно распознает токены логических операторов и операторов сравнения языка Ruby.
В качестве входных данных рассматривается следующий код на языке Ruby:
< > <= >= == != and or not\
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
< > <= >= == != and or not | Operators.LESS Operators.GREATER Operators.LESS_EQUAL Operators.GREATER_EQUAL Operators.DOUBLE_EQUALS Operators.NOT_EQUALS KeyWords.AND KeyWords.OR KeyWords.NOT Special.EOF |
Operators.LESS Operators.GREATER Operators.LESS_EQUAL Operators.GREATER_EQUAL Operators.DOUBLE_EQUALS Operators.NOT_EQUALS KeyWords.AND KeyWords.OR KeyWords.NOT Special.EOF |
Задача теста, проверить, что лексер правильно распознает токены специальных символов языка Ruby (запятые, точки и т.п).
В качестве входных данных рассматривается следующий код на языке Ruby:
, .. ; .\
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
, .. ; . | Special.COMMA Special.DOUBLE_DOT Special.SEMICOLON Special.DOT Special.EOF |
Special.COMMA Special.DOUBLE_DOT Special.SEMICOLON Special.DOT Special.EOF |
Задача теста, проверить, что лексер правильно распознает токены скобок языка Ruby.
В качестве входных данных рассматривается следующий код на языке Ruby:
\t \t
\t
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
Код выше | Special.NEWLINE Special.NEWLINE Special.EOF |
Special.NEWLINE Special.NEWLINE Special.EOF |
Задача теста, проверить, что лексер правильно распознает токены скобок языка Ruby.
В качестве входных данных рассматривается следующий код на языке Ruby:
-
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
- | Special.EOF | Special.EOF |
Задача теста, проверить, что лексер правильно распознает позиции токенов в коде языка Ruby.
В качестве входных данных рассматривается следующий код на языке Ruby:
my_array = [1, 2, 3, 4, 5]
puts my_array.sum\
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
my_array = [1, 2, 3, 4, 5] | (1, 1) (1, 10) (1, 12) (1, 13) (1, 14) (1, 16) (1, 17) (1, 19) (1, 20) (1, 22) (1, 23) (1, 25) (1, 26) (1, 27) |
(1, 1) (1, 10) (1, 12) (1, 13) (1, 14) (1, 16) (1, 17) (1, 19) (1, 20) (1, 22) (1, 23) (1, 25) (1, 26) (1, 27) |
puts my_array.sum | (2, 1) (2, 6) (2, 14) (2, 15) (2, 18) |
(2, 1) (2, 6) (2, 14) (2, 15) (2, 18) |
End Of File | (3, 1) | (3, 1) |
Задача теста, выявить потенциальные ошибки лексера, так как входные данные в этом тесте являются некорректными и лексер должен обрабатывать их выдавая соответствующие ошибки.
В качестве входных данных рассматривается следующий код на языке Ruby:
1.1.1
1abvgd
000111
000000000
До правок в программу результаты её работы были следующие:
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
1.1.1 | FLOAT:1.1 DOT:1 INTEGER:1 |
Incorrect number token: 1.1. |
1abvgd | Incorrect number token: 1a | Incorrect number token: 1a |
000111 | INTEGER:000111:3:1 | Incorrect number token:000111 |
000000000 | INTEGER:000000000:4:1 | Incorrect number token:000000000 |
Как можно видеть, часть неправильных конструкций кода лексер обработал правильно, а другая часть не была учтена при реализации. После выявление ошибок и внесения соответствующих правок, результат работы стал следующим:
Входные данные | Выходные данные | Ожидаемые данные |
---|---|---|
1.1.1 | Incorrect number token: 1.1. | Incorrect number token: 1.1. |
1abvgd | Incorrect number token: 1a | Incorrect number token: 1a |
000111 | Incorrect number token:000111 | Incorrect number token:000111 |
000000000 | Incorrect number token:000000000 | Incorrect number token:000000000 |