kapunta gist felülvizsgálása . Revízióhoz ugrás
1 file changed, 8 insertions, 6 deletions
Thue.Mod
@@ -88,9 +88,9 @@ MODULE Thue; | |||
88 | 88 | IF Find(B, L[i].s, L[i].n, j) THEN | |
89 | 89 | IF NS - L[i].n + R[i].n <= MaxB THEN | |
90 | 90 | IF L[i].n < R[i].n THEN | |
91 | - | FOR k := S+NS-L[i].n-1 TO S+j BY -1 DO B[k+R[i].s] := B[k+L[i].s] END | |
91 | + | FOR k := S+NS-L[i].n-1 TO S+j BY -1 DO B[k+R[i].n] := B[k+L[i].n] END | |
92 | 92 | ELSE | |
93 | - | FOR k := S+j TO S+NS-L[i].n-1 DO B[k+R[i].s] := B[k+L[i].s] END | |
93 | + | FOR k := S+j TO S+NS-L[i].n-1 DO B[k+R[i].n] := B[k+L[i].n] END | |
94 | 94 | END; | |
95 | 95 | FOR k := 0 TO R[i].n-1 DO B[S+j+k] := B[R[i].s+k] END; | |
96 | 96 | NS := NS - L[i].n + R[i].n; | |
@@ -107,12 +107,14 @@ END Thue. | |||
107 | 107 | ||
108 | 108 | ~~~ | |
109 | 109 | ||
110 | - | To compile: System.Free Thue~ ORP.Compile Thue.Mod/s~ | |
110 | + | To compile: System.Free Thue~ ORP.Compile Thue.Mod/s~ | |
111 | 111 | ||
112 | 112 | To load a program: Thue.Read | |
113 | - | a::=bb | |
114 | - | bbb::=c | |
113 | + | kingdom, no knight.::=A kingdom was lost, all for the want of a nail. | |
114 | + | no horse::=no knight | |
115 | + | no shoe::=no horse | |
116 | + | no nail::=no shoe | |
115 | 117 | ::= | |
116 | - | acaabcaabbba | |
118 | + | kingdom, no nail. | |
117 | 119 | ||
118 | 120 | To run: Thue.Go |
kapunta gist felülvizsgálása . Revízióhoz ugrás
1 file changed, 118 insertions
Thue.Mod(fájl létrehozva)
@@ -0,0 +1,118 @@ | |||
1 | + | MODULE Thue; | |
2 | + | IMPORT Texts, Oberon; | |
3 | + | ||
4 | + | CONST MaxB = 10000; | |
5 | + | MaxRules = 1000; | |
6 | + | ||
7 | + | VAR W: Texts.Writer; | |
8 | + | B: ARRAY MaxB OF CHAR; | |
9 | + | S, NS, NR: INTEGER; | |
10 | + | L, R: ARRAY MaxRules OF RECORD s, n: INTEGER END; | |
11 | + | ||
12 | + | PROCEDURE Write(s, n: INTEGER); | |
13 | + | VAR i: INTEGER; | |
14 | + | BEGIN | |
15 | + | FOR i := s TO s+n-1 DO Texts.Write(W, B[i]) END; | |
16 | + | Texts.Append(Oberon.Log, W.buf) | |
17 | + | END Write; | |
18 | + | ||
19 | + | PROCEDURE Find(s: ARRAY OF CHAR; start, n: INTEGER; VAR pos: INTEGER): BOOLEAN; | |
20 | + | VAR i, j: INTEGER; | |
21 | + | f: BOOLEAN; | |
22 | + | BEGIN | |
23 | + | IF NS < n THEN f := FALSE | |
24 | + | ELSE | |
25 | + | i := 0; | |
26 | + | WHILE i <= NS-n DO | |
27 | + | f := TRUE; j := 0; | |
28 | + | WHILE j < n DO | |
29 | + | IF B[S+i+j] # s[start+j] THEN f := FALSE; j := n ELSE INC(j) END | |
30 | + | END; | |
31 | + | IF f THEN pos := i; i := NS ELSE INC(i) END | |
32 | + | END | |
33 | + | END; | |
34 | + | RETURN f | |
35 | + | END Find; | |
36 | + | ||
37 | + | PROCEDURE Reset; | |
38 | + | BEGIN | |
39 | + | NR := 0; S := 0; NS := 0 | |
40 | + | END Reset; | |
41 | + | ||
42 | + | PROCEDURE Read*; | |
43 | + | VAR Rr: Texts.Reader; | |
44 | + | i, sep: INTEGER; | |
45 | + | f: BOOLEAN; | |
46 | + | ||
47 | + | PROCEDURE ReadLine(VAR R: Texts.Reader); | |
48 | + | VAR i: INTEGER; | |
49 | + | ch: CHAR; | |
50 | + | BEGIN | |
51 | + | i := 0; Texts.Read(R, ch); | |
52 | + | WHILE (S+i < MaxB) & ~R.eot & (ch # 0DX) DO | |
53 | + | B[S+i] := ch; INC(i); Texts.Read(R, ch) | |
54 | + | END; | |
55 | + | NS := i; | |
56 | + | IF S+i = MaxB THEN Texts.WriteString(W, "Out of space"); Texts.WriteLn(W) END | |
57 | + | END ReadLine; | |
58 | + | ||
59 | + | BEGIN | |
60 | + | Reset; | |
61 | + | Texts.OpenReader(Rr, Oberon.Par.text, Oberon.Par.pos); | |
62 | + | f := FALSE; | |
63 | + | REPEAT ReadLine(Rr); | |
64 | + | IF Find("::=", 0, 3, sep) THEN | |
65 | + | IF NS = 3 THEN ReadLine(Rr); Rr.eot := TRUE | |
66 | + | ELSIF NR < MaxRules THEN | |
67 | + | L[NR].s := S; L[NR].n := sep; | |
68 | + | R[NR].s := S + sep + 3; R[NR].n := NS - sep - 3; | |
69 | + | INC(NR); INC(S, NS) | |
70 | + | ELSE Texts.WriteString(W, "Too many rules"); Texts.WriteLn(W); f := TRUE END | |
71 | + | ELSE | |
72 | + | i := 0; | |
73 | + | WHILE i < NS DO | |
74 | + | IF B[S+i] # " " THEN f := TRUE; i := NS ELSE INC(i) END | |
75 | + | END; | |
76 | + | IF f THEN Texts.WriteString(W, "Invalid rule"); Texts.WriteLn(W) END | |
77 | + | END | |
78 | + | UNTIL Rr.eot OR f; | |
79 | + | IF f THEN Reset ELSE Write(S, NS); Texts.WriteLn(W) END; | |
80 | + | Texts.Append(Oberon.Log, W.buf) | |
81 | + | END Read; | |
82 | + | ||
83 | + | PROCEDURE Go*; | |
84 | + | VAR i, j, k: INTEGER; | |
85 | + | BEGIN | |
86 | + | i := 0; | |
87 | + | WHILE i < NR DO | |
88 | + | IF Find(B, L[i].s, L[i].n, j) THEN | |
89 | + | IF NS - L[i].n + R[i].n <= MaxB THEN | |
90 | + | IF L[i].n < R[i].n THEN | |
91 | + | FOR k := S+NS-L[i].n-1 TO S+j BY -1 DO B[k+R[i].s] := B[k+L[i].s] END | |
92 | + | ELSE | |
93 | + | FOR k := S+j TO S+NS-L[i].n-1 DO B[k+R[i].s] := B[k+L[i].s] END | |
94 | + | END; | |
95 | + | FOR k := 0 TO R[i].n-1 DO B[S+j+k] := B[R[i].s+k] END; | |
96 | + | NS := NS - L[i].n + R[i].n; | |
97 | + | Write(S, NS); Texts.WriteLn(W); | |
98 | + | i := 0 | |
99 | + | ELSE Texts.WriteString(W, "Out of space"); Texts.WriteLn(W); i := NR END | |
100 | + | ELSE INC(i) END | |
101 | + | END; | |
102 | + | Texts.Append(Oberon.Log, W.buf) | |
103 | + | END Go; | |
104 | + | ||
105 | + | BEGIN Texts.OpenWriter(W); | |
106 | + | END Thue. | |
107 | + | ||
108 | + | ~~~ | |
109 | + | ||
110 | + | To compile: System.Free Thue~ ORP.Compile Thue.Mod/s~ | |
111 | + | ||
112 | + | To load a program: Thue.Read | |
113 | + | a::=bb | |
114 | + | bbb::=c | |
115 | + | ::= | |
116 | + | acaabcaabbba | |
117 | + | ||
118 | + | To run: Thue.Go |