Поиск по номерам упражнений:
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;