Slide 1

Slide 1 text

10 εςοϓͰͭ͘Δ ͓खܰΠϯλϓϦλ։ൃ ࠡ ᲒᲶ @ushitora anqou 1

Slide 2

Slide 2 text

΍Δ͜ͱ • ؆୯ͳΠϯλϓϦλΛ C ݴޠͰॻ͘ɻ • ϑΟϘφον਺ྻΛܭࢉͰ͖Δɻ • Strongly inspired by https://youtu.be/JAtN0TGrNE4 2

Slide 3

Slide 3 text

Θ͔ͬͯ΄͍͜͠ͱ • ݴޠॲཧܥ͸ݴ͏΄Ͳ೉͘͠ͳ͍ɻ • ཧ࿦͸൥ࡶ͕࣮ͩ૷͢Ε͹Θ͔Δɻ • ΈΜͳ΋ C ίϯύΠϥΛͭ͘Ζ͏ʂ 3

Slide 4

Slide 4 text

ιʔε https://github.com/ ushitora-anqou/ simplinterp 4

Slide 5

Slide 5 text

5

Slide 6

Slide 6 text

6

Slide 7

Slide 7 text

7

Slide 8

Slide 8 text

ΠϯλϓϦλͬͯͳΜͩΖ͏ ΠϯλϓϦλʢӳ: interpreterʣͱ ͸ɺϓϩάϥϛϯάݴޠͰॻ͔Ε ͨιʔείʔυͳ͍͠தؒදݱΛ ஞ࣍ղऍ͠ͳ͕Β࣮ߦʢӳޠ൛ʣ ͢ΔϓϩάϥϜͷ͜ͱɻ ʢWikipedia ΑΓʣ 8

Slide 9

Slide 9 text

ΠϯλϓϦλͬͯͳΜͩΖ͏ ͭ͘Ε͹Θ͔Δ 9

Slide 10

Slide 10 text

Step

Slide 11

Slide 11 text

Step 0 C ݴޠͷจࣈྻॲཧ ↓ H e l l o \0 char *p = "Hello"; • C ݴޠʹ͓͍ͯจࣈྻ͸ʮจࣈ͕ϝϞ Ϧ্ʹฒͼɺऴ୺͕\0 ͷ΋ͷʯ • ϙΠϯλͰจࣈྻͷઌ಄ཁૉΛࢦ͢ɻ 10

Slide 12

Slide 12 text

Step 0 C ݴޠͷจࣈྻॲཧ ↓ H e l l o \0 char *p = "Hello"; p; // address *p; // ’H’ *(p + 1); // ’e’ p[1]; // ’e’ *p++; // ’H’ *p; // ’e’ 11

Slide 13

Slide 13 text

Step 1 ಈ͘ίʔυΛॻ͘ #include int eval(char *p) { return 0; } int main(int argc , char ** argv) { return eval(argv [1]); } eval() ͰϓϩάϥϜͷ࣮ߦΛߦ͏ɻ ./main "program" 12

Slide 14

Slide 14 text

Step 1 ಈ͘ίʔυΛॻ͘ ςετΛॻ͘ɻ #!/bin/sh # ʢதུʣ runtest "0" 0 runtest ͰϓϩάϥϜͷਖ਼ৗ࣮ߦΛ͔֬ ΊΔɻ 13

Slide 15

Slide 15 text

Step 2 ࣗવ਺ΛಡΉ ੔਺ΛҰݸಡΈࠐΜͰɺͦΕΛฦ͢ɻ runtest "0" 0 runtest "1" 1 runtest "42" 42 ͜ͷΑ͏ͳग़ྗΛಘΔʹ͸ʁ 14

Slide 16

Slide 16 text

Step 2 ࣗવ਺ΛಡΉ ੔਺ΛҰݸಡΈࠐΜͰɺͦΕΛฦ͢ɻ int eval(char *p) { int ival = 0; while (isdigit (*p)) { ival = ival * 10 + *p - ’0’; p++; } return ival; } ٙ໰఺͸ϗϫΠτϘʔυͰղઆɻ 15

Slide 17

Slide 17 text

Step 3 ଍͠ࢉΛ଍͢ ଍͠ࢉͬͯԿͩΖ͏ɻ runtest "1+42" 43 runtest "23+42" 65 runtest "1+2+4" 7 runtest "1+2+4+10" 17 ͜ͷΑ͏ͳग़ྗΛಘΔʹ͸ʁ 16

Slide 18

Slide 18 text

Step 3 ଍͠ࢉΛ଍͢ ʮ଍͠ࢉʯͱ͸ 1. ॳΊʹ੔਺͕དྷΔɻ 2. ͦͷޙʹʮ+ ੔਺ʯ͕ 0 ճҎ্܁Γ ฦ͢ɻ e.g. 42, 1+2, 1+2+3 17

Slide 19

Slide 19 text

Step 3 ଍͠ࢉΛ଍͢ 1. ॳΊʹ੔਺͕དྷΔɻ 2. ͦͷޙʹʮ+ ੔਺ʯ͕ 0 ճҎ্܁Γ ฦ͢ɻ ଍͠ࢉ := ੔਺ ( ‘+’ ੔਺ )* 18

Slide 20

Slide 20 text

Step 3 ଍͠ࢉΛ଍͢ ଍͠ࢉ := ੔਺ ( ‘+’ ੔਺ )* int ival = parse_integer (); while (*p++ == ’+’) ival += parse_integer (); return ival; ٙ໰఺͸ϗϫΠτϘʔυͰղઆɻ 19

Slide 21

Slide 21 text

Step 4 Ҿ͖ࢉΛ଍͢ ಉ͡Α͏ʹ଍ͯ͠ΈΔɻ runtest "1+2 -3+5" 5 ͜ͷΑ͏ͳग़ྗΛಘΔʹ͸ʁ 20

Slide 22

Slide 22 text

Step 4 Ҿ͖ࢉΛ଍͢ ଍͠ࢉ := ੔਺ ( ( ‘+’ | ‘-’ ) ੔਺ )* e.g. 42, 1+3, 12-3, 4+2-5+4-1 ଍͠ࢉ :thinking face: 21

Slide 23

Slide 23 text

int ival = parse_integer (); while (*p != ’\0’) { switch (*p) { case ’+’: p++; ival += parse_integer (); break; case ’-’: p++; ival -= parse_integer (); break; default: goto end; } } end: return ival; 22

Slide 24

Slide 24 text

Step 5 ֻ͚ࢉɾׂΓࢉΛ଍͢ ಉ͡Α͏ʹ࣮૷͢Δʁ runtest "1*2+3" 5 runtest "13/3+4" 8 runtest "1+2*3" 7 runtest "1*2+3*4" 14 runtest "5/2+99/3" 35 ͜ͷΑ͏ͳग़ྗΛಘΔʹ͸ʁ 23

Slide 25

Slide 25 text

Step 5 ֻ͚ࢉɾׂΓࢉΛ଍͢ ଍͠ࢉ:= ੔਺ ( ( ‘+’ | ‘-’ | ‘*’ | ‘/’) ੔਺ )* 2*3+4 ͸Αͦ͞͏ɻ 24

Slide 26

Slide 26 text

Step 5 ֻ͚ࢉɾׂΓࢉΛ଍͢ ଍͠ࢉ:= ੔਺ ( ( ‘+’ | ‘-’ | ‘*’ | ‘/’) ੔਺ )* 2*3+4 ͸Αͦ͞͏ɻ 4+2*3 ͸ʁ 24

Slide 27

Slide 27 text

Step 5 ֻ͚ࢉɾׂΓࢉΛ଍͢ ԋࢉࢠͷ༏ઌॱҐͱ͸ʁ 4 + (2 * 3) - (6 / 3) ଍͠ࢉͷཁૉͱֻ͚ͯ͠ࢉΛ࢖͑Δɻ ੔਺ͱֻ͚ࢉ͸ಉ͡ѻ͍ɻ 25

Slide 28

Slide 28 text

Step 5 ֻ͚ࢉɾׂΓࢉΛ଍͢ ֻ͚ࢉ:= ੔਺ ( ( ‘*’ | ‘/’ ) ੔਺ )* ଍͠ࢉ:= ֻ͚ࢉ ( ( ‘+’ | ‘-’ ) ֻ͚ࢉ )* શͯͷϓϩάϥϜ͸ʮ଍͠ࢉʯ e.g. 42, 1+2-3, 2*3/2, 2*3+4*5-10/3 26

Slide 29

Slide 29 text

int parse_add () { int ival = parse_mul (); while (*p != ’\0’) { switch (*p) { case ’+’: p++; ival += parse_mul (); continue; case ’-’: p++; ival -= parse_mul (); continue; } break; } return ival; } 27

Slide 30

Slide 30 text

int parse_mul () { int ival = parse_integer (); while (*p != ’\0’) { switch (*p) { case ’*’: p++; ival *= parse_integer (); continue; case ’/’: p++; ival /= parse_integer (); continue; } break; } return ival; } 28

Slide 31

Slide 31 text

Step 6 ؔ਺ݺͼग़͠Λ࣮૷ ੔਺ͷग़ྗΛߦ͏ؔ਺ P() Λͭ͘Δɻ ؔ਺ͷ໭Γ஋͸ 0 ͱ͓ͯ͘͠ɻ runtest "P(1)" 0 # 1 on screen 29

Slide 32

Slide 32 text

Step 6 ؔ਺ݺͼग़͠Λ࣮૷ F(2) / 2 + G(3+4*2) * H(0) - 5 • ؔ਺ͷ໭Γ஋͸੔਺ͱಉ͡ѻ͍ɻ • ؔ਺ͷҾ਺͸ʮ଍͠ࢉʯ 30

Slide 33

Slide 33 text

Step 6 ؔ਺ݺͼग़͠Λ࣮૷ ؔ਺ݺग़:= ‘P’ ‘(’ ଍͠ࢉ ‘)’ | ੔਺ ֻ͚ࢉ:= ؔ਺ݺग़ ( ( ‘*’ | ‘/’ ) ؔ਺ݺग़ )* ଍͠ࢉ:= ֻ͚ࢉ ( ( ‘+’ | ‘-’ ) ֻ͚ࢉ )* 31

Slide 34

Slide 34 text

int parse_mul () { int ival = parse_funccall (); while (*p != ’\0’) { switch (*p) { case ’*’: p++; ival *= parse_funccall (); continue; case ’/’: p++; ival /= parse_funccall (); continue; } break; } return ival; } 32

Slide 35

Slide 35 text

int parse_funccall () { if (*p == ’P’) { p++; expect(’(’); int ival = parse_add (); expect(’)’); printf("%d\n", ival ); return 0; } return parse_integer (); } 33

Slide 36

Slide 36 text

Step 7 ࣜͷ۠੾ΓΛ௥Ճ ‘;’ ͰࣜΛ۠੾ΕΔΑ͏ʹ͢Δɻ runtest "P(1);10+2;3" 3 ࠷ऴతͳ஋͸Ұ൪࠷ޙͷࣜͷ஋ɻ 34

Slide 37

Slide 37 text

Step 7 ࣜͷ۠੾ΓΛ௥Ճ ؔ਺ݺग़:= ‘P’ ‘(’ ࣜ ‘)’ | ੔਺ ֻ͚ࢉ:= ؔ਺ݺग़ ( ( ‘*’ | ‘/’ ) ؔ਺ݺग़ )* ଍͠ࢉ:= ֻ͚ࢉ ( ( ‘+’ | ‘-’ ) ֻ͚ࢉ )* ࣜ:= ଍͠ࢉ ( ‘;’ ଍͠ࢉ )* શͯͷϓϩάϥϜ͸ʮࣜʯ 35

Slide 38

Slide 38 text

int eval() { int ival = parse_add (); while (*p == ’;’) { p++; ival = parse_add (); } return ival; } 36

Slide 39

Slide 39 text

Step 8 Ҿ਺ͳؔ͠਺ఆٛΛ௥Ճ Ҿ਺ͳ͠ͷؔ਺ఆ͕ٛͰ͖ΔΑ͏ʹ͢Δɻ runtest "F{1}F()" 1 runtest "F{5/2+99/3 -3*4}F()" 23 runtest "F{5/2+99/3 -3*4;100 -24}F()"\ 76 ؔ਺໊͸େจࣈΞϧϑΝϕοτ 1 จࣈɻ ؔ਺ఆٛ͸ϓϩάϥϜͷઌ಄ͷΈͰՄೳɻ 37

Slide 40

Slide 40 text

Step 8 Ҿ਺ͳؔ͠਺ఆٛΛ௥Ճ F{5/2+99/3-3*4;100-24} • ؔ਺໊͕࢝ΊʹདྷΔɻ • {ͱ}Ͱؔ਺ຊମΛғΉɻ • ؔ਺ຊମ͸ࣜΛ; Ͱ۠੾ͬͨ΋ͷɻ • ؔ਺ͷ໭Γ஋͸ؔ਺ຊମΛධՁ͠ ͨ஋ɻ 38

Slide 41

Slide 41 text

Step 8 Ҿ਺ͳؔ͠਺ఆٛΛ௥Ճ F{5/2+99/3-3*4;100-24} ؔ਺ఆٛ := [ ‘A’-‘Z’ ] ‘{’ ࣜ ‘}’ ؔ਺ݺग़ := ‘P’ ‘(’ ࣜ ‘)’ | [ ‘A’-‘Z’ ] ‘(’ ‘)’ | ੔਺ 39

Slide 42

Slide 42 text

int eval() { while (1) { if (’A’ <= *p && *p <= ’Z’ && *(p + 1) == ’{’) { parse_funcdef (); continue; } return parse_exprs (); } } 40

Slide 43

Slide 43 text

char *funcbuf [256]; void parse_funcdef () { int n = *p++; expect(’{’); funcbuf[n] = p; while (*p != ’\0’ && *p++ != ’}’) ; } 41

Slide 44

Slide 44 text

int parse_funccall () { // ... process of P()... // then other functions if (’A’ <= *p && *p <= ’Z’) { int name = *p; p++; expect(’(’); expect(’)’); char *old_p = p; p = funcbuf[name ]; int ival = parse_exprs (); p = old_p; return ival; } return parse_integer (); } 42

Slide 45

Slide 45 text

Step 9 Ҿ਺͋Γؔ਺ఆٛΛ௥Ճ Ҿ਺͋Γͷؔ਺ఆ͕ٛͰ͖ΔΑ͏ʹ͢Δɻ runtest "F{a}F(42)" 42 runtest "F{a+b;a*b}F(1 ,1+1)" 2 Ҿ਺͸খจࣈΞϧϑΝϕοτ 1 จࣈɻ ݺͼग़͠ଆ͸ΧϯϚͰ۠੾ͬͯ౉͢ɻ 43

Slide 46

Slide 46 text

Step 9 Ҿ਺͋Γؔ਺ఆٛΛ௥Ճ F{a+b;a*b} • ੔਺ͱҾ਺Λಉ౳ʹѻ͏ɻ • ؔ਺ͷத਎ΛධՁ͢Δͱ͖ʹɺҾ਺Λ ରԠ͢Δ஋ʹ͢Γସ͑Δɻ ͺͦ͜ΜΘ͔ΒΜʂ͆ͷͰҾ਺Λม਺ ʢvariableʣͱ͍͏໊લͰ࣮૷ͨ͠ɻ 44

Slide 47

Slide 47 text

Step 9 Ҿ਺͋Γؔ਺ఆٛΛ௥Ճ F{a+b;a*b} ม਺ := [ ‘a’-‘z’ ] | ੔਺ ؔ਺ݺग़ := ‘P’ ‘(’ ࣜ ‘)’ | [ ‘A’-‘Z’ ] ‘(’ ‘)’ | ม਺ 45

Slide 48

Slide 48 text

int *varbuf; int parse_variable () { if (’a’ <= *p && *p <= ’z’) return varbuf [(int)*p++]; return parse_integer (); } 46

Slide 49

Slide 49 text

Step 9 Ҿ਺͋Γؔ਺ఆٛΛ௥Ճ parse funccall() ͷղઆ 1. ؔ਺໊ͱ (ΛಡΉɻ 2. ม਺ςʔϒϧΛ࡞ΔɻҾ਺ΛධՁͯ͠ tmpbuf ʹೖΕΔɻ 3. ) ΛಡΉɻ 4. p ͱ funcbuf[name] ΛೖΕସ͑Δɻ 5. tmpbuf ͱ varbuf ΛೖΕସ͑Δɻ 47

Slide 50

Slide 50 text

Step 9 Ҿ਺͋Γؔ਺ఆٛΛ௥Ճ parse funccall() ͷղઆ 6. parse exprs() ΛݺͿ͜ͱͰؔ਺ຊମΛಡ Ήɻ͜ͷ஋͕໭Γ஋ɻ 7. ্ͰೖΕସ͑ͨ p ͱ varbuf Λݩʹ໭͢ɻ 8. ໭Γ஋Λฦ͢ɻ 47

Slide 51

Slide 51 text

Step 10 ϑΟϘφον਺ྻΛग़ྗ͢Δ ඞཁͳݴޠػೳ͸શ࣮ͯ૷ɻ runtest "1*2+3" 5 runtest "13/3+4" 8 runtest "P(1);10+2;3" 3 runtest "F{a+b;a*b}F(1 ,1+1)" 2 ͜ΕΒΛ༻͍ͯϑΟϘφον਺ྻΛग़ྗ͢ Δʹ͸ʁ 48

Slide 52

Slide 52 text

Step 10 ϑΟϘφον਺ྻΛग़ྗ͢Δ F{P(a);F(b,a+b)}F(1,1) % ./main "F{P(a);F(b,a+b)}F(1,1)" | head -25 2 ͷྦྷ৐ͱ͔΋ܭࢉͰ͖Δɻ 49

Slide 53

Slide 53 text

·ͱΊ 50

Slide 54

Slide 54 text

·ͱΊ ݴޠॲཧܥ͸ ΍Δ͚ͩ 50

Slide 55

Slide 55 text

͝ਗ਼ௌ ͋Γ͕ͱ͏͟͝ ͍·ͨ͠ 51