интерпретатор программного кода (на C++)

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: интерпретатор программного кода (на C++)

Непрочитанное сообщение Olej » 24 июн 2017, 14:41

Olej писал(а): Задача там изрядно сложная, поэтому для её отработки собирается несколько отдельных приложений (для тестирования, проверок и т.д.):
- z211r - это, собственно, интерпретатор программ на языке Z ... но о нём позже;
- reglex - препроцессор, построенный на регулярных выражениях, z211r запускает его как дочерний процесс;
- regs - тестер вариантов регулярных выражений, используемых reglex;
- ppntest - тестер конвертора инфиксных (скобочных) выражений в постфиксные (обратная польская запись);
- exec - вспомогательная запускающая программа для тестирования препроцессора reglex;

Код: Выделить всё


Там же имеются 2 каталога [b]тестовых кодов[/b] (программ) на языке Z:
[olej@dell z211]$ ls -l | grep ^d
drwxrwxr-x 1 olej olej    164 май 16 20:13 test_lex.z
drwxrwxr-x 1 olej olej    676 май 26 11:20 tests.z
- test.z - окончательные тесты для интерпретатора z211r;
- test_lex.z - более тонкие тесты для контроля работы лексического препроцессора reglex;

Код: Выделить всё

[olej@dell z211]$ ls tests.z 
a0_1.z  a2_1.z  a2.z    a6_1.z   aif1.z  al2.z    arw2.z  av26_1.z  b0_0.z  b0.z    b2_4.z  ba0_3.z  bt1.z
a0_2.z  a2_2.z  a3_1.z  a6_2.z   aif2.z  al3.z    at1.z   av26_2.z  b0_1.z  b1.z    b2_5.z  bio_1.z
a0.z    a2_3.z  a4s.z   ab0.z    al01.z  aout1.z  at2.z   aw1.z     b0_2.z  b2_1.z  b2.z    bio_2.z
a1.z    a2_4.z  a4.z    ab1.z    al0.z   arw0.z   at3.z   aw2.z     b0_3.z  b2_2.z  b3.z    bl2.z
a2_0.z  a2_5.z  a5.z    acmt1.z  al1.z   arw1.z   at4.z   aw3.z     b0_4.z  b2_3.z  b4.z    bs1.z

[olej@dell z211]$ ls test_lex.z 
a1.z  a3.z  ab1.z  ab2.z  ab3.z  ab4.z  ab5.z  ad1.z  ad2.z  af1.z  af2.z  ai1.z  ai2.z  as.z  aw1.z  aw2.z  aw3.z
Тесты a*.z - это корректные коды программ, тесты b*.z - это коды в которые сознательно внесены ошибки и хороший интерпретатор (как и компилятор) должен не только распознать эти ошибки, но и указать место в коде (ткнуть пальцем ;-) ) и диагностировать (описать) характер и причину ошибки.
Ну ... наш интерпретатор не настолько хорош :-?

Ещё там есть несколько файлов *.pat - это наборы (сколь угодно большие) текстовых строк регулярных выражений (патернов), через которые тестером regs можно прогонять (в диалоге) любые синтаксические конструкции Z, и смотреть как (так ли?) каждое регулярное выражение на конструкции реагирует:

Код: Выделить всё

[olej@dell z211]$ ls *.pat
for.pat  if.pat  op.pat
Например, for.pat - это патерны для разнообразных циклов, а if.pat - патерны для разнообразных условных операторов.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: интерпретатор программного кода (на C++)

Непрочитанное сообщение Olej » 24 июн 2017, 14:57

Olej писал(а):Задача там изрядно сложная, поэтому для её отработки собирается несколько отдельных приложений (для тестирования, проверок и т.д.):
Проблема здесь в том, что задача имеет великое множество степеней свободы ... в зависимости от входного кода программы Z.
Тестировать, тестировать и ещё раз тестировать :cry:
Вот только некоторые примеры (исчерпывающими или даже показательными они быть не могут, из-за многообразия ... но только для того, чтобы показать что, как и для чего используется):

Код: Выделить всё

[olej@dell 2a]$ cat tests.z/a2_5.z
program {
   int a = 7, b= 5 , c = -2, d =4, e; ;
   a = b = c = e = a + ( b - c ) * d;
   write( a, b );
}
// 35
// 35

[olej@dell 2a]$ ./reglex tests.z/a2_5.z
int a = 7, b= 5 , c = -2, d =4, e
a = b = c = e = a + ( b - c ) * d
write( a, b )

[olej@dell 2a]$ ./exec tests.z/a2_5.z
получено от транслятора:
1: int a = 7, b= 5 , c = -2, d =4, e
2: a = b = c = e = a + ( b - c ) * d
3: write( a, b )

[olej@dell 2a]$ ./z211r tests.z/a2_5.z
int a = 7, b= 5 , c = -2, d =4, e
a = b = c = e = a + ( b - c ) * d
write( a, b )
получено от транслятора: 3 строк
.t
a = 7 b= 5  c = -2 d =4 e
a = b = c = e = a + ( b - c ) * d
write( a, b )
.i
a b c - d * + = e = c = b = a
a write
b write
.q

Код: Выделить всё

[olej@dell ppn]$ ./ppntest ok.p
a+(b-c)*d => a b c - d * +
a1+bb2 => a1 bb2 +
a+b+345 => a b + 345 +
alpha+beta*123 => alpha beta 123 * +
((a1-b2+1)/(c3+d4+2)) => a1 b2 - 1 + c3 d4 + 2 + /
(a+b)*(c+d) => a b + c d + *
(aa - b) * ( d * (aa / (x1 + x2) )) => aa b - d aa x1 x2 + / * *

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: интерпретатор программного кода (на C++)

Непрочитанное сообщение Olej » 24 июн 2017, 15:02

Olej писал(а):Вот только некоторые примеры
А дальше сам интерпретатор z211r:

Код: Выделить всё

[olej@dell 2]$ ./z211 tests.z/a3_1.z
.t
a2 = 7, b3= 5 , c4 = -2, d5x =4, e0
e0 = a2 + ( b3 - c4 ) * d5x
e0 = a2 + b3 - c4 * d5x - e0
s11="1111", s22="2222", s33
s33= s11 + s22
.i
a2 b3 c4 - d5x * + = e0
a2 b3 + c4 d5x * - e0 - = e0
s11 s22 + = s33
.v
a2      int     <7>
b3      int     <5>
c4      int     <-2>
d5x     int     <4>
e0      int     <0>
s11     string  <1111>
s22     string  <2222>
s33     string  <>
.r
.v
a2      int     <7>
b3      int     <5>
c4      int     <-2>
d5x     int     <4>
e0      int     <-15>
s11     string  <1111>
s22     string  <2222>
s33     string  <11112222>
.q

Код: Выделить всё

[olej@dell 2a]$ ./z211r test_lex.z/aw2.z
.t
a = 7 b=5  c=-2 d = +4 e
B0001: ( a + c ) > ( b - d ) ifn F0001
a = a - 1
d = 2 * b
e = e + 1
goto B0001
F0001:
.i
a 1 - = a
2 b * = d
e 1 + = e
goto B0001
.v
a       int     <7>
b       int     <5>
c       int     <-2>
d       int     <+4>
e       int     <0>
.r
.v
a       int     <4>
b       int     <5>
c       int     <-2>
d       int     <10>
e       int     <2>
.q

Код: Выделить всё

[olej@dell 2a]$ ./z211r test_lex.z/aw2.z
.а
недопустимая команда
допустимые команды: f t i v g s b r l ? e q h
.f
program {
   int a = 7, b=5 , c=-2, d = +4, e; ;
   while( ( a + c ) > ( b - d ) ) {
      { a = a - 1; }
      d = 2 * b;
      { e = e + 1; }
   };
}
.t
a = 7 b=5  c=-2 d = +4 e
B0001: ( a + c ) > ( b - d ) ifn F0001
a = a - 1
d = 2 * b
e = e + 1
goto B0001
F0001:
.g
B0001   0
F0001   4
.q

Код: Выделить всё

[olej@dell 2a]$ ./z211r tests.z/al01.z
.f
program {
   int a = 7, b= 5 , c = -2, d =4, e; ;
   xxx: a = 5 + a;
   lx: ;
   l2 : b = a + 2;
   l3:c=c+11;
}
.t
a = 7 b= 5  c = -2 d =4 e
xxx: a = 5 + a
lx:
l2 : b = a + 2
l3:c=c+11
.g
l2      2
l3      3
lx      1
xxx     0
.q

Код: Выделить всё

[olej@dell 2a]$ ./z211r tests.z/al2.z
.f
program {
   int a = 7, b = 5;
   a = a - 2;
   goto l3;
   b = b / 2;
   l1:l2: l3: b = a + 1;
   write( a, b );
}
.t
a = 7 b = 5
a = a - 2
goto l3
b = b / 2
l1:l2: l3: b = a + 1
write( a, b )
.g
l1      3
l2      3
l3      3
.i
a 2 - = a
goto l3
b 2 / = b
a 1 + = b
a write
b write
.q

Код: Выделить всё

[olej@dell 2a]$ ./z211r  tests.z/aw2.z
.i
a 3 + = a
a write
a c < if1 B0001
.t
a = 1 c = 10
B0001:
a = a + 3
write( a )
a < c if1 B0001
.s
.s
4
.s
.s
.s
7
.s
.s
.s
10
.s
.s
выполнение - достигнут конец программы
.b
.r
13
.q

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: интерпретатор программного кода (на C++)

Непрочитанное сообщение Olej » 24 июн 2017, 15:14

Olej писал(а):
Olej писал(а):Вот только некоторые примеры
А дальше сам интерпретатор z211r:
Чуть более сложные конструкции:

Код: Выделить всё

[olej@dell z211]$ ./z211r tests.z/at3.z
.f
program {
   string z = "zero";
   string o = "one";
   write( o + " x y z  " + z );
}
.t
z = "zero"
o = "one"
write( o + " x y z  " + z )
.i
o " x y z  " + z + write
.s
one x y z  zero
.v
o       string  <one>
z       string  <zero>
.q

Код: Выделить всё

[olej@dell z211]$ ./z211r tests.z/aw1.z
.
.
.f
program {
   int a = 1, c = 10;
   while( a < c ) {
      a = a + 2;
      write( a );
   };
}
.t
a = 1 c = 10
B0001: a < c if0 F0001
a = a + 2
write( a )
goto B0001
F0001:
.v
a       int     <1>
c       int     <10>
.r 40
3
5
7
9
11
.s
выполнение - достигнут конец программы
.q

Код: Выделить всё

[olej@dell z211]$ ./z211r tests.z/aw2.z
.f
program {
   int a = 1, c = 10;
   do {
      a = a + 3;
      write( a );
   } while( a < c );
}
.t
a = 1 c = 10
B0001:
a = a + 3
write( a )
a < c if1 B0001
.r 40
4
7
10
.v
a       int     <10>
c       int     <10>
.s
выполнение - достигнут конец программы
.q

Код: Выделить всё

[olej@dell z211]$ ./z211r tests.z/aw3.z
.f
program {
   int a = 1, b = 3, c = 10, d = 20;
   for( a = 1; a < c; a = a + 3 ) {
      write( a );
   };
}
.t
a = 1 b = 3 c = 10 d = 20
a = 1
B0001: a < c if0 F0001
write( a )
a = a + 3
goto B0001
F0001:
.r 30
1
4
7
.s
выполнение - достигнут конец программы
.q

Код: Выделить всё

[olej@dell z211]$ ./z211r tests.z/aif2.z
.f
program {
   int a = 1, b = 3, c = 4, d = 20; 
   if( c ^ 3 / d > a + 1 ) {
      write( "зашли в блок if" );
   }    
   write( "=== завершение ===" );
}
.t
a = 1 b = 3 c = 4 d = 20
c ^ 3 / d > a + 1 if0 F0001
write( "зашли в блок if" )
F0001:
write( "=== завершение ===" )
.i
c 3 ^ d / a 1 + > if0 F0001 
"зашли в блок if" write 
"=== завершение ===" write 
.s
.s
зашли в блок if
.s
=== завершение ===
.s
выполнение - достигнут конец программы
.b
.r
зашли в блок if
=== завершение ===
.q

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: интерпретатор программного кода (на C++)

Непрочитанное сообщение Olej » 24 июн 2017, 15:19

Подтверждение того, что имена переменных и имена меток находятся в различных адресных пространствах (это разные сущности):

Код: Выделить всё

[olej@dell z211]$ ./z211r tests.z/al3.z
.f
program {
    int ax = 7, bx = 5;
bx: ax = ax - 2;
    goto ax;
    bx = bx / 2;
ax: write( ax, bx );
}
.v
ax      int     <7>
bx      int     <5>
.g
ax      3
bx      0
.v
ax      int     <7>
bx      int     <5>
.s
.s
.s
5
.s
5
.s
выполнение - достигнут конец программы
.t
ax = 7 bx = 5
bx: ax = ax - 2
goto ax
bx = bx / 2
ax: write( ax, bx )
.i
ax 2 - = ax
goto ax
bx 2 / = bx
ax write
bx write
.q
Но не исключено, что в некоторых других синтаксисах интерпретируемого языка они могли бы быть объектами единого адресного пространства. Тогда могли бы быть допустимыми такие конструкции как:

Код: Выделить всё

goto ax + 3
... ну и другие самые замысловатые.
Это могло бы дать дополнительную гибкость.
Но с таким синтаксисом можно и чудовищно начудить.
Такие вещи нужно изучать дополнительно...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: интерпретатор программного кода (на C++)

Непрочитанное сообщение Olej » 24 июн 2017, 15:29

Справка и допустимые команды интерпретатора:

Код: Выделить всё

[olej@dell z211]$ ./z211r
.?
версия 0.35
.h
допустимые команды: f t i v g s b r l ? e q h
.q
.f - исходный текст (код) из файла
.t - текст (в несколько модифицированном виде ... разделённый пооператорно на строки, убраны комментарии);
.i - внутреннее представление (постфиксное);
.v - содержимое таблицы переменных;
.g - содержимое таблицы меток;
.s - шаг выполнения;
.b - начать выполнение с начала;
.r - выполнять полностью;
.l <файл> - перезагрузить файл программы;
.? - версия;
.e , .q - завершение;
.h - справка (перечисление команд);

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 20 гостей