Moduel_RealUpto.Mod 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. MODULE Moduel;
  2. IMPORT In, Out, Files;
  3. CONST
  4. null = 0; module = 1; import = 2; const = 3; var = 4; begin = 5;
  5. end = 6; if = 7; then = 8; else = 9; elsif = 10; while = 11;
  6. ident = 12; semicol = 13; colon = 14; comma = 15; period = 16;
  7. becomes = 17; equ = 18; neq = 19; les = 20; leq = 21; gtr = 22; geq = 23;
  8. lparen = 24; rparen = 25; lbrak = 26; rbrak = 27; lbrace = 28; rbrace = 29;
  9. int = 30; string = 31; not = 32; and = 33; or = 34; plus = 35; minus = 36;
  10. rdiv = 37; div = 38; mod = 39; times = 40; real = 41; upto = 42; eot = 64;
  11. VAR f: Files.File;
  12. r: Files.Rider;
  13. ch: CHAR;
  14. sym: INTEGER;
  15. id: ARRAY 32 OF CHAR;
  16. idlen: INTEGER;
  17. ival: INTEGER;
  18. rval: REAL;
  19. error: BOOLEAN;
  20. PROCEDURE ReadCh;
  21. BEGIN
  22. IF r.eof THEN ch := 0X
  23. ELSE Files.Read(r, ch)
  24. END
  25. END ReadCh;
  26. PROCEDURE Get;
  27. VAR k: REAL;
  28. BEGIN
  29. WHILE (ch # 0X) & (ch <= " ") DO
  30. ReadCh
  31. END;
  32. IF r.eof THEN sym := eot
  33. ELSIF ch = "," THEN sym := comma; ReadCh
  34. ELSIF ch = "." THEN sym := period; ReadCh
  35. ELSIF ch = ";" THEN sym := semicol; ReadCh
  36. ELSIF ch = "+" THEN sym := plus; ReadCh
  37. ELSIF ch = "-" THEN sym := minus; ReadCh
  38. ELSIF ch = "&" THEN sym := and; ReadCh
  39. ELSIF ch = "~" THEN sym := not; ReadCh
  40. ELSIF ch = "(" THEN sym := lparen; ReadCh
  41. ELSIF ch = ")" THEN sym := rparen; ReadCh
  42. ELSIF ch = "[" THEN sym := lbrak; ReadCh
  43. ELSIF ch = "]" THEN sym := rbrak; ReadCh
  44. ELSIF ch = "{" THEN sym := lbrace; ReadCh
  45. ELSIF ch = "}" THEN sym := rbrace; ReadCh
  46. ELSIF ch = ":" THEN
  47. ReadCh;
  48. IF ch = "=" THEN sym := becomes; ReadCh
  49. ELSE sym := colon
  50. END
  51. ELSIF ("A" <= ch) & (ch <= "Z") OR ("a" <= ch) & (ch <= "z") THEN
  52. id[0] := ch; idlen := 1; ReadCh;
  53. WHILE ("A" <= ch) & (ch <= "Z") OR
  54. ("a" <= ch) & (ch <= "z") OR
  55. ("0" <= ch) & (ch <= "9") DO
  56. IF idlen < LEN(id) - 1 THEN
  57. id[idlen] := ch;
  58. INC(idlen)
  59. END;
  60. ReadCh
  61. END;
  62. id[idlen] := 0X;
  63. IF id = "MODULE" THEN sym := module
  64. ELSIF id = "IMPORT" THEN sym := import
  65. ELSIF id = "CONST" THEN sym := const
  66. ELSIF id = "VAR" THEN sym := var
  67. ELSIF id = "BEGIN" THEN sym := begin
  68. ELSIF id = "END" THEN sym := end
  69. ELSIF id = "IF" THEN sym := if
  70. ELSIF id = "THEN" THEN sym := then
  71. ELSIF id = "ELSE" THEN sym := else
  72. ELSIF id = "ELSIF" THEN sym := elsif
  73. ELSIF id = "WHILE" THEN sym := while
  74. ELSIF id = "DIV" THEN sym := div
  75. ELSIF id = "MOD" THEN sym := mod
  76. ELSIF id = "OR" THEN sym := or
  77. ELSE sym := ident
  78. END
  79. ELSIF ("0" <= ch) & (ch <= "9") THEN
  80. ival := 0;
  81. REPEAT
  82. ival := ival * 10 + ORD(ch) - ORD("0");
  83. ReadCh
  84. UNTIL (ch < "0") OR (ch > "9");
  85. (*UNTIL ~(("0" <= ch) & (ch <= "9"));*)
  86. IF ch = '.' THEN (* REAL или ".." *)
  87. ReadCh;
  88. IF ("0" <= ch) & (ch <= "9") THEN
  89. rval := ival; k := 0.1;
  90. REPEAT 32.51 + 9/1000 = 32.519
  91. rval := rval + (ORD(ch) - ORD("0")) * k;
  92. k := k * 0.1;
  93. ReadCh
  94. UNTIL (ch < "0") OR (ch > "9");
  95. sym := real
  96. ELSIF ch = '.' THEN
  97. sym := int;
  98. ch := 7FX
  99. ELSE sym := null
  100. END
  101. END
  102. ELSIF ch = 7FX THEN sym := upto; ReadCh
  103. ELSE
  104. sym := null;
  105. ReadCh
  106. END
  107. END Get;
  108. PROCEDURE Mark(msg: ARRAY OF CHAR);
  109. BEGIN
  110. error := TRUE;
  111. Out.String("Ошибка на поз. ");
  112. Out.Int(SHORT(Files.Pos(r)), 0);
  113. Out.String(": "); Out.String(msg);
  114. Out.Char("."); Out.Ln
  115. END Mark;
  116. PROCEDURE Declarations;
  117. BEGIN
  118. (*Пусто*)
  119. END Declarations;
  120. PROCEDURE StatSeq;
  121. VAR name: ARRAY 32 OF CHAR;
  122. BEGIN
  123. WHILE (sym = ident) OR (sym = semicol) DO
  124. IF sym = ident THEN name := id; Get;
  125. IF sym = equ THEN Get; sym := becomes; Mark("Ожидается :=") END;
  126. IF sym = becomes THEN Get;
  127. IF sym = int THEN
  128. Out.String("Переменной "); Out.String(name);
  129. Out.String(" присвоено значение "); Out.Int(ival, 0); Out.Ln;
  130. Get
  131. ELSE Get;
  132. Mark("Можно присваивать только числа")
  133. END
  134. END
  135. ELSE Get
  136. END
  137. END
  138. END StatSeq;
  139. PROCEDURE Module;
  140. VAR name: ARRAY 32 OF CHAR;
  141. BEGIN
  142. IF sym = module THEN
  143. Get;
  144. IF sym = ident THEN name := id; Get
  145. ELSE Mark("Ожидается идентификатор"); name[0] := 0X
  146. END;
  147. IF sym = semicol THEN Get
  148. ELSE Mark("Ожидается точка с запятой")
  149. END;
  150. Declarations;
  151. IF sym = begin THEN Get; StatSeq END;
  152. IF sym = end THEN
  153. Get;
  154. IF sym = ident THEN
  155. IF name # id THEN Mark("Название модуля не совпадает") END;
  156. Get;
  157. IF sym # period THEN Mark("Нет точки в конце модуля") END
  158. END
  159. ELSE Mark("Ожидается END")
  160. END
  161. ELSE Mark("Ожидается модуль")
  162. END
  163. END Module;
  164. BEGIN
  165. f := Files.Old("Test.Mod");
  166. IF f = NIL THEN
  167. Out.String("No file");
  168. Out.Ln
  169. ELSE
  170. Files.Set(r, f, 0);
  171. ReadCh;
  172. Get;
  173. error := FALSE;
  174. Module;
  175. IF error THEN Out.String("Были ошибки."); Out.Ln END
  176. END
  177. END Moduel.
  178. Пример работы лексического анализатора (# обозначает литеру 7FX).
  179. x := {12..15}
  180. x := {12..#15}
  181. x ident (id="x",idlen=1)
  182. := becomes
  183. { lbrace
  184. 12 int (ival=12)
  185. .. upto
  186. 15 int (ival=15)
  187. } rbrace
  188. *)