Molchanov a. Sistemnoe Programmnoe Obe.a4

261

Transcript of Molchanov a. Sistemnoe Programmnoe Obe.a4

. http://www.litres.ru/pages/biblio_book/?art=174317 . : ; -; 2005 ISBN 978-5-469-00391-4

, , . , . , , . , , , , , . , , . , .

. . . .

1 - - - - - 2 () 7 9 10 10 11 11 12 12 14 16 18 19 21 23 23 23 23 25 26 26 26 27 29 31 32 34 34 35 35 36 37 38 41 41 41 41 43 45 45 45 45 503

. . . .

3 - - - 4 () - -

53 55 57 57 58 58 59 60 62 65 71 74 74 74 75 76 76 76 78 78 78 85 88 89 91 91 92 92 93 94 95 97 98 101 102 104 105 107 107 107 109 110 111 111 111 1134

. . . .

1 2 3 - - , 4 1. 2.

116 122 124 126 126 127 128 129 131 134 135 136 136 137 138 138 142 149 159 161 166 168 171 177 177 182 185 187 190 199 202 209 210 211 216 222 229 239 249 249 252 259 2595

. . . .

260

6

. . . .

. ,1 2003 . , , , , . , . , . , , . , . , , [13, 7], [3, 5, 6]. ( ) , , ( , , [3]). , , . , , , , , . Object Pascal Delphi, Intel 80x86. C. , [13, 2325, 28, 31, 32, 37, 39, 41, 44]. Delphi 5 Object Pascal VCL. , , .

1

. . : . .: , 2003. 396 .

7

. . . .

Delphi, , C++, . , , . , , . , , , . , , . . : . , , , . , , , , , . . , , . : , , , , . . , , ( ). . , , . , , . . , - . , ( ). . . [3, 5], ( - [7]). , .

8

. . . .

, [email protected] ( , ). ! - : http:// www.piter.com.

9

. . . .

1 : , , . , , , . . 32 .

10

. . . .

, , , . ( ), ( ). , , , () , , , . , . , . , , , , . , [1, 3, 7]. . , , . . () . , , [13, 7], , . , , , , . , , . (), . . , , . , , [1, 2].

11

. . . .

, . , . , , . , , , , . , , . , ( ), . , , . : ; ; - ; - ; - . . [3, 7].

, , . . , . , ( ), , N , N/2 . , (T), (N). N , . (T) T = O(N). , . , . , () . ,12

. . . .

. N , , . : (N + 1)/2 ; , , 1 (N + 1)/2 1, (N + 1)/2 + 1 N , , . . , , , ( ). , , , 1 + log2 N. T = O(log2 N). : N = 128 8 , 64 . , , , , . . , , , . , , , . , . , , , , :

k , , . . , , , . , .

13

. . . .

, , . . , . , , . , . . . , , . , , . : 1. . , . 2. . 3. , . 4. , 5, ( !), 7. 5. , 3, 6. 6. , , 1. 7. , 3, 8. 8. , , 1. Ga, D1, 22, , 12, , F. . 1.1 .

14

. . . .

. 1.1. . , : 1. . 2. , . 3. , , , 4. 4. , 5, 6. 5. , 2, , . 6. , 2, , . , . , Ga, D1, 22, , 12, , F 12, , D1, , F, Ga, 22, . 15

. . . .

. : . , ( ), , . () () [3, 7]:

, . . [1, 2, 3, 7].

- - , . . , , - -. - F R Z:

- hash function (hash , , ). R . - F Z:

, F:

- .16

. . . .

- . - . - , -, . -. , - . , , , -, . - . - , ( , ). , , . , , , , , . . : -, . -. , - . - . . - . - , . , - : , , -. - , . , -, . , -, , - . , - . -, ? - : - , . - 17

. . . .

. , - ( ), ( ) , . , - . , - . , , . . , , , 32 128 ( - ). , -, ( ). , - . , . -. , .

- . ( ). , n0 = h(A), - h, , n 1 = h1(A) 1. , h 2(A), , , h i() h(A). , . , , : 1. - n = h(A) . 2. , , , n A. , , i:= 1 3. 3. ni = hi(A). ni n = ni, , ni A. , , i:= i + 1 3. . , . , . , -, , 18

. . . .

. , , , . - hi i. hi - h. , hi(A) hi(A) = (h(A) + pi) mod Nm, pi , Nm - h. , pi = i. hi(A) = (h(A) + i) mod Nm. - - , - h(A). : - , . . , . pi hi(A) = (h(A) + pi) mod Nm p1, p2, , pk. k = Nm. hi(A), , , : hi(A) = (h(A)Ni) mod N'm, N'm , Nm. (, ), - , . . [1, 3, 7].

- , . , . , -. - , . - , -, . , - . - , ( , - ).19

. . . .

: -, -; -, . -, , , - , . -, . , . ( ). , ( ). : 1. - , , FreePtr ( ) . 2. - n A. n , FreePtr 5; 3. 3. - m 4. 4. m . , FreePtr 5; m 4. 5. , A ( ), FreePtr . , , , 2. , , : 1. - n A. n , , - m. 2. m A. , , 3. 3. m. , ; m 2. , . , -. , . , .20

. . . .

. 1.2 - : A1, A2, A3, A4, A5 , h(A1) = h(A2) = h(A5) = n1; h(A3) = n2; h(A4) = n4. A 1 , A2 , A3 , A4 A5 ( , ). . , . , , , -. , .

. 1.2. .

-. - , , 21

. . . .

, . , - ( ), . : , , . : -, . , , - : , . -, - . - , . -, , - , . , , - . , , -. - . , , , . , ( ), . , , . , , . , . , . - , , , . - , . -, , , . - , . , [5, 6, 11].22

. . . .

, -. , . , . . -, . - 200 , 32 . -, . : 1. . 2. -. 3. , . 4. . 5. . 6. .

: ; -; ( ); ( ); ( ); ( ) , ; .

? ? ? ? ?23

. . . .

? ? ? . ? - ? -? ? ? ? ? ? - . ? - . -? .

24

. . . .

. 1.1 , .

1.1.

. 1.2 , . 1.1.

1.2.

25

. . . .

: - - . . 1.1, 2 7 ( . 1.2 ).

- - - , , , . , , , . , .2 ASCII, Microsoft Windows. , , - , - 0, z. , - Object Pascal : (Ord(0 )+Ord(0 )+Ord(0 ))..(Ord('z')+Ord('z')+Ord('z')) 223 , ( 200 ). . , -: HASH_MIN = Ord(0 )+Ord(0 )+Ord(0 ); HASH_MAX = Ord('z')+Ord('z')+Ord('z'). - : Ord(sName[1]) + Ord(sName[(Length(sName)+1) div 2]) + Ord(sName[Length(sName); sName ( -). , F = i-H1 mod 2, 1 2 , , H1 2/2 2. , HASH_MIN HASH_MAX, 2 HASH_MAX HAS_IN + 1. 223 , 223 , 2 = 223 ( , 2

, , , , . Delphi 5 Upper TblElem ( 3.1, 3). , , [7, 13, 23, 25, 28, 32].

26

. . . .

2 ). H1 127: H1 = 127. : REHASH1 = 127; REHASH2 = 223; - : function VarHash(const sName: string; iNum: integer):longint; begin Result:=(Ord(sName[1])+Ord(sName[(Length(sName)+1) div 2]) + Ord(sName[Length(sName)]) HASH_MIN + iNum*REHASH1 mod REHASH2) mod (HASH_MAX-HASH_MIN+1) + HASH_MIN; if Result < HASH_MIN then Result:= HASH_MIN; end; : sName , iNum ( iNum = 0, ). (Result < HASH_MIN) , , , 0 ..'z' ( , ). - - . - Object Pascal : (Ord(0 )+Ord(0 ))..(Ord('z')+Ord('z')) 200 , , ( ). - , - : function VarHash(const sName: string): longint; begin Result:=(Ord(sName[1])+Ord(sName[(Length(sName)+1) div 2]) HASH_MIN) mod (HASH_MAX-HASH_MIN+1) + HASH_MIN; if Result < HASH_MIN then Result:= HASH_MIN; end.

, . ( ) . , . . ( TVarInfo) ( sName: string), . - 27

. . . .

, TVarInfo TAddVarInfo ( pInfo: TAddVarInfo). Object Pascal , class, , , , , ( ). , , . , , , , ( TVarInfo) . , , , , , . , ( 4). TVarInfo : constructor Create destructor Destroy; procedure SetInfo procedure ClearInfo. . TVarInfo , : () () minEl, maxEl: TVarInfo; function AddElCnt function AddElem; function FindElCnt function FindElem; procedure ClearAllInfo; ( ) function GetElList. , , . , , (minEl maxEl). TVarInfo TblElem. 3.1 3. (function TVarInfo.FindElCnt). ( sN 28

. . . .

sName) Object Pascal, : if sN < sName then begin end else if sN > sName then begin end else : (sN < sName), (sN > sName). , ( !). , , : i:= StrComp(PChar(sN), PChar(sName)); if i < 0 then begin end else if i > 0 then begin end else , , .

HASH_MIN..HASH_MAX, TVarInfo. Object Pascal, , . nil. , , . . 1.3 , . 1 , 2 - . nil -.29

. . . .

. 1.3. . : - InitTreeVar InitHashVar; - ClearTreeVar ClearHashVar; ClearTreeInfo ClearHashInfo; AddTreeVar AddHashVar; GetTreeVar GetHashVar; , GetTreeCount GetHashCount. , . (AddTreeVar AddHashVar ; GetTreeVar GetHashVar ). ( TblElem) . , , , , . , . , . : FncHash , , FncTree , - . , .

30

. . . .

(FncHash FncTree) - , FncHash.pas FncTree.pas. , FncTree 3.2 3. , (initialization) , (finalization) . , Object Pascal .

, . (FormLab1) TLab1Form TForm VCL. Graphical User Interface (GUI) Windows . ( FormLab1.pas) ( FormLab1.dfm). GUI [3, 5, 6, 7]. FormLab1 (iCountNum, iCountHash, iCountTree), , (procedure ViewStatistic) . , , : (EditFile), (BtnFile), (BtnLoad); (Listldents); (EditSearch); (BtnSearch) (procedure SearchStr); (BtnAllSearch) (procedure SearchStr) ( , Listldents); (BtnReset); ; (BtnExit). . 1.4.

31

. . . .

. 1.4. 1. (procedure TLab1Form. BtnLoadClick) BtnLoad. , Listldents, . , . (, 223 , ). (procedure TLab1Form.SearchStr) BtnSearch ( procedure TLab1Form.BtnSearchClick) BtnAllSearch ( procedure TLab1Form. BtnAllSearchClick). , . , - , FormLab1.pas FormLab1.dfm . , 1, , , LABS COMMON ( COMMON , ). LAB1.DPR LABS. , FncTree 3.1 3.

, 20 % ( 45 ) , - . 32

. . . .

20 % 40 % ( 4590 ) , , 40 % (90-223 ), . 223 , . , , - ( 35 , 500700 ), - .

33

. . . .

2 : , (), .

34

. . . .

( ) , () . , . ( ) , . , , , . . . , . . , . : , ; , , ; , . , , , , . , : , , , , () . . , , , . , , . , . [14, 7].35

. . . .

. . , DO 10 I=1 ( , ). DO 10 I=1.15 DO10I 1.15 ( ), DO 10 I=1,15 1 15 I 10. C++ k=i+++++j;, ( ): k = i++ + ++j;. , . , . , , , , . , . [3, 7]. , , , . , , . . , . , C++ , . k=i+++++j; , + (+ C++, ++ ) ++ ( ) k = i++ ++ +j; ( ), , C++ . , , ( C++), ( k=i++ + ++j;, ). , .36

. . . .

, . , .

. , . , , . , , , . , , : , . , , , ( , ). ! , . , . , , . . , () , . , ( ) . , , ( ), , . Object Pascal , . 2.1: begin for i:=1 to N do fg:= fg * 0.5

2.1. Pascal

37

. . . .

. 2.1 , . , , , . . , ( , :, ).

() , ( ). , [14, 7]. (). , , , . [3, 7, 26]. : M(Q,,,q0,F), : Q ; ( ); Q P(Q): Q P(Q) ( );

;

.38

. . . .

. , , , () . q q' , , , q q'. , , , , , . , . M(Q,,,q0,F) :

, , [3, 7, 26] (, ). . [3, 7, 26]. , . , , , . , . . , , , . , . ( ) ( ). . . . , . ( ), . , , , (, .). . , . , :39

. . . .

, ; ; , ; , : , ( ). - , .

40

. . . .

, . () . , . 32 . . . : 1. . 2. , ( ). 3. . 4. . 5. .

: . - . ( ). ( ). .

. , , , ? ? -

? ? , . ? ? ? ? ? ? ? . . ? ?41

. . . .

? . . ? .

42

. . . .

1. , ; ( ). , ( ), (:=), +, , *, / . 2. , ; ( ). , true false, (:=), or, xor, and, not . 3. if then else if then, ; ( ). , , =, ( ), (:=). 4. for (; ; ) do, ; ( ). , , =, ( ), (:=). 5. , ; ( ). , , (:=), +, , *, / . 6. , ; ( ). , 0 1, (:=), or, xor, and, not . 7. if then else if then, ; ( ). , , =, , (:=). 8. for (; ; ) do, ; ( ). , , =, , (:=). 9. , ; ( ). , , (:=), +, , *, / . 10. , ; ( ). , , (:=), or, xor, and, not . 11. if then else if then, ; ( ). , , =, , (:=). 12. for (; ; ) do, ; ( ). , , =, , (:=). 13. , ; ( ). , ( ), (:=), +, -, *, / . 14. , ; ( ). , 'F', (:=), or, xor, and, not .43

. . . .

15. if then else if then, ; ( ). , , =, ( ), (:=). 16. for (;;) do, ; ( ). , , =, ( ), (:=). . X, V I; , , , d, f, (: 89, 459, 0abc4); 2 3, , 3 .

44

. . . .

, if then else if then, ; ( ). , or, xor and, . (:=), . , ({) (}). - , .

- G({if,then,else,a,=,or,xor,and,(,),},{S,F,E,D,C},P,S) : S F; F if E then T else F | if E then F | a:= E T if E then T else T | a:= E E E or D | E xor D | D D D and | a | (E) . . . , , , . , , . 2, 3 4.

, . : (if, then, else, or, xor and); : , ; ; ;45

. . . .

. , . . , . , , , . . : ( Z z), ( 0 9) (_), ; ( 0 9), . , , , , , . , , , , , . , .

46

. . . .

. 2.1. , . , . . 2.1 , , , , ( , ). . 2.2 , if then ( , . 2.1). .

47

. . . .

. 2.2. if then. , . 2.1 2.2, : - ; (*) - , ; (, , , ); ( ) (_); (*) ( ) (_), ; 0 9; F , . : v , ; d , ; a . , : M(Q,,,q0,F): Q = {H, C, G, V, D, I1, I2, T1, T2, T3, T4, E1, E2, E3, E4, O1, O2, X1, X2, X3, A1, A2, A3, F} = ( - ); q 0 = H; F = {F}.48

. . . .

() 2. i, t, e, o, x a , : I1, I2 if; T1, T2, T3, T4 then; E1, E2, E3, E4 else; O1, O2 or; X1, X2, X3 xor; A1, A2, A3 and. , (), V. - , , , V, ( , i els, ). , , D. C, , . G . , , . H , F . , , , . . , . , , . F, , . . , , , . , . , , H. , , ( ). , V. , , . , , . 2.1. ( ). , , , , ( , ). 49

. . . .

, ! , . , , , , . . , .

, , : , ; , . : LexElem ; FormLab2 . : LexType , ; LexAuto . . 2 (TblElem FncTree), , 1. , , . , .

LexType . ( TLexType), . LexTypeName, LexTypeInfo. , (LEXSTART), . LexElem (TLexem) (TLexList), , .

( LexInfo). (LexType), :50

. . . .

;

VarInfo -

ConstVal ; szInfo . . , , . 1. , . , , , ( 3 4). , , . : iStr , ; iPos ; iAllP . , , . : : CreateVar ; CreateConst ; CreateInfo ; CreateKey ; Destroy , ( ); . ( , ). ( TLexList) TList VCL ( Classes) Delphi 5. TList , ( ). TLexList , , , ( Clear Destroy), GetLexem Lexem, ( ).

LexAuto, , , . . 51

. . . .

, . 2.1 2.2, . LexList, . ( listFile) , ( listLex). 0, , , . . ( ). TAutoPos . . MakeLexList, , . ( , ), case . case , case . : AddVarToList ; AddVarKeyToList ; AddConstToList ; AddConstKeyToList ; AddKeyToList ; Add2KeysToList . , , , F. . , ( T2, T3, E2, E3, X2 A2) ( I2, T4, E4, O2, X3 A3). : (, 2a :6 ); ( , ); ( : , :=). . , ,52

. . . .

.

, . 1, (FormLab2) TLab2Form TForm VCL : ( FormLab2.pas); ( FormLab2.dfm). FormLab2 (listLex), . , , : (PageControll) (SheetFile SheetLexems) ; SheetFil: (EditFile), (BtnFile), (BtnLoad); (Listldents); SheetLexems: (GridLex) ; (BtnExit). . 2.3 2.4.

53

. . . .

. 2.3. 2.

54

. . . .

2.

. 2.4.

, 1. ( listLex) MakeLexList, iErr. , , . , listLex GridLex, : ; ( ); . 2.4 2, 2.5 2. , 2, 2.

2 . :55

. . . .

(if, then, else, or, xor and); ( ); ; ; ( ). , , , . ( , ), ( :) . . , . , , .

56

. . . .

3 : , () -, .

57

. . . .

( ) [1, 3, 4, 7]. - () . . , , . : , , , , . (). , . . . -, . ( ) , . : ; ; , . . , , , . . . . , . , . . , . , , , . . , , , . , 58

. . . .

. 2. , . , -; , . , , -. .

- , , . : , , , () . . - - ( [1, 4, 3, 7]). , - - . , . - (), ( ). - , . , : , ( ) . - , , , . . , ( ). ^-. , , ( ). . - , . ( - ) - (-). -, -. 59

. . . .

, [14, 7]. -

-, , [13, 7]. - . . , - , , , -, , , - -. - . , , - . - [1, 3, 7]. , -, .

- -, , - . [1, 3, 7]. : ; -. : - A, , A , ( ); a, , ( ). - , A , (q,,A) . , - , . , , .60

. . . .

: . , , ().3 - : - , A , A , ( ); , a, , ( ). , , . : : ; , ( ); , , A ( ). - , -. , . - : . , , . , [3, 7]. n = ||, , . , , , . , [1, 3]. (n3 n2 -). -. . . , , . -.

3

, , .

61

. . . .

-. , -, . , , , -. , . : ( ); LL(1) LL(k) ( ); LR(0) LR(1) ( -); SLR(1) LALR(1) ( -); ( -). [14, 7].

. , , . , , , . , , . . , . , - [1, 2, 7]. , , , , 4, . , . . , , . , -, 62

. . . .

. , ( , , ). - , , . , ( , -, , ). , - . , -, , . - : - , -, , . , , , , . - , . , -, . , : . , ( ). - , -, . , . , , . : , -. , , . , , . [1, 7]. . , . . , , . - , 63

. . . .

. , . , , . , , , , . , . : 1. -. 2. -, , -, . 3. , , , . 4. , . 2 - . 2. 5. . 3, . 4 ( ), . 6. , ( ). . 3 5 , . 6. , . , , - , . . , , , - LR(1) LALR(1), , , , ( [1, 2, 7]). . , ( LL(1) ). , . . , 64

. . . .

- ( - [13, 7]).

- . . . . , , . - , . , . , . . , . , . =., . . - , . , , ( ) , . , , i.> j, j : Add2KeysToList(keyAdd,LEX_GT,AP_SIGN); ': AddVarKeyToList(LEX_GT,AP_SIGN); ', >, ,'), {else}( , >, >, , ,', ,', ,', ,', ,', ,', ', , , , ), {whil}( , , , , = , , , , , , , , , , , , , , , , , ', , , , ), {do} ( , >, >, , >, ,'>, ,', ,', =, >, >, >, >, >, >, >, ', >, >, ,'), {c} ( , >, >, ,', >, >, ,'>, ,', ,', ,'>, >, >, >, >, >, >, ', >, >, ,'), {:=} ( , >, >, ,', ,', , ,', ,', ', , ,', ,', ', , ,', ,', ', , ,'>, ,', , >, , >, ,', >, ,'>, ,', , >, , >, ,', >, ,'>, ,', , >, 0 then begin sPrev:= listCode[j-1]; sVal:= StrPas(PChar(listCode.Objects[j-1])); end else begin sPrev:= ; sVal:= ; end; end; procedure MakeOper1(const sOp,{ } sAddOp: string;{ } iOp: integer{ }); { } var sReg{ }: string; begin TakePrevAsm; { eax} { } sReg:= GetOpName(i,listTriad,iOp); if sReg then { , eax ,} begin { eax } { } sReg:= MakeMove(sReg,sPrev,sVal,flagOpt); if sReg then listCode.Add(sReg); end; { } listCode.Add(Format(#9 %s'#9'eax'#9 { %s }, [sOp,listTriad[i].MakeString(i)])); if sAddOp then { , } listCode.Add(Format(#9 %s'#9'eax,1,[sAddOp])); if listTriad[i].Info 0 then { begin { , } sReg:= GetRegName(listTriad[i].Info);234

. . . .

{ , eax } listCode.AddObject(Format(#9'mov'#9 %s,eax',[sReg]), TObject(PChar(sReg))); end; end; procedure MakeOper2(const sOp,{ } sAddOp: string{ }); { } var sReg1,sReg2{ }: string; begin TakePrevAsm; { eax} { } sReg1:= GetOpName(i,listTriad,1); sReg2:= GetOpName(i,listTriad,2); { , , eax } if (sReg1 = ) or (sReg1 = sVal) then listCode.Add(MakeOpCode(i,listTriad,sOp,sReg2, sPrev,sVal,flagOpt)) else { , eax } if (sReg2 = ) or (sReg2 = sVal) then begin listCode.Add(MakeOpCode(i,listTriad,sOp,sReg1, sPrev,sVal,flagOpt)); { , ( "-") } if sAddOp then listCode.Add(Format(#9 %s'#9'eax',[sAddOp])); end else { , : eax ; .} begin sReg1:= MakeMove(sReg1,sPrev,sVal,flagOpt); if sReg1 then listCode.Add(sReg1); listCode.Add(MakeOpCode(i,listTriad,sOp,sReg2, sPrev,sVal,flagOpt)); end; if listTriad[i].Info 0 then { begin { , } sReg1:= GetRegName(listTriad[i].Info); { , eax } listCode.AddObject(Format(#9'mov'#9 %s,eax',[sReg1]), TObject(PChar(sReg1))); end;235

. . . .

end; procedure MakeCompare(const sOp: string { }); { } var sReg1,sReg2{ }: string; begin TakePrevAsm; { eax} { } sReg1:= GetOpName(i,listTriad,1); sReg2:= GetOpName(i,listTriad,2); { , eax eax } if sReg1 = then listCode.Add(Format(#9'cmp'#9'eax,%s'#9 { %s }, [sReg2,listTriad[i].MakeString(i)])) else { , eax eax } if sReg2 = then listCode.Add(Format(#9'cmp'#9 %s,eax'#9 { %s }, [sReg1,listTriad[i].MakeString(i)])) else { , : eax ; eax . } begin sReg1:= MakeMove(sReg1,sPrev,sVal,flagOpt); if sReg1 then listCode.Add(sReg1); listCode.Add(Format(#9'cmp'#9'eax,%s'#9 { %s }, [sReg2,listTriad[i].MakeString(i)])); end; { eax 1 0 } listCode.Add(Format(#9'set%s'#9'al',[sOp])); listCode.Add(#9'and'#9'eax,1); { } if listTriad[i].Info 0 then { begin { , } sReg1:= GetRegName(listTriad[i].Info); { , eax } listCode.AddObject(Format(#9'mov'#9 %s,eax',[sReg1]), TObject(PChar(sReg1))); end; end; begin { } iCnt:= listTriad.Count-1; { } for i:=0 to iCnt do begin { } { , } if listTriad[i].IsLinked then236

. . . .

listCode.Add(Format(@M%d:,[i+1])); { } case listTriad[i].TrdType of { IF } TRD_IF: { , } begin {( )} if listTriad[i][1].OpType = OP_CONST then begin { , = 0,} if listTriad[i][1].ConstVal = 0 then listCode.Add(Format(#9'jmp'#9 @M%d'#9 { %s }, [listTriad[i][2].TriadNum+1, listTriad[i].MakeString(i)])); end { .} else { } begin { } sR:= GetOpName(i,listTriad,1); { , eax , } if sR = then { Z, eax , , IF , , } else { eax } listCode.Add(Format(#9'cmp'#9 %s,0,[sR])); { NOT Z } listCode.Add(Format(#9'jnz'#9 @F%d'#9 { %s }, [i,listTriad[i].MakeString(i)])); { } listCode.Add(Format(#9'jmp'#9 @M%d', [listTriad[i][2].TriadNum+1])); { } listCode.Add(Format(@F%d:,[i])); end; end; { } TRD_OR: MakeOper2('or', ); TRD_XOR: MakeOper2('xor', ); TRD_AND: MakeOper2('and', ); { NOT ( NOT(0)=FFFFFFFF, : AND eax,1 } TRD_NOT: MakeOper1('not','and',1); { } TRD_LT: MakeCompare('l'); TRD_GT: MakeCompare('g'); TRD_EQ: MakeCompare('e'); TRD_NEQ: MakeCompare('ne');237

. . . .

{ } TRD_ADD: MakeOper2('add', ); TRD_SUB: MakeOper2('sub','neg'); { } TRD_UMIN: MakeOper1('neg', ,2); TRD_ASSIGN: { } begin { eax} TakePrevAsm; sR:= GetOpName(i,listTriad,2); { } { , eax } if sR then begin { } sVal:= MakeMove(sR,sPrev,sVal,flagOpt); if sVal then listCode.Add(sVal); end; { eax } sVal:= listTriad[i][1].VarLink.VarName; if sVal = NAME_FUNCT then sVal:= NAME_RESULT; sVal:= Format(#9'mov'#9 %s,eax'#9 { %s }, [sVal,listTriad[i].MakeString(i)]); { , eax } listCode.AddObject(sVal,TObject(PChar(sR))); end; { } TRD_JMP: listCode.Add( Format(#9'jmp'#9 @M%d'#9 { %s }, [listTriad[i][2].TriadNum+1, listTriad[i].MakeString(i)])); { NOP } TRD_NOP: listCode.Add(Format(#9'nop'#9#9 { %s }, [listTriad[i].MakeString(i)])); end{case}; end{for}; Result:= listCode.Count; end; end.

238

. . . .

3.14. unit FormLab4; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Grids, ExtCtrls, LexElem, SyntSymb, Triads; type { : , , , } TErrType = (ERR_FILE,ERR_LEX,ERR_SYNT,ERR_TRIAD,ERR_NO); TCursovForm = class(TForm) { } PageControl1: TPageControl; SheetFile: TTabSheet; SheetLexems: TTabSheet; BtnExit: TButton; GroupText: TGroupBox; ListIdents: TMemo; EditFile: TEdit; BtnFile: TButton; BtnLoad: TButton; FileOpenDlg: TOpenDialog; GridLex: TStringGrid; SheetSynt: TTabSheet; TreeSynt: TTreeView; SheetTriad: TTabSheet; GroupTriadAll: TGroupBox; Splitter1: TSplitter; GroupTriadSame: TGroupBox; Splitter2: TSplitter; GroupTriadConst: TGroupBox; ListTriadAll: TMemo; ListTriadConst: TMemo; ListTriadSame: TMemo; CheckDel_C: TCheckBox; CheckDelSame: TCheckBox; SheetAsm: TTabSheet; ListAsm: TMemo; CheckAsm: TCheckBox; procedure BtnLoadClick(Sender: TObject); procedure BtnFileClick(Sender: TObject);239

. . . .

procedure EditFileChange(Sender: TObject); procedure BtnExitClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private listLex: TLexList; { } symbStack: TSymbStack; { } listTriad: TTriadList; { } { : , } sInpFile,sOutFile,sErrFile: string; { } procedure StartInfo(const sErrF: string); { } procedure ProcessParams( var flOptC,flOptSame,flOptAsm: Boolean); { } procedure InitLexGrid; { } procedure MakeTree(nodeTree: TTreeNode; symbSynt: TSymbol); { } procedure ErrInfo(const sErrF,sErr: string; iPos,iLen: integer); { } function CompRun(const sInF,sOutF,sErrF: string; var symbRes: TSymbol; flTrd,flDelC,flDelSame,flOptC, flOptSame,flOptAsm: Boolean): TErrType; end; var CursovForm: TCursovForm; implementation {$R *.DFM} uses FncTree,LexType,LexAuto,TrdType,TrdMake,TrdAsm,TrdOpt; procedure TCursovForm.InitLexGrid; { } begin with GridLex do begin RowCount:= 2; Cells[0,0]:= /'; Cells[1,0]:= ''; Cells[2,0]:= ''; Cells[0,1]:= ; Cells[1,1]:= ; Cells[2,1]:= ; end; end; procedure TCursovForm.StartInfo( const sErrF: string{ }); { } var i,iCnt: integer;{ } sT: string;{ } begin240

. . . .

sErrFile:= sErrF; { } { } ErrInfo(sErrFile, Format( %s ,[DateTimeToStr(Now)]),0,0); iCnt:= ParamCount; { } sT:= ParamStr(0); { } { } for i:=1 to iCnt do sT:= sT + + ParamStr(i); { } ErrInfo(sErrFile,sT,0,0); end; procedure TCursovForm.ProcessParams( var flOptC,flOptSame,flOptAsm: Boolean{}); { } var i,iCnt,iLen: integer; { } sTmp: string; { } { } listErr: TStringList; begin { } flOptC:= True; flOptSame:= True; flOptAsm:= True; { } listErr:= TStringList.Create; try { } iCnt:= ParamCount; for i:=2 to iCnt do begin { } sTmp:= ParamStr(i); { } iLen:= Length(sTmp); { } { - } if (iLen < 3) or (sTmp[1] ) then { } listErr.Add(Format(' %d: %s! [i,sTmp])) else { ( ) } case sTmp[2] of { } 'a','A': flOptAsm:= (sTmp[3] = 1 ); { } 'c','C': flOptC:= (sTmp[3] = 1 ); { } 's','S': flOptSame:= (sTmp[3] = 1 ); { } 'o','O': sOutFile:= System.Copy(sTmp,3,iLen-2); { } 'e','E': StartInfo(System.Copy(sTmp,3,iLen-2)); else { }241

. . . .

{ } listErr.Add(Format(' %d: %s! [i,sTmp])); end{case}; end{for}; { , } if sOutFile = then sOutFile:= ChangeFileExt(sInpFile, asm'); if sErrFile = then StartInfo(ChangeFileExt(sInpFile, err')); iCnt:= listErr.Count-1; { } { } for i:=0 to iCnt do ErrInfo(sErrFile,listErr[i],0,0) finally listErr.Free; { } end{try}; end; procedure TCursovForm.FormCreate(Sender: TObject); var flOptC,flOptSame,flOptAsm: Boolean; symbRes: TSymbol; iErr: TErrType; begin symbRes:= nil; sOutFile:= ; sErrFile:= ; { , , } InitTreeVar; listLex:= TLexList.Create; symbStack:= TSymbStack.Create; listTriad:= TTriadList.Create; { , } if ParamCount > 0 then begin { } sInpFile:= ParamStr(1); { } ProcessParams(flOptC,flOptSame,flOptAsm); iErr:= CompRun({ } sInpFile,sOutFile,sErrFile{ }, symbRes{ }, False{ }, flOptC{ "C"}, flOptSame{ SAME}, flOptC{ }, flOptSame{ }, flOptAsm{ }); { , } if iErr ERR_FILE then Self.Close; end; end;242

. . . .

procedure TCursovForm.FormClose(Sender: TObject; var Action: TCloseAction); { , , } begin listTriad.Free; symbStack.Free; listLex.Free; ClearTreeVar; Application.Terminate; end; procedure TCursovForm.EditFileChange(Sender: TObject); begin { , } BtnLoad.Enabled:= (EditFile.Text ); end; procedure TCursovForm.BtnFileClick(Sender: TObject); begin { } if FileOpenDlg.Execute then begin EditFile.Text:= FileOpenDlg.FileName; BtnLoad.Enabled:= (EditFile.Text ); end; end; procedure TCursovForm.ErrInfo(const sErrF,sErr: string; iPos,iLen: integer); { } var fileErr: TextFile; { } begin { } if sErrF then try { } AssignFile(fileErr,sErrF); if FileExists(sErrF) then Append(fileErr) else Rewrite(fileErr); writeln(fileErr,sErr); CloseFile(fileErr); { } except { , } MessageDlg(Format(' %s! #13#10 + ' : %s![sErrF,sErr]), mtError,[mbOk],0); end { , } else { } begin { } ListIdents.SelStart:= iPos; ListIdents.SelLength:= iLen; MessageDlg(sErr,mtWarning,[mbOk],0);{ } ListIdents.SetFocus; { } end; end; function TCursovForm.CompRun({ } const sInF,{ } sOutF,{ }243

. . . .

sErrF{ }:string; var symbRes: TSymbol;{ } flTrd,{ } flDelC,{ "C"} flDelSame,{ SAME} flOptC,{ } flOptSame,{ } flOptAsm{ } : Boolean): TErrType; var i,iCnt,iErr: integer; { } lexTmp: TLexem; { . } sVars,sAdd: string; { } asmList: TStringList; { } begin{ , } listLex.Clear; symbStack.Clear; listTriad.Clear; try { } ListIdents.Lines.LoadFromFile(sInF); except { } Result:= ERR_FILE; MessageDlg(' !mtError,[mbOk],0); Exit; { } end; { } iErr:= MakeLexList(ListIdents.Lines,listLex); if iErr0 then { } begin { } ErrInfo(sErrF, Format(' %s %d! [listLex[0].LexInfoStr,iErr]), listLex[0].PosAll,listLex[0].PosNum); Result:= ERR_LEX; { } end else { } begin { } with ListIdents do listLex.Add(TLexem.CreateInfo(' ', Length(Text), Lines.Count-1,0)); { } symbRes:= BuildSyntList(listLex,symbStack); { , , , } if symbRes.SymbType = SYMB_LEX then begin { } ErrInfo(sErrF, Format(' %d . %d! [symbRes.Lexem.StrNum+1,symbRes.Lexem.PosNum]), symbRes.Lexem.PosAll,0); symbRes.Free; { } symbRes:= nil;244

. . . .

Result:= ERR_SYNT; { } end else { } begin { } lexTmp:= MakeTriadList(symbRes,listTriad); { , , } if lexTmp nil then begin { } ErrInfo(sErrF, Format(' %d . %d! [lexTmp.StrNum+1,lexTmp.PosNum]), lexTmp.PosAll,0); Result:= ERR_TRIAD; { } end else { , , } begin Result:= ERR_NO; { } { , } if flTrd then listTriad.WriteToList(ListTriadAll.Lines); if flOptC then { , } begin { } OptimizeConst(listTriad); { , C } if flDelC then DelTriadTypes(listTriad,TRD_CONST); end; { ,} if flTrd then { } listTriad.WriteToList(ListTriadConst.Lines); if flOptSame then { , begin{ } OptimizeSame(listTriad); { , SAME } if flDelSame then DelTriadTypes(listTriad,TRD_SAME); end; { ,} if flTrd then { } listTriad.WriteToList(ListTriadSame.Lines); { } iCnt:= MakeRegisters(listTriad); { } asmList:= TStringList.Create; try with asmList do begin Clear; { } { }245

. . . .

Add(Format('program %s;,[NAME_PROG])); { } sVars:= IdentList(, ,NAME_INPVAR,NAME_FUNCT); if sVars then begin{ ,} Add( ); { } Add('var'); { } Add(Format(%s: %s;,[sVars,NAME_TYPE])); end; Add( ); { } Add(Format('function %0:s(%1:s: %2:s): %2:s; + stdcall;, [NAME_FUNCT,NAME_INPVAR,NAME_TYPE])); if iCnt > 0 then { } begin { } Add('var'); { ,} sVars:= ; { .} for i:=0 to iCnt do begin sAdd:= Format(%s%d',[TEMP_VARNAME,i]); if sVars = then sVars:= sAdd else sVars:= sVars +, + sAdd; end; Add(Format(%s: %s;,[sVars,NAME_TYPE])); end; Add('begin'); { } Add(asm'); { , } Add(#9'pushad'#9#9 { ,}); MakeAsmCode(listTriad,asmList,flOptAsm); Add(#9'popad'#9#9 { ,}); Add(end;); Add('end;); Add( ); { } Add(Format('var %s: %s;, [NAME_INPVAR,NAME_TYPE])); Add( ); Add('begin'); { } Add(Format(readln(%s);,[NAME_INPVAR])); Add(Format(writeln(%s(%s));, [NAME_FUNCT,NAME_INPVAR])); Add(readln;); Add('end.); end{with}; { , } if flTrd then { } ListAsm.Lines.AddStrings(asmList); if sOutF then { . ,} try { } asmList.SaveToFile(sOutF);246

. . . .

except Result:= ERR_FILE; end; finally asmList.Free; { } end{try}; { } end; end; end; end; procedure TCursovForm.BtnLoadClick(Sender: TObject); { } var i,iCnt: integer; { } iRes: TErrType; { } symbRes: TSymbol; { } nodeTree: TTreeNode; { } begin symbRes:= nil; { } InitLexGrid; { } TreeSynt.Items.Clear; { } iRes:= CompRun({ } EditFile.Text, , ,{ } symbRes{ }, True{ }, CheckDel_C.Checked { "C"}, CheckDelSame.Checked { SAME}, True { }, True { }, CheckAsm.Checked { }); if iRes > ERR_LEX then { ,} begin { } GridLex.RowCount:= listLex.Count+1; { } iCnt:= listLex.Count-1; for i:=0 to iCnt do begin { } { } GridLex.Cells[0,i+1]:= IntToStr(i+1); { } GridLex.Cells[1,i+1]:= LexTypeName(listLex[i].LexType); { } GridLex.Cells[2,i+1]:= listLex[i].LexInfoStr; end; end; if (iRes > ERR_SYNT) and (symbRes nil) then { ,} begin { } { } nodeTree:= TreeSynt.Items.Add(nil,symbRes.SymbolStr); MakeTree(nodeTree,symbRes); { } nodeTree.Expand(True); { }247

. . . .

{ } TreeSynt.Selected:= nodeTree; end; if iRes > ERR_TRIAD then { } begin { , } MessageDlg(' ! mtInformation,[mbOk],0); PageControl1.ActivePageIndex:= 4; end; end; procedure TCursovForm.MakeTree( { } nodeTree: TTreeNode; { } symbSynt: TSymbol { , }); var i,iCnt: integer; { } nodeTmp: TTreeNode; { } begin { } iCnt:= symbSynt.Count-1; for i:=0 to iCnt do begin { } { } nodeTmp:= TreeSynt.Items.AddChild(nodeTree, symbSynt[i].SymbolStr); { , } if symbSynt[i].SymbType = SYMB_SYNT then MakeTree(nodeTmp,symbSynt[i]); end; end; procedure TCursovForm.BtnExitClick(Sender: TObject); { } begin Self.Close; end; end.

, - , FormLab4.dfm CURSOV.

248

. . . .

4 1. 4.1. prog if ((InpVar > 31) or InpVar (InpVar, 31) } setg al249

. . . .

and eax,1 mov ebx,eax mov eax,InpVar cmp eax,0 { 2: < (InpVar, 0) } setl al and eax,1 or eax,ebx { 3: or (^1, ^2) } jnz @F3 { 4: if (^3, ^7) } jmp @M7 @F3: xor eax,eax mov Result,eax { 5::= (CompileTest, 0) } jmp @M31 { 6: jmp (1, ^31) } @M7: mov eax,InpVar cmp eax,0 { 7: = (InpVar, 0) } sete al and eax,1 jnz @F7 { 8: if (^7, ^11) } jmp @M11 @F7: xor eax,eax inc eax mov Result,eax { 9::= (CompileTest, 1) } jmp @M31 { 10: jmp (1, ^31) } @M11: mov eax,InpVar mov i,eax { 11::= (i, InpVar) } xor eax,eax inc eax mov Fact,eax { 12::= (Fact, 1) } @M13: mov eax,i cmp eax,1 { 13: (i, 1) } setne al and eax,1 jnz @F13 { 14: if (^13, ^30) } jmp @M30 @F13: mov eax,i dec eax { 15: (i, 1) } mov j,eax { 16::= (j, ^15) } mov eax,Fact mov Sum,eax { 17::= (Sum, Fact) } @M18: mov eax,j cmp eax,0 { 18: = (j, 0) } sete al and eax,1250

. . . .

not eax { 19: not (^18, 0) } and eax,1 jnz @F19 { 20: if (^19, ^26) } jmp @M26 @F19: mov eax,Sum add eax,Fact { 21: + (Sum, Fact) } mov Sum,eax { 22::= (Sum, ^21) } mov eax,j dec eax { 23: (j, 1) } mov j,eax { 24::= (j, ^23) } jmp @M18 { 25: jmp (1, ^18) } @M26: mov eax,Sum mov Fact,eax { 26::= (Fact, Sum) } mov eax,i dec eax { 27: (i, 1) } mov i,eax { 28::= (i, ^27) } jmp @M13 { 29: jmp (1, ^13) } @M30: mov eax,Fact mov Result,eax { 30::= (CompileTest, Fact) } @M31: nop { 31: nop (0, 0) } popad { } end; end; var InpVar: integer; begin readln(InpVar); writeln(CompileTest(InpVar)); readln; end.

251

. . . .

2. 4.3. prog D:= 0; B:= 1; C:= 1; A:= C + InpVar; D:= C+B+234; C:= A + B + C; D:= ((C) +(A+B)) (InpVar + 1) + (A+B); E:= (D 22) (A + B); CompileTest:= 0; if (a