C 语言 编程漫谈


(²µŠöÓ¿ò©gdD§ØíU)(²9±e3S?ÛSN" <Œò{1˜^/¥u<¬ÚI´ó<?+!±óà醏Ä:!< ¬¬Ì;¬ÌÂI["0?U/¥I´Nú¬|¤§—åuæú¬Ä |§ú¬)†uÐJøûÐú‚¸{£I["¥INú¬Ä|˜ Ʋ"¥IØI"0 —— ú²†¬Ú34[̐áu]uJ¦<‚ C ŠŠŠ óóó ??? §§§ ûûû !!!(V0.8.0) ¶ïu£ÃÅ: 158-3818-9433¤2012.01.03 ©´/û!0§²ƒ!§¿Ø´XÚz§"´©ý­¢y§ ÀÕA§Œw‰´é˜„ákÃÖ¿" 2012.01.03 v0.8.0 O\ 1Ô! LR(0) Š{©Û§Ú1l!SLR Š{©Û"©¥ ÃØ´gŽSN„´Lˆª§M#ƒ?¹õ"ƒ&Ööw ƒ gC¬‰Ñä"·Òؘ˜Þ " aŒ[|±"©ŠöÆ£k§©¥†¦ƒ?3¤J§HŒ[1 µ" Contents 1 WHello.c 3 1.1 #include................................ 4 1.2 int Ú unsignedint .......................... 6 1.3 char§char[] Ú char*......................... 12 1.4 stdcall Ú cdecl .......................... 17 1.5 extern Ú static ............................ 23 1.6 ¬z?§ .............................. 26 1.7 ó .................................. 28 1.8 C1†­½  ............................. 33 1.9 declspec(dllimport) ÚÄó .................. 34 1.10 Þ©‡ ................................. 36 1.11 ¥ ................................... 39 1.12 éĬ ............................... 40 1 2 ^^^rrrêêêâââaaa... 43 2.1 enum.................................. 43 2.2 struct ................................. 44 2.3 sizeof() Ú offsetof().......................... 47 2.4 (i@†™¤ (incomplete) a................. 48 2.5 Š{ä†Lˆª¦Š ......................... 49 2.6 union ................................. 49 2.7 typedef ................................ 50 3 C ŠŠŠóóó OO???§§§ 51 3.1 xout .................................. 51 3.2 zout .................................. 53 3.3 g· (this) †¼ê­1 (overload) ............... 54 3.4 new Ú delete ............................. 55 3.5 µC.................................. 56 3.6 ·é?†Äé?......................... 59 3.7 ê|¯K†(i@¯K...................... 60 3.8 U?µCY............................ 60 3.9  (interface) ............................ 61 3.10 a†¢~ .......................... 64 3.11 ¡•§SO......................... 65 3.12 U«.................................. 66 3.13 õ .................................. 68 4 gggÄÄÄÅÅņ††///ªªªŠŠŠóóó 69 4.1 ã(Å................................. 69 4.2 †^ C?1ã(Å?§ ...................... 73 4.3 ã(ÅSÜG† C ŠóŠéI\.............. 76 4.4 {üã(ņŒãXÚ...................... 77 4.5 /ªŠó†gÄÅ©a ...................... 79 5 ggg½½½ÂŠŠŠóóóYYY~~~µµµOOOŽŽŽììì 80 5.1 ^ flex Ú bison 5¢y ........................ 80 5.2 ^ re2c Ú yacc 5¢y ........................ 82 2 6 ccc{{{©©©ÛÛÛ 92 6.1 ˜‡Ãó?c{©Û~f ................. 92 6.2 l5Lˆª NDFA........................ 93 6.3 NDFA (½z ............................ 94 6.4 DFA z ............................. 95 6.5 l DFA  C Šó§S..................... 96 7 LR(0) ŠŠŠ{{{©©©ÛÛÛ 98 7.1 ~{$Ž©{............................ 98 7.2 ÿ2©{†Ñ\(åÎ........................102 7.3 mí†l†•mÖ........................102 7.4 ኆéY..............................103 7.5 ҆G ...............................103 7.6 ‘8!‘88 .............................105 7.7 LR(0) ©ÛL.............................108 8 SLR ŠŠŠ{{{©©©ÛÛÛ 110 8.1 \{Lˆª©{..........................110 8.2 £O\{Lˆª¹cM DFA.................... 114 8.3 iĪ(Î8ښª(΋‘ª(Î8 ............116 8.4 SLR ©ÛL..............................117 ©9öŠXڏ WindowsXP§mu‚¸± OpenWatcom Ì§k ž¬† Cygwin þ gcc ‰ '" 1 WHello.c Äk·‚5wù˜‡§S whello1.c µ // wcl386 -bcl=nt_win -wx -"option start=start" whello1.c int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); void __stdcall ExitProcess(unsigned int uExitCode); #pragma off (check_stack); #pragma aux start "*" aborts; 3 void start() { MessageBoxA(0, "Hello", "App", 1); ExitProcess(0); } § Cygwin/gcc ‡´ù whello2.c µ // gcc -Wall -nostdlib -owhello2 -estart whello2.c -lkernel32 -luser32 int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); void __stdcall __attribute__((noreturn)) ExitProcess(unsigned int uExitCode); __attribute__((noreturn)) void start() asm("start"); void start() { MessageBoxA(0, "Hello", "App", 1); ExitProcess(0); } kw(Ò¯3µO<ù C Šó§Ñ´lù hello.c ùåµ // wcl386 -bcl=nt -wx hello.c #include int main() { printf("Hello, world!\n"); return 0; } \Ÿo†¯ØÓQº Ϗ§stdio.h ´Ÿoºmain ´Ÿoºprintf ´Ÿoº1³`ÒU` ²xíº<µfJ§ú„¢"Æ?§§ØU1fO<`§‡ŠgÄ Ã‰¢§¦ŒUõ/yˆ«ŒUy–§ü؈«ŒU¦:" y3Òm©j§yŸo´ #include" 1.1 #include rþã whello1.c ©¤n‡©‡§˜‡´ whello1a.c µ // wcl386 -bcl=nt_win -wx -"option start=start" whello1.c int __stdcall MessageBoxA(unsigned int hWnd, char ˜‡´ whello1b.c µ 4 *lpText, char *lpCaptioin, unsigned int uType); void __stdcall ExitProcess(unsigned int uExitCode); #pragma off (check_stack); #pragma aux start "*" aborts; void start() { MessageBoxA(0, "Hello", ,˜‡´ whello1c.c µ #include "whello1a.c" #include "whello1b.c" "App", 1); ExitProcess(0); } ,‰1 wcl386 -bcl=nt_win -wx -"option start=start" whello1c.c · -§Ò¬)¤˜‡ whello1c.exe ©‡§Ú5 whello1.exe ˜" ùš~)Ä/ü« #include Š^µÒ´r½@‡©‡SN< L5§©c ˜þ" ¢Sþ #include ´˜«ý?n-"ÃØ´ OpenWatcom§„´ gcc§Ñ Jø ÑÑý?n(Jå»"'X§‰1 wcl386 -p whello1c.c§ò XeÑѵ int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); void __stdcall ExitProcess(unsigned int uExitCode); #pragma off (check_stack); #pragma aux start "*" aborts; void start() { MessageBoxA(0, "Hello", "App", 1); ExitProcess(0); } ‰1 gcc -E whello1c.c§ÑÑ(Jµ # 1 "whello1c.c" # 1 "" 5 # 1 "" # 1 "whello1c.c" # 1 "whello1a.c" 1 int __attribute__((__stdcall__)) MessageBoxA(unsigned int hWnd, char # 2 "whello1c.c" 2 # 1 "whello1b.c" 1 *lpText, char *lpCaptioin, unsigned int uType); void __attribute__((__stdcall__)) ExitProcess(unsigned int uExitCode); #pragma off (check_stack); #pragma aux start "*" aborts; void start() { MessageBoxA(0, "Hello", # 3 "whello1c.c" 2 "App", 1); ExitProcess(0); } Ù¥ # 3 "whello1c.c" 2 ´^uNÁ" ú hello.c {üíºÁÁ wcl386 -p hello.c Ú gcc -E hello.c §Ñ Ñ(JéÐÆö5`§ýé´>8¯%BœkXUrùÀÜù²xQº e5§·‚!˜!/êâ0" 1.2 int ÚÚÚ unsigned int y3¢^ˆ«êiEâ§ÄþÑ´Äu/0ü§'X>Ø kÚç>6ÏÚä§^4ڇ§"XJ·‚^ü˜‡G L« 0§,˜‡GL« 1§@oTüҌ±Lˆ½ö;˜‡'A(bit) &Eþ"ëYl‡'A¡˜‡i!(byte)§ÙSNŒ±^ü ›8?› êi5L«"'X§`˜‡i!SN´ 0xA3§Ò´Ti!Sl‡'A g 10100011" ‰OŽÅS?/Œ§Ï~°(i!" \óêâü̇´ CPU"§SÜk˜ /Mì0"~?1 öŠ´rêâÖ\,‡M쥧†S¥,‡/Œêâ?1\!~!¦! ØŽâ$Ž§½ö?1/U †0!/U ½0!/U É½0!±9/U  š0Ü6$Ž"M쌴 CPU $ŽUå­‡I"@Ï´ 16  §y3ÊH´ 32  §Ð CPU ®²´ 64   "ƒA§/ê0§= int§.´õŒ§Òk l 16  § 32  §2 64  ˜‡ÅÚuÐL 6 §" int ´ 16  žÿ§·‚` 32  /ê0´ long int¶ int ´ 32  žÿ§·‚` 16  /ê0´ short int§ 64  /ê0´ long long int" /ê0Ø Œ§„kKÒ"·‚5w˜eêÚKê´NoL «" // wcc386 -bc=nt -wx int1.c int one = 1; int two = 2; int three = 3; int four = 4; int minusone = -1; int minustwo = -2; int minusthree = -3; int minusfour = -4; ?Ȥƒ§)¤˜‡ int1.obj ©‡§‰1 wdis -l int1 ·-§)¤˜‡ int1.lst ©‡§ÙSNXeµ Module: D:\cygwin\home\U2\wd\cprog\int1.c GROUP: ’DGROUP’ CONST,CONST2,_DATA Segment: _TEXT BYTE USE32 00000000 bytes Routine Size: 0 bytes, Routine Base: _TEXT + 0000 No disassembly errors Segment: CONST DWORD USE32 00000000 bytes Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000020 bytes 0000 _one: 0000 01 00 00 00 .... 0004 _two: 0004 02 00 00 00 .... 0008 _three: 0008 03 00 00 00 .... 000C _four: 000C 04 00 00 00 .... 0010 _minusone: 0010 FF FF FF FF .... 0014 _minustwo: 0014 FE FF FF FF .... 0018 _minusthree: 0018 FD FF FF FF .... 001C _minusfour: 001C FC FF FF FF .... 7 ù´ OpenWatcom )®?ŠóL"ƒA gcc ·-´ gcc -S int1.c" ´ gcc ¦^®?Šó† Intel úikŒ O§ISÐÆöé>"· ‚ÒØ}@‡Úk " lþãL¥Œ±w§int1.c ¥l‡ê.Cþ§N˜‡S «§z‡CþÓo‡i!§Ù¥Cþ one L«ù‡S«å© ˜§Ù ¦CþU^S ü" ùpk‡š~ky–"one Š´ 1§= 0x00000001§´UìS /Œ^S§§%´ 0x01000000§o‡i!ü^S´‡"kü^S ´OŽÅXÚ"ù´ØÓúiÀJ ØÓEⴂE¤"ù«/‡0 L«ª¡ little endian§ /0L«ª¡ big endian" ·‚„w§-2 L« 0xFFFFFFFE§XJ§\ 2§Òu 0x100000000§ ´@‡ 1 ‡Ñ ‰Œ§¡/ÄÑ0"U  32  ;˜m3e5§ k@˜G 0"ùÐLˆ -2 \ 2 u 0 Žâ'X" Œ´§J 0xFFFFFFFE Ø´˜‡/~0êíº,§Š w,éŒéŒ"XJ^§5L«-2§@où‡êNo§† -2 No« ©º·3S¥wëYo‡i!´ 0xFE,0xFF,0xFF,0xFF žÿ§·N où´ -2§„´@‡éŒêQº £‰´µ\Žr§¤ -2§ÒŒ±r§¤ -2¶Žr§¤ê§ÒŒ ±r§¤ê"\„Œ±r§¤o‡iΧ½ör§¤,‡ã”¥ ˜1”ƒ"{󃧧/¿Â0´d\5Dƒ§ Ø´§Òäk" Ÿo¿gºwe¡ù‡§S int2.c µ // wcc386 -bc=nt -wx -d2 int2.c int four = 4; int minusthree = -3; int r; unsigned int ufour = 4; unsigned int uminusthree = -3; unsigned int ur; void dummy() { r = four + minusthree; r = four - minusthree; r = four * minusthree; r = four / minusthree; ur = ufour + uminusthree; ur = ufour - uminusthree; ur = ufour * uminusthree; ur = ufour / uminusthree; } 8 ?È)¤ int2.obj§2‰1 wdis -l -s int2§)¤Xe int2.lst µ Module: D:\cygwin\home\U2\wd\cprog\int2.c GROUP: ’DGROUP’ CONST,CONST2,_DATA,_BSS Segment: _TEXT BYTE USE32 000000A6 bytes // wcc386 -bc=nt -wx -d2 int2.c int four = 4; int minusthree = -3; int r; unsigned int ufour = 4; unsigned int uminusthree = -3; unsigned int ur; void dummy() 0000 dummy_: 0000 68 20 00 00 00 push 0x00000020 0005 E8 00 00 00 00 call __CHK 000A 53 push ebx 000B 51 push ecx 000C 52 push edx 000D 56 push esi 000E 57 push edi 000F 55 push ebp 0010 89 E5 mov ebp,esp 0012 81 EC 04 00 00 00 sub esp,0x00000004 { r = four + minusthree; 0018 L$1: 0018 A1 00 00 00 00 mov eax,dword ptr _four 001D 03 05 00 00 00 00 add eax,dword ptr _minusthree 0023 A3 00 00 00 00 mov dword ptr _r,eax r = four - minusthree; 0028 A1 00 00 00 00 mov eax,dword ptr _four 002D 2B 05 00 00 00 00 sub eax,dword ptr _minusthree 0033 A3 00 00 00 00 mov dword ptr _r,eax r = four * minusthree; 0038 A1 00 00 00 00 mov eax,dword ptr _four 003D 0F AF 05 00 00 00 00 imul eax,dword ptr _minusthree 0044 A3 00 00 00 00 mov dword ptr _r,eax r = four / minusthree; 0049 A1 00 00 00 00 mov eax,dword ptr _four 004E 99 cdq 004F F7 3D 00 00 00 00 idiv dword ptr _minusthree 9 0055 A3 00 00 00 00 mov dword ptr _r,eax ur = ufour + uminusthree; 005A A1 00 00 00 00 mov eax,dword ptr _ufour 005F 03 05 00 00 00 00 add eax,dword ptr _uminusthree 0065 A3 00 00 00 00 mov dword ptr _ur,eax ur = ufour - uminusthree; 006A A1 00 00 00 00 mov eax,dword ptr _ufour 006F 2B 05 00 00 00 00 sub eax,dword ptr _uminusthree 0075 A3 00 00 00 00 mov dword ptr _ur,eax ur = ufour * uminusthree; 007A A1 00 00 00 00 mov eax,dword ptr _ufour 007F 0F AF 05 00 00 00 00 imul eax,dword ptr _uminusthree 0086 A3 00 00 00 00 mov dword ptr _ur,eax ur = ufour / uminusthree; 008B A1 00 00 00 00 mov eax,dword ptr _ufour 0090 31 D2 xor edx,edx 0092 F7 35 00 00 00 00 div dword ptr _uminusthree 0098 A3 00 00 00 00 mov dword ptr _ur,eax } 009D L$2: 009D 89 EC mov esp,ebp 009F 5D pop ebp 00A0 5F pop edi 00A1 5E pop esi 00A2 5A pop edx 00A3 59 pop ecx 00A4 5B pop ebx 00A5 C3 ret 00A6 L$3: Routine Size: 166 bytes, Routine Base: _TEXT + 0000 No disassembly errors Segment: CONST DWORD USE32 00000000 bytes Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000010 bytes 0000 _four: 0000 04 00 00 00 .... 0004 _minusthree: 0004 FD FF FF FF .... 10 0008 _ufour: 0008 04 00 00 00 .... 000C _uminusthree: 000C FD FF FF FF .... Segment: _BSS DWORD USE32 00000008 bytes 0000 _ur: 0004 _r: BSS Size: 8 bytes ¡„k NÁ&E6žíØØ+"lù‡L©‡¥Œ±wѧkÎÒê (signed int)ÚÃÎÒê (unsigned int)§Š˜G?›“觿vk ¢ŸØÓ"duŽâþϧüö3\{!~{Ú¦{þvk¢ŸØ Ó"´3Ø{þ§üö?nª§Ò´¤AÀJ®?Šó-§´Ø Ó" Òþã~f5`§ a=4,b=-3 ´kÎÒê§ua=4,ub=0x100000000-3 ´ÃÎÒê"@o§du ub ¥ 1 ´Äѧ¤± ub † b 3 4 i!S¿Ã «O" \{!~{Ú¦{$Ž ua + ub = 4+0x100000000 − 3=0x100000000+ (a + b) ua − ub = 4 − 0x100000000+ 3 = −0x100000000+ (a − b) ua ∗ ub = 4 ∗ (0x100000000 − 3)=0x400000000+ (a ∗ b) rÄÑܩѧ3o‡i!SN§w„ü«êâa.ùn«$Ž Ñ´˜—" ´3Ø{þ§ü«êâa.ÒØ´oU˜— "'X a=-4,b=-3§ ua=0x100000000-4,ub=0x100000000-3§Küö®?Šó-´µ r = four / minusthree; 0049 A1 00 00 00 00 mov eax,dword ptr _four ;eax=-4 004E 99 cdq ;edx=-1 004F F7 3D 00 00 00 00 idiv dword ptr _minusthree ;(-4)/(-3) 0055 A3 00 00 00 00 mov dword ptr _r,eax ;r=1 ur = ufour / uminusthree; 008B A1 00 00 00 00 mov eax,dword ptr _ufour ;eax=0x100000000-4 0090 31 D2 xor edx,edx ;edx=0 0092 F7 35 00 00 00 00 div dword ptr _uminusthree ;(0x100000000-4)/(0x100000000-3) 0098 A3 00 00 00 00 mov dword ptr _ur,eax ;r=0 XJ\Ø&{§·‚Œ±‡§Sy˜e int3.c µ // wcl386 -wx int3.c 11 #include int mfour=-4, mthree=-3; unsigned int umfour=-4, umthree=-3; int main() { printf("signed (-4)/(-3)=%d, unsigned (-4)/(-3)=%d.\n", mfour/mthree, umfour/umthree); return 0; } Ñѵsigned (-4)/(-3)=1, unsigned (-4)/(-3)=0." 3®?Šó§Sž§\ÏLÀJØÓÅì-§5Ny\rê⤠´Ÿoa.¶3 C Šó§Sž§\rê⤟oa.§Ò†½ù‡ a.‰§§,?È쬊â\½§gÄÀJÜ·Åì-?nTê â"ù,4Œ/ü$ §S NÄrÝ" \Œ±6ž5/UCêâa.§¡a.=†"'Xù‡ int4.c µ // wcl386 -wx int4.c #include int mfour=-4, mthree=-3; int main() { printf("signed (-4)/(-3)=%d, unsigned (-4)/(-3)=%d.\n", mfour/mthree, ((unsigned int)mfour)/((unsigned int)mthree)); return 0; } ÑÑ(J† int3.c ˜" ‡5¿§Ø´?¿ü«a.ь±ƒp=†"=Bl˜«a.,˜« a.Œ±=†§äNNo=†„kéõ[!Š&?"ù¡5½¡a .=†5K"[œ¹ž© " 1.3 char§§§char[] ÚÚÚ char* ·‚®²õg^iÎG §2‡§S8¥w˜e ch1.c µ // wcc386 -wx ch1.c char ai=’a’, bi=’b’; char ca[2]={’c’,’d’}; char cv[]="ef"; char *cp="gh"; char *str="\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\y\z"; ?È)¤ ch1.obj§2‰1 wdis -l ch1§ ch1.lst Xeµ Module: D:\cygwin\home\U2\wd\cprog\ch1.c 12 GROUP: ’DGROUP’ CONST,CONST2,_DATA Segment: _TEXT BYTE USE32 00000000 bytes Routine Size: 0 bytes, Routine Base: _TEXT + 0000 No disassembly errors Segment: CONST DWORD USE32 0000001D bytes 0000 L$1: 0000 67 68 00 gh. 0003 L$2: 0003 07 08 63 64 65 0C 67 68 69 6A 6B 6C 6D 0A 6F 70 ..cde.ghijklm.op 0013 71 0D 73 09 75 0B 77 79 7A 00 q.s.u.wyz. Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 0000000F bytes 0000 _ai: 0000 61 a 0001 _bi: 0001 62 b 0002 _ca: 0002 63 64 cd 0004 _cv: 0004 65 66 00 ef. 0007 _cp: 0007 00 00 00 00 DD offset L$1 000B _str: 000B 03 00 00 00 DD offset L$2 Œ±w§iÎ’a’ Ó˜‡i!§ÙSN´ 0x61§riÎNi!ù‡ ?èY¡ ASCII è" ca ´‡½iÎê|§½ kü‡ƒ§?Èìҏù‡ê|©ü‡ ƒ;˜m" cv ´‡™½Ýê|§?ÈìÙЩzSN©˜m"ùã˜m å©/ŒÒ´ù‡ê|/Š0"cv ŠÒ´¬ ch1 ¥êâã (Segment DATA) ¥/Œ 0x0004  ˜"´§?Èì¿Øù‡Š©;˜ m"ù‡Š´3?ÈÏm3u?ÈìÎÒL¥" 3§S¥ cp=cv k¿Â§?ÈìlÎÒL¥Ñ cv Š§¿)¤˜ã /rù‡Š; cp ¥0®?Šó“è"´ cv=cp vk¿Â§?Èì Ã{)¤/r cp Š; cv ¥0®?Šó“è§Ï cv vk ©˜m§ŠØ3/;ù‡˜m¥0¯K" XJ˜‡LˆªŒ±¤DŠŠé†>§K¡TLˆªk†Š (lvalue)¶ XJŒ±¤m>§K¡ÙkmŠ (rvalue)"cv ŠLˆª§k rvalue§´ 13 vk lvalue" cp ´•i΍ char *§§/Š0ÚiÎê|˜§´,‡i Î;/Œ"´?È쏍Š© ;˜m§ù‡˜m/ŒÒ´ T lvalue"cp  lvalue Ò´¬ ch1 ¥êâã (Segment DATA) ¥/ Œ 0x0007  ˜" ú„¢"wù‡§S cb2.c µ // wcc386 -d2 -wx ch2.c char cv[]="ef"; // cv[3], not cv[2] char *cp="gh", **pp, (*pa)[3], (q[])[3], r[][3]; void foo() { cp = cv; // cv = cp; //Error! E1014: Left operand must be an ’lvalue’ cp++; // cv++; //Error! E1014: Left operand must be an ’lvalue’ pp = &cp; pa = &cv; pp = &cp + 1; pa = &cv + 1; //Warning! W115: &array may not produce intended result pa++; //q[0]=*(&cv+1); //Error! E1014: Left operand must be an ’lvalue’ //q[1]=cv; //Error! E1014: Left operand must be an ’lvalue’ q[1][2]=cv[1]; r[1][2]=cv[2]; } ?È)¤ ch2.obj§2‰1 wdis -l -s ch2§ ch2.lst Xeµ Module: D:\cygwin\home\U2\wd\cprog\ch2.c GROUP: ’DGROUP’ CONST,CONST2,_DATA,_BSS Segment: _TEXT BYTE USE32 00000074 bytes // wcc386 -d2 -wx ch2.c char cv[]="ef"; // cv[3], not cv[2] char *cp="gh", **pp, (*pa)[3], (q[])[3], r[][3]; void foo() 0000 foo_: 0000 68 20 00 00 00 push 0x00000020 0005 E8 00 00 00 00 call __CHK 000A 53 push ebx 000B 51 push ecx 000C 52 push edx 000D 56 push esi 000E 57 push edi 000F 55 push ebp 0010 89 E5 mov ebp,esp 14 0012 81 EC 04 00 00 00 sub esp,0x00000004 { cp = cv; 0018 L$1: 0018 C7 05 00 00 00 00 00 00 00 00 mov dword ptr _cp,offset _cv // cv = cp; //Error! E1014: Left operand must be an ’lvalue’ cp++; 0022 FF 05 00 00 00 00 inc dword ptr _cp // cv++; //Error! E1014: Left operand must be an ’lvalue’ pp = &cp; 0028 C7 05 00 00 00 00 00 00 00 00 mov dword ptr _pp,offset _cp pa = &cv; 0032 C7 05 00 00 00 00 00 00 00 00 mov dword ptr _pa,offset _cv pp = &cp + 1; 003C C7 05 00 00 00 00 04 00 00 00 mov dword ptr _pp,offset _cp+0x4 pa = &cv + 1; //Warning! W115: &array may not produce intended result 0046 C7 05 00 00 00 00 03 00 00 00 mov dword ptr _pa,offset _cv+0x3 pa++; 0050 83 05 00 00 00 00 03 add dword ptr _pa,0x00000003 //q[0]=*(&cv+1); //Error! E1014: Left operand must be an ’lvalue’ //q[1]=cv; //Error! E1014: Left operand must be an ’lvalue’ q[1][2]=cv[1]; 0057 A0 01 00 00 00 mov al,byte ptr _cv+0x1 005C A2 05 00 00 00 mov byte ptr _q+0x5,al r[1][2]=cv[2]; 0061 A0 02 00 00 00 mov al,byte ptr _cv+0x2 0066 A2 05 00 00 00 mov byte ptr _r+0x5,al } 006B L$2: 006B 89 EC mov esp,ebp 006D 5D pop ebp 006E 5F pop edi 006F 5E pop esi 15 0070 5A pop edx 0071 59 pop ecx 0072 5B pop ebx 0073 C3 ret 0074 L$3: Routine Size: 116 bytes, Routine Base: _TEXT + 0000 No disassembly errors Segment: CONST DWORD USE32 00000003 bytes 0000 L$4: 0000 67 68 00 gh. Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000007 bytes 0000 _cv: 0000 65 66 00 ef. 0003 _cp: 0003 00 00 00 00 DD offset L$4 Segment: _BSS DWORD USE32 0000000E bytes 0000 _q: 0003 _r: 0006 _pa: 000A _pp: BSS Size: 14 bytes ·‚w§cv Ú&cv 3êŠþ´ƒ§Ñ´ offset _cv§´üö êâa.ØÓ"?ÈìŠâ§‚a.§gÄä駂= öŠU‰§= öŠØU‰§U‰qTNo‰" r pa = &cv + 1 ¤ pa=&cv, pa++§ÒŒ±;>u´w"?ÈìuÑ ´w´Ï§kõ<éù‡LˆªkØ)§Ø^œ¹²~u)" ·‚„w§?Èìr¤kõ‘ê|ÑÄk=z¤˜‘ê|§,2? n"¤±§– q[1][] ù¥m/ê|0§Ñ´vkgC;˜m§? vk lvalue " char (*p)[3] † char *(s[3]) ´ØÓ§öq~¤ char *s[3]§ L«ëYn‡§z‡•˜‡iÎG" ch1.c ¥ str Ы´/=ÂÎ0¦^"'X’n’ L«i1 n§ASCII è´ 0x6E"´ ’\n’ ÒL«˜‡4ªà1Ie£˜1››i ΧÙASCII è´ 0x0A"Ò´`§i1 n ¹Â=C "¤±¡/= ÂÎ0"œž© " 16 iΏŒ±w‰´üi!ê§kÎÒP signed char§ÃÎÒ P unsigned char",i¡þwEδ char§Œ±‰üi!ê 5^§¤k\~¦Ø!Œ'!Ü6Ú£ $Žь‰§Ø‡Éi¡å P"XJkX=ØL 5§Œ±r char n)¤ tiny int§gCõ‰˜Ú€È Ҍ± " C Šó¥iÎGѱ 0x00§= ’\0’ (—§¤±iÎG"ab" ¢Sþ¹ n‡iםg´ ’a’§’b’ Ú’\0’" 1.4 stdcall ÚÚÚ cdecl Øõ`§w§S func1.c µ // wcc386 -d2 -wx func1.c int __stdcall f(int a, int b); int __cdecl g(int a, int b); int h(int a, int b); int r; void foo() { r = f(1,2); r = g(3,4); r = h(5,6); } P{§)¤®?L func1.lst µ Module: D:\cygwin\home\U2\wd\cprog\func1.c GROUP: ’DGROUP’ CONST,CONST2,_DATA,_BSS Segment: _TEXT BYTE USE32 00000054 bytes // wcc386 -d2 -wx func1.c int __stdcall f(int a, int b); int __cdecl g(int a, int b); int h(int a, int b); int r; void foo() 0000 foo_: 0000 68 28 00 00 00 push 0x00000028 0005 E8 00 00 00 00 call __CHK 000A 53 push ebx 000B 51 push ecx 000C 52 push edx 000D 56 push esi 000E 57 push edi 000F 55 push ebp 0010 89 E5 mov ebp,esp 17 0012 81 EC 04 00 00 00 sub esp,0x00000004 { r = f(1,2); 0018 L$1: 0018 6A 02 push 0x00000002 001A 6A 01 push 0x00000001 001C E8 00 00 00 00 call _f@8 0021 A3 00 00 00 00 mov dword ptr _r,eax r = g(3,4); 0026 6A 04 push 0x00000004 0028 6A 03 push 0x00000003 002A E8 00 00 00 00 call _g 002F 83 C4 08 add esp,0x00000008 0032 A3 00 00 00 00 mov dword ptr _r,eax r = h(5,6); 0037 BA 06 00 00 00 mov edx,0x00000006 003C B8 05 00 00 00 mov eax,0x00000005 0041 E8 00 00 00 00 call h_ 0046 A3 00 00 00 00 mov dword ptr _r,eax } 004B L$2: 004B 89 EC mov esp,ebp 004D 5D pop ebp 004E 5F pop edi 004F 5E pop esi 0050 5A pop edx 0051 59 pop ecx 0052 5B pop ebx 0053 C3 ret 0054 L$3: Routine Size: 84 bytes, Routine Base: _TEXT + 0000 No disassembly errors Segment: CONST DWORD USE32 00000000 bytes Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000000 bytes Segment: _BSS DWORD USE32 00000004 bytes 0000 _r: 18 BSS Size: 4 bytes ·‚w§Šé r = f(1,2); “è´ 0018 6A 02 push 0x00000002 001A 6A 01 push 0x00000001 001C E8 00 00 00 00 call _f@8 0021 A3 00 00 00 00 mov dword ptr _r,eax Šé r = g(3,4); “è´ 0026 6A 04 push 0x00000004 0028 6A 03 push 0x00000003 002A E8 00 00 00 00 call _g 002F 83 C4 08 add esp,0x00000008 0032 A3 00 00 00 00 mov dword ptr _r,eax Šé r = h(5,6); “è´ 0037 BA 06 00 00 00 mov edx,0x00000006 003C B8 05 00 00 00 mov eax,0x00000005 0041 E8 00 00 00 00 call h_ 0046 A3 00 00 00 00 mov dword ptr _r,eax ùÒ´ØÓ¼êN^½¤)J"¼ê h N^½´ __watcall" OpenWatcom  C?Èì3¼êvk²N^½ž§Òæ^ __watcall" Òù‡äN~f 󧷂wµ • n«½ÑÏL eax Mì5ˆ£ê.¼êŠ" •ØÓ½ÏL±ØӐª?U¼ê¶¡ª5ƒp«©"ù«{Ø UJøýéy§´3¢‚þ§E,U užÑûÐJ«Š^" •__watcall `k¦^Mì5D4ëê"k3ëêõ§ŒÀMì ^¦ž§â¦^Ò5Dëê" •__stdcall Ú__cdecl Ѧ^Ò5Dëê"ØÒ^SÑ´lm•†" •__stdcall dN^ö?nëêòÒ¯K§ __cdecl dN^ö?në êòÒ¯K" ü«òҐªˆk|6"w§S func2.c µ // wcc386 -d2 -wx func2.c int __stdcall f(int a, int b) { return a+b; } int __cdecl g(int a, int b) { return a+b; } 19 )¤®?Lµ Module: D:\cygwin\home\U2\wd\cprog\func2.c GROUP: ’DGROUP’ CONST,CONST2,_DATA Segment: _TEXT BYTE USE32 00000054 bytes // wcc386 -d2 -wx func2.c int __stdcall f(int a, int b) 0000 _f@8: 0000 68 18 00 00 00 push 0x00000018 0005 E8 00 00 00 00 call __CHK 000A 53 push ebx 000B 56 push esi 000C 57 push edi 000D 55 push ebp 000E 89 E5 mov ebp,esp 0010 81 EC 04 00 00 00 sub esp,0x00000004 { return a+b; 0016 L$1: 0016 8B 45 14 mov eax,dword ptr 0x14[ebp] 0019 03 45 18 add eax,dword ptr 0x18[ebp] 001C 89 45 FC mov dword ptr -0x4[ebp],eax } 001F 8B 45 FC mov eax,dword ptr -0x4[ebp] 0022 L$2: 0022 89 EC mov esp,ebp 0024 5D pop ebp 0025 5F pop edi 0026 5E pop esi 0027 5B pop ebx 0028 C2 08 00 ret 0x0008 int __cdecl g(int a, int b) Routine Size: 43 bytes, Routine Base: _TEXT + 0000 002B _g: 002B 68 18 00 00 00 push 0x00000018 0030 E8 00 00 00 00 call __CHK 0035 53 push ebx 0036 56 push esi 0037 57 push edi 0038 55 push ebp 0039 89 E5 mov ebp,esp 003B 81 EC 04 00 00 00 sub esp,0x00000004 20 { return a+b; 0041 L$3: 0041 8B 45 14 mov eax,dword ptr 0x14[ebp] 0044 03 45 18 add eax,dword ptr 0x18[ebp] 0047 89 45 FC mov dword ptr -0x4[ebp],eax } 004A 8B 45 FC mov eax,dword ptr -0x4[ebp] 004D L$4: 004D 89 EC mov esp,ebp 004F 5D pop ebp 0050 5F pop edi 0051 5E pop esi 0052 5B pop ebx 0053 C3 ret 0054 L$5: Routine Size: 41 bytes, Routine Base: _TEXT + 002B No disassembly errors Segment: CONST DWORD USE32 00000000 bytes Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000000 bytes ¼ê _f@8 ˆ£- ret 0x0008" ¼ê _g ˆ£-´{ü ret§7L 3£N^ö“襃§2 add esp,0x00000008 òÒ"ƒ'ƒe§,´ __stdcall p˜:" ù«p“dÒ´½k ëê‡ê" __cdecl `³ƒ˜§Ò´Œ± ?nCÝëêL"w§S func3.c µ // wcc386 -d2 -wx func3.c int __cdecl g(int a, ...); void foo() { g(1); g(2,3,4); } )¤®?LXeµ Module: D:\cygwin\home\U2\wd\cprog\func3.c GROUP: ’DGROUP’ CONST,CONST2,_DATA 21 Segment: _TEXT BYTE USE32 00000039 bytes // wcc386 -d2 -wx func3.c int __cdecl g(int a, ...); void foo() 0000 foo_: 0000 68 2C 00 00 00 push 0x0000002c 0005 E8 00 00 00 00 call __CHK 000A 53 push ebx 000B 51 push ecx 000C 52 push edx 000D 56 push esi 000E 57 push edi 000F 55 push ebp 0010 89 E5 mov ebp,esp 0012 81 EC 04 00 00 00 sub esp,0x00000004 { g(1); 0018 L$1: 0018 6A 01 push 0x00000001 001A E8 00 00 00 00 call _g 001F 83 C4 04 add esp,0x00000004 g(2,3,4); 0022 6A 04 push 0x00000004 0024 6A 03 push 0x00000003 0026 6A 02 push 0x00000002 0028 E8 00 00 00 00 call _g 002D 83 C4 0C add esp,0x0000000c } 0030 L$2: 0030 89 EC mov esp,ebp 0032 5D pop ebp 0033 5F pop edi 0034 5E pop esi 0035 5A pop edx 0036 59 pop ecx 0037 5B pop ebx 0038 C3 ret 0039 L$3: Routine Size: 57 bytes, Routine Base: _TEXT + 0000 No disassembly errors Segment: CONST DWORD USE32 00000000 bytes 22 Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000000 bytes Œ±w§N^ö3N^ g(1) ƒ§^ add esp,4 òÒ¶ 3N^ g(2,3,4) ƒ§^ add esp,12 òÒ"ùJø ˜«é¢^(¹5" J¦(¹5“d´›”î‚5"~^CëêL¼ê´ printf" § × £ ˜ ‡ i ÎG ¥  SN § ± ( ½ Y ë ê  ‡ ê Ú a ." ¯ K 3 u§OpenWatcom  C?Èì†NõÙ¦?È옧¿Øuù‡iÎ GSN†Yëꘗ5"ù¦˜ †Øk$1žâU³Ñ5§ Ï O\ NÁڑo¤"gcc Jø éÎÜ printf IOiÎGSN† Yëꘗ5uõU"´é˜„¿ÂþCëêL§Ø3d?È ì?1uÏ^{"3ù‡¯Kþ§(¹5†î‚5،o" ‡^ Win32 API "Žæ^ __stdcall N^½§k4‡O API ¼ êæ^ __cdecl§„k4‡O¼êæ^ __pascal"–u C Šó$1ÏÄó ¥¥¼ê§K"Žæ^ __cdecl" 1.5 extern ÚÚÚ static ®?Šó¥CþÚ ¼ê§þŒ©naµEXTRNL«/l ܼ 0§PUBLICL«/• ÜJø0§üöÑØ´§@Ò´/3¬S ¦^0"C Šó¥éCþÚ¼ê§k†®?ŠóƒéA?n{"w§S ex1.c µ // wcc386 -wx ex1.c extern int a; static int b; int c; extern void f(); static void g(); void h(); void g(){c=a+b;}//Or will W202: Symbol ’b’ has been defined, but not referenced void h(){f();g();}//Or will W202: Symbol ’g’ has been defined, but not referenced ?Ȥ ex1.obj§^ wdis -l=ex1.sep -s -e -p ex1 )¤ ex1.sep Xeµ Module: D:\cygwin\home\U2\wd\cprog\ex1.c GROUP: ’DGROUP’ CONST,CONST2,_DATA,_BSS File contains no line numbers. Segment: _TEXT BYTE USE32 0000002C bytes 0000 g_: 0000 68 04 00 00 00 push 0x00000004 23 0005 E8 00 00 00 00 call __CHK 000A A1 00 00 00 00 mov eax,dword ptr _a 000F 03 05 00 00 00 00 add eax,dword ptr _b 0015 A3 00 00 00 00 mov dword ptr _c,eax 001A C3 ret Routine Size: 27 bytes, Routine Base: _TEXT + 0000 001B h_: 001B 68 04 00 00 00 push 0x00000004 0020 E8 00 00 00 00 call __CHK 0025 E8 00 00 00 00 call f_ 002A EB D4 jmp g_ Routine Size: 17 bytes, Routine Base: _TEXT + 001B No disassembly errors List of external references SYMBOL ------- __CHK 0006 0021 _a 000B _b 0011 _c 0016 f_ 0026 Segment: CONST DWORD USE32 00000000 bytes Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000000 bytes Segment: _BSS DWORD USE32 00000008 bytes 0000 _b: 0004 _c: BSS Size: 8 bytes List of public symbols SYMBOL SECTION OFFSET -------------------------------------------------------- _c _BSS 00000004 h_ _TEXT 0000001B ^·- wdis -l=ex1.a -a ex1 )¤ ex1.a Xeµ 24 .387 .386p .model flat PUBLIC h_ PUBLIC _c EXTRN __CHK:BYTE EXTRN _a:BYTE EXTRN f_:BYTE DGROUP GROUP CONST,CONST2,_DATA,_BSS _TEXT SEGMENT BYTE PUBLIC USE32 ’CODE’ ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP g_: push 4 call near ptr FLAT:__CHK mov eax,dword ptr FLAT:_a add eax,dword ptr FLAT:_b mov dword ptr FLAT:_c,eax ret h_: push 4 call near ptr FLAT:__CHK call near ptr FLAT:f_ jmp g_ _TEXT ENDS CONST SEGMENT DWORD PUBLIC USE32 ’DATA’ CONST ENDS CONST2 SEGMENT DWORD PUBLIC USE32 ’DATA’ CONST2 ENDS _DATA SEGMENT DWORD PUBLIC USE32 ’DATA’ _DATA ENDS _BSS SEGMENT DWORD PUBLIC USE32 ’BSS’ ORG 0 _b LABEL BYTE ORG 4 _c LABEL BYTE ORG 8 _BSS ENDS END é'ƒe·‚Œ±wµ • extern int a; L«Cþ a l ܼ§´ EXTRN§ÃI3¬SÙ ©;˜m" • static int b; L«Cþ b 3¬S¦^"I‡3¬SÙ© ;˜m"Ø7òÙPUBLIC" 25 • int c; L«Cþ c • ÜJø§´ PUBLIC§I‡3¬SÙ© ;˜m" • extern void f(); L«¼ê f l ܼ§´ EXTRN§ÃI3¬S Jø¼êN"´§XJ3¬SJø ¼êN§@o§ÒӞ´ PUBLIC"˜„@§PUBLIC á5¬CXEXTRN á5"XJQüêN§ q™Ú^§KTŠéuØ3" • static void g(); L«¼ê g 3¬S¦^"XJQüêN§ q™Ú^§KTŠéuØ3"XJk¼êN§´™Ú^§ K?Èì¬uј‡´wµW202: Symbol ’g’ has been defined, but not referenced"XJkÚ^§´vk¼êN§K´‡†ØµE1035: static function ’g’ has not been defined" • void h(); Óu extern void h();" ˜‡¼ê§XJÚ^§ üêN§Kéu static ¼ê§ù´‡†Ø§ éu extern ¼ê§ùé~§Ï¼êNò3óžÿlO¬¥¼ "XJóžE,éؼêN§@Ò´‡ó†Ø" extern é¼ê5ùŒkŒÃ§ éuCþ5ù§kÚvkҌk«O " k extern ÒØ©;˜m§Ã extern Ò©˜m" 1.6 ¬¬¬zzz???§§§ ˜‡ C Šó½ö®?Šó©‡§²?È)¤˜‡8I©‡§3 OpenWat- com Ò´ *.obj ©‡§3 gcc Ò´ *.o ©‡§ù˜‡?Èü Ò¡˜‡ ¬" Xþ!¤ã§˜‡¬Œ±¹=øgCSܦ^êâړ觏Œ ±Ú^O¬¥ PUBLIC êâړ觏Œ±ògC, êâړè PUBLICÑ5§øO¬Ú^" ^n‡¬5‰‡~f"1˜‡¬ md1.c µ // wcc386 -bc=nt -wx md1.c int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); #pragma off (check_stack);//To avoid the __CHK extern int pub_d2;// allocated in md2.c int pub_d1;// allocated in this module, public to outsize static int stc_d1;// private data extern void pub_f2(int, char *); static void stc_f1(){MessageBoxA(0, "I’m stc_f1", "App", 1);} 26 void pub_f1(char *s){MessageBoxA(0, "I’m pub_f1", "App", 1);}//public to outside void foo1(){stc_f1();stc_d1=pub_d1+pub_d2;}//To avoid warnings 1‡¬ md2.c µ // wcc386 -bc=nt -wx md2.c int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); #pragma off (check_stack);//To avoid the __CHK extern int pub_d1;// allocated in md1.c int pub_d2;// allocated in this module, public to outsize static int stc_d2;// private data extern void pub_f1(char *); static void stc_f2(){MessageBoxA(0, "I’m stc_f2", "App", 1);} void pub_f2(int n, char *s){MessageBoxA(0, "I’m pub_f2", "App", 1);}//public void foo2(){stc_f2();stc_d2=pub_d1+pub_d2;}//To avoid warnings 1n‡¬ md3.c µ // wcl386 -bcl=nt_win -wx -"option start=start option map" md3.c md1.obj md2.obj void __stdcall ExitProcess(unsigned int uExitCode); #pragma off (check_stack); extern int pub_d1;// allocated in md1.c extern int pub_d2;// allocated in md2.c void pub_f1(char *);// defined in md1.c void pub_f2(int, char *);// defined in md2.c #pragma aux start "*" aborts; void start() { pub_f1("Hello"); pub_f2(3, "World"); ExitProcess(pub_d1+pub_d2); } ·‚w˜e md3.c ®?Lµ Module: D:\cygwin\home\U2\wd\cprog\md3.c GROUP: ’DGROUP’ CONST,CONST2,_DATA Segment: _TEXT BYTE USE32 0000002A bytes 0000 start: 0000 B8 00 00 00 00 mov eax,offset L$1 0005 E8 00 00 00 00 call pub_f1_ 000A BA 06 00 00 00 mov edx,offset L$2 27 000F B8 03 00 00 00 mov eax,0x00000003 0014 E8 00 00 00 00 call pub_f2_ 0019 A1 00 00 00 00 mov eax,dword ptr _pub_d1 001E 03 05 00 00 00 00 add eax,dword ptr _pub_d2 0024 50 push eax 0025 E8 00 00 00 00 call _ExitProcess@4 Routine Size: 42 bytes, Routine Base: _TEXT + 0000 No disassembly errors Segment: CONST DWORD USE32 0000000C bytes 0000 L$1: 0000 48 65 6C 6C 6F 00 Hello. 0006 L$2: 0006 57 6F 72 6C 64 00 World. Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000000 bytes ´Ø´š~ZÀ§š~¤º md3.c §S §ØI‡ pub_f2 äN´ XÛ¢y§‡§¼ê.´ void pub_f2(int, char *); Ҍ± (/N^ " 1.7 óóó þ~¥§n‡¬/ó§S0|C¤˜‡Œ‰1 *.exe ©‡"ó §Séùn‡¬ˆ‡Ü©3Œ‰1©‡¥½ §Œ±ÏL*.map ©‡w ‡ŒV"md3.map SNXeµ Open Watcom Linker Version 1.9 Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved. Created on: 11/12/13 16:12:07 Executable Image: md3.exe creating a Windows NT windowed executable +------------+ | Groups | +------------+ Group Address Size ===== ======= ==== DGROUP 00402000 00000054 .idata 00403000 00000090 28 +--------------+ | Segments | +--------------+ Segment Class Group Address Size ======= ===== ===== ======= ==== _TEXT CODE AUTO 00401000 000000ac TRANSFER CODE CODE AUTO 004010ac 0000000c CONST DATA DGROUP 00402000 00000042 CONST2 DATA DGROUP 00402044 00000000 _DATA DATA DGROUP 00402044 00000000 _BSS BSS DGROUP 00402044 00000010 .idata .idata .idata 00403000 00000090 +----------------+ | Memory Map | +----------------+ * = unreferenced symbol + = symbol only referenced locally Address Symbol ======= ====== Module: md3.obj(D:\cygwin\home\U2\wd\cprog\md3.c) 00401000 start Module: md1.obj(D:\cygwin\home\U2\wd\cprog\md1.c) 00402044 _pub_d1 00401042 pub_f1_ 00401052* foo1_ Module: md2.obj(D:\cygwin\home\U2\wd\cprog\md2.c) 0040204c _pub_d2 00401080 pub_f2_ 00401096* foo2_ +----------------------+ | Imported Symbols | +----------------------+ Symbol Module ====== ====== _ExitProcess@4 KERNEL32.DLL 29 _MessageBoxA@16 USER32.DLL +--------------------+ | Libraries Used | +--------------------+ f:\watcom/lib386/nt\kernel32.lib f:\watcom/lib386/nt\user32.lib +-----------------------+ | Linker Statistics | +-----------------------+ Stack size: 1000 (4096.) Memory size: 019c (412.) Entry point address: 00401000 Link time: 00:00.10 Äk·‚®²wLéõ®?L §êâړèÑ´‡˜,ãëY ;˜m¥"ù˜ãëY˜mÒ¡ Segment§§Œ±k¶i§' X“è3 OpenWatcom ¥˜„˜3¶ _TEXT 㥧3 gcc ¥K˜3¶ .text ã¥"ã¶i´½‚¤§¿Ãõ¹Â"\Œ±gC嘇㠶§¿½‰˜‡¼ê"?È쌱rT¼ê“è˜\½ã¶ã ¥" ㌱k/´ÄŒ‰10§/´ÄÖ0˜ á5"˜„5`§k‰ 1“è㴐Ö"´k <Žé‰1“è?1\—!)—§½ök < Ž&¢g·A½¢DŽ{§Šâ?nêâ¢Sœ¹§N‰1“è §ùžŒ±3§S¥ž˜ãS§r“èp¡§,a?§4Å ì‰1‘žÑŒU?U/ˆx0“è" “èãÖØ=S§ …Œ±õ?§§l !ŽÔnS"y“ ŒõêöŠXÚ§¤¢‰1˜‡§S§Ò´ŠâŒ‰1©‡SN§M ?§"ù‡?§´3˜‡ÕáJ[S˜m¥$1"ù«J[S˜m˜ „´ 2G ½ö 4G§y©¤Nõ/0§z˜„´ 4K Œ"öŠXڑo XJ[S¥¡ÔnS¡éA'X"XJ˜‡§SӞõg‰ 1§'X§S ŒUӞ$1õg‡^ Notepad §S5?6õ‡©‡§@o ùõ‡?§“èãÒ´ƒÓ"öŠXÚ3ÔnS¥3˜°§, rù˜°Nõ‡?§¥"ÄÄó¥ *.dll Œþ¦^§ù˜ üÑ´Rk¤" •Ö¡\@´ØATu)¯§öŠXڬᏆ¿(åÑ †?§"ü«ù˜œ¹I˜1 int main(){return *((int*)main)=0;}" 30 ;.á5|Ü¡a (Class)"lþã map ©‡Œ±w§Ì‡a kµ • “èa CODE"‰1“èÑ\da㥶 •Ð©zêâa DATA"Dƒ ЩSNêâ§Ñ\da㥶 • ™Ð©zêâa BSS"vk½Ð©SNêâ§\daã¥" 3 *.exe ©‡©‡Þ¥§¹Xü@&Eµ˜@´ˆãSN3©‡¥ ˜ ڌ§,˜@´ˆãSN3?§˜m¥ ˜ÚŒ"CODE aÚDATA a ã§3©‡¥kã¢N§ÙSN©O´‰1“èÚЩzê⧠BSS a 㧐3©‡Þ¥kP¹§^5`²§3?§˜m¥ ˜ÚŒ§ v kã¢N"ù¦ *.exe ©‡Œ±¦ŒU" ·‚Œ±r㩤+ (Group)§¿‰+½˜‡¶i"óìÄkr¤k ãUì+5©|"3Ә+S§2Uìa5©|"ӘaS§2Uìã¶5 ©|"ˆ‡¬Әã¶êâ§Uìk^SÚéàIOgü§Ò ¤ óóŠ1˜Ú" óóŠ1Ú´/)û0¬ƒmCþÚ¼êÚ^¯K"3?È md3.c žÿ§?È쐇N^ pub_f1_§%Ã{§3=p§Ur call -¥8I/ŒW"§¢SþÒ´˜X"k3óã§rˆãƒ 領Ñ(½Ð §\pub_f1_ “è¢S/ŒâU(½e5"óì‡rù ‡¢S/Œ£W call -¥§¡/)û0 ù‡ÎÒÚ^¯K" ^ gcc  objdump -sd md3.exe Œw«ù‡Œ‰1©‡Ü©SNXeµ md3.exe: file format pei-i386 Contents of section AUTO: 401000 b8002040 00e83800 0000ba06 204000b8 .. @..8..... @.. 401010 03000000 e8670000 00a14420 40000305 .....g....D @... 401020 4c204000 50e88800 00005152 6a01680c L @.P.....QRj.h. 401030 20400068 10204000 6a00e86d 0000005a @.h. @.j..m...Z 401040 59c35152 6a01680c 20400068 1b204000 Y.QRj.h. @.h. @. 401050 ebe6e8d3 ffffffa1 44204000 03054c20 ........D @...L 401060 4000a348 204000c3 51526a01 68282040 @..H @..QRj.h( @ 401070 00682c20 40006a00 e82f0000 005a59c3 .h, @.j../...ZY. 401080 516a0168 28204000 68372040 006a00e8 Qj.h( @.h7 @.j.. 401090 18000000 59c3e8cd ffffffa1 44204000 ....Y.......D @. 4010a0 03054c20 4000a350 204000c3 ff254c30 ..L @..P @...%L0 4010b0 4000ff25 54304000 @..%T0@. Contents of section DGROUP: 402000 48656c6c 6f00576f 726c6400 41707000 Hello.World.App. 402010 49276d20 7374635f 66310049 276d2070 I’m stc_f1.I’m p 402020 75625f66 31000000 41707000 49276d20 ub_f1...App.I’m 31 402030 7374635f 66320049 276d2070 75625f66 stc_f2.I’m pub_f 402040 32000000 00000000 00000000 00000000 2............... 402050 00000000 .... Contents of section .idata: 403000 3c300000 00000000 00000000 5c300000 <0..........\0.. 403010 4c300000 44300000 00000000 00000000 L0..D0.......... 403020 67300000 54300000 00000000 00000000 g0..T0.......... 403030 00000000 00000000 00000000 74300000 ............t0.. 403040 00000000 82300000 00000000 74300000 .....0......t0.. 403050 00000000 82300000 00000000 55534552 .....0......USER 403060 33322e44 4c4c004b 45524e45 4c33322e 32.DLL.KERNEL32. 403070 444c4c00 01004d65 73736167 65426f78 DLL...MessageBox 403080 41000100 45786974 50726f63 65737300 A...ExitProcess. Contents of section .reloc: 404000 00100000 30000000 01300b30 1a302030 ....0....0.0.0 0 404010 2f303430 47304c30 58305e30 63306d30 /040G0L0X0^0c0m0 404020 72308430 89309c30 a230a730 b430ae30 r0.0.0.0.0.0.0.0 404030 00000000 00000000 00000000 00000000 ................ Disassembly of section AUTO: 00401000 : 401000: b8 00 20 40 00 mov $0x402000,%eax 401005: e8 38 00 00 00 call 0x401042 40100a: ba 06 20 40 00 mov $0x402006,%edx 40100f: b8 03 00 00 00 mov $0x3,%eax 401014: e8 67 00 00 00 call 0x401080 401019: a1 44 20 40 00 mov 0x402044,%eax 40101e: 03 05 4c 20 40 00 add 0x40204c,%eax 401024: 50 push %eax 401025: e8 88 00 00 00 call 0x4010b2 40102a: 51 push %ecx 40102b: 52 push %edx 40102c: 6a 01 push $0x1 40102e: 68 0c 20 40 00 push $0x40200c 401033: 68 10 20 40 00 push $0x402010 401038: 6a 00 push $0x0 40103a: e8 6d 00 00 00 call 0x4010ac 40103f: 5a pop %edx 401040: 59 pop %ecx 401041: c3 ret 401042: 51 push %ecx 401043: 52 push %edx 401044: 6a 01 push $0x1 401046: 68 0c 20 40 00 push $0x40200c 40104b: 68 1b 20 40 00 push $0x40201b 401050: eb e6 jmp 0x401038 401052: e8 d3 ff ff ff call 0x40102a 32 401057: a1 44 20 40 00 mov 0x402044,%eax 40105c: 03 05 4c 20 40 00 add 0x40204c,%eax 401062: a3 48 20 40 00 mov %eax,0x402048 401067: c3 ret 401068: 51 push %ecx 401069: 52 push %edx 40106a: 6a 01 push $0x1 40106c: 68 28 20 40 00 push $0x402028 401071: 68 2c 20 40 00 push $0x40202c 401076: 6a 00 push $0x0 401078: e8 2f 00 00 00 call 0x4010ac 40107d: 5a pop %edx 40107e: 59 pop %ecx 40107f: c3 ret 401080: 51 push %ecx 401081: 6a 01 push $0x1 401083: 68 28 20 40 00 push $0x402028 401088: 68 37 20 40 00 push $0x402037 40108d: 6a 00 push $0x0 40108f: e8 18 00 00 00 call 0x4010ac 401094: 59 pop %ecx 401095: c3 ret 401096: e8 cd ff ff ff call 0x401068 40109b: a1 44 20 40 00 mov 0x402044,%eax 4010a0: 03 05 4c 20 40 00 add 0x40204c,%eax 4010a6: a3 50 20 40 00 mov %eax,0x402050 4010ab: c3 ret 4010ac: ff 25 4c 30 40 00 jmp *0x40304c 4010b2: ff 25 54 30 40 00 jmp *0x403054 ·‚Œ±w§“èãÚêâã©O|C ˜å§ … call 8I/Œ ÑWþ äNŠ"ù´ó§Sü‘Ì‡óŠ"£,Ù¦ˆ«ÎÒ Ú^œ/kéõéõ§Ñ‡)û§Ø´?n call ¯K"¤ 1.8 CCC111†††­­­½½½    `˜e .reloc ã"*.exe Ú*.dll!*.ocx Ñ´ PE ‚ªN” (im- age) ©‡"Ù©‡Þ¹˜‘/N”ÄO/Œ (ImageBase)0§¢SþÒ´% @C1/Œ"ÃØ´“è㧄´êâã§ÑŒU3˜ /Œ&E´±% @C1/ŒÄOW"'Xþ¡“èü‡ jmp -§Ù8I/ŒÒ ´†ÄO/Œƒ!" XJ¢SC1/ŒØ´©‡Þp²ù‡§@oùü‡ jmp -8I /Œ’½‡N§U¤†¢SC1/ŒƒÎ/Œ"ù«?UöŠ¡/­# (½ ˜0§{¡­½  (reloc)"r¤kŒUI‡­½ êâ/ŒÂ8å 5§¤˜‡ã§Ò´ .reloc ã" 33 kw(Ò¯3µjmp ´3“èãp¡§ “è㴐Ö§NoŒ±U Qº ¯œ´ù"öŠXÚ3C1N”©‡žÿ§`kUìN”ÄO/Œ 5C1"XJùãJ[S˜mk˜Ü©®²Ó^§@oöŠXÚ¬ÀJ, ˜ã˜m5C1"ùã˜mž˜¤Œ§±B¤­½ öŠ" ¤ƒ§2rùã˜m˜¤Ö"ù§ý?\^r“èžÿ§“è㠄´Ö" *.exe ©‡Œ±Ø.reloc ã"ϏC1 *.exe ©‡ž§J[S¥´ ˜§Ø3%@C1/ŒÓ^¯K" 1.9 declspec(dllimport) ÚÚÚÄÄÄóóó qkw(¯3µ3n‡¬®?L¥Ñvkþãü‡ jmp -§§ ‚´No?§åŸoŠ^º ·‚„´‰‡¢§^¯¢`{"w§S trcode1.c µ // wcl386 -bcl=nt_win -wx -"op start=start op m" trcode1.c __declspec(dllimport) int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); __declspec(dllimport) void __stdcall ExitProcess(unsigned int uExitCode); #pragma off (check_stack); #pragma aux start "*" aborts; int __stdcall foo(){MessageBoxA(0, "I’m foo", "App", 1);return 0;} int __stdcall ( *ifoo)() = (int __stdcall (*)())foo; __declspec(naked) int __stdcall foo2(){_asm{jmp dword ptr ifoo}} void start() { foo(); (*ifoo)();// with __declspec(dllimport) foo2(); // without __declspec(dllimport) ExitProcess(0); } §®?L´ùµ Module: D:\cygwin\home\U2\wd\cprog\trcode1.c GROUP: ’DGROUP’ CONST,CONST2,_DATA Segment: _TEXT BYTE USE32 00000035 bytes 0000 _foo@0: 0000 6A 01 push 0x00000001 0002 68 00 00 00 00 push offset L$1 0007 68 04 00 00 00 push offset L$2 000C 6A 00 push 0x00000000 34 000E FF 15 00 00 00 00 call dword ptr __imp__MessageBoxA@16 0014 31 C0 xor eax,eax 0016 C3 ret Routine Size: 23 bytes, Routine Base: _TEXT + 0000 0017 _foo2@0: 0017 FF 25 00 00 00 00 jmp dword ptr _ifoo Routine Size: 6 bytes, Routine Base: _TEXT + 0017 001D start: 001D E8 DE FF FF FF call _foo@0 0022 FF 15 00 00 00 00 call dword ptr _ifoo 0028 E8 EA FF FF FF call _foo2@0 002D 6A 00 push 0x00000000 002F FF 15 00 00 00 00 call dword ptr __imp__ExitProcess@4 Routine Size: 24 bytes, Routine Base: _TEXT + 001D No disassembly errors Segment: CONST DWORD USE32 0000000C bytes 0000 L$1: 0000 41 70 70 00 App. 0004 L$2: 0004 49 27 6D 20 66 6F 6F 00 I’m foo. Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000004 bytes 0000 _ifoo: 0000 00 00 00 00 DD offset _foo@0 5ù‡¯†Äó¥§= *.dll ©‡¦^k'"–T~¥ foo() ù Êϼê§Ù¼êN´3uó¤)¤ *.exe ©‡p¡"ÏdT¼ êN† call -ƒm £þ3óƒÒ´(½§ù¦·‚Œ±æ^ call -{ü‚ª§= call _foo@0" ´§MessageBoxA ¼êN3 user32.dll p¡§ ExitProcess ¼ êN3 kernel32.dll p¡"3óž·‚Ã{(½$1žùü‡ *.dll N” ¢SC1/Œ§? ÒÃ{(½ù /Ú\(import)0¼ê¼êN† call -ƒm £þ"d§ó§S‡M .idata ã§3p¡˜ ¤k7‡/Ú\L(import table)0"ù‡Lp­‡˜‘êâÒ´/z‡ Ú\¼ê¢SC1/Œ0",§T/ŒUdöŠXÚ3Mï?§ž§ ¤ ƒA dll N”C1ƒ§âUW" 35 XJ?Èì MessageBoxA ´˜‡Ú\¼ê§@o§ÒŒ±( &§3Ú\Lp3,‡êâü __imp__MessageBoxA@16§p¡˜´ T¼ê¢SC1/Œ" ù‡êâü call -ƒm £þ3 óƒ´(½ §ù?ÈìÒÀJ call -mό‚ª§= call dword ptr __imp__MessageBoxA@16§5?1¼êN^"ùŒ±Jp‰ 1Ç"w,§__imp__MessageBoxA@16 ¢SþÒ´˜‡¼ê" XJ?ÈìØ MessageBoxA ´˜‡Ú\¼ê§Ò¬r§ŠÊϼ ê5?n§)¤ call _MessageBoxA@16 ù“è"rù«‚ªN^§= †¤éÚ\¼êN^§´óìŠâ/Ú\¥0SN5¤" óì3)ûÎÒÚ^¯Kž§¬×£½˜X/¥0"¥ *.lib © ‡´d¥+nì5Mïڑo"ÊÏ¥Ò´rƒ'¬ *.obj ‹§± JpéÇ!!ŽM˜m"Ú\¥´¥+nìŠâé *.dll £ã )¤ §ØI‡?Èìë†"‡¦^ *.dll ©‡§7LÄkMï½öƒA Ú\¥" ¼ê MessageBoxA 3Ú\¥ user32.lib ¥éA˜‡¬§T¬Jø MessageBoxA /¼êN0§´ù‡/¼êN0%k˜^-§= jmp dword ptr __imp__MessageBoxA@16"ù‡“衏=†“è (transfer code)"OpenWatcom r¤k=†“èј3˜‡;€㥧Ù¦mu óä™7Xd" óì )ûéÎÒ_MessageBoxA@16 Ú^¯K§×£½¥§3 user32.lib ¥é §/¼êN0§u´rT/¼êN0\\N”ƒ¥§T Ú^¯K)û"´§ùq) ˜‡éÎÒ__imp__MessageBoxA@16  Ú^¯K"óìuyTÎÒ± __imp_ mÞ§Ò@½ù´˜‡Ú\¼ê" u´r§\\Ú\L"TÚ^¯K)û" 3 trcode1.c ¥§·‚Œ—Ы þãL§¥ƒ'Vg§Ù¥ • int foo() ƒu *.dll N”¥ý¼êN" • int (*ifoo)() ƒuÚ\L¥¼ê" • int foo2() ƒu=†“è§=¤¢/¼êN0" XJvk¦^ __declspec(dllimport) éÚ\¼ê\±`²§@o?ÈìÒU ìÊϼêN^ foo2(); 5?n"XJ¦^ __declspec(dllimport)§@o ?ÈìréT¼ê¤kN^§ÑUì¼êN^ (*ifoo)(); 5?n" 1.10 ÞÞÞ©©©‡‡‡ 3c¡ md1.c!md2.c Ú md3.c ¥§Ó˜‡¼ê.E›z˜‡ N^T¼ê¬¥"NoâUyùü°€´˜—QºXJؘ—§@ 36 ÒkŒæ† "Ә‡¼ê§˜‡¬Uì __stdcall ½N^§,˜‡ ¬Uì __cdecl ½N^§ó˜å§XJU¤õ{§@o)¤‰1 §S3$1ž§ÒSN¬u)®Ï§§S¬×„$"¤3ØÓN^ ½§é¼ê¶¡?UªØÓ§3óìw5§üö´ØӼꧽ¡ /ÎÒ(symbol)0"Ïd§Ø¬ó¤õ"¦+Xd§ŒÝ/; extern ¼ê.½êâ(²†Ø§E,´‡I‡@ýé–¯K" {ƒ˜§Ò´¦^ #include"·‚rþã‘8­#©8‡©‡"1 ˜‡©‡ md20.h µ #ifndef __MD20_H__ #define __MD20_H__ int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); void __stdcall ExitProcess(unsigned int uExitCode); #pragma off (check_stack); #endif 1‡©‡ md21.h µ #ifndef __MD21_H__ #define __MD21_H__ #include "md20.h" extern int pub_d1; void pub_f1(char *s); #endif 1n‡©‡ md21.c µ // wcc386 -bc=nt -wx md21.c #include "md21.h" // prototype of pub_f1 must match #include "md22.h" // for pub_d2, MessageBoxA int pub_d1;// allocated in this module, public to outsize static int stc_d1;// private data static void stc_f1(){MessageBoxA(0, "I’m stc_f1", "App", 1);} void pub_f1(char *s){MessageBoxA(0, "I’m pub_f1", "App", 1);}//public void foo1(){stc_f1();stc_d1=pub_d1+pub_d2;}//To avoid warnings 1o‡©‡ md22.h µ 37 #ifndef __MD22_H__ #define __MD22_H__ #include "md20.h" extern int pub_d2; void pub_f2(int, char *s); #endif 1ʇ©‡ md22.c µ // wcc386 -bc=nt -wx md22.c #include "md22.h" // prototype of pub_f2 must match #include "md21.h" // for pub_d1, MessageBoxA int pub_d2;// allocated in this module, public to outsize static int stc_d2;// private data static void stc_f2(){MessageBoxA(0, "I’m stc_f2", "App", 1);} void pub_f2(int n, char *s){MessageBoxA(0, "I’m pub_f2", "App", 1);}//public void foo2(){stc_f2();stc_d2=pub_d1+pub_d2;}//To avoid warnings 18‡©‡ md23.c µ // wcl386 -bcl=nt_win -wx -"op start=start op m" md23.c md21.obj md22.obj #include "md21.h" // for pub_f1, pub_d1 #include "md22.h" // for pub_f2, pub_d2 #pragma aux start "*" aborts; void start() { pub_f1("Hello"); pub_f2(3, "World"); ExitProcess(pub_d1+pub_d2); // in md20.h } ^ wcl386 -bcl=nt_win -"op start=start op m" md23.c md21.c md22.c =Œ?ÈÚó§)¤ md23.exe ©‡" Äk§ù« #ifndef __XXX_H__ #define __XXX_H__ //blah blah #endif (§Œ±;õg¹ƒÓSN"õg(²Ó˜‡Cþ½ö¼ê§3?È ìw5§´‡†Ø" 38 1§Þ©‡´N^ö†¢yöƒmƧ¹Xéêâ(Ú¼ê .½"¤±§¢y¬I‡¹gCù‡¬Þ©‡"ù§XJN ^ö†¢yöé¼ê.n)ؘ—§?È쌱9ž‰Ñ´w" 1n§^rrÞ©‡¹?5§Ù¥ void pub_f1(char *s); Ϗvk ¼êN§)´ EXTRN J" T¼ê¢y¬§ÏkT¼ê¼ê N§Ò) PUBLIC J" 1o§Þ©‡¥Cþ extern ،Ž§ ¼ê extern Œ±ŽÑ"3¢ y¬§‡ PUBLICÑCþ،V\ extern§ ¼êŒ±V\ extern" 1ʧ¢y¬¥ŒU3™\Þ©‡ PUBLICCþ½¼ê"'X foo1 Ú foo2"˜„Eâ© éÞ©‡¥CþÚ¼ê\±`²"™\Þ ©‡ PUBLICCþ½¼ê´Ãæ"¢yöÐò§‚U¤ static§ N ^öÐ؇/ß0Cþ(²½¼ê.§kx¦^§‚" 1.11 ¥¥¥ ‡¬¥k˜‡ÎÒÚ^§@o‡¬Ñ¬\\N”©‡¥" N”©‡,´Ð"ù҇¦¬3±Œ‘o5cJe§y© [Ð"C ŠóIO¥¥§kéõ¬Ñ¢y˜‡½ü‡¼ê"ù§¯õ [”¬+nÒ¤ ¯K§éǏ$"u´§¥©‡ *.lib Ú¥+nì BA$ )" ±þ!‘8~"b md21.obj Ú md22.obj ®²­½§·‚Œ±r §‚‹¤˜‡µwlib -n md2x md21 md22"ùÒ)¤˜‡ md2x.lib © ‡§Ù¥¹ ùü‡¬§ §‚ÎÒLÜ¿¤˜‡MFL§ùŒ±Œ ÌJpé„Ý" ^ wlib -l md2x ·-)¤¥¥SNL md2x.lst µ _pub_d1.......................................D:\cygwin\home\U2\wd\cprog\md21.c _pub_d2.......................................D:\cygwin\home\U2\wd\cprog\md22.c foo1_.........................................D:\cygwin\home\U2\wd\cprog\md21.c foo2_.........................................D:\cygwin\home\U2\wd\cprog\md22.c pub_f1_.......................................D:\cygwin\home\U2\wd\cprog\md21.c pub_f2_.......................................D:\cygwin\home\U2\wd\cprog\md22.c D:\cygwin\home\U2\wd\cprog\md21.c Offset=00000200H _pub_d1 foo1_ pub_f1_ D:\cygwin\home\U2\wd\cprog\md22.c Offset=00000600H _pub_d2 foo2_ pub_f2_ 39 ¦^ù‡¥kõ«{"3 §S¥^ #pragma library ´{ü˜ «"wù‡§S md24.c µ // wcl386 -bcl=nt_win -wx -"op start=start op m" md24.c #include "md21.h" #include "md22.h" #pragma library(md2x); #pragma aux start "*" aborts; void start() { pub_f1("Hello"); pub_f2(3, "World"); ExitProcess(pub_d1+pub_d2); } 5¿§·‚‡kÞ©‡ md21.h Ú md22.h§±9¥©‡ md2x.lib§ÒŒ±¦ ^úmCþÚN^úm¼ê §ØI‡ù ¼ê3¢yþ[!"ù, k|uó§+n" OpenWatcom  C ŠóIO¥´ clib3r.lib"ؔ^ wlib -l clib3r )¤ÙL©‡wwp¡kŸo" 1.12 éééÄÄĬ¬¬ ·‚˜†3^óìÀ‘ option start=xxx 5½ *.exe N”?\: (entry point)"´·‚q C Šó§SIO?\:´ main() ¼ê"ùü ö¿Øgñ§cö´öŠXÚ5½§ö´ C Šó?ÈXÚ5½"rüö éXå5xùÒ´¤¢éĬ" ·‚5½›˜‡éĬ"w§S as0.c µ // wcc386 -wx as0.c // wdis -l=as0.asm -a as0 // append "as0" to the "END" line of as0.asm // wasm -wx as0.asm // append the new as0.obj to your module list, then enjoy AppMain() #pragma off (check_stack); void __stdcall ExitProcess(unsigned int uExitCode); int AppMain(); #pragma aux as0 "*" aborts; void as0() { ExitProcess(AppMain()); } ?È)¤ as0.obj§2‡®?¤ as0.asm§?Uف˜1Xeµ 40 .387 .386p .model flat PUBLIC as0 EXTRN AppMain_:BYTE EXTRN ‘_ExitProcess@4‘:BYTE DGROUP GROUP CONST,CONST2,_DATA _TEXT SEGMENT BYTE PUBLIC USE32 ’CODE’ ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP as0: call near ptr FLAT:AppMain_ push eax call near ptr FLAT:‘_ExitProcess@4‘ _TEXT ENDS CONST SEGMENT DWORD PUBLIC USE32 ’DATA’ CONST ENDS CONST2 SEGMENT DWORD PUBLIC USE32 ’DATA’ CONST2 ENDS _DATA SEGMENT DWORD PUBLIC USE32 ’DATA’ _DATA ENDS END as0 ù¢Sþ´ù‡¬½ /?\:0"2^ wasm as0.asm ·-­#®? ¤ as0.obj"@o§ù‡¹k?\:¬ÒŒ±^ŠéĬ" ?‡§Swwù‡éĬ^{"w§S app1.c µ // wcl386 -bcl=nt_win -wx app1.c as0.obj #pragma off (check_stack); int __stdcall MessageBoxA(unsigned int hWnd, char *lpText, char *lpCaptioin, unsigned int uType); int AppMain() { MessageBoxA(0, "Hello", "App", 1); return 0; } ^ gcc  objdump -sd app1.exe wwó(Jµ app1.exe: file format pei-i386 Contents of section AUTO: 401000 51526a01 68002040 00680420 40006a00 QRj.h. @.h. @.j. 401010 e8190000 0031c05a 59c3e8e1 ffffff50 .....1.ZY......P 401020 e8030000 00000000 ff254c30 4000ff25 .........%L0@..% 401030 54304000 T0@. Contents of section DGROUP: 41 402000 41707000 48656c6c 6f000000 App.Hello... Contents of section .idata: 403000 3c300000 00000000 00000000 5c300000 <0..........\0.. 403010 4c300000 44300000 00000000 00000000 L0..D0.......... 403020 69300000 54300000 00000000 00000000 i0..T0.......... 403030 00000000 00000000 00000000 74300000 ............t0.. 403040 00000000 82300000 00000000 74300000 .....0......t0.. 403050 00000000 82300000 00000000 4b45524e .....0......KERN 403060 454c3332 2e444c4c 00555345 5233322e EL32.DLL.USER32. 403070 444c4c00 01004578 69745072 6f636573 DLL...ExitProces 403080 73000100 4d657373 61676542 6f784100 s...MessageBoxA. Contents of section .reloc: 404000 00100000 10000000 05300a30 30302a30 .........0.000*0 404010 00000000 00000000 00000000 00000000 ................ Disassembly of section AUTO: 00401000 : 401000: 51 push %ecx 401001: 52 push %edx 401002: 6a 01 push $0x1 401004: 68 00 20 40 00 push $0x402000 401009: 68 04 20 40 00 push $0x402004 40100e: 6a 00 push $0x0 401010: e8 19 00 00 00 call 0x40102e 401015: 31 c0 xor %eax,%eax 401017: 5a pop %edx 401018: 59 pop %ecx 401019: c3 ret 40101a: e8 e1 ff ff ff call 0x401000 40101f: 50 push %eax 401020: e8 03 00 00 00 call 0x401028 401025: 00 00 add %al,(%eax) 401027: 00 ff add %bh,%bh 401029: 25 4c 30 40 00 and $0x40304c,%eax 40102e: ff 25 54 30 40 00 jmp *0x403054 y3§XJ\k,§Œ±mu˜‡ App Šó§§?\:´ int AppMain() ¼êœ Windows ã/.¡(GUI) A^§S†iÎ.¡(CUI) A^§S?\: ØÓ§cö´ WinMain ¼ê§ö´ main ¼ê§üöëêؘ"éÄ ¬‡kOÐ̼êëê§,âUN^̼ê"Ïd§ùü«A^§S éĬ7½´Ø˜"ó§SŠâ‡)¤A^§Sa.§gÄÀJ ƒAéĬ"´§XJk˜‡^r¬¹ ?\:§@oÒ±T¬ éĬ" 42 2 ^^^rrrêêêâââaaa... 2.1 enum enum ¡qÞ"w§S enu1.c µ // wcc386 -wx -s enu1.c enum dm {zero, one, two, four=4, five, two2=2, three, mone=-1, big=255}; enum dm z=zero, b=two, b2=two2, f=five, x=mone, c=three, g=big; int i=four; // assign a enum value to int variable enum dm m=7; // assign a int value to enum variable enum shu {ling, yi, er, si=4, wu};// chinese pinyin enum shu jia=one;// assign a enum value to another enum variable enum dm rt7(enum dm i, enum shu j){i=j+1; return 7;} void foo(){rt7(yi, two);}//no warning! :(( §®?L´µ Module: D:\cygwin\home\U2\wd\cprog\enu1.c GROUP: ’DGROUP’ CONST,CONST2,_DATA Segment: _TEXT BYTE USE32 00000018 bytes 0000 rt7_: 0000 B8 07 00 00 00 mov eax,0x00000007 0005 C3 ret Routine Size: 6 bytes, Routine Base: _TEXT + 0000 0006 foo_: 0006 52 push edx 0007 BA 02 00 00 00 mov edx,0x00000002 000C B8 01 00 00 00 mov eax,0x00000001 0011 E8 EA FF FF FF call rt7_ 0016 5A pop edx 0017 C3 ret Routine Size: 18 bytes, Routine Base: _TEXT + 0006 No disassembly errors Segment: CONST DWORD USE32 00000000 bytes Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000015 bytes 0000 _z: 0000 00 00 .. 0002 _b: 0002 02 00 .. 43 0004 _b2: 0004 02 00 .. 0006 _f: 0006 05 00 .. 0008 _x: 0008 FF FF .. 000A _c: 000A 03 00 .. 000C _g: 000C FF 00 .. 000E _i: 000E 04 00 00 00 .... 0012 _m: 0012 07 00 .. 0014 _jia: 0014 01 . l¥Œ±wµ • OpenWatcom ?ÈìUì enum a.S¤kkÎÒêŠ5û½C þŒ"'X enum shu ¥ŠÑ3 0  5 ƒm§^˜‡i!5;Ò v §¤±Cþ jia Ó˜‡i!" enum dm ¥§ƒ big Š 255§‡Ñ üi!kÎÒꉌ"¤±?ÈìTqÞa.Cþ © ü‡i!"^?Èì -ei À‘§Œ±‡¦?È쏤kqÞa .CþÑ©o‡i!"3§S¥Œ±^ #pragma enum xxx 5UC ©üÑ"„© " •?Èì¿Øu enum a.SŠ´Äk­E"­EƒŒ±Š/O ¶05¦^"'X two2 Œ±w‰´ two O¶" • rêŠD‰qÞa.Cþž§?Èì¿Øuù‡Š´Ä3TqÞ a.¥k½Â"'X§7 ¿Ø´ enum dm ¥?ÛƒŠ§%U DŠ‰ m"?Èìéd؊?Û´w" • ¤kqÞa.Cþƒm§Œ±ƒp†DŠ§Ò´‰Ûªa. =†"ù¦˜‡qÞa.Äþ҃ué˜Xê~ê?1÷½ §éJ5¿§Ù¢´êâa."ù¿Ø¬›³ C Š/ra.0Š ó/–"Ϗ§Äk§¢‚þAvkndr˜‡qÞa.ŠD‰ ,˜‡qÞa.Cþ¶Ùg§Q,Œ±ÉÃꊧ@oÉ ÓÃ,˜‡qÞa.Š¿Øw<" 2.2 struct struct ¡("§r˜|ƒ'êâ(ܤ˜‡Nêâü"ê âK¡T(ê⤠"ù´˜«ý¿Âþ^rêâa.§Œ±^ 5½ÂCþ§ïáê|§½Â§D\ëê"w§S stct1.c µ 44 // wcc386 -wx -s -ecc stct1.c struct st { int i1, i2; char c3[3]; short int s4; int i5;}; struct st a={0x10111213,0x20212223, {’a’,’b’,’c’}, 0x4041, 0x50515253}; void bar(struct st *p){p->i5 = p->i1 + p->s4;} void foo(){a.i5 = a.i1+a.s4; bar(&a);} )¤®?L´µ Module: D:\cygwin\home\U2\wd\cprog\stct1.c GROUP: ’DGROUP’ CONST,CONST2,_DATA Segment: _TEXT BYTE USE32 00000035 bytes 0000 _bar: 0000 8B 54 24 04 mov edx,dword ptr 0x4[esp] 0004 8B 4A 0A mov ecx,dword ptr 0xa[edx] 0007 C1 F9 10 sar ecx,0x10 000A 8B 02 mov eax,dword ptr [edx] 000C 01 C8 add eax,ecx 000E 89 42 10 mov dword ptr 0x10[edx],eax 0011 C3 ret Routine Size: 18 bytes, Routine Base: _TEXT + 0000 0012 _foo: 0012 8B 15 0A 00 00 00 mov edx,dword ptr _a+0xa 0018 C1 FA 10 sar edx,0x10 001B A1 00 00 00 00 mov eax,dword ptr _a 0020 01 D0 add eax,edx 0022 A3 10 00 00 00 mov dword ptr _a+0x10,eax 0027 68 00 00 00 00 push offset _a 002C E8 00 00 00 00 call _bar 0031 83 C4 04 add esp,0x00000004 0034 C3 ret Routine Size: 35 bytes, Routine Base: _TEXT + 0012 No disassembly errors Segment: CONST DWORD USE32 00000000 bytes Segment: CONST2 DWORD USE32 00000000 bytes Segment: _DATA DWORD USE32 00000014 bytes 0000 _a: 0000 13 12 11 10 23 22 21 20 61 62 63 00 41 40 00 00 ....#"! abc.A@.. 0010 53 52 51 50 SRQP 3T§S¥§·‚½Â ˜‡kʇê⤠( st§^§(² ˜‡Cþ a§¿D Њ"‡é(¥êâ?1öŠ§Œ±^ a.i5 ½ö p->i5 ù 45 Lˆª" ?Èì‰(¢S©;˜m¥ŒU¬3/˜Y0§¤±(¢ Sº€ŒU¬Œu¤k¤ º€ƒÚ"l®?L¥Œ±w§(Cþ a ê⤠c3 ¡, k˜‡i!˜Y§ s4 ¡§kü‡i!˜Y"ù ´ y CPU é s4 Ú i5 pÖ" XJ˜‡êCþ _i Ø3oi!êS/Œþ§@oÓ˜^ mov eax, dword ptr _i -§CPU ‡õs˜ ž¨±ÏâU¤"¤±§  Jp§S$1„ݧ?Èì¬rØÓº€CþSü3ƒA/º €0/Œþ§¡/éà (alignment)0" Œõê˜YŒ±ÏLU?é(½Â\±žØ"'Xrþ~U¤ struct st { int i1, i2; int i5; short int s4; char c3[3];}; struct st a={0x10111213,0x20212223, 0x50515253, 0x4041, {’a’,’b’,’c’}}; Ҍ± Segment: _DATA DWORD USE32 00000014 bytes 0000 _a: 0000 13 12 11 10 23 22 21 20 53 52 51 50 41 40 61 62 ....#"! SRQPA@ab 0010 63 00 00 00 c... ¤k˜YÑ£ (—Ü" /BºùkŸo^Bœ0ù w(`3"/ù¯„‡?U¤kЩ zê⧁˜‡i!vkŽe5œ0 Ø´ù"ŽŽw§XJ\½Â ˜‡(ê| a[4]§3 a[0] ƒ‡ ;X˜ a[1]§bXvk"—n‡˜Y§@o a[1] ¥ i1!i2!i5 æØ´ q/Øéà0 íº¤±§(º€7L¦3(ê|¥§z‡¤ é à‡¦ÑU ÷v"ù¢SþÒ´Œ¤ éàIO"þ~¥§Œ ¤ éàIO´oi!§¤±T(º€7L´oi!ê" ú„¢"w§S stct2.c µ // wcc386 -wx -s -ecc stct2.c struct st1 { char c1; long long int i1; char c2; long long int i2;}; struct st1 x={’a’, 1, ’b’, 2}; #pragma pack (push, 1); struct st2 { char c1; long long int i1; char c2; long long int i2;}; struct st2 y={’c’, 3, ’d’, 4}; #pragma pack (pop); struct st3 { long long int i1, i2; char c1, c2; }; struct st3 z={’e’, 5, ’f’, 6}; Ù®?L´µ Segment: _DATA DWORD USE32 0000004A bytes 0000 _x: 46 0000 61 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 a............... 0010 62 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 b............... 0020 _y: 0020 63 03 00 00 00 00 00 00 00 64 04 00 00 00 00 00 c........d...... 0030 00 00 .. 0032 _z: 0032 65 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 e............... 0042 66 06 00 00 00 00 00 00 f....... ·‚w st3 ' st1 !Ž l‡i!" 3ù‡§Sp·‚^ #pragma pack(push,1); Ï?ÈìUi!éৢ SþÒ´žéà›"ùž¤k¤ éà‡¦Ñ´˜i!§¤± st2 º €Ò´˜i!ê"ù´Œ±2Že8‡i!§´§S$1„ݬ ü$" 2.3 sizeof() ÚÚÚ offsetof() XJ^ wcc386 -wx -s -ecc -zp1 stct2.c ?Èfâ@‡§S§Ò¬ µ Segment: _DATA DWORD USE32 00000036 bytes 0000 _x: 0000 61 01 00 00 00 00 00 00 00 62 02 00 00 00 00 00 a........b...... 0010 00 00 .. 0012 _y: 0012 63 03 00 00 00 00 00 00 00 64 04 00 00 00 00 00 c........d...... 0022 00 00 .. 0024 _z: 0024 65 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 e............... 0034 66 06 f. ¤±§Ø‡3§S¥é(º€‰?Ûb§‡^ sizeof(struct st1) ½ ö sizeof(x) /ί0?Èì§4§5wŠ\§Ä¾´NoSü"5¿ sizeof(x) Ø´3$1ã饼êN^§ ´?Èãé?ÈìÎ" §ˆ£(J‰ê.~ê5w–§Ò–êi 2!4!8 ˜" 3fâ§S¥\˜1µ int sz1=sizeof(struct st1), sz2=sizeof(y), sz3=sizeof(z); ?ȞØ^ -zp1 À‘§Ò´Uì%@ -zp8 5?ȧµ 004A _sz1: 004A 20 00 00 00 ... 004E _sz2: 004E 12 00 00 00 .... 0052 _sz3: 0052 18 00 00 00 .... 47 XJ^ -zp1 5?ȧ@o sz1!sz2!sz3 ÒÑ´ 18" w,§¤ 3(¥¢S £þ´†?ÈÀ‘ƒ'"ØLùg·‚ Œ±/gCÄ紟v 0"w§S ofst1.c µ // wcc386 -wx -s -ecc ofst1.c struct st { char c; int i;}; int i_st=(int)&(((struct st *)0)->i); #define offsetof(t,m) ((int)&(((struct t *)0)->m)) int i_st2=offsetof(st, i); w˜e®?L§Òü‡êÑ´ 4"XJ^ -zp1 5?ȧ@oü‡ê Ñ´ 1"ù‡÷ offsetof() 3Þ©‡ ¥" ŸoØ^÷5¢y sizeof() Qºw§S szof1.c µ // wcc386 -wx -s -ecc szof1.c struct st { char c; int i;}; int sz1 = (int)(((struct st *)0) + 1); #define sizeofstruct(t) ((int)(((struct t *)0) + 1)) int sz2 = sizeofstruct(st);// Good. int sz6 = sizeof(struct st[3]); int sz7 = (int)(((struct st (*)[3])0) + 1); #define sizeofsarray(t,n) ((int)(((struct t (*)[n])0) + 1)) int sz8 = sizeofsarray(st,3);// Well done! struct st v; int sz9 = sizeof(v);// :(( ÷Ã{)û¼Cþº€¯K"¤± C ŠóâJø sizeof öŠÎ" 2.4 (((iii@@@†††™™™¤¤¤ (incomplete) aaa... (Œ±i@"'Xµ struct sa {int i,j;} a = {1,2}; struct sb {int i; struct sa s;} b = {3,{4,5}}; k 1==a.i, 3==b.i, 4==b.s.i" ´(ØUi@gC"e¡“èÃ{?ÈÏLµ struct ss {int i; struct ss s;};//E1114: Struct or union cannot contain itself Ϗ?ÈìØù˜@˜§AT3۞âU(å"†¤Òvk¯ K µ struct ss {int i; struct ss *s;} c = {7, &c}; ÒcXÚ ó§¤kÑ´oi!§l d~¥Cþ c º€´ (½"§´¹ ˜‡•§gC ®" ÿ™‰Ñ½Â(¡/™¤0("XJ struct sd ´™ ¤§@oe¡ù1“èÃ{?ÈÏLµ 48 struct sc {int i; struct sd s;};//E1044: Variable ’s’ has incomplete type Ϗ7‡ s º€ÚéàA5&EÿØ3§Ã{UY?È" •™¤(´Œ±‰¤ "$–Œ±^™¤(5( ²Cþ§,^ù‡Cþ/Œ5éЩz"'Xµ struct sd t; struct sc {int i; struct sd* p;} d = {9, &t}; struct sd {int i, j;}; ´§t ØUЩz"Ϗ t (²žÿ§(ÿ™½Â¶(k ½ žÿ§˜U ?1ЩzžÅ®²L " 2.5 ŠŠŠ{{{ää䆆†LLLˆˆˆªªª¦¦¦ŠŠŠ b‡‰‡OŽì§@oŒ1{ƒ˜´×£iÎG§'X"2+3*5"§ âdïáŠ{ä§=µ + / \ / * / / \ 2 3 5 ,éŠ!:‰1¦ŠöŠ"w§S cq1.c µ // wcl386 -wx -s -ecc cq1.c #include struct node {int (*eval)(struct node *); struct node *left, *right;}; int add(struct node *nd){return nd->left->eval(nd->left) + nd->right->eval(nd->right);} int mul(struct node *nd){return nd->left->eval(nd->left) * nd->right->eval(nd->right);} int get(struct node *nd){return (int)nd->left;} struct node two = {get, (struct node *)2, (struct node *)0}, three = {get, (struct node *)3, (struct node *)0}, five = {get, (struct node *)5, (struct node *)0}, t = {mul, &three, &five}, p = {add, &two, &t}; int main(){return printf("2+3*5=%d.\n", p.eval(&p));} ‹Ñ5 2+3*5=17." 2.6 union union Ò´éÜ"^§UrӘã;˜mŠõ«ØÓa.êâ5? n"¦+^(Úêâa.=†v±¤Ó¯œ§´¦^é܌±r ù‘󊌌{z"w§S cq2.c µ 49 // wcl386 -wx -s -ecc cq2.c #include struct node {int (*eval)(struct node *); union {int val; struct node *left;}; union {int dummy; struct node *right;};}; int add(struct node *nd){return nd->left->eval(nd->left) + nd->right->eval(nd->right);} int mul(struct node *nd){return nd->left->eval(nd->left) * nd->right->eval(nd->right);} int get(struct node *nd){return nd->val;} struct node two = {get, 2, 0}, three = {get, 3, 0}, five = {get, 5, 0}, t = {mul, (int)&three, (int)&five}, p = {add, (int)&two, (int)&t}; int main(){return printf("2+3*5=%d.\n", p.eval(&p));} 5¿µéÜЩzUì1˜‘a.5?1"XJé܈¤ º€Ø ˜§@oéܺ€ÚéàA5цŒ¤ ƒ˜—" 2.7 typedef typedef 4·‚U ‰(!éÜ!¼ê.!ˆa!ê|E,ê âa.§½˜‡{ü¶i§,Ҍ±– char Ú int @¦^§l J póŠÇ"w§S cq3.c µ // wcl386 -wx -s -ecc cq3.c #include typedef struct node node_t; typedef int (*eval_t)(node_t *); struct node {eval_t eval; union {int val; node_t *left;}; union {int dummy; node_t *right;};}; int add(node_t *nd){return nd->left->eval(nd->left) + nd->right->eval(nd->right);} int mul(node_t *nd){return nd->left->eval(nd->left) * nd->right->eval(nd->right);} int get(node_t *nd){return nd->val;} node_t two = {get, 2, 0}, three = {get, 3, 0}, five = {get, 5, 0}, t = {mul, (int)&three, (int)&five}, p = {add, (int)&two, (int)&t}; int main(){return printf("2+3*5=%d.\n", p.eval(&p));} ·‚Œ± typedef struct node *node_p; , node_p left; 5½ ÂÚ¦^a."´·‡< Ð´µk¢Nêâa.â\±·¶§ j±^ * 5I£" ¼êa.·¶ typedef int (*eval_t)(node_t *); ÐwД8Ø 4­:"´c[ŽŽ§?Û¼ê§ëêLы3¼ê¶¡§¤±¼êa .ëêL‹3a.¶¡´g,Lˆª",§„‡†ÊÏ¼ê¶ ƒ«O"@o\‡)Ò´{ü" ê|a.·¶Ú•ê|a.·¶§w§S typ1.c µ 50 // wcl386 -wx -s -ecc typ1.c typedef unsigned char (img_t)[8][8]; img_t g; int gsz=sizeof(g);// 64 typedef unsigned char (*img_p)[8][8]; img_p p; int psz=sizeof(p);// 4 Ù®?Lµ Segment: _DATA DWORD USE32 00000008 bytes 0000 _gsz: 0000 40 00 00 00 @... 0004 _psz: 0004 04 00 00 00 .... Segment: _BSS DWORD USE32 00000044 bytes 0000 _g: 0040 _p: BSS Size: 68 bytes 3 C ŠŠŠóóó OO???§§§ 3.1 xout C++  HelloWorld ´ùº‚µ cout << "Hello, world!" << endl; â`ùŒ±; C Šó printf ‚ªG†ëêLؚ†Øu)"@ o§C ´Ø´kUåUùº‚5ÑÑQºw§S xout1m.c µ // wcl386 -wx -s -ecc xout1m.c xout1.c #include "xout1.h" int main() { xop->at(stderr)->s("3!=")->d(6)->s(".\n"); return 0; } ùa.†ŠÒجؚ j"wÞ©‡ xout1.h µ #ifndef _XOUT1_H_ #define _XOUT1_H_ #include typedef struct st_os osT; struct st_os { 51 FILE *tm; osT *(*at)(FILE *tm); osT *(*s)(char *s); osT *(*d)(int i); }; extern osT *xop; #endif ¢y¬´ xout1.c µ // wcc386 -wx -s -ecc xout1.c #include "xout1.h" static osT * os_at(FILE *tm); static osT * os_s(char *s); static osT * os_d(int i); static osT _xout = {stdout, os_at, os_s, os_d}; osT *xop = &_xout;// xop is public osT *os_at(FILE *tm) { _xout.tm = tm; return xop; } osT *os_s(char *s) { fprintf(_xout.tm,"%s",s); return xop; } osT *os_d(int i) { fprintf(_xout.tm,"%d",i); return xop; } ù‡O3X˜:ØvµXÚ¥k˜‡ osT ¢N" XJ‡õ‡¢N¿§Ò7LwŠ¼ê§\‡é=‡¢N?1öŠ"Ò ´`§\7Lr¢ND?"w§S xout2m.c µ // wcl386 -wx -s -ecc xout2m.c xout2.c #include "xout2.h" int main() { x->at(x,stdout)->s(x,"3!=")->d(x,6)->s(x,".\n"); y->at(y,stderr)->s(y,"4!=")->d(y,24)->s(y,".\n"); return 0; } 52 Þ©‡ xout2.h ´µ #ifndef _XOUT2_H_ #define _XOUT2_H_ #include typedef struct st_os osT; struct st_os { FILE *tm; osT *(*at)(osT *, FILE *tm); osT *(*s)(osT *, char *s); osT *(*d)(osT *, int i); }; extern osT *x, *y; #endif ¢y¬ xout2.c µ // wcc386 -wx -s -ecc xout2.c #include "xout2.h" static osT * os_at(osT *, FILE *tm); static osT * os_s(osT *, char *s); static osT * os_d(osT *, int i); static osT _xout = {stdout, os_at, os_s, os_d}, _yout = {stderr, os_at, os_s, os_d}; osT *x = &_xout, *y = &_yout;// x, y are public osT *os_at(osT *self, FILE *tm) { self->tm = tm; return self; } osT *os_s(osT *self, char *s) { fprintf(self->tm,"%s",s); return self; } osT *os_d(osT *self, int i) { fprintf(self->tm,"%d",i); return self; } 3.2 zout )ûþã¯K„k,˜«g´"w§S zout1.c µ 53 // wcl386 -wx -s -ecc zout1.c #include // in header file typedef void (*zP)(FILE*,int); typedef int (*zF)(FILE*,zP,int); typedef zF (*zF1)(FILE*,zP,int); typedef zF1 (*zF2)(FILE*,zP,int); typedef zF2 (*zF3)(FILE*,zP,int); void s(FILE *o, int d); void d(FILE *o, int d); zF3 out(FILE *o, zP p, int d); // in implementation file void s(FILE *o, int d){fprintf(o,"%s",(char*)d);} void d(FILE *o, int d){fprintf(o,"%d",(int)d);} zF3 out(FILE *o, zP p, int d){p(o,d); return (zF3)out;} // in client code int main() { FILE *o=stdout, *e=stderr; int i; i = out(o,s,(int)"3!=")(o,d,6)(o,s,(int)".\n")(o,d,9)(o,d,8); out(e,s,(int)"4!=")(e,d,24)(e,s,(int)".\n"); return 0; } ù‡ out ¼êõ‹Ê‡ëêL"?n˜‡ëêL§ˆ£Ša.Ò´ ê§Ø2´¼ê "¤±§^ù‡¼êõŒʑêâ"3 C Šó¥§¼ ꈣŠa.،U´¼êa.§½Â typedef zF (*zF)(); ´1Ø Ï"XJ\Ž4ù‡¼ê‘õëêL§UUY½Â zF4§zF5§,,§ † ^Ž" 'å5§„´ xout2 nܵdÐ"¢Sþ§cout Ò´^Ón ¢y" 3.3 ggg··· (this) †††¼¼¼êêê­­­111 (overload) k<`§ x->at(x,stdout)->s(x,"3!=")->d(x,6)->s(x,".\n"); † cout << "3!=" << 6 << ".\n"; ²²xxؘB§\No`üö´ÓnQº 54 Äk§cout ´˜‡§Ùg§<< ´˜‡¼ê"ؔPcö c§ö out" ,§C++ a¥™^ friend (²¤ ¼ê§ÑÛ¹/‘k˜‡•¢ ~§P this§ŠëêL1˜‡ëê"‡^ VC++ ^Mì ecx 5D4ù‡ëê"Ò´`§3 VC++ ¥§g· this ´Ø\Ò" £3 xout2 ¥§·‚A¿rg·P self§±J2Ööù´ C §S§ Ø´ C++ §S"¤ ,˜¡§C++ ?È쬊⤠¼êëêL§é¤ ¼ê¶i?1 Ö¿?U§ŠSܦ^¼ê¶"l Üw§´Ó˜‡¼ê­1µÓ˜‡ ¼ê¶§Œ±‘õ«ëêL", lSÜw§§‚Ò´ØÓSܼê¶ÊÏ ¼ê" ØÓ?Èì?U¼ê¶5K¿ØƒÓ"Ò·‚~f ó§Ø”P out Sܼ궧˜‡´ outs§,˜‡´ outd" ù˜5§ cout << "3!=" << 6 << ".\n"; ¢SN^ªÒ´µ c->outs(c,"3!=")->outd(c,6)->outs(c,".\n"); 3 outs Ú outd ¢yþ§´4§‚ªˆ£g·"ù˜ƒÑ‹ xout2 ´˜—" 3.4 new ÚÚÚ delete ˜‡a clz§‡)¤˜‡gC¢~ obj§Ï~‡©˜ãS§éÙ¥ êâDЊ"XJù‡¢~†©‡½öÙ¦XÚ] ƒ'é§@o„‡‰Ð ù ] OóŠ"ù ¯œÏ~^˜‡¼ê5¤§·U‰§åaq clz__new ù¼ê¶" ‡¤¢~§Ï~Äk‡˜n¤'é] §,º˜¤Ó^S"ù ‡¼ê§·Uå clz__delete ù¼ê¶"w§S nd1.c µ // wcl386 -wx -s -ecc nd1.c #include #include typedef struct { int count; } clzT; typedef struct { char *name; } objT; 55 static clzT clz = {0}; objT *clz__new(char *n) { objT *p = malloc(sizeof(*p)); p->name = n; clz.count++; return p; } void clz__delete(objT *o) { clz.count--; free(o); } void clz__report() { printf("# is %d.\n", clz.count); } int main() { objT *a, *b; clz__report();//0 a = clz__new("Alice"); clz__report();//1 b = clz__new("Bob"); clz__report();//2 clz__delete(a); clz__report();//1 clz__delete(b); clz__report();//0 return 0; } Ù¥ clz.count ¢SþŒw‰´˜«/] 0"3 clz__new Ú clz__delete ¥§‡¤éù‘/] 0OóŠÚ˜nóŠ" 3 C++ ¥§new Ú delete ´Œ­1öŠÎ"c¡JL§¤¢­1§Ù¢ Ò´?U¼ê¶"¤±§3 C++ ?ÈL§¥§¬)éõaqþã clz__new Ú clz__delete Sܼê¶" 3.5 µµµCCC µCkü‡¡§˜‡´hk (private) ¤ (member) Ûõ§˜‡´é úm (public) ¤ ?U›"w˜ã^r§S clz1m.c µ 56 // wcl386 -wx -s -ecc clz1m.c clz1.c #include #include #include "clz1.h" int main() { objT *a, *b; a = clz__new("Alice"); b = clz__new("Bob"); a->say(a);//I’m Alice, I’m a Klass. clz__teachChinese(a); a->say(a);//Wo shi Alice, wo shi yige Klass. b->say(b);//I’m Bob, I’m a Klass. // b->say = a->say; // E1013: Constant variable cannot be modified a->teach(a, b); b->say(b);//Wo shi Bob, wo shi yige Klass. free(a); free(b); return 0; } l¥Œ±wµ •·‚ØI‡ objT S܍õ&E§‡U (N^ say Ú teach Ҍ± "¤±§·‚^ clz__new 5)¤¢~" • ~¥§)¤˜‡¢~I©S¿DЊ§¿ÃÙ¦¯‘"ƒA /§¤˜‡¢~Iº˜S=Œ§ÃÙ¦¯‘"¤±ÒvkJø clz__delete" • ¤ ƒm!¢~†Xڃm§ 3A½'é'X§¡ê☠—5"{ü/?Uü˜¤ ØÙ¦§ÒŒU»€ê☗5"¤ ±§·‚F"U ;– b->say = a->say ù^r“觓ƒ± a->teach(a, b) ùkŬ?1?n“è" âd·‚OÞ©‡ clz1.h Xeµ #ifndef _CLZ1_H_ #define _CLZ1_H_ typedef struct obj_st objT; struct obj_st { // ’const’, and no private part void (*const say)(objT *o); void (*const teach)(objT *t, objT *s); }; objT *clz__new(char *n); void clz__teachChinese(objT *o); #endif 57 3ù‡Þ©‡¥§'u objT m˜ ü‡¤ ¼ê§ …Ñ´ const§^r “èØU/UÏ~{0?Uùü‡¼ê"XJ^r2½Â˜‡(a .§íØÙ¥ const§,‰r›a.=†§@„´Œ±?U" ¢y¬ clz1.c µ // wcc386 -wx -s -ecc clz1.c #include #include #include "clz1.h" typedef struct clz_st clzT; struct clz_st {char *name;}; static clzT clz = {"Klass"}; typedef struct _obj_st _objT; struct _obj_st { // public: (with ’const’ removed) void (*say)(objT *o); void (*teach)(objT *t, objT *s); // private: clzT *clazz; char *name; }; static void obj__say(objT *o); static void obj__sayChinese(objT *o); static void obj__teach(objT *t, objT *s); objT *clz__new(char *n) { _objT *p; if (NULL == (p = malloc(sizeof(_objT)))) exit(1); p->clazz = &clz; p->name = n; p->say = obj__say; p->teach = obj__teach; return (objT *)p; } void clz__teachChinese(objT *o) { _objT *_o = (_objT *)o; _o->say = obj__sayChinese; } void obj__say(objT *o) { 58 _objT *_o = (_objT *)o; printf("I’m %s, I’m a %s.\n", _o->name, _o->clazz->name); } void obj__sayChinese(objT *o) { _objT *_o = (_objT *)o; printf("Wo shi %s, wo shi yige %s.\n", _o->name, _o->clazz->name); } void obj__teach(objT *t, objT *s) { _objT *_t = (_objT *)t, *_s = (_objT *)s; _s->say = _t->say; } Œ±wѧ·‚^Ò´/­#½Â˜‡(§¿¦^r›a.=†0 {§5O\hk¤ ¿¼?U" –a¶¡ù/aêâ0§·‚^˜‡( clzT 5µC"ù‡( Øé úm"‡XÚ¥3 clzT ˜‡¢N"^r“èÃ{–¯ù‡¢ N"§3UÏL¢~/10LyÑ5"'X a->say(a) ¬‹<Ñ I’m Alice, I’m a Klass.§Ù¥iÎG Klass Ò´ clzT ¢Npêâ" 3.6 ···ééé???†††ÄÄÄééé??? þ~¥§é clz__new z˜gN^§Ñ‰1ƒÓ“è¢N"ù«lN ^Šé“è¢N½'X¡·é?" ´§3e¡ùã“襵 a->say(a);//I’m Alice, I’m a Klass. clz__teachChinese(a); a->say(a);//Wo shi Alice, wo shi yige Klass. éÎÒ a->say ügN^§‰1´ØÓ“è¢N"1˜g´ obj__say§ 1g´ obj__sayChinese"Ò´`§a->say .†=‡“è¢Nƒ'é§ ´‡‘X§S$1 ŒUu)ÄUC¯œ"ù«lN^Šé“è¢N Ä'X¡Äé?" 3 C Šó¡§·é?Ò´ func()§Äé?Ò´ (*pfunc)()"3 ®?¡§cöÒ´ call _func§öÒ´ call dword ptr _pfunc"½ö `§écö§“è¢Nå©/Œ´z3“è㥍-p¡§¤±ØŒ U¶ éö§“è¢Nå©/Œ´;3êâã¼êp¡§Œ ±?Uù‡§4§•.ƒÓ,˜‡¼ê§¤±^ù‡‰N^§ Ò´Ä" 59 óìr˜‡¬¢N˜?N”©‡§¡·ó¶rÚ\¼ê __import__xxx ˜?Ú\L(import table)§4C1ì3$1ž§ŠâN”¢ SC1œ¹5?UÚ\L§ª(½¼ê¢S•§¡Äó" 3.7 êêê|||¯¯¯KKK†††(((iii@@@¯¯¯KKK Þ©‡´¬^r†¢yöƒmÆ"þãY¥§¢yö3¬S Üra(‰ ­#½Â§ ^rÃ{¡"ù¬‘5˜ ¯K" Äk´ê|¯K"^rŒUù˜ã§Sµ objT a[2]; a[1].say(&a[1]);//NO! ùž a[1] ?u a[0] hkê⫍§§¢SþCX a[0].clazz" )û{Œ±´˜ï¦^ C?Èìê|öŠÎ§z‡¦^ê|a ѽ˜‡ clz__newArray()!clz__deleteArray() Ú clz__getAt"XJ\ ´O˜‡#Šó§U 4?Èìrù˜ƒgÄ?n§Ò– C++ @§½N „Œ±É"‡<ó‰ù ¯§¤Òp " „k(i@¯K"XJ^rµ struct usr_st { objT obj; int id; }; @o§ù‡ id qr obj hkêâCX " (i@I‡3?Èϼ(º€Úéà‡¦§ ¼êUé$1Ï êâ?1+n"¤±§ù‡¯KÃ)" 3.8 UUU???µµµCCCYYY XJr clz1.h O†¤XeSNµ #ifndef _CLZ1_H_ #define _CLZ1_H_ typedef struct obj_st objT; struct obj_st { // without the private part // public: (with ’const’ removed) void (*const say)(objT *o); void (*const teach)(objT *t, objT *s); // private: struct clz_st *__1; char *__2; }; 60 objT *clz__new(char *n); void clz__teachChinese(objT *o); #endif @o§ê|¯KÚ(i@¯KÒÑ)û " 5¿µUÞ©‡ƒ§·‚^r¬Ú¢y¬ “èÃI?ÛC ħ´I‡­#?È" 3.9  (interface) OO Nõ¶c§¹Â¿Ø˜—"©¤ù§Q– Java  interface§q– C++ Ėa"äN¹Â„´^§S5`{j"w nf1m.c µ // wcl386 -wx -s -ecc nf1m.c nf1alice.c nf1bob.c #include #include "nf1alice.h" #include "nf1bob.h" int main() { Alice->s_nf.say(& Alice->s_nf);//Wo shi Alice. Bob->s_nf.say(& Bob->s_nf);//I’m Bob. Alice->t_nf.teach(& Alice->s_nf, & Bob->s_nf); Bob->s_nf.say(& Bob->s_nf);//Wo shi Bob. return 0; } ù‡§Sü«ù˜‡¯µAlice `¥©§Bob `=©§Alice  Bob `¥ ©§Bob Ƭ `¥©" Alice ¢ykü‡§˜‡/U`0§,˜‡/U0" kw/U`0Þ©‡ nf1s.h µ #ifndef _nf1s_h_ #define _nf1s_h_ typedef struct s_nf_st s_nfT; typedef void (s_nf__say)(s_nfT *o); struct s_nf_st { char **pname; s_nf__say *say; }; #endif XJ˜‡a¢yk/U`0§@o§¢~Ҍ±N^ù‡p¼ê say" 2w/U0 nf1t.h µ 61 #ifndef _nf1t_h_ #define _nf1t_h_ #include "nf1s.h" typedef void (t_nf__teach)(s_nfT *t, s_nfT *s); typedef struct { t_nf__teach *teach; } t_nfT; #endif ¢ykù‡¢~ь±N^ teach" main p¡1˜é Alice->s_nf.say(& Alice->s_nf); ¿g´`µAlice Š˜‡/U`0<§/`0'ugCŠ˜‡U`<¯œ"ù‡{ ¹éõ‡ƒ"·‚˜‡˜‡5©Ûµ • Alice Š˜‡/U0<§U/`0Ÿo¯œíºØU"Ϗ/U 0p¡§k˜‡/0¼ê§vk/`0¼ê"t_nf.say Ø 3"Ón§s_nf.teach Ø3" • Alice U/`0'uO<Š˜‡/U`0<¯œíº‡@‡<¢ y /U`0§ÒŒ±" • Alice U/`0'uO<Š˜‡/U0<¯œíºØU"ù´ /`0¼ê¼ê.û½" 2w1néµ Alice->t_nf.teach(& Alice->s_nf, & Bob->s_nf); Alice Š/U0<§r Alice Š/U`0<˜ +§‰ Š /U`0< Bob" Alice Ú Bob ´ü‡a"kw Alice Þ©‡ nf1alice.h µ #ifndef _nf1alice_h_ #define _nf1alice_h_ #include "nf1s.h" #include "nf1t.h" typedef struct { t_nfT t_nf; s_nfT s_nf; //private char *__1; } AliceT; extern AliceT *Alice; #endif 62 ¢y“è´‘nt1alice.c µ #include #include "nf1alice.h" typedef struct { t_nfT t_nf; s_nfT s_nf; // private char *name; } _AliceT; static s_nf__say alice__say; static t_nf__teach alice__teach; static _AliceT _Alice = {{alice__teach}, {&(_Alice.name), alice__say}, "Alice"}; AliceT *Alice = (AliceT *)&_Alice; void alice__say(s_nfT *s) { printf("Wo shi %s.\n", *(s->pname)); } void alice__teach(s_nfT *t, s_nfT *s) { s->say = t->say; } Bob ¢y ˜‡"ÙÞ©‡´ nf1bob.h µ #ifndef _nf1bob_h_ #define _nf1bob_h_ #include "nf1s.h" typedef struct { s_nfT s_nf; //private char *__1; } BobT; extern BobT *Bob; #endif ¢y“è´ nf1bob.c µ #include #include "nf1bob.h" typedef struct { 63 s_nfT s_nf; // private char *name; } _BobT; static s_nf__say bob__say; static _BobT _Bob = {{&(_Bob.name), bob__say}, "Bob"}; BobT *Bob = (BobT *)&_Bob; void bob__say(s_nfT *s) { printf("I’m %s.\n", *(s->pname)); } Ÿo/U`0p¡‡^•iÎG§ Ø´†¦^iÎG Qº Ϗ˜‡a§=¦vk¢y/U`0§ŒUk¶i name"/U `0´Ú^ù‡¶i§ Ø´½Âù‡¶i§ØKIù‡¶iJø ;˜m"¹…§OŒUÚ^ù‡¶i"'X/UU¶0§Jø˜ ‡/­·¶0¼ê"XJ^rÏL/­·¶0¼êr Alice ¶iU¤ Anny §@o say ¼êAT‹Ñ/·´ Anny0§‡‡NÑù«Cz" oƒ§þãVg§3ÊÏOOÄ:þ§q\ ˜Ä–"r a->func(a,b); C¤ a->nfA.func(a->nfA, b->nfB); ¦閆閃mpžÿ§7LÏL˜½"ùQo SÜê â§q´LÚ5‰ 閃mp§ 3.10 aaa†††¢¢¢~~~ þ~ ㎯§ü‡aѐ^·ۍ‰ ˜‡¢~"¢Sþ§· ‚Œ±^ new Ú delete )¤Ú¤¢~"a struct Ú¢~Œ±ØÓ"ƒ A/Òk aÚ¢~ØÓ" a(¥¡a"§Úaê☧k˜°·€§Ï~ ج?U" ¢~(¥¡¢~"§Ú¢~ê☧z‡¢~k˜°€ §Œ±?U§l UCT¢~/1ª0§جKÙ¦¢~" •¥V\#¤ §¡*¿"=Ò*¿ù‡öŠ ó§˜ „kaЩzêâI‡Ö¿ƒA‘8§Ù¦“èÑØÉK" 64 Ø3¢~z¯K"§7L˜3a¥§Ša½ö¢~ §âU¢SužŠ^" 3.11 ¡¡¡•••§§§SSSOOO [%w(ŒU¬uyµþ~¥§Bob SC Alice ¬p˜‡¼ ê"ù3˜„œ¹e´éˆx"XJ Alice ´˜‡Ä©¢~§@o3 Alice ¤§Sº˜ƒ§2N^ Bob ù‡¼ê§Ò¬)é/ý ÂS«0?1Ú^¯K§Ù(J´Ø(½" ·‚3 nf1s.h ¥\ü1µ void s_nf__say_en(s_nfT *s); void s_nf__say_zh(s_nfT *s); ¿^ nf1s.c 5¢yùü‡¼êµ #include #include "nf1s.h" void s_nf__say_en(s_nfT *s) { printf("I’m %s.\n", *(s->pname)); } void s_nf__say_zh(s_nfT *s) { printf("Wo shi %s.\n", *(s->pname)); } r nf1alice.c ¥ alice__say .Ú¼êNÑK§r _Alice Щz ŠéU¤µ static _AliceT _Alice = {{alice__teach}, {&(_Alice.name), s_nf__say_zh}, "Alice"}; é nf1bob.c ùo‰§K bob__say .Ú¼êN§r _Bob ЩzŠ éU¤µ static _BobT _Bob = {{&(_Bob.name), s_nf__say_en}, "Bob"}; ^ wcl386 -wx -s -ecc nf1m.c nf1alice.c nf1bob.c nf1s.c ­#?ȧ Òrþã¯K)û "y3§say_en Ú say_zh ®²†äN¢~ø§Œ±Õ á3"teach J§† Bob ЩzžÀJ say_zh ´˜" ØUüÕ¢~z§¿Ø¿›XØU±Ä:?1?§"± Ä:?1?§¡¡•?§§Œ±Ž´ OO?§˜‡©|" ±þ·‚3 s_nf ¢y¬¥§¼ê say O ü‡¢y" 3Щzaêâ½öMï¢~žÿ§^rŒ±ÀJæ^Û«¢y"3ù‡¿ 65 Âþ§é”´ C++ ¥J¼êL(virtual function table)"XJp ,‡¼ê3¬¥vk?Û¢y§7Ld¢yTa5Jø¼êN§ @où‡¼ê҃u C++ ¥XJ¼ê (pure virtual function)" 3.12 UUU««« “We are what we do.” aÚ¢~´Xd"§‚´Ÿo§û½u§‚‰Ÿ o"Q,§‚/‰¯07LÏL§@oaÚ¢~¤¢y§¢Sþ½  aÚ¢~ÜSº" ƒmŒ±3U«'X"Xeãµ A:(a, b) B:((a, b), c, d) C:(g, h) D:(((a, b), c, d), e, f, (g, h))  BU«  A§¡üU«" DU«  BÚC§¡õU «"õU«S1˜‡¤ §¡1˜I"~X§A ´ B 1˜I §B ´ D 1˜I" þãU«'XŒ±^§S nf3.c 5ü«µ // wcl386 -wx -s -ecc nf3.c #include #define P(x) fprintf(stderr, "%s", x) typedef void (*F)(); typedef struct {F a, b;} A; typedef struct {A _A; F c, d;} B; typedef struct {void (*g)(B *); F h;} C; typedef struct {B _B; F e, f; C _C;} D; typedef struct {D _D;} O; void a(){P("a");} void b(){P("b");} void c(){P("c");} void d(){P("d");} void e(){P("e");} void f(){P("f");} void g(B *i){P("g");} void h(){P("h");} O _J = {{{{a,b},c,d},e,f,{g,h}}}, *J=&_J; int main() { J->_D.e(); P("\n"); J->_D._C.g(& J->_D._B); P("\n"); J->_D._B.c(); P("\n"); J->_D._B._A.a(); P("\n"); 66 return 0; } ùpŒCzœ¹š~õ§A^š~(¹"Ø2˜˜Þ" XJ\vù«˜˜Ú^ª憧Œ±3 new žÿ§W˜‡ SÜÚ^L§P¥¼ê/Œ",3T¢~)·ÏS§ÏLS ÜÚ^L5?1¼êN^"X nf5.c ¤«µ // wcl386 -wx -s -ecc nf5.c #include #include #define P(x) fprintf(stderr, "%s", x) typedef void (*F)(); typedef struct {F a, b;} D; typedef struct {F *_a, *_b;} O_imtT; typedef struct {D _D; O_imtT imt; void (*f)(void*);} O; void a(){P("a");} void b(){P("b");} void f(void *d) { O *p = (O *)d; O_imtT *t = & p->imt; (* t->_a)(); } O *O__new() { O *p = (O*) malloc(sizeof(O)); p->_D.a = a; p->_D.b = b; p->imt._a = & p->_D.a; p->imt._b = & p->_D.b; p->f = f; return p; } int main() { O *J = O__new(); J->f(J); P("\n"); free(J); return 0; } 3i@gõ!¶¡žÿ§(* t->_a)(); U' J->_D.a(); {B˜ " 67 3.13 õõõ õ´Ó˜¯Ô!½Ó˜a¯Ô§LyÑõ«5"'Xc¡ùL Bob§¦k´`=Š§,qƬ `NJ"¦Ә‡1/say0LyÑü «ØÓ(J"l,«¿Âþù§ùŽ´˜«õ"?§þ~„œ¹ ´ê|Ú¼êëêõ" ˜„@kÓa.ƒ§âU|¤ê|"´·‚§´NX 3a½ö¢~þ§‘XaЩz½ö¢~)¤ ¼DŠ"ù§Óa. §Ù¢S¹ÂҌU‘¤NXa½ö¢~ØÓ ØÓ"Ï §• ê|§Œ±LyÑõ"w§S p1.c µ // wcl386 -wx -s -ecc p1.c #include typedef struct nfA_st nfAT; typedef void (*F)(nfAT *a); struct nfA_st {F say;}; typedef struct {nfAT A;} CT; typedef struct {int i; nfAT A;} DT; static void f1(nfAT *a){printf("Hello!\n");} static void f2(nfAT *a){printf("Nihao!\n");} CT _C = {{f1}}, *C = &_C; DT _D = {0, {f2}}, *D = &_D; void p(nfAT *t) { t->say(t); } int main() { nfAT *a[2] = {&(_C.A), &(_D.A)}; int i; for (i=0; i<2; i++) { a[i]->say(a[i]); p(a[i]); } return 0; } Ó˜é a[i]->say(a[i]);§‰1¢S“è%ØÓ" ¼êëêXJ´§@o3¼êNSܦ^ù‡¥¼ê§ ŒU)õ"'X§S¥ t->say(t);"D\ØÓ§ù‡Šé¢S N^“èØÓ" Nõ OO ?§ŠóÑ5½§3a.=†ž§Nrfa=†¤ˆ?1˜ Ia§ ØU=†¤õU«¥Ù¦Ia"Ϗ§éù Šó5`§˜‡/é –0k˜‡ ˜Œ±Ú^§@Ò´§¢Nå© ˜"´§±þ0  68 ¡•?§§‰½˜‡¢~§§¤kIÑkŒ±Ú^ ˜§¤ ±§Ø3a.=†þ(J"ù¦?È쌱‰é¡a.u" 4 gggÄÄÄÅÅņ††///ªªªŠŠŠóóó 4.1 ããã(((ÅÅÅ ã(Å(Turing) ´8c®OŽUårnØOŽÅ")öÒ 5Computability and Unsolvability by Martin Davis (McGraw-Hill, 1958)6§ £k¥È5ŒOŽ5†ØŒ)5£®ŒÆч§1984¤6¤‰L˜ ) P"éØùÖw(Œ±l)P¥é˜ ƒ'SN" )ö¢y ˜‡ã(Å"Ø ‘½ÚiÎ8kü‡i1ƒ § §äkã(ÅÙ¦܇ƒ"ùéu0 ã(ÅÄVg5`§®² ^ " w§S turing.c µ //wcl386 -wx -s -ecc turing.c #include #include typedef unsigned char byte; #define Q(i) (128+(i)) #define P(i) ((i)-128) #define X(c) ((c)==’B’?0:(c)==’1’?1:(c)) #define Y(i) ((i)==0?’B’:(i)==1?’1’:(i)) enum {B=’B’, I=’1’, N=’N’, R=’R’, L=’L’}; typedef struct { byte qk;// > 128, qk; otherwise B/1/R/L byte ql;// > 128 } Inst; Inst _instplus[][2] = { // instplus {{0,0}, {0,0}}, {{R, Q(2)}, {B, Q(1)}},//q1 {{R, Q(3)}, {R, Q(2)}},//q2 {{N, 0}, {B, Q(3)}}//q3 }; byte _bandplus[] = "11B111"; // (1,2) Inst _instCA[][2] = { // instCA {{0,0}, {0,0}}, {{Q(2), Q(3)}, {B, Q(1)}},//q1 {{R, Q(4)}, {N, 0}},//q2 {{R, Q(5)}, {N, 0}},//q3 {{N, 0}, {B, Q(2)}},//q4 {{I, Q(3)}, {B, Q(3)}}//q5 69 }; byte _bandCA3[] = "1111B"; // (3) byte _bandCA4[] = "11111B"; // (4) int A[] = {2,4,6,8}; typedef struct { Inst (*inst)[][2]; byte (*tape)[]; byte *head; byte pc; } Turing; Turing tmplus = {&_instplus, &_bandplus, _bandplus, 1}, tmCA = {&_instCA, &_bandCA3, _bandCA3, 1}; int res(Turing *t) // result { int i, r; byte *p; r = 0, p = * t->tape; for (i = 0; i < strlen(p); i++) if (I == p[i]) r++; return r; } int inA(Turing *t) // \in A { int i, r; for (r = res(t), i = 0; i < sizeof(A)/sizeof(A[0]); i++) if (r == A[i]) return 1; return 0; } void id(Turing *t) // instante description { int i; Inst *s; for (i = 0; i < strlen(* t->tape); i++) { if (&(* t->tape)[i] == t->head) { printf("<%c>", (* t->tape)[i++]); if (i >= strlen(* t->tape)) break; } else { printf(" "); } printf("%c", (* t->tape)[i]); } if (&(* t->tape)[i-1] != t->head) printf(" "); s = &(* t->inst)[t->pc][X(* t->head)]; if (N != s->qk) { 70 printf(" ; q%d %c", t->pc, * t->head); switch (s->qk) { case R: case L: case B: case I: printf(" %c", s->qk); break; default: printf(" q%d", P(s->qk)); } printf(" q%d\n", P(s->ql)); } } int final(Turing *t) { Inst *s; s = &(* t->inst)[t->pc][X(* t->head)]; return (N == s->qk); } void step(Turing *t) { Inst *s; s = &(* t->inst)[t->pc][X(* t->head)]; switch (s->qk) { case N: return; case R: t->head ++; t->pc = P(s->ql); break; case L: t->head --; t->pc = P(s->ql); break; case B: * t->head = B; t->pc = P(s->ql); break; case I: * t->head = I; t->pc = P(s->ql); break; default: // qk if (inA(t)) t->pc = P(s->qk); else t->pc = P(s->ql); } } int main() { for (id(&tmplus); !final(&tmplus); ) { step(&tmplus); id(&tmplus); } printf(" ; res = %d.\n\n", res(&tmplus)); for (id(&tmCA); !final(&tmCA); ) { step(&tmCA); id(&tmCA); } printf(" ; res = %d.\n\n", res(&tmCA)); 71 tmCA.tape = &_bandCA4; tmCA.head = _bandCA4; tmCA.pc =1; for (id(&tmCA); !final(&tmCA); ) { step(&tmCA); id(&tmCA); } printf(" ; res = %d.\n\n", res(&tmCA)); return 0; } T§Sü« ü‡ã(ÅngOŽL§" 1˜‡´ 1+2=3 OŽL§"ÑÑ(Jµ <1>1 B 1 1 1 ; q1 1 B q1 1 B 1 1 1 ; q1 B R q2 B<1>B 1 1 1 ; q2 1 R q2 B 11 1 1 ; q2 B R q3 B 1 B<1>1 1 ; q3 1 B q3 B 1 B1 1 ; res = 3. 1‡´·K 3 ∈{2, 4, 6, 8} ½L§"ÑÑ(Jµ <1>1 1 1 B ; q1 1 B q1 1 1 1 B ; q1 B q2 q3 1 1 1 B ; q3 B R q5 B<1>1 1 B ; q5 1 B q3 B1 1 B ; q3 B R q5 B B<1>1 B ; q5 1 B q3 B B1 B ; q3 B R q5 B B B<1>B ; q5 1 B q3 B B BB ; q3 B R q5 B B B B ; q5 B 1 q3 B B B B<1> ; res = 1. ù‡ res = 1 L«Ä½"ù«† C Šóƒ‡½§5guù*gµ XJ x ∈ A§@o§´§ CA(x)=0 )"y3OŽ(JL² CA(3) = 1§ @o˜½k 3 6∈ A" 1n‡^„´þ˜‡ã(ŧ´UC Ñ\§Ò´·K 4 ∈ {2, 4, 6, 8} ½L§"ÑÑ(Jµ <1>1 1 1 1 B ; q1 1 B q1 1 1 1 1 B ; q1 B q2 q3 1 1 1 1 B ; q2 B R q4 B<1>1 1 1 B ; q4 1 B q2 B1 1 1 B ; q2 B R q4 72 B B<1>1 1 B ; q4 1 B q2 B B1 1 B ; q2 B R q4 B B B<1>1 B ; q4 1 B q2 B B B1 B ; q2 B R q4 B B B B<1>B ; q4 1 B q2 B B B BB ; q2 B R q4 B B B B B ; res = 0. ù‡ res = 0 L«’½" §SA´g²"E,Ž{ã(ŌUI‡Ú?#ÎÒ"ùž _inst ‡U¤n§$–oL§ Ø´y3ü"ù UÄé†x§[ ØKã" 4.2 †††^^^ C???111ããã(((ÅÅÅ???§§§ ˜‡g,Ž{´µO˜‡§S§Ö\£©/ª¤ã(ō-8Ú Ð©Ñ\§¦ÑTã(ÅéTÑ\OŽ(J" ·‚ØI‡˜‡/ã(ō-80?Èì§Ï$^ C Šó÷½ÂA 5§Œ±†3 C §S¥Öã(ō-8"w§S cturing.c µ //wcl386 -wx -s -ecc cturing.c #include #include int A[] = {2,4,6,8}; char *tape, *head; int rB(){return ’B’==*head;} void R(){head++;} void L(){head--;} void B(){*head = ’B’;} void I(){*head = ’1’;} int res() // result { int r, i; for (r = 0, i = 0; i < strlen(tape); i++) if (’1’ == tape[i]) r++; return r; } int inA() // \in A { int i, r; for (r = res(), i = 0; i < sizeof(A)/sizeof(A[0]); i++) if (r == A[i]) return 1; return 0; } 73 void id(char *s) // instante description { int i; for (i = 0; i < strlen(tape); i++) { if (&tape[i] == head) { printf("<%c>", tape[i++]); if (i >= strlen(tape)) break; } else { printf(" "); } printf("%c", tape[i]); } if (&tape[i-1] != head) printf(" "); printf(" // %s\n", s); } // ’S’ stands for Simple #define IS(x,y) {x(); goto y;} // ’R’ stands for Relative #define IR(x,y) {if(inA()) goto x; else goto y;} // ’N’ stands for NULL #define IN {return;} #define Q(z,x,y) z: id(#z ": " #x ", " #y); if(rB()) x else y void plus() { Q(q1, IS(R, q2), IS(B,q1)) Q(q2, IS(R, q3), IS(R, q2)) Q(q3, IN, IS(B,q3)) } void CA() { Q(q1, IR(q2,q3), IS(B,q1)) Q(q2, IS(R, q4), IN) Q(q3, IS(R, q5), IN) Q(q4, IN, IS(B,q2)) Q(q5, IS(I,q3), IS(B,q3)) } int main() { head = tape = "11B111"; plus(); 74 printf("res = %d.\n\n", res()); head = tape = "1111B"; CA(); printf("res = %d.\n\n", res()); head = tape = "11111B"; CA(); printf("res = %d.\n\n", res()); return 0; } ÑÑ(Jµ <1>1 B 1 1 1 // q1: IS(R, q2), IS(B,q1) 1 B 1 1 1 // q1: IS(R, q2), IS(B,q1) B<1>B 1 1 1 // q2: IS(R, q3), IS(R, q2) B 11 1 1 // q2: IS(R, q3), IS(R, q2) B 1 B<1>1 1 // q3: IN, IS(B,q3) B 1 B1 1 // q3: IN, IS(B,q3) res = 3. <1>1 1 1 B // q1: IR(q2,q3), IS(B,q1) 1 1 1 B // q1: IR(q2,q3), IS(B,q1) 1 1 1 B // q3: IS(R, q5), IN B<1>1 1 B // q5: IS(I,q3), IS(B,q3) B1 1 B // q3: IS(R, q5), IN B B<1>1 B // q5: IS(I,q3), IS(B,q3) B B1 B // q3: IS(R, q5), IN B B B<1>B // q5: IS(I,q3), IS(B,q3) B B BB // q3: IS(R, q5), IN B B B B // q5: IS(I,q3), IS(B,q3) B B B B<1> // q3: IS(R, q5), IN res = 1. <1>1 1 1 1 B // q1: IR(q2,q3), IS(B,q1) 1 1 1 1 B // q1: IR(q2,q3), IS(B,q1) 1 1 1 1 B // q2: IS(R, q4), IN B<1>1 1 1 B // q4: IN, IS(B,q2) B1 1 1 B // q2: IS(R, q4), IN B B<1>1 1 B // q4: IN, IS(B,q2) B B1 1 B // q2: IS(R, q4), IN B B B<1>1 B // q4: IN, IS(B,q2) B B B1 B // q2: IS(R, q4), IN B B B B<1>B // q4: IN, IS(B,q2) B B B BB // q2: IS(R, q4), IN B B B B B // q4: IN, IS(B,q2) res = 0. 75 4.3 ããã(((ÅÅÅSSSÜÜÜGGG††† C ŠŠŠóóóŠŠŠéééIII\\\ rþ~÷Ðm§2Ø id(s)§ÒŒ±XeN´n)/ªµ //wcl386 -wx -s -ecc ctm2.c #include #include int A[] = {2,4,6,8}; char *tape, *head; int rB(){return ’B’==*head;} void R(){head++;} void L(){head--;} void B(){*head = ’B’;} void I(){*head = ’1’;} int res() // result { int r, i; for (r = 0, i = 0; i < strlen(tape); i++) if (’1’ == tape[i]) r++; return r; } int inA() // \in A { int i, r; for (r = res(), i = 0; i < sizeof(A)/sizeof(A[0]); i++) if (r == A[i]) return 1; return 0; } void plus() { q1: if(rB()) {R(); goto q2;} else {B(); goto q1;} q2: if(rB()) {R(); goto q3;} else {R(); goto q2;} q3: if(rB()) {return; } else {B(); goto q3;} } void CA() { q1: if(rB()) {if(inA()) goto q2; else goto q3;} else {B(); goto q1;} q2: if(rB()) {R(); goto q4; } else {return;} q3: if(rB()) {R(); goto q5; } else {return;} q4: if(rB()) {return; } else {B(); goto q2;} q5: if(rB()) {I(); goto q3; } else {B(); goto q3;} } int main() 76 { head = tape = "11B111"; plus(); printf("res = %d.\n\n", res()); head = tape = "1111B"; CA(); printf("res = %d.\n\n", res()); head = tape = "11111B"; CA(); printf("res = %d.\n\n", res()); return 0; } ·‚wã(ÅSÜG£q¡SÜÙÛ¤† C ŠóŠéI\ƒm§kX ˜«¿›éX" 4.4 {{{üüüããã(((ÅÅņ††ŒŒŒãããXXXÚÚÚ Ø¹ IR(qi,qj) /ª-ã(ŧ¡{ü (simple) ã(Å"þ㉠\{ã(ŧҴ˜‡{üã(Å"þã‰\{L§qŒ±£ãµ {q1} 1 1 B 1 1 1 // q1: IS(B,q1) P {q1} 1 Q => P {q1} B Q {q1} B 1 B 1 1 1 // q1: IS(R, q2) P {q1} B Q => P B {q2} Q B {q2} 1 B 1 1 1 // q2: IS(R, q2) P {q2} 1 Q => P 1 {q2} Q B 1 {q2} B 1 1 1 // q2: IS(R, q3) P {q2} B Q => P B {q2} Q B 1 B {q3} 1 1 1 // q3: IS(B,q3) P {q3} 1 Q => P {q3} B Q B 1 B {q3} B 1 1 // q3: IN Ù¥ P {q1} B Q => P B {q2} Q ùªf¡)ª (production)"Šâ þã\{ō-8§Œ±‰Ñʇ)ªµ {q1} B => B {q2}, {q1} 1 => {q1} B, {q2} B => {q3} B, {q2} 1 => 1 {q2}, {q3} 1 => {q3} B. rù )ªA^uЩ£ãiÎG{q1} 1 1 B 1 1 1§ÒŒ±˜ÚÚ?1 þã/í0L§§†vk)ªŒø?1e˜Ú폎" ±ù‡gŽÄ:§2Ö¿XeEâ[!§Ò¤¤¢Œã (semi- Thue) XÚµ •O\n‡ÎÒ h, q, r" 77 • rЩ£ãiÎG)3ü‡ h ƒm§= h {q1} 1 ... h" • éz‡m£- qiSjRqℓ§Ö¿˜‡)ª qiSjh ⇒ SjqℓBh" • éz‡†£- qiSjLqℓ§Ö¿˜‡)ª hqiSj ⇒ hqℓBSj" • éz‡Ê- qiSjN§Ö¿˜‡)ª qiSj ⇒ qSj" • é¤k Si§Ö¿)ª qSi ⇒ q, qh ⇒ rh, Sir ⇒ r" ù˜5§þã\{(J„Œ±UYíµ h B 1 B {q3} B 1 1 h // q3 B => q B hB1BqB11h //qB=>q hB1Bq11h //q1=>q hB1Bq1h //q1=>q hB1Bqh //qh=>rh hB1Brh //Br=>r hB1rh //1r=>r hBrh //Br=>r h r h // Done dd‘5Ð?´µXJ‰½{üã(Å3‰½Ñ\eU Êŧ@oéA ŒãXÚ3éAЩGeҘ½U í hrh" ‘d3¦@Ö¥y² þãL§Œ±L5µ?ۘ‡ÎÒG§Œ ±^þãŒãXÚ_)ª§lЩÎÒG hrh m©§ÅÚíÑ5§ …=§r§˜ƒA{üã(Åþ‰OŽ§Tã(ÅU ªÊÅ"' X§þãã(ÅÑ\GŒ±ùíÑ5µ h r h // Start hBrh //r=>Br hB1rh //r=>1r hB1Brh //r=>Br hB1Bqh //rh=>qh hB1Bq1h //q=>q1 hB1Bq11h //q=>q1 hB1BqB11h //q=>qB h B 1 B {q3} B 1 1 h // q B => q3 B h B 1 B {q3} 1 1 1 h // {q3} B => {q3} 1 h B 1 {q2} B 1 1 1 h // B {q2} => {q2} B h B {q2} 1 B 1 1 1 h // 1 {q2} => {q2} 1 h {q1} B 1 B 1 1 1 h // B {q2} => {q1} B h {q1} 1 1 B 1 1 1 h // {q1} B => {q1} 1 5¿ q Ú r ØU3ã(ÅÑ\G¥Ñy"ùÎÒ¡šª(Î(non- terminal)"Ù¦ÎÒ¡ª(Î(terminal)"U lЩÎÒG hrh í Ñ5ÎÒG§¡é."عšª(Îé.¡Šé (sentence)"‰½ )ªXÚ§¡©{(gramma)"^‰½©{U íÑ5¤kŠé8 ܧ¡T©{¤)/ªŠó (formal language)" 78 4.5 ///ªªªŠŠŠóó󆆆gggÄÄÄÅÅÅ©©©aaa †ã(ŃéA©{¡ 0-.©{"§¤)Šó3êÆþ¡/4 8ŒqÞ(recursively enumerable)08Ü" XJ¤k)ª†>Ý،um>ݧ@oT©{¡ 1-.©{" ˜„ŒãXÚ©{Ø´ 1-.©{"Ϗéuã(ņ£Úm£ -§éAkü‡)ª hqℓBSj ⇒ hqiSj ÚSjqℓBh ⇒ qiSjh§§‚†>Ý Œum>Ý"£5¿ŠéíÚã(ÅOŽ´•ƒ‡"¤ù¿›Xã( ʼn/©Û0ž§I‡¦^ЩŠéƒ ‘þ˜m" é©Û 1-.Šóã(Å5`§I‡ý3‘õ‘©ÛŠéÝ O ‚5O"¤±§ùã(Å¡‚5k.gÄÅ(Linear Bounded Automaton, LBA)" 1-.©{;.~f´)¤ {anbncn : n ∈ N} Šó©{"§˜‡í ¢~µ S ⇒ aS BC {S ⇒ aSBC} ⇒ aaB CB C {S ⇒ aBC} ⇒ aaB HB C {CB ⇒ HB} ⇒ aaB HC C {HB ⇒ HC} ⇒ a aB BCC {HC ⇒ BC} ⇒ aa bB CC {aB ⇒ ab} ⇒ aab bC C {bB ⇒ bb} ⇒ aabb cC {bC ⇒ bc} ⇒ aabbcc {cC ⇒ cc} 5¿ C k3;‹ B žÿâC¤ H§= CB ⇒ HB"Ò´`§šª( ÎÐm¤Ÿo§†§¤?þe©‚¸k'"¤±§1-.©{q¡þe©ƒ '©{(Context Sensitive Grammar§CSG)" XJã(ÅÖÞ´Ö§ …´•m£Ä§@o§ù«ã( ÅÒ¡kGgÄÅ(Finite State Automaton, FSA)"ƒA©{¡ †‚5 (left linear) ©{§¡†5 (left regular) ©{"§kn«/ª )ªµA ⇒ ε!A ⇒ Ba ÚA ⇒ a"'X)¤Šó {(ab)n : n ≥ 0} ©{ ´µS ⇒ ε, S ⇒ Ab, A ⇒ Sa" z‡†5©{Ñk˜‡dm5©{§üö)Ә‡Šó"¤ ±§ùŠó~~†¡5Šó§ Ø7«©§´†„´m" ´§XJ˜‡©{¥§Qk†‚5)ª§qkm‚5)ª§@ o§§¤)ŠóÒØ´5Šó "§¤k)ª˜„5Ÿ´µ†> k˜‡šª(Χ m>õk˜‡šª(Î"ù©{¡‚5© {" 79 r‚5©{^‡?˜Ú˜°§#N)ªm>Ñyõ‡šª(Χ@o T©{Ò¡ 2-.©{"duùa©{¥§)ª†>šª(ÎÐm¤Ÿ o§Ø7ħ¤?þe©œ¹§¤±§2-.©{q¡þe©Ã'©{ (Context Free Gramma, CFG)"‚5©{´ CFG A~" kGgÄÅFSA ÖÞØU§ù¦§U£O 3-.ŠóŠ é"XJ#N§ØU£ÞÖ§@ ´x"XJQ#N§q#N£ ÞÖ§@Ò¤ ‚5k.gÄÅLBA§Œ£OŠóÒ´ 1-.Šó"@o§Ä ¾ŸogÄÅTÐU £O 2-.ŠóQº ù҇ FSAÚ?˜«#/;0§¡/Ò(stack)0"r· GÚª(Îí?ÒS§¡/£?(shift)0"ÒºA‡üT¤, ‡)ªm>ž§r§‚òÑÒ §r·GÚT)ª†>@‡š ª(Îí?ÒS§¡/8 (reduce)0"FSA þùÒ§±9ƒA£ ?Ú8-§Ò¤eígÄÅ(Pushdown Automaton, PDA)"§TÐU £O 2-.Šó" 5 ggg½½½ÂŠŠŠóóóYYY~~~µµµOOOŽŽŽììì OŽì,vŸoŒîˆ")öЫùã è§==´F"U éÐÆ ök¤Ï"ÐÆöŒ±3ùã èÄ:þ‰O!í!U§±ÆS!y© ¥ƒ'SN" 5.1 ^^^ flex ÚÚÚ bison 555¢¢¢yyy gcc Òk compiler compiler ƒ¡§¿/?Èì?Èì0"flex ´ ~^c{©Ûì)¤ì§bison ´~^Š{©Ûì)¤ì"Øõ`§kw makefileµ app = calc objects = $(app).lex.o $(app).tab.o $(app).exe : $(objects) gcc -o $(app) $^ -lfl $(app).lex.c : $(app).l $(app).tab.c flex -o $(app).lex.c $(app).l $(app).tab.c : $(app).y bison -d $(app).y %.o : %.c gcc -c $(CFLAGS) $< -o $@ 80 .PHONY : clean clean : -rm $(app).lex.c $(app).tab.c $(app).tab.h $(app).exe $(objects) 5¿µmakefile ¥ ?‡^›LÎ’\t’§ Ø´ 8 ‡˜‚" 2w calc.l µ %{ #include #include #include "calc.tab.h" %} DIGIT [0-9] %% {DIGIT}+ { yylval.dbl = atoi(yytext); return NUM; } {DIGIT}+"."{DIGIT}* { yylval.dbl = atof(yytext); return NUM; } "+"|"-"|"*"|"/"|"^"|"n" return *yytext; "\n" return *yytext; [ \t]+ . return *yytext; %% ´ calc.y µ %{ #include #include void yyerror (char const *); %} %union { double dbl; } %token NUM %type exp %left ’-’ ’+’ %left ’*’ ’/’ 81 %left NEG %right ’^’ %% input: | input line ; line: ’\n’ | exp ’\n’ { printf ("\t%.10g\n", $1); } | error ’\n’ { yyerrok; } ; exp: NUM { $$ = $1; } | exp ’+’ exp { $$ = $1 + $3; } | exp ’-’ exp { $$ = $1 - $3; } | exp ’*’ exp { $$ = $1 * $3; } | exp ’/’ exp { $$ = $1 / $3; } | ’-’ exp %prec NEG { $$ = -$2; } | exp ’^’ exp { $$ = pow ($1, $3); } | ’(’ exp ’)’ { $$ = $2; } ; %% void yyerror (char const *s) { fprintf (stderr, "%s\n", s); } int main (void) { return yyparse(); } ˜3Ә‡8¹e§† make Ҍ± " 5.2 ^^^ re2c ÚÚÚ yacc 555¢¢¢yyy Openwatcom  èp¡§¹kü‡f‘8"˜‡´c{©Ûì)¤ì re2c§˜‡´Š{©Ûì)¤ì yacc"·‚Þ˜‡A^ùü‡óä¢~" w makefile µ CDEBUG = -g LDFLAGS = -g SRCS = icmain.c icscan.c icutils.c ytab.c OBJS = icmain.o icscan.o icutils.o ytab.o 82 icalc.exe : $(OBJS) gcc $(LDFLAGS) -o $@ $(OBJS) ytab.c ytab.h : icparse.y icpdrvr.c wyacc icparse.y icpdrvr.c icscan.c : icscan.re ytab.h re2c -s icscan.re > icscan.c .c.o: ytab.h gcc $(CDEBUG) -c -o $@ $< ©‡ icmain.h µ /* icmain.h * integer calculator, the header file for the main module */ #ifndef _ICMAIN_H_ #define _ICMAIN_H_ extern int g_debug; extern ICScanner g_scnr; extern ICParser g_prsr; #endif ©‡ icmain.c µ /* icmain.c * integer calculator, the main module */ #include "icutils.h" #include "icscan.h" #include "icparse.h" #include "icmain.h" int g_debug = 0; ICScanner g_scnr; ICParser g_prsr; int main() { char data[] = "2 + 3*(4-5)\n12/ 3\n"; char empty[] = ""; g_stdio_init(); g_prsr.scanner = &g_scnr; icparse_buf(&g_prsr, data, sizeof(data)); // including the trailing ’\0’ icparse_buf(&g_prsr, empty, sizeof(empty)); 83 icparse_file(&g_prsr, g_stdin); } ©‡ icparse.h µ /* icparse.h * integer calculator, the parser module */ #ifndef _ICPARSE_H_ #define _ICPARSE_H_ #include #include "icscan.h" typedef struct { ICScanner *scanner; } ICParser; extern int icparse_buf(ICParser *prsr, char *data, int size); extern int icparse_file(ICParser *prsr, HANDLE hndl); #endif ©‡ icparse.y µ %{ /* icparse.y * integer calculator, the parser module */ #include "icutils.h" #include "icscan.h" #include "icparse.h" #include "icmain.h" #include "ytab.h" static void yyerror(char const *s); static int yylex(); %} %union { int integer; } %token INTEGER %type expr %left ’+’ ’-’ %left ’*’ ’/’ ’%’ 84 %left NEG %start input %% input: {if (g_debug) g_errf("\nAn empty string or file.\n");} | input line ’\n’ {if (g_debug) g_errf("\nOne more line parsed.\n"); // The trailing eol forces the parser to reduce the symbol ’line’. } | input error ’\n’ { yyerrok; // When an error occurs, we discard the whole line. } ; line: {if (g_debug) g_errf("\nAn empty line.\n");} | expr { g_outf("\t%d\n", $1); } ; expr: INTEGER { $$ = $1; } | expr ’+’ expr { $$ = $1 + $3; } | expr ’-’ expr { $$ = $1 - $3; } | expr ’*’ expr { $$ = $1 * $3; } | expr ’/’ expr { $$ = $1 / $3; } | expr ’%’ expr { $$ = $1 % $3; } | ’-’ expr %prec NEG { $$ = -$2; } | ’(’ expr ’)’ { $$ = $2; } ; %% void yyerror(char const *s) { g_errf("\nError: %s\n", s); } int yylex() // should change to yylex(scnr) someday { short tok; tok = icscan(&g_scnr); if (g_debug) switch (tok) { case INTEGER: g_errf("\nToken: INTEGER(%d)\n", yylval); break; case 0: g_errf("\nToken: EOF\n"); break; 85 default: g_errf("\nToken: ’%c’\n", (char)tok); } return tok; } int icparse_buf(ICParser *prsr, char *data, int size) { ICScanner *scnr; scnr = prsr->scanner; scnr->cursor = data; scnr->marker = data; scnr->limit = &data[size]; scnr->file = INVALID_HANDLE_VALUE; return yyparse(); // should change to yyparse(prsr) someday } int icparse_file(ICParser *prsr, HANDLE hndl) { ICScanner *scnr; scnr = prsr->scanner; scnr->cursor = &scnr->buffer[0]; scnr->marker = &scnr->buffer[0]; scnr->limit = &scnr->buffer[0]; scnr->file = hndl; return yyparse(); // should change to yyparse(prsr) someday } ©‡ icpdrvr.c ´ yacc èp¡ yydriver.c €L5"5¿T©‡ ¥kü‡˜1ATO†¤†Î(form feed)"äN ˜ww èÒØJé " ©‡ icscan.h µ /* icscan.h * integer calculator, the header file for the scanner module */ #ifndef _ICSCAN_H_ #define _ICSCAN_H_ #include #define ICSCNR_BSIZE 4096 typedef struct _ICScanner { unsigned char *token; unsigned char *cursor; 86 unsigned char *marker; unsigned char *limit; unsigned char buffer[ICSCNR_BSIZE+1]; // extra one byte for $eof (’\0’) HANDLE file; } ICScanner; extern int icscan(ICScanner *scnr); #endif ©‡ icscan.re µ /* icscan.re * integer calculator, the scanner module */ #include #include "icutils.h" #include "icscan.h" #include "ytab.h" extern YYSTYPE yylval; // lex-value, declared in yydriver.c #define YYCTYPE unsigned char #define YYCURSOR (scnr->cursor) #define YYMARKER (scnr->marker) #define YYLIMIT (scnr->limit) #define YYFILL(n) { if (INVALID_HANDLE_VALUE != scnr->file) fill(scnr,(n)); } // Ensure the buffer containing at least n unprocessed charaters by reading in // more data, // unless you know some special shorter token does exist in the buffer // and should be processed before more data can be read in. static void fill(ICScanner *scnr, int n) { DWORD nr, offset, len, siz, nlen; if (scnr->cursor < scnr->limit && ’\0’ == scnr->limit[-1]) return; // $eof has occured, no more data can be read in if (scnr->cursor < scnr->limit && ’\n’ == scnr->limit[-1]) return; // eol must be processed before more data can be read in offset = scnr->token - &scnr->buffer[0]; len = scnr->limit - scnr->token; if (0 != offset) { MoveMemory(&scnr->buffer[0], scnr->token, len); scnr->token -= offset; scnr->cursor -= offset; scnr->marker -= offset; scnr->limit -= offset; } 87 // Only when (YYLIMIT-YYCURSORlimit - scnr->cursor; nlen < n; nlen += nr) { siz = &scnr->buffer[ICSCNR_BSIZE] - scnr->limit; if (FALSE == ReadFile(scnr->file, scnr->limit, siz, &nr, NULL)) g_fatal(1, NULL); if (0 == nr) { // EOF if (scnr->limit == &scnr->buffer[0] || ’\0’ != scnr->limit[-1]) *scnr->limit++ = ’\0’; // $eof // else // it must be (limit==&buffer[0] && ’\0’==limit[-1]), i.e., // $eof has already been put into the buffer return; } scnr->limit += nr; } } /*!re2c any = [\000-\377]; dot = any \ [\n]; digit = [0-9]; */ // We’ve already known that s points to digit+, so the implementation of // this function is much straight forward. int a2i(char *s, char *e) { int n; n = 0; for (; s < e; ++s) n = n*10 + (*s - ’0’); return n; } int icscan(ICScanner *scnr) { scan: scnr->token = scnr->cursor; /*!re2c [()+\-*/%] { return *scnr->token; } [ \t\r]+ { goto scan; // restart the scanning, as if the space does not exist at all 88 } [\n] { return *scnr->token; // FIXME: total-lines++ etc. } digit+ { yylval.integer = a2i(scnr->token, YYCURSOR); return INTEGER; } [\000\004] { return 0; // $eof } any { g_errf("\nError: unexpected character: ’%c’\n", *scnr->token); goto scan; // ignore it, go on scanning. } */ } ©‡ icutils.h µ /* icutils.h * integer calculator, the header file for the utilities module */ #ifndef _ICUTILS_H_ #define _ICUTILS_H_ #include extern HANDLE g_stdin; extern HANDLE g_stdout; extern HANDLE g_stderr; extern void g_stdio_init(); extern void g_msgbx(char *fmt, ...); extern void g_exit(UINT code); extern void _g_fatal(UINT code, char *file, int line, DWORD error, char *hint); #define g_fatal(code,hint) do { \ _g_fatal((code), __FILE__, __LINE__, GetLastError(), (hint)); \ } while(0) extern int g_vhoutf(HANDLE hndl, char *fmt, va_list arglist); extern int g_houtf(HANDLE hndl, char *fmt, ...); extern int g_outf(char *fmt, ...); extern int g_errf(char *fmt, ...); 89 #endif ©‡ icutils.c µ /* icutils.c * integer calculator, the utilities module */ #include #include "icutils.h" HANDLE g_stdin; HANDLE g_stdout; HANDLE g_stderr; void g_stdio_init() { if (INVALID_HANDLE_VALUE == (g_stdin = GetStdHandle(STD_INPUT_HANDLE))) g_fatal(1, NULL); if (INVALID_HANDLE_VALUE == (g_stdout = GetStdHandle(STD_OUTPUT_HANDLE))) g_fatal(1, NULL); if (INVALID_HANDLE_VALUE == (g_stderr = GetStdHandle(STD_ERROR_HANDLE))) g_fatal(1, NULL); } void g_msgbx(char *fmt, ...) { char buf[8*1024]; va_list arg; va_start(arg, fmt); wvsprintf(buf, fmt, arg); MessageBox(NULL, buf, "App Msg", MB_OK); } void g_exit(UINT code) { /* FIXME: cleanup jobs here. closehandles, etc. */ ExitProcess(code); } void _g_fatal(UINT code, char *file, int line, DWORD error, char *hint) { char buf[2048]; int n; buf[2047] = ’\0’; wsprintf(buf, "File: %s\nLine: %d\nError: %d\nMessage: ", file, line, error); 90 n = lstrlen(buf); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &buf[n], sizeof(buf)-n, NULL); if (NULL != hint) { n = lstrlen(buf); wsprintf(&buf[n], "\nHint: %s", hint); } MessageBox(NULL, buf, "Fatal Error", MB_OK | MB_ICONINFORMATION); g_exit(code); } int g_vhoutf(HANDLE hndl, char *fmt, va_list arglist) { char buf[8*1024+32]; unsigned long n; int i; i = wvsprintf(buf, fmt, arglist); if (0 == (WriteFile(hndl, buf, lstrlen(buf), &n, NULL))) g_fatal(1, NULL); return i; } int g_houtf(HANDLE hndl, char *fmt, ...) { va_list arg; va_start(arg, fmt); return g_vhoutf(hndl, fmt, arg); } int g_outf(char *fmt, ...) { va_list arg; va_start(arg, fmt); return g_vhoutf(g_stdout, fmt, arg); } int g_errf(char *fmt, ...) { va_list arg; va_start(arg, fmt); return g_vhoutf(g_stderr, fmt, arg); } ©‡ ic.data µ 91 2+3 4*(2+3) „k˜‡©‡ icempty.data ´‡˜©‡" 6 ccc{{{©©©ÛÛÛ 6.1 ˜˜˜‡‡‡ÃÃÃóóó???ccc{{{©©©ÛÛÛ~~~fff ù‡§S real1.c ֘‡{üL«¢êiÎG§ˆ£ÙŠµ // wcl386 -wx -s -ecc real1.c #include // y = [123456789], d = (y | ’0’), // (’-’)? (yd* | ’0’) (’.’d+)? ’\0’ char *s[4]={"0","-3","0.2","-1.35"}; double scan(char *str) { double v,f; char *p; int n; p = str; v = 0.0; f = 0.0; if (’-’ == *p) p++; if (’0’ == *p) p++; else for (;’0’<=*p && ’9’>=*p; p++) v = v*10 + (*p - ’0’); if (’.’ == *p) { for (n = 0, p++; ’0’<=*p && ’9’>=*p; p++, n++) f = f*10 + (*p - ’0’); for (; n > 0; n--) f /= 10; v += f; } if (’-’ == *str) v = -v; return v; } int main() { int i; for (i = 0; i < 4; i++) 92 printf("%s is %f.\n", s[i], scan(s[i])); return 0; } XJ\ww OpenWatcom  clib\streamio ¥ scnf.c Ú mathlib ¥ strtod.c§Òù‡¯‡¡Ä{§¬kõE,")öØ´Ž2‰˜ ‡ scan_float§ ´‡/ù‡~f?ؘec{©Û†gÄŃ'¯K" 6.2 lll555LLLˆˆˆªªª NDFA ·‚‡©ÛiÎGŒ±xµ // y = [123456789], d = (y | ’0’), // (’-’)? (yd* | ’0’) (’.’d+)? ’\0’ Ù¥ d+ ¢SþÒ´ d d*"ù˜5§l5Lˆªš(½5kGg ÄÅ(NDFA) =z{Ò´é†x " • ab L«ü‡lãGé§ • | L«ü‡©|¿é§ •?L«¿é˜‡˜G ε ©|§ •*L«ˆ£˜ã|´å:§Ò´/¤˜‡Ì‚" äNþ~§§ NDFA G=£ãXã 1 ¤«" c¡ùL§gÄÅG 0 1 2 3 4 5ε ’-’ 0 ’.’ d y ε d d ε ã 1: ŠâKLˆªG=£ã †§S¥ŠéIÒkXS3˜—5"¤±§ù‡G=£ã¢SþÒ´ ˜‡/20§S6§ã" ù‰¤ NDFA ¢Sþ„k˜‡/ц0G§P θ"TG´˜‡ ª(G¿…vk?Û=£A5"3G=£ã¥§?ۚª(G(:þ§ vkéAÚÑlÙ¦ÎÒ§¢SþÑéA˜‡ÚÑl•G θ"XJrù lÑ\þ§G=£ã¬wéϧ­:ØâÑ"¤±§G θ ڍ•§ lÏ~юÑØx§ 93 6.3 NDFA (((½½½zzz  ž NDFA ¥˜i=£§Äk·‚5¿§XJlG s1 G s2 Œ±˜i=£§@o s2 ¤‰¯œ§ATŽ s1 Þþ"Ϗ s1 Œ±/Ø G?ۓd0C¤ s2 ‰ s2 U‰?Û¯œ"ùÒ´˜i4 (ε-closure) ¹Â"þ~¥¤kG˜i4Œ±LXeµ si 01 2 345 θ Cε(si){0, 1}{1}{2, 3, 5}{3, 5}{4}{5}{θ} TNDFA G8) θ 3Sk 7 ‡ƒ§Ï k 27 = 128 ‡Gf8", ˜G˜i4w,´˜‡Gf8" ?¿‰½˜‡Gf8 {si1 ,si2 ,...,sin }§Ù=£A5´ùû½µ a :{si1 ,si2 ,...,sin } = n [k=1 Cε(a : sik ) ! r {θ}. 'X 0 : {s0,s1} = (Cε(0 : s0) ∪ Cε(0 : s1)) r {θ} = (Cε(θ) ∪ Cε(s3)) r {θ} = ({θ}∪{s3,s5}) r {θ} = {s3,s5}. ddЩ8‡Gf8=£A5Xeµ ’-’ 0 y ’.’ {0, 1}{1}{3, 5}{2, 3, 5} ∅ {1} ∅ {3, 5}{2, 3, 5} ∅ {2, 3, 5} ∅ {2, 3, 5}{2, 3, 5}{4} {3, 5} ∅ ∅ ∅ {4} {4} ∅ {5}{5} ∅ {5} ∅ {5}{5} ∅ XJù˜L§) #š˜f8§@o҇rù #f8V\Lp§¿ OŽ§‚=£A5§Xd‡E§†vk#š˜f8)Ž"Ò·‚ù ‡äN~f ó§1˜Ú‰Òvk#f8) " ”ù§± NDFA Gf85I£#G§UþL¤ã?1=£§Ò ‰¤ ˜‡d(½5kGgÄÅ(DFA)"rþãf8UL¥1˜ ^S§g?þ#GSÒ 0′, 1′,..., 5′§ÒŒ±±›#G=£ã§Xã 2 ¤«" ù‡ DFA k˜‡/ц0G θ′§3šª(G‘?ÛvkI ÑÎҞ§Ñ¬=£ù‡Ñ†G θ′" 94 0′ 1′ 2′ 3′ 4′ 5′’-’ y 0 d y 0 ’.’ ’.’ d d ã 2: (½zƒG=£ã 6.4 DFA zzz ?ÛDFAь±rGy©˜ a§)µ 1. šª(GaµÖI²iÎK=£§Ö™I²iÎK=\,‡ /ц?n0G" 2. ª(GaµÖI²iÎK=£§Ö™I²iÎK=\,‡ /ˆ£?n0G" 3. ц ?nGaµz‡Ñ† ?nGÑüÕ¤˜ ‡a§ ~P {θ1},{θ2},... " 4. ˆ£?nGaµz‡ˆ£?nGÑüÕ¤˜ ‡a§ ~P {ω1},{ω2},... " цaڈ£aGÑvk=£A5" Òþã~f 󧚪(Ga´ {0′, 1′, 4′}§ª(Ga´ {2′, 3′, 5′}§ цGa´ {θ′}§ˆ£Ga´ {ω′}"5w§‚=£A5µ Ik ’-’ 0 y ’.’ otherwise {0′, 1′, 4′}{1′,θ′,θ′}{3′, 3′, 5′}{2′, 2′, 5′}{θ′,θ′,θ′}{θ′,θ′,θ′} {2′, 3′, 5′}{ω′,ω′,ω′}{2′,ω′, 5′}{2′,ω′, 5′}{4′, 4′,ω′}{ω′,ω′,ω′} {θ′} ∅ ∅ ∅ ∅ ∅ {ω′} ∅ ∅ ∅ ∅ ∅ ·‚w§G 0′ ‘iÎ’-’ ¬=\G 1′§Øª(§ G 1′Ú 4′ ‘ iÎ’-’ ¬†§áª("¤±ùüö،Ud"Ïda {0′, 1′, 4′}AT ©¤ü‡fa {0′}Ú{1′, 4′}"ù˜Ú½Œ±˜„/£ãµ 95 éua Ii = {si1 ,...,sin }§XJ a :Ii = {a : si1 ,...,a : sin } 6⊆ Ik§ üö8qš˜§Kr Ii ©¤ Ii′ = {si ∈ Ii : (a : si) ∈ Ik}Ú Ii′′ = Ii r Ii′ ü‡fa" ‡E?1ù˜Ú½§†vkaI‡©Ž"ùž§Uì¤y©daÚ ƒA=£A5§‰¤˜‡ DFA§§Gê´¤kd DFA ¥" ùÒ´ DFA z" £fâ~f"·‚w§a {2′, 3′, 5′} 3iÎ’0’ e© {2′, 5′}Ú {3′}§3iÎ’.’ e© {2′, 3′}Ú{5′}"ù¢Sþ´`ùn‡Gz‡Ñü Õ¤˜a"­#‰LXeµ Ik ’-’ 0 y ’.’ otherwise {0′}{1′}{3′}{2′}{θ′}{θ′} {1′, 4′}{θ′,θ′}{3′, 5′}{2′, 5′}{θ′,θ′}{θ′,θ′} {2′}{ω′}{2′}{2′}{4′}{ω′} {3′}{ω′}{ω′}{ω′}{4′}{ω′} {5′}{ω′}{5′}{5′}{ω′}{ω′} {θ′} ∅ ∅ ∅ ∅ ∅ {ω′} ∅ ∅ ∅ ∅ ∅ G 3′ÚG 5′ ©ü‡ØÓda§ù¦Ga {1′, 4′} 3iÎ’0’ e©ü‡fa {1′}Ú{4′}"–dŽ{(å" ù‡~fÀØ ;.µª(½daÑ´üƒ"·‚¢Sþ´ /y²0 k@‡ DFAÒ´"3˜„œ¹e§ª(½d akŒU¹õ‡G§l ék DFA 僢{zŠ^" 6.5 lll DFA  C ŠŠŠóó󧧧SSS ŠâþだDFA§Œ±‰ C Šó§S real3.c Xeµ // wcl386 -wx -s -ecc real3.c #include // y=[123456789], d=y|’0’, // (’-’)? (yd* | ’0’) (’.’d+)? ’\0’ char *s[4]={"0","-3","0.2","-1.35"}; double scan(char *str) { double v,f; char *p,ch; int pm, n; p = str; v = f = 0.0; pm = n = 0; // FSA start 96 goto s0; s0: ch = *p++; if (’-’==ch) { {pm=1;} goto s1;} if (’0’==ch) { goto s3;} if (’1’<=ch && ’9’>=ch) { {v = v*10 + (ch-’0’);} goto s2;} goto stheta; s1: ch = *p++; if (’0’==ch) { goto s3;} if (’1’<=ch && ’9’>=ch) { {v = v*10 + (ch-’0’);} goto s2;} goto stheta; s2: ch = *p++; if (’.’==ch) { goto s4;} if (’0’<=ch && ’9’>=ch) { {v = v*10 + (ch-’0’);} goto s2;} goto somega; s3: ch = *p++; if (’.’==ch) { goto s4;} goto somega; s4: ch = *p++; if (’0’<=ch && ’9’>=ch) { {n++; f = f*10 + (ch-’0’);} goto s5;} goto stheta; s5: ch = *p++; if (’0’<=ch && ’9’>=ch) { {n++; f = f*10 + (ch-’0’);} goto s5;} goto somega; stheta: fprintf(stderr, "Wrong real number ’%s’.\n", str); return 0.0; somega: for (;n>0;n--) f/=10; v += f; if (pm) v=-v; return v; } int main() { int i; for (i = 0; i < 4; i++) printf("%s is %f.\n", s[i], scan(s[i])); return 0; } ù‡§S(š~5§š~´ugÄ)¤" 97 )öY²Ú°åÑk§U0 ùoõ §F"U éŒ[\Æ S§±9w re2c ½ flex c{©Ûì)¤ì è§k¤Ï" 7 LR(0) ŠŠŠ{{{©©©ÛÛÛ 7.1 ~~~{{{$$$ŽŽŽ©©©{{{ XJ˜‡8ÜS = {a,b,c,...}ÚÙþ˜‡$Ž ∗§÷vé?¿n‡ƒ x,y,z ∈ S§þk (x ∗ y) ∗ z = x ∗ (y ∗ z)§K¡T$Ž÷v(ÜÆ"éù$ Ž§Œ±ŽÑ)Ò" Ø÷v(ÜÆ$ŽØUŽÑ)Ò"'Xéuê~{§k (x−y)−z 6= x−(y −z)"·‚Ę«{z~{LˆªµE => d (E - E)—§±d~§ 0 LR Š{©Ûƒ'Vg" Äk·‚rT©{‰¤ *.y ©‡§= lrp1.y Xeµ /* yacc -ps lrp1.y bison -rall lrp1.y */ %token d %type E %% E: d | ’(’ E ’-’ E ’)’ {$$ = $2 - $4;} ; %% ^ Openwatcom  yacc -ps lrp1.y IOÑÑXeµ 0 (000): E <- d (unit production) 1 (001): E <- ’(’ E ’-’ E ’)’ 2 (002): $start <- E $eof state 0: parent states: 2 (002): $start <- . E $eof actions: ’(’:s001 E:s002 d:s003 state 1: parent states: 6 1 0 1 (001): E <- ’(’ . E ’-’ E ’)’ actions: ’(’:s001 E:s004 d:s003 state 2: parent states: 0 98 2 (002): $start <- E . $eof actions: $eof:s005 state 3: parent states: 6 1 0 0 (000): E <- d . (unit production) actions: ’)’ ’-’ $eof:r000 state 4: parent states: 1 1 (001): E <- ’(’ E . ’-’ E ’)’ actions: ’-’:s006 state 5: parent states: 2 2 (002): $start <- E $eof . actions: :r002 state 6: parent states: 4 1 (001): E <- ’(’ E ’-’ . E ’)’ actions: ’(’:s001 E:s007 d:s003 state 7: parent states: 6 1 (001): E <- ’(’ E ’-’ E . ’)’ actions: ’)’:s008 state 8: parent states: 7 1 (001): E <- ’(’ E ’-’ E ’)’ . actions: ’)’ ’-’ $eof:r001 state 9: parent states: actions: actions combined: 0 parser states: 10 # states (1 reduce only): 3 reduce/reduce conflicts: 0 99 shift/reduce conflicts: 0 number of rules not reduced: 0 bytes used in tables: 456 states with defaults: 2 states with parents: 7 ^ gcc  bison -rall lrp1.y ÑÑ©‡ lrp1.output Xeµ Grammar 0 $accept: E $end 1 E: d 2 | ’(’ E ’-’ E ’)’ Terminals, with rules where they appear $end (0) 0 ’(’ (40) 2 ’)’ (41) 2 ’-’ (45) 2 error (256) d (258) 1 Nonterminals, with rules where they appear $accept (7) on left: 0 E (8) on left: 1 2, on right: 0 2 state 0 0 $accept: . E $end 1 E: . d 2 | . ’(’ E ’-’ E ’)’ d shift, and go to state 1 ’(’ shift, and go to state 2 E go to state 3 state 1 1 E: d . 100 $default reduce using rule 1 (E) state 2 1 E: . d 2 | . ’(’ E ’-’ E ’)’ 2 | ’(’ . E ’-’ E ’)’ d shift, and go to state 1 ’(’ shift, and go to state 2 E go to state 4 state 3 0 $accept: E . $end $end shift, and go to state 5 state 4 2 E: ’(’ E . ’-’ E ’)’ ’-’ shift, and go to state 6 state 5 0 $accept: E $end . $default accept state 6 1 E: . d 2 | . ’(’ E ’-’ E ’)’ 2 | ’(’ E ’-’ . E ’)’ d shift, and go to state 1 ’(’ shift, and go to state 2 E go to state 7 101 state 7 2 E: ’(’ E ’-’ E . ’)’ ’)’ shift, and go to state 8 state 8 2 E: ’(’ E ’-’ E ’)’ . $default reduce using rule 2 (E) 7.2 ÿÿÿ222©©©{{{†††ÑÑÑ\\\(((åååÎÎÎ Openwatcom T©{V\ ˜‡)ª $start <- E $eof"gcc KV\ ˜‡ $accept: E $end"üö´˜‡¿g§´ÎÒ¶iØÓ"V\ƒ ©{§¡©{ÿ2©{" $start ½ö $accept ´#婚ª(Χ©z¥õP S′"?Û© {§²ÿ2ƒ§1˜Úío´ù‡#V\)ª"ùk|urŠ{©Û 󊧪z" $eof ½ö $end ¡Ñ\(åΧ©z¥õP #§kP $ " 7.3 mmmíí톆†lll†††•••mmmÖÖÖ XJ3íL§¥§z˜ÚÑ´ré.m>šª(ÎÐm§@où‡ íÒ¡mí (rightmost derivation)"'X((d−d)−d) m폵 S′ ⇒ E#{S′ ⇒ E#} ⇒ (E − E)#{E ⇒ (E − E)} ⇒ (E − d)#{E ⇒ d} ⇒ ((E − E) − d)#{E ⇒ (E − E)} ⇒ ((E − d) − d)#{E ⇒ d} ⇒ ((d − d) − d)#{E ⇒ d} 102 rmíL§L5§Ò´˜‡8L§µ ((d − d) − d)#{E ⇒ d} → ((E − d) − d)#{E ⇒ d} → ((E − E) − d)#{E ⇒ (E − E)} → (E − d)#{E ⇒ d} → (E − E)#{E ⇒ (E − E)} → E#{S′ ⇒ E#} → S′ ù‡L§I‡·‚l†•mÖÑ\§9žuyŒ8fG§ÀJ· )ª?18"LR ©Ûì¥ L /l†•mÖ0§R /mí0" d¯KJÝ3u§éu, ©{§·‚l†•mŇÖ\üc (token) žÿ§™7oU9žO(/½´ÄAT8§±9AT^=‡)ª?1 8"rù‡¯KØӜ/©a§æéA„–\±)û§Ò´¤¢ LR(0)!SLR!LR(k)!LALR!GLR ØÓ LR ©Ûì" 7.4 ááኊŠ†††éééYYY ‰½˜‡é.§U lšª(ÎA íÑ5Té.fG§¡Té. ƒéu A áŠ"'Xé.((d − d) − d) ¥§ƒéu E áŠkʇµn‡ d§˜‡ (d − d)§Ú˜‡ ((d − d) − d)" P,‡ù኏ β§XJA ⇒ β T˜‡)ª§Ò´`§β U d A †íѧK¡TáŠ β Té.ƒéu A †áŠ"'Xé. ((E − E) − d) ƒéu E †áŠkü‡µ˜‡´ (E − E)§˜‡´ d" ‰½é.§ƒéu,‡šª(Ό±kõ‡†ኧƒéuØÓšª (΄Œ±kõ"¤kù †እ§3é.¥ ˜‚†@‡§¡ Té.éY(handle)"'Xé.((d − d) − d) éY´1˜‡ d§ é. ((E − E) − d) éY´ (E − E)" ^éY?18§¡5‰8"XJ©{´Ã§@o5‰8 †míp_"½N´duù‡ϧkžrmí¡5‰í§ míÑé.¡5‰é." 7.5 ÒÒ҆††GGG c¡<Ú/`LeígÄÅPDA Œ±^5£Oþe©Ã'Šó"y35 w˜‡äNóŠL§"·‚^/X  #s0′(′sa  ªfL«Ò.´ (#,s0)§Ò º´ (′(′,sa) Ò"·‚6žØ?ØGäN?Ґ{§¤±^ a,b,c,... 5 PGeI"¤¢cG§Ò´Òº¤P1G"dueígÄÅPDA ÖÞÚkGgÄÅFSA ˜§´Ö …•m£Ä§XJkŸo 103 &EI‡3§@®² Òp§¤±ÖL‘ÒØ23 "ù§c ã8L§ÒŒ±L«µ  #s0  ((d − d) − d)# ; shift, goto sa, i.e. push(′(′,sa)  #s0 ′(′sa  (d − d) − d)# ; shift sb, i.e. push(′(′,sb)  #s0 ′(′sa ′(′sb  d − d) − d)# ; shift sc, i.e. push(d, sc)  #s0 ′(′sa ′(′sbdsc  − d) − d)# ; reduce {E ⇒ d}, goto sd ; i.e. pop(d, sc), push(E,sd)  #s0 ′(′sa ′(′sbEsd  − d) − d)# ; shift se  #s0 ′(′sa ′(′sbEsd−se  d) − d)# ; shift sf  #s0 ′(′sa ′(′sbEsd−sedsf  ) − d)# ; reduce {E ⇒ d}, goto sg  #s0 ′(′sa ′(′sbEsd−seEsg  ) − d)# ; shift sh  #s0 ′(′sa ′(′sbEsd−seEsg ′)′sh  − d)# ; reduce {E ⇒ (E − E)}, goto si ; pop(′(′sb · · · ′)′sh), push(E,si)  #s0 ′(′saEsi  − d)# ; shift sj  #s0 ′(′saEsi−sj  d)# ; shift sk  #s0 ′(′saEsi−sjdsk  )# ; reduce {E ⇒ d}, goto sℓ  #s0 ′(′saEsi−sjEsℓ  )# ; shift sm  #s0 ′(′saEsi−sjEsℓ ′)′sm  # ; reduce {E ⇒ (E − E)}, goto sn  #s0Esn  # ; accept ·‚w§ù‡ PDA Ċ̇k£?(shift) Ú8 (reduce) ü«" 'X1˜Ú  #s0  ((d − d) − d)#§cG´ s0§cÎÒ´ ′(′"ù«œ ¹e§{üã(Ō±k†£˜‚!m£˜‚!\,ÎÒn«ÀJ§, =\G sa¶DFAØU†£Ú\§Um£˜‚§,=\G sa"PDA 'DFA õ˜‡Ò§§U rffÖÑÎÒÚ=ò?\GØÒ§= push (′(′,sa)§,2‰ DFA ¤‰¯§=m£˜‚¿¢S=\G sa"ùÒ´ PDA £?Ċ" 3  #s0′(′sa ′(′sbEsd−seEsg ′)′sh  − d)# œ/e§cG sh§cÎ Ò −"PDAU ?uG sh§Ò`²Ò¥®²; ƒAfG(E − E)§ qÖÎÒ −§PDAÒ(&Ò¥¤fG´˜‡éY§éA)ª´ E ⇒ (E − E)§´žÿUìù‡)ª?18 "u´§§rÒ¥ (E − E) ëӊ‘G˜åòÒ§= pop (′(′sb · · · ′)′sh)§,rcÎÒU E" 5¿µù‡žÿœ/¢SþC¤  #s0′(′sa  E − d)#"ù´˜‡šÓ… ¯œ§PDAØ= ‘þ § …´†£ ˜‚2§¢Sþ´r˜‡š 104 ª(Î\ ª(ÎG¥§¦/cG0sa lÑ\G¥/Ö0 ˜‡ šª(Μ Ø+No`§cG sa Öšª(ÎE§AT‰1˜‡£?öŠ§r= ò?\G si ÚcÎÒE\Ò§,m£˜‚§?\G si"l /¤  #s0′(′saEsi  − d)# Û¡" ùÒ´`§PDA †£Ú\´š~ہ!š~á6§;‘Ù7½k ˜‡£?Ċò§†£Ú\!àK§¤±§Œ±r§†£Ú\w ‰´˜‡8ĊSÜ¢yþ[! ؃JÄ"ù´y3õêá Ý"ù árGÖª(Ξ‡A¡ÄŠ (action)§/Ö0š ª(Ξ‡A¡=† (goto)§¿éüöæ^ØÓP{§Ð–§‚kŸo ¢ŸØÓq"Ù¢§áþ`/Œ0!8Ċ§u·‚þ ¡`/0!üX8Ċ§\þ˜‡/險(Σ?0Ċ" 2wþ¡©ÛL§˜Ú  #s0Esn  #"cG sn§ÖÎÒ#§ ØI‡28 §†‰1É(accept) Ċ=Œ"Ϗ·‚¯ké©{?1 ÿ2§¤±3 PDA GĊL¥§ÉĊk˜‡" 3 PDA GĊL¥§„kNõ/† (error)0Ċ"þ¡Þ´‡ ¤õ©Û~f§¤±vkÑy†ÄŠ"XJ´  #s0  )# œ/§@ow, AT‰1†ÄŠ" y3§¯KÒ8(µù G´XÛ(½§qTXÛWGĊ L" 7.6 ‘‘‘888!!!‘‘‘888888 ˜‡ÎÒGcM´ù‡G?¿cÜ"míé.¡5‰ é."˜‡5‰é.,‡cMXJ؇LTé.éY"—§K¡Té. ˜‡¹cM" ‰Ñ\ª(ÎGc¡Öþ˜‡/Ñ\m©Î0§^ #L«"@o§ þã5‰8L§¥§?۞§Ò¥¤3ÎÒG§þ–ÖÑ\G§ Ѥ˜‡5‰é.§ Ò¥¤3ÎÒG§T´ù‡5‰é.˜‡¹c M" ‰½©{G§ŒE˜‡ DFA§5䉽ÎÒG´Ä´,‡5‰é. ¹cM"·‚k‰˜‡ù NDFA§2òÙ(½z¤ DFA" ‰½©{G ˜‡)ª§3Ùm>,‡ ˜þ\˜‡ :§ù ªfÒ¡©{G ˜‡ LR(0) ‘8 (item)"'Xc¡¤ù~{Lˆªÿ 2©{§ÒŒ±‰Ñ 11 ‡‘8µ (0)S′ ⇒•E#,(1)S′ ⇒ E•#,(10)S′ ⇒ E#•,(2)E ⇒•d, (3)E ⇒ d•, (4)E ⇒•(E − E),(5)E ⇒ (•E − E),(6)E ⇒ (E•−E), 105 (7)E ⇒ (E −•E),(8)E ⇒ (E − E•),(9)E ⇒ (E − E)•. rz‡‘8w‰´˜‡G"r S′ ⇒ •E# w‰´å©G"٦Ѵª( "G=£kü«œ¹µ 1. Ә)ª§ :•cò?˜‡ÎÒ§dd)ü‡‘8§lcö öژ‡lã§Iҏ¤òLÎÒ"'X§l‘8 E ⇒ •d  E ⇒ d•ATژ‡lã§Iҏ d" 2. 3˜‡‘8¥§ :ƒ´,‡šª(Χ@o§lù‡‘8§T šª(ΤkÐm‘8¥ :3†>‘8§Ú˜‡lã§IÒ ˜i"'X§l‘8 S′ ⇒ •E#ATÚü‡lã©O E ⇒ •d Ú E ⇒•(E − E)§IÒÑ´ ε" ù‰¤ NDFA§ÒŒ±£O©{G ¹cM" :3m>‘8§¡8‘8"þ~¥kn‡8‘8µ(10)S′ ⇒ E#•!(3)E ⇒ d•Ú(9)E ⇒ (E − E)•" ‰½ÿ2©{§k˜˜‡'u S′ 8‘8§~ò§AO¡ɑ 8§P acc"þ~¥ɑ8´ S′ ⇒ E#•" éþã NDFA§XJr8‘8Šª(§Ù¦GÑŠšª( "@o§§ÒC¤ £O¹cM¥éY NDFA" äNþ~§£O¹cM¥éY NDFAXã 3 ¤«" 0 1 2 3 4 5 6 7 8 910 accE d #E′−′E ′)′ ε ε ε ε ′(′ ε ε ã 3: £O~{Lˆª¹cM¥éY NDFA  rþã NDFA(½z§Ĉ‡G˜i4µ si 0 5 7 1,2,3,4,6,8,9,10,θ  Cε(si){0, 2, 4}{2, 4, 5}{2, 4, 7}{1},{2},...,{θ}  ddЩ 11 ‡Gf8=£A5Xeµ 106 ’(’’-’’)’ d E # {0, 2, 4}{2, 4, 5} ∅ ∅ {3}{1} ∅ {1} ∅ ∅ ∅∅∅ {10} {2} ∅ ∅ ∅ {3} ∅ ∅ {3} ∅ ∅ ∅∅∅∅ {4}{2, 4, 5} ∅ ∅∅∅∅ {2, 4, 5}{2, 4, 5} ∅ ∅ {3}{6} ∅ {6} ∅ {2, 4, 7} ∅ ∅ ∅ ∅ {2, 4, 7}{2, 4, 5} ∅ ∅ {3}{8} ∅ {8} ∅ ∅ {9} ∅ ∅ ∅ {9} ∅ ∅ ∅∅∅∅ {10} ∅ ∅ ∅∅∅∅ âd±› DFA G=£ãXã 4 ¤«" 5¿§lÐ s0 Ñu§Š، 0 1 2 3 4 5 6 7 8 910 acc# d d d d E E E ′(′ ′(′ ′(′ ′(′ ′−′′)′ ã 4: £O¹cM¥éY DFA UˆG s2 Ú s4§Ïdùü‡GŒ±íØ"ù§·‚Ò˜‡k 9 ‡ G DFA"Œyù‡ DFA ´z" 5¿ù‡ DFA G´‘88§ Ø2´‘8"'XG s0§´‘88 {(0)S′ ⇒•E#,(2)E ⇒•d, (4)E ⇒•(E − E)}" l yacc Ú bison ‰Ñw5w§§‚´‡‰ù˜‡ DFA§´?Ò ØÓ"nö'Xeµ 012345678910 yacc02 3 14678 5 bison03 1 24678 5 107 7.7 LR(0) ©©©ÛÛÛLLL XJ˜‡‘83 :ƒ‹ª(ΧK¡£?‘ 8"'XE ⇒ •d§E ⇒ (E•−E) " XJ˜‡‘83 :ƒ‹šª(ΧK¡–‘8"'XE ⇒ (•E − E)§E ⇒ (E −•E) " c¡ù PDA 5‰8L§ž`L§Ò¥˜ÑyéY§PDA ¬‰1˜‡ /80Ċ§kréYÑÒ§2r8šª(Î\Ñ\Gc  ˜";‘Ù§7½´˜‡/éTšª(Σ?0§˜„ᡏ/=† (goto)0"ù‡/šª(Σ?0§‡N‘8þ§Ò´˜‡–‘8 :/òL0 §m>@‡šª(Î"ù´38ƒgÄu)§Ø¬— ?ÛgñÛ¡½Ñ†œ¹"Ò´`§–‘8ج†Ù¦‘8u)Àâ" ´§XJ˜‡‘88¹kü‡8‘8§@oþã DFA 3?\ù‡ Gƒ§ØëÙ¦&E§ÒÃ{û½ATæ=‡‘8?18"ù œ¹¡/8/8Àâ (reduce/reduce conflict)0" XJ˜‡‘88Q¹k£?‘8§q¹k8‘8§@oþã DFA 3? \ù‡Gƒ§ØëÙ¦&E§Ã{û½AT?1£?§„´AT?1 8"ùœ¹¡/£?/8Àâ (shift/reduce conflict)0" XJ˜‡©{þã DFA§Ù¤k‘88ÑØ3þãü«Àâ§@oT ©{Ò¡ LR(0) ©{"þã~{Lˆª©{‘88§k s0!s5 Ú s7 ¹ kõ‡‘8§ …§‚Ñ´d–‘8Ú£?‘8¤|¤§Ø3þãü«À ⧤±T©{´˜‡ LR(0) ©{" 3 LR(0) ©{ DFAG=£Lþ§‰¤kª(ÎÑÖþ¹8‘8 ‘888Ċ§¿íؤkšª(Î¥ θ§Ò‰¤ LR(0) ©ÛL" 'X§é~{Lˆª©{§XJ‰)ª?Ò (0)S′ ⇒ E#,(1)E ⇒ d, (2)E ⇒ (E − E). @o§T©{ LR(0) ©ÛLÒ´ ’(’ ’-’ ’)’ d # E 0 s5 θ θ s3 θ s1 1 θ θ θ θ acc 3 r1 r1 r1 r1 r1 5 s5 θ θ s3 θ s6 6 θ s7 θ θ θ 7 s5 θ θ s3 θ s8 8 θ θ s9 θ θ 9 r2 r2 r2 r2 r2 10 r0 r0 r0 r0 r0 108 Ù¥ s5 L«/£?cÎÒ§¿?\G s50§r1 L«/Uì)ª (1) ‰1 ˜‡80"I‡`²ü:µ 1. G s1 ÖÎÒ#§AT´‡£?Ċ s10"´du s10 ´/ É0G§·‚Œ±†‰1/É0Ċ§ v7‡¢S£? #"¤±§·‚r£?Ċ s10 U¤ acc"ù˜5§G s10 ù˜ 1ь±yK"Ϗ·‚Šجý?\ù‡G" 2. é¤kšª(אk/3u),‡8ƒá=£?0ù˜«œ /"3Lþšª(Î¥§ØŒU8§ØŒUц"¤±§ !ŽL‚˜m§˜„rª(Άšª(Ωm‰L§cö¡ÄŠL (action)§ö¡=£L(goto)" ·‚Uìù‡ LR(0) ©ÛL§rc¡ùL@‡©Û¢~W"  #s0  ((d − d) − d)# ;s5  #s0 ′(′s5  (d − d) − d)# ;s5  #s0 ′(′s5 ′(′s5  d − d) − d)# ;s3  #s0 ′(′s5 ′(′s5ds3  − d) − d)# ;r1  #s0 ′(′s5 ′(′s5  E − d) − d)# ;s6  #s0 ′(′s5 ′(′s5Es6  − d) − d)# ;s7  #s0 ′(′s5 ′(′s5Es6−s7  d) − d)# ;s3  #s0 ′(′s5 ′(′s5Es6−s7ds3  ) − d)# ;r1  #s0 ′(′s5 ′(′s5Es6−s7  E) − d)# ;s8  #s0 ′(′s5 ′(′s5Es6−s7Es8  ) − d)# ;s9  #s0 ′(′s5 ′(′s5Es6−s7Es8 ′)′s9  − d)# ;r2  #s0 ′(′s5  E − d)# ;s6  #s0 ′(′s5Es6  − d)# ;s7  #s0 ′(′s5Es6−s7  d)# ;s3  #s0 ′(′s5Es6−s7ds3  )# ;r1  #s0 ′(′s5Es6−s7  E)# ;s8  #s0 ′(′s5Es6−s7Es8  )# ;s9  #s0 ′(′s5Es6−s7Es8 ′)′s9  # ;r2  #s0  E# ;s1  #s0Es1  # ;acc 109 8 SLR ŠŠŠ{{{©©©ÛÛÛ 8.1 \\\{{{LLLˆˆˆªªª©©©{{{ ~{Lˆª¥)Ò§éŠ{©Ûå J«Š^§¤±§T©{´ LR(0) ©{§Ù¤k‘88ÑØ3Àâ"XJvk)ҧҌU)¹À â‘88"'Xù‡\{Lˆª©{ lrp3.yµ /* yacc -ps lrp3.y bison -rall lrp3.y */ %token d %type E T %% E: T ; T: T ’+’ d {$$ = $1 * $3;} | d ; %% § yacc IOÑÑ´µ 0 (000): E <- T (unit production) 1 (001): T <- T ’+’ d 2 (002): T <- d (unit production) 3 (003): $start <- E $eof state 0: parent states: 3 (003): $start <- . E $eof actions: T:s001 E:s002 d:s003 state 1: parent states: 0 0 (000): E <- T . (unit production) 1 (001): T <- T . ’+’ d actions: ’+’:s004 $eof:r000 state 2: parent states: 0 3 (003): $start <- E . $eof actions: $eof:s005 state 3: parent states: 0 110 2 (002): T <- d . (unit production) actions: ’+’ $eof:r002 state 4: parent states: 1 1 (001): T <- T ’+’ . d actions: d:s006 state 5: parent states: 2 3 (003): $start <- E $eof . actions: :r003 state 6: parent states: 4 1 (001): T <- T ’+’ d . actions: ’+’ $eof:r001 state 7: parent states: actions: actions combined: 0 parser states: 8 # states (1 reduce only): 3 reduce/reduce conflicts: 0 shift/reduce conflicts: 0 number of rules not reduced: 0 bytes used in tables: 440 states with defaults: 3 states with parents: 5 5¿Ù¥G 1 µ state 1: parent states: 0 0 (000): E <- T . (unit production) 1 (001): T <- T . ’+’ d actions: ’+’:s004 $eof:r000 Uì1˜‡‘8§§AT8¶ Uì1‡‘8§§AT£?"¤±§ù´ ˜‡£?/8Àâ"´ yacc ¿vkwù‡Àâ"Ϗ§®²rù‡Àâ )û "§kv rº`µXJciδ #§@oÒ8¶XJciÎ 111 ´ ′+′§@oÒ£?¶Ù¦œ¹§Ñ†"§³Ÿo‰ùäóQº–¬ 2ù" bison éù‡©{‰Ñw lrp3.output ´µ Grammar 0 $accept: E $end 1 E: T 2 T: T ’+’ d 3 | d Terminals, with rules where they appear $end (0) 0 ’+’ (43) 2 error (256) d (258) 2 3 Nonterminals, with rules where they appear $accept (5) on left: 0 E (6) on left: 1, on right: 0 T (7) on left: 2 3, on right: 1 2 state 0 0 $accept: . E $end 1 E: . T 2 T: . T ’+’ d 3 |.d d shift, and go to state 1 E go to state 2 T go to state 3 state 1 3 T: d . 112 $default reduce using rule 3 (T) state 2 0 $accept: E . $end $end shift, and go to state 4 state 3 1 E: T . [$end] 2 T: T . ’+’ d ’+’ shift, and go to state 5 $default reduce using rule 1 (E) state 4 0 $accept: E $end . $default accept state 5 2 T: T ’+’ . d d shift, and go to state 6 state 6 2 T: T ’+’ d . $default reduce using rule 2 (T) §G 3 `´Ó¯œµ state 3 1 E: T . [$end] 2 T: T . ’+’ d ’+’ shift, and go to state 5 113 $default reduce using rule 1 (E) §r #I 8‘8¡§L«/XJcÖª(δ #§K^ù‡ )ª?180" 8.2 £££OOO\\\{{{LLLˆˆˆªªª¹¹¹cccMMM DFA \{Lˆªÿ2©{´µ (0) S′ ⇒ E# (1) E ⇒ T (2) T ⇒ T + d (3) T ⇒ d Œ‰ LR(0) ‘8Xeµ (0)S′ ⇒•E#,(1)S′ ⇒ E•#,(2)S′ ⇒ E#•,(3)E ⇒•T, (4)E ⇒ T•,(5)T ⇒•T + d, (6)T ⇒ T• +d, (7)T ⇒ T + •d, (8)T ⇒ T + d•,(9)T ⇒•d, (10)T ⇒ d •. ddŒ±›£OT©{¹cM¥éY NDFAG=£ãXã 5 ¤«" 0 1 2 3 4 5 6 7 8 9 10 acc#E T T + d d ε ε ε ε ã 5: £O\{Lˆª¹cM¥éY NDFA TNDFA ˆ‡G˜i4µ 114 si 0 12 3 45678910 Cε(si) 0,3,5,9 1 2 3,5,9 4 5,9 6 7 8 9 10 ˜i4ƒm=£A5µ d +#E T 0,3,5,9 10 ∅ ∅ 1 4,6 1 ∅ ∅ 2 ∅ ∅ 2 ∅∅∅∅ ∅ 3,5,9 10 ∅ ∅ 1 4,6 4 ∅∅∅∅ ∅ 5,9 10 ∅ ∅ ∅ 6 6 ∅ 7 ∅ ∅ ∅ 7 8 ∅∅∅ ∅ 8 ∅∅∅∅ ∅ 9 10 ∅∅∅ ∅ 10 ∅∅∅∅ ∅ 4,6 ∅ 7 ∅ ∅ ∅ Ù¥‘88 {4, 6} ´31˜1WL¥)Ñ5§Ö¿LþŠ11‘8 8"é¤k‘88­#?Ò§‘88 {4, 6}?ҏ 11"^ù #GŒ±‰ ˜‡d DFA"TDFA G 3!G 4!G 5 ÚG 9 ´lG 0 Ñu ،ˆ§¤±Œ±"eG‰¤ DFAXã 6 ¤«" 0 1 2 6 7 8 10 11 acc E # T + d T +d ã 6: £O¹cM¥éY DFA ù‡ DFA Œ±?˜Úz"Uìo‡)ª?18´ù‡ DFA o ‡ˆ£?nG§U)ª?Ò©OP ω0,ω1,ω2,ω3"âdÐÚy©da Xeµ 115 Ik d + # E T otherwise 0,1,7 10, θ, 8 θ,θ,θ θ, 2,θ E,θ,θ 6,θ,θ θ,θ,θ 2 ω0 ω0 ω0 ω0 ω0 ω0 6,11 ω1,ω1 7,7 ω1,ω1 ω1,ω1 ω1,ω1 ω1,ω1 8 ω2 ω2 ω2 ω2 ω2 ω2 10 ω3 ω3 ω3 ω3 ω3 ω3 5¿§G s10,θ,s8 áun‡ØÓa§Ï a {0, 1, 7} 3ÎÒ d e© n‡fa"´vkÎҌ±ò {s6,s11}«©m5§Ïd§üöŒ±Ü ˜"·‚EÎ^ s6 5L«ù‡da"ùÒdz DFAXã 7 ¤«" 0 1 2 6 7 8 10 acc E # T + d d ã 7: £O¹cM¥éYz DFA yacc Ú bison ´ù˜‡(J"nöéG?Ҍ±é'X eµ 0 1 2 6 7 8 10 yacc 025146 3 bison 024356 1 Ϗ¹k8‘8‘883£OéY DFA ¥§Lyª(§¤± £?/8Àâ3TDFA G=£ãþ§Lylª(þqÚÑ ˜‡I ҏª(Îl"ã 7 þG s6 Ò´ù~f" 8.3 iiiÄÄĪªª(((ÎÎÎ888ÚÚښššªªª(((ÎÎ΋‹‹‘‘‘ªªª(((ÎÎÎ888 ‰½©{G§lÙÎÒ8˜‡š˜i α Ñu§¤UíÑ5ÎÒ G§k ±ª(ÎmÞ"¤kù ŒUmÞª(Î8ܧ¡i α Ī (Î8§P FIRST(α)" 116 þe©Ã'©{?ۚ˜i α = A1A2 · · · An þ3š˜Ī( Î8"äN‰{´µÄkm˜‡/®–¯0šª(Î8ܧ¡ VISITED§,48N^eãL§µ 1. XJA1 ∈ VT §= α 1˜‡ÎÒ´ª(Χ@o FIRST(α)= {A1}" 2. ÄK§A1 ∈ VN §= α 1˜‡ÎÒ´šª(Î"@or A1 \\VIS- ITED§é± A1 †>¤k)ª§XJÙm>ÎÒG1˜‡ÎÒ Ø3 VISITED ¥§K¦TG FIRST§¿\\ FIRST(α) ¥" 'X§éþã\{Lˆª©{§k FIRST(E) = FIRST(T)= {d}" ‰½©{G§Œ‰*Щ{G′§3 G′ ¤ké.¥§kŒUÑy3š ª(ÎA ∈ G m>ª(Î8ܧ¡Tšª(ÎA ‹‘ª(Î8§P  FOLLOW(A)"5¿µÿ2©{G′ #婚ª(ÎS′§¿Ø3©{G ¥§Ïd§Ø3 FOLLOW(S′) ƒ`" ‰½þe©Ã'©{G§§?¿šª(ÎA þ3š˜‹‘ª(Î 8"äN‰{´µÄkm˜‡šª(Î8ÜVISITED§,48N^eL §µÅ‡uÙÿ2©{G′ LR(0) ‘8§éz˜‡ A• Ñy§ 1. XJ§m>ؘ§KòÙm>ÎÒGĪ(Î8\\FOLLOW(A)¶ 2. ÄK§XJT)ª†>šª(ÎØ3 VISITED ¥§Kò§\\VIS- ITED§¿ò§‹‘ª(Î8\\FOLLOW(A)" 'X§þã\{Lˆª©{¥§FOLLOW(T)= {′+′,#}" ‰½˜‡¹k£?/8Àâ‘88§z‡8‘8Ñk˜‡†>šª( ΋‘ª(Î8§ ¤k£?ª(Τ˜‡£?ª(Î8§XJ¤kù 8Üüü؃§@o·‚ÒŒ±Šâcª(Îáu=‡8ܧ5û½‰£ ?„´‰8§±9‰Ÿo£?§½ö‰Ÿo8"XJcª(Î Øáuù 8Ü¿§@oÒAT†"ù«)ûÀâ{¡ SLR(1) ) û{"U ÏLù«{¼)û©{§¡ SLR(1) ©{" äN·‚~f§‘88 s6 ¹k£?/8À⧣?ª(Î8´ {′+′}§8‘8†>šª(δ E§§‹‘ª(Î8´ {#}§üö؃ "cª(ÎXJ´ ′+′§K£?¶XJ´ #§K8¶Ù¦œ¹§Ñ †"Ïd§þã\{Lˆª©{´ SLR(1) ©{" 8.4 SLR ©©©ÛÛÛLLL SLR(1) ©{©ÛL´3 LR(0) ©ÛLÄ:þ§é¹kÀâ‘8 8¤3@˜1?1?U" þã\{Lˆª©{ SLR ©ÛLXeµ 117 d +# ET 0 s10 θ θ s1 s6 1 θ θ acc 2 r0 r0 r0 6 θ s7 r1 7 s8 θ θ 8 r2 r2 r2 10 r3 r3 r3 kéõáé@ vkÀâ8‘88U¤é‹‘ª(ÎW8§éÙ ¦ª(ÎW†"ù´Ø7‡"Ϗù«œ¹e§ÃØXÛч8§3 8¤ƒ§;‹X7½´˜‡šª(Σ?§ù‡£?¬¦ DFA? \#G"‘@‡ª(Îk5§dù‡#G5½§†5 8‘88®²vk†'X " ·‚éü‡{üŠé‹l˜e SLR ©Ûì©ÛL§"Äk´ d#"  #s0  d# ;s10  #s0ds10  # ;r3  #s0  T# ;s6  #s0Ts6  # ;r1  #s0  E# ;s1  #s0Es1  # ;acc ,´ d + d#"  #s0  d + d# ;s10  #s0ds10  + d# ;r3  #s0  T + d# ;s6  #s0Ts6  + d# ;s7  #s0Ts6+s7  d# ;s8  #s0Ts6+s7ds8  # ;r2  #s0  T# ;s6  #s0Ts6  # ;r1  #s0  E# ;s1  #s0Es1  # ;acc 118 Œ[М·´¶ïu"©83ƒE²! ©£"ŸÞ¿š©ÙÌN§žÕ3nó ‡¡?ØT" XJ·‚§@’½v
还剩118页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 5 人已下载

下载pdf

pdf贡献者

0cean

贡献于2012-01-17

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!