Поиск по номерам упражнений:
| 1.1. | 1.2. | 1.3. | 1.4. | 1.5. | 1.6 |
| 2.1. | 2.2. | 2.3. | 2.4. | 2.5. | 2.6. |
| 3.1. | 3.2. | 3.3. | 3.4. | 3.5. | 3.6. |
| 3.7. | 3.8. | 3.9. | 3.10. | 3.11. | 3.12. |
| 4.1. | 4.2. | 4.3. | 4.4. | 4.5. | |
| 6.1. | 6.2. | 6.3. | 6.4. | 6.5. |
'Joe''s Pizza is "cute"' "Joe's Pizza is ""cute"""
'-'16 0
(a) e1 sX sX ; (b) e1 tX e2 tX e3 ; (c) t1 e2 or e1 t2 .
(a) tX превращается в b ; (b) неудача; (c) e6 превращается в A(B) , e4 превращается в C D ; (d) неудача.
Add {
(eX) '0' = eX;
(eX) eY's'= <Add (eX) eY>'s'; }
Addb {
(eX'0')(eY s1) = <Addb (eX)(eY)> s1;
(eX'1')(eY'0') = <Addb (eX)(eY)>'1';
(eX'1')(eY'1') =
<Addb (<Addb (eX)('1')>)(eY)>'0';
(eX)(eY) = eX eY; }
$ENTRY Go { = <Job> }
Job { = <Prout 'Please enter a line'>
<Job1 <Card>>; }
Job1 {
0 = <Prout 'Good-bye!'>;
eX = <Prout 'The translation is:'>
<Prout <Trans-line eX>>
<Job>; }
(a) Sum-1 and '#SUM_1 ' (b) Sum'-'1 and '#SUM -#1 ' (c) as above (d) (9'+'25)'()' and '(#9 +#25 )#(#)'
* Conv-xx, conversion of a file typed for Input
* into a file for Xxin.
* Call: refgo conv-xx+reflib file-name
$ENTRY Go { =
<Xxout (<Arg 1>) <Input <Arg 1>>>; }
$EXTERN Input,Xxout;
Merge { s1 s2 =
<Implode <Explode s1> <Explode s2>>; }
(a) 7 6 8 5 4 9 3 2 10 11 1 eA ( t2 ) ( Sunday ) ( s.Day s.Night )
Переменная eA (No.7) является закрытой.
(b) 1 3 2 4 5 7 9 8 10 6 11 ( e.Word ) e1 ( ( e.Word ) e.Transl ) e2
No.3 является закрытым, No.4 открытым вхождением, No.9 повторным, No.11 закрытым.
(c) 1 8 9 10 7 6 2 11 12 13 4 5 3 ( e1 '+' e2 '+' e3 ) e1 '+' e2 ( e3 )
No.5 является закрытым, No.6 повторным, No.8 открытым, No.10 закрытым, No.11 и No.13 повторными.
(a) ('di'
eA)('f'
t1)('ident'
eB)
(b) (
e1)('d'
sX)('iffi'
e2) ('ent'
e3)
(c) Failure
(d) (
e1)(
e2)(A B C
e3)
(e) (A(A B)
e1)((C)
eX)(D
e2)
Второй знак уничтожения появится в ответе:
#Crocodile
Для выдачи сообщения в предложение следует вставить:
()'#'e2 = <Prout 'Extra delete signs!'> <Prout '#'e2>;
между предложениями 2 и 3.
Cut {
(e1)(e2) = <Cut1 (()e1) (()e2)>; }
Cut1 {
((e.R1) tX e1) ((e.R2) tX e2) =
<Prout (e.R1 tX)(e.R2 tX)>
<Cut1 (()e1) (()e2)>;
((e.R1) tX e1) ((e.R2) tY e2) =
<Cut1 ((e.R1 tX) e1) ((e.R2 tY) e2)>;
eZ = ; }
Equal {
(sX e1) (sX e2) = <Equal (e1) (e2)>;
((e.T1)e1) ((e.T2)e2) =
<Equal1 <Equal (e.T1)(e.T2)> (e1)(e2)>;
() () = T;
(e1) (e2) = F; }
Equal1 {
T eA = <Equal eA>;
F eA = F; }
F {
sX e1 = <F1 sX()e1>;
= <Prout 'No repeated symbols'>; }
F1 {
sX(e2)sX e1 = sX e2 sX;
sX(e2)sY e1 = <F1 sX(e2 sY) e1>;
sX(e2) = <F e2>; }
При неявной рекурсии:
Isect {
(sX e1)(e2 sX e3) = sX <Isect (e1)(e2 e3)>;
(sX e1)(e2) = <Isect (e1)(e2)>;
()(e2) = ; }
Без применения неявной рекурсии:
Isect {
(sX e1) eI (sX e2) = sX <Isect (e1)(eI e2)>;
(sX e1) eI (sY e2) =
<Isect (sX e1) eI sY (e2)>;
(sX e1) eI () = <Isect (e1) (eI)>;
() eI (e2) = ; }
ЗАМЕЧАНИЕ: Был использован "закрытый'' формат функции Isect , который обеспечивает память еще для одного выражения, вначале пустого. Если бы форматом функции был Isect (e1)e2> , необходимо было бы ввести некоторую вспомогательную функцию.
2c + t , где t = 1, если одна строка является началом другой. А при таком определении:
* Precedence-conservative
* <Prec eC(e1)(e2)> == T(e1)(e2)
* == F(e1)(e2)
* where eC is the common part of e1 and e2.
Prec {
eC ()(e2) = T(eC)(eC e2);
eC (e1)() = F(eC e1)(eC);
eC (t1eX)(t1eY) = <Prec eC t1 (eX)(eY)>;
eC (t1eX)(t2eY) =
<Addc eC <Pre-term t1 t2>(t1eX)(t2eY)>;}
Addc { eC sT(eX)(eY) = sT(eC eX)(eC eY); }
время составляет c + t.
String {
e1 s2 = <String e1> s2;
= T;
e1(e2) = F e1(e2); }
Pal { eX = <Pal1 ()eX()>; }
Pal1 {
(eL) s1 e2 s1 (eR) =
<Pal1 (eL s1) e2 (s1 eR)>;
(eL)(eR) = T eL eR;
(eL) eI (eR) = F eL eI eR; }
Fact {sN = <Loop F(1) I(1) N(sN)>; }
Loop {
F(sF) I(sN) N(sN) = <* sN sF>;
F(sF) I(sI) N(sN) =
<Loop F(<* sI sF>) I(<+ sI 1>) N(sN)>;
}
* Recursive definition
Reverse {
s1 e2 = <Reverse e2> s1;
= ; }
*Iterative definition
Reversei { eX = <Revit ()(eX)>; }
Revit {
(eR)(s1 e2) = <Revit (s1 eR)(e2)>;
(eR)() = eR; }
См. функцию Pprout в reflib .
* Multibracket Backtracking
Mback {
[e1(e2 ^e3)e4] = <Mback [e1 ^(e2 e3)e4]>;
[.e1 ^e2.] = e1 e2; };
Функция достигает результата ,перемещая указатель обратно к началу выражения. Тот же результат может быть получен при перемещении указателя вперед.
(a)
* Call: <Tree [. ^sX.]>
* where sX is the root node.
Tree {
*1. A leaf. Jump over.
[e1 ^sX'.'e2] = <Tree [e1 sX'.' ^e2]>;
*2. A node with subtree. Enter it.
[e1 ^sX(eT) e2] = <Tree [e1 sX( ^eT)e2]>;
*3. A 'hanging' node. Generate subtree.
[e1 ^sX e2] = <Tree [e1 ^<Subtree sX> e2]>;
*4. Up the tree.
[e1(e2 ^)e3] = <Tree [e1(e2) ^e3]>;
*5. End of work
[.e1 ^.] = e1; }
(b) Все те узлы, обработка которых завершена, находятся в левой мультискобке, причем в формате sX(eS) , где eS является обработанным поддеревом для sX . Те узлы, обработка которых уже начата, но не завершена, также находятся в левой мультискобке, но в формате
sX)( ,
поскольку левая круглая скобка, следующая за sX, представляется инвертированной парой скобок. Поэтому указанное выше предложение 3 модифицируется как:
*3. A 'hanging' node. See whether repeated. [e1 ^sX e2] = <Tree1 (<Rep sX[. ^e.ML(e1 ).]> )(sX e2)e.MR>;
Две новые функции определяют следующим образом:
* See whether the subtree was already built
Rep {
*1. Repeated node found.
sX [e1 ^sX(eS) e2] =
Yes(eS) <Mback [e1 ^sX(eS) e2]>;
*2. A different symbol.
sX [e1 ^sY e2] = <Rep sX [e1 sY ^e2]>;
*3. Enter a parenthesis
sX [e1 ^(e2)e3] = <Rep sX [e1( ^e2)e3]>;
*4. Exit a parethesis
sX [e1(e2 ^)e3] = <Rep sX [e1(e2) ^e3]>;
*5. End of work.
sX [.e1 ^.] = No e1; }
Tree1 {
*1. Repeated node. Cope subtree.
(Yes(eS)e1)(sX e2)e.MR =
<Tree (e1)(sX(eS) e2)e.MR>;
*2. New node. Compute subtree.
(No e1)(sX e2)e.MR =
<Tree (e1)(<Subtree sX> e2)e.MR>;
}
Addop {
e1 s.Op e2, '+-': eX s.Op eY =
(e1) s.Op e2;
e1 = <Prout 'No additive operations'>; }
Less {
(e1) e2, <- e1 e2>: '-'eZ = T;
(e1) e2 = F;
eA = <Less <Format eA>>; }
Lesseq {
(e1) e2, <- e2 e1>: '-'eZ = F;
(e1) e2 = T;
eA = <Lesseq <Format eA>>; }
Format {
'-'s1 e2 = ('-'s1) e2;
'+'s1 e2 = (s1) e2;
s1 '-'e2 = (s1) '-'e2;
s1 '+'e2 = (s1) e2;
s1 e2 = (s1) e2; }
S123 {
eA 1 e1, e1:
{eB 2 e2, e2:
{eC 3 eD = T;
eC = F };
eB = F };
eA = F }
Fa {
e1 sX sY e2,
<Less sY sX>: T,
<Less 100 <+ sX sY>>: T = sX sY;
e1 = <Prout 'No such pair'>;
}
Fb {
e1 sX sY e2, <Less sY sX>: T,
<Less 100 <+ sX sY>>:
{T = <Prout 'It is greater'>;
F = <Prout 'It is not greater'>;
};
e1 = <Prout 'No such pair'>;
}
* Dictionary is stored as DICT
$ENTRY Go { =
<Br 'dict='<Xxin 'DICT'>>
<Prout 'Type in additions'>
<Addition <Input>> ;
}
Addition {
= <Prout 'No additions. Go ahead.'>
<Job>;
eX = <Prout 'OK. Go ahead.'>
<Xxout ('DICT') eX<Cp 'dict'>>
<Br 'dict='eX<Dg 'dict'>>
<Job>;
}
$EXTRN Input,Xxout,Xxin;
... etc. as before
Fun-n {
sN eA = <Mu <Implode 'Fun'<Symb sN>> eA>; }
Вставьте между третьим и четвертым предложениями:
'*'e1 = <Prout 'Error: no upgrade of 'e1>;
(a) '*'((Add) (35)16)
(b) '*'((Up) ('*V'((F) ('*VE'1)'*VE'2)) '*V!'('*E'3))
(c) <Comp 'A*B'>
(d) Невозможно. Это эквивалентно <Dn 'A*B'> , а ни одно выражение не становится активным, будучи погруженным в метакод. Сравнить с Упражнением 6.4(b).
(a) 51 (b) 'A*B'
На начало
Следует модифицировать две функции:
Check-end {
= <Prout 'End of session'>;
'*'Error = <Job>;
eX = <Out <Ev-met eX>>; }
Out {
0 eX = <Prout 'The result is:'>
<Prout <Up eX>> <Prout> <Job>;
1 eX = <Prout 'Result depends on unknowns'>
<Prout> <Job>;
2 eX = <Prout 'Recognition impossible'>
<Prout 'View field in metacode:'>
<Pprout eX> <Error eX>;
}
$EXTRN Pprout,Error;