M2S.mod 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. IMPLEMENTATION MODULE M2S;
  2. (* Scanner generated by Coco/R - using the FileIO library supplied with this project. *)
  3. IMPORT FileIO, Storage;
  4. FROM Storage IMPORT ALLOCATE; (* gm2 needs this for NEW substitution *)
  5. CONST
  6. noSYMB = 82; (*error token code*)
  7. (* not only for errors but also for not finished states of scanner analysis *)
  8. eof = CHR(26) (* MS-DOS Keyboard eof char *);
  9. EOF = CHR(0);
  10. EOL = CHR(13);
  11. CR = CHR(13);
  12. LF = CHR(10);
  13. Long0 = 0;
  14. Long1 = 1;
  15. BlkSize = 16384;
  16. TYPE
  17. BufBlock = ARRAY [0 .. BlkSize-1] OF CHAR;
  18. Buffer = ARRAY [0 .. 31] OF POINTER TO BufBlock;
  19. StartTable = ARRAY [0 .. 255] OF INTEGER;
  20. GetCH = PROCEDURE (INT32): CHAR;
  21. VAR
  22. lastCh,
  23. ch: CHAR; (*current input character*)
  24. curLine: INTEGER; (*current input line (may be higher than line)*)
  25. lineStart: INT32; (*start position of current line*)
  26. apx: INT32; (*length of appendix (CONTEXT phrase)*)
  27. oldEols: INTEGER; (*number of EOLs in a comment*)
  28. bp, bp0: INT32; (*current position in buf
  29. (bp0: position of current token)*)
  30. inputLen: INT32; (*source file size*)
  31. buf: Buffer; (*source buffer for low-level access*)
  32. start: StartTable; (*start state for every character*)
  33. CurrentCh: GetCH;
  34. (* ---- TopSpeed conditional compilation ---- *)
  35. condStk: ARRAY [0 .. 31] OF BOOLEAN;
  36. nCond: CARDINAL;
  37. defs: ARRAY [0 .. 31] OF ARRAY [0 .. 31] OF CHAR;
  38. nDefs: CARDINAL;
  39. defsInit: BOOLEAN;
  40. PROCEDURE Err (nr, line, col: INTEGER; pos: INT32);
  41. BEGIN
  42. INC(errors)
  43. END Err;
  44. PROCEDURE NextCh;
  45. (* Return global variable ch *)
  46. BEGIN
  47. lastCh := ch; INC(bp); ch := CurrentCh(bp);
  48. IF (ch = EOL) OR (ch = LF) AND (lastCh # EOL) THEN
  49. INC(curLine); lineStart := bp
  50. END
  51. END NextCh;
  52. PROCEDURE Comment (): BOOLEAN;
  53. VAR
  54. level, startLine: INTEGER;
  55. oldLineStart: INT32;
  56. BEGIN
  57. level := 1; startLine := curLine; oldLineStart := lineStart;
  58. IF (ch = "/") THEN
  59. NextCh;
  60. IF (ch = "/") THEN
  61. NextCh;
  62. LOOP
  63. IF (ch = CHR(10)) THEN
  64. DEC(level); oldEols := curLine - startLine; NextCh;
  65. IF level = 0 THEN RETURN TRUE END;
  66. ELSIF ch = EOF THEN RETURN FALSE
  67. ELSE NextCh END;
  68. END; (* LOOP *)
  69. ELSE
  70. IF (ch = CR) OR (ch = LF) THEN
  71. DEC(curLine); lineStart := oldLineStart
  72. END;
  73. DEC(bp); ch := lastCh;
  74. END;
  75. END;
  76. IF (ch = "(") THEN
  77. NextCh;
  78. IF (ch = "*") THEN
  79. NextCh;
  80. LOOP
  81. IF (ch = "*") THEN
  82. NextCh;
  83. IF (ch = ")") THEN
  84. DEC(level); NextCh;
  85. IF level = 0 THEN RETURN TRUE END
  86. END;
  87. ELSIF (ch = "(") THEN
  88. NextCh;
  89. IF (ch = "*") THEN INC(level); NextCh END;
  90. ELSIF ch = EOF THEN RETURN FALSE
  91. ELSE NextCh END;
  92. END; (* LOOP *)
  93. ELSE
  94. IF (ch = CR) OR (ch = LF) THEN
  95. DEC(curLine); lineStart := oldLineStart
  96. END;
  97. DEC(bp); ch := lastCh;
  98. END;
  99. END;
  100. RETURN FALSE;
  101. END Comment;
  102. (* ---- TopSpeed conditional compilation: (*%T cond*) / (*%F cond*) /
  103. (*%E*) ---- Blank the inactive regions of the source buffer (CR/LF
  104. kept, so line numbers survive) before scanning. Conditions are
  105. evaluated against a small define set (see InitDefs); an unknown
  106. symbol is 'undefined'. *)
  107. PROCEDURE CopyStr (s: ARRAY OF CHAR; VAR t: ARRAY OF CHAR);
  108. VAR i: CARDINAL;
  109. BEGIN
  110. i := 0;
  111. WHILE (i <= HIGH(t)) AND (i <= HIGH(s)) AND (s[i] # CHR(0)) DO
  112. t[i] := s[i]; INC(i)
  113. END;
  114. IF i <= HIGH(t) THEN t[i] := CHR(0) END
  115. END CopyStr;
  116. PROCEDURE Same (a, b: ARRAY OF CHAR): BOOLEAN;
  117. VAR i: CARDINAL;
  118. BEGIN
  119. i := 0;
  120. WHILE (a[i] # CHR(0)) AND (b[i] # CHR(0)) AND (a[i] = b[i]) DO INC(i) END;
  121. RETURN a[i] = b[i]
  122. END Same;
  123. PROCEDURE AddDef (s: ARRAY OF CHAR);
  124. BEGIN
  125. IF nDefs <= HIGH(defs) THEN CopyStr(s, defs[nDefs]); INC(nDefs) END
  126. END AddDef;
  127. PROCEDURE InitDefs;
  128. (* Define set used to select conditional branches. Tuned for the
  129. TS-V3 corpus: the "_fdata"/"_mthread" variants are the plain,
  130. parseable ones; "_OS2"/"_fcall"/... are left undefined so the
  131. non-OS2 branches are taken. *)
  132. BEGIN
  133. nDefs := 0;
  134. (* DEFINES:BEGIN *)
  135. AddDef("_fdata");
  136. AddDef("_mthread");
  137. AddDef("_fptr");
  138. AddDef("_fcall");
  139. (* DEFINES:END *)
  140. END InitDefs;
  141. PROCEDURE IsDefined (id: ARRAY OF CHAR): BOOLEAN;
  142. VAR k: CARDINAL;
  143. BEGIN
  144. k := 0;
  145. WHILE k < nDefs DO
  146. IF Same(id, defs[k]) THEN RETURN TRUE END;
  147. INC(k)
  148. END;
  149. RETURN FALSE
  150. END IsDefined;
  151. PROCEDURE CondIdent (c: CHAR): BOOLEAN;
  152. BEGIN
  153. RETURN ((c >= "A") AND (c <= "Z")) OR ((c >= "a") AND (c <= "z"))
  154. OR ((c >= "0") AND (c <= "9")) OR (c = "_")
  155. END CondIdent;
  156. PROCEDURE CondBlank (p: INT32);
  157. VAR c: CHAR;
  158. BEGIN
  159. IF (p < 0) OR (p >= inputLen) THEN RETURN END;
  160. c := buf[ORD(p DIV BlkSize)]^[ORD(p MOD BlkSize)];
  161. IF (c # CR) AND (c # LF) THEN
  162. buf[ORD(p DIV BlkSize)]^[ORD(p MOD BlkSize)] := " "
  163. END
  164. END CondBlank;
  165. PROCEDURE CondFilter;
  166. VAR p, q, j, b: INT32;
  167. c, letter: CHAR;
  168. id: ARRAY [0 .. 31] OF CHAR;
  169. k: CARDINAL;
  170. parentOk, cond, active: BOOLEAN;
  171. BEGIN
  172. IF NOT defsInit THEN InitDefs; defsInit := TRUE END;
  173. nCond := 0;
  174. p := 0;
  175. WHILE p < inputLen DO
  176. c := buf[ORD(p DIV BlkSize)]^[ORD(p MOD BlkSize)];
  177. IF (c = "(") AND (p + 3 < inputLen)
  178. AND (buf[ORD((p+1) DIV BlkSize)]^[ORD((p+1) MOD BlkSize)] = "*")
  179. AND (buf[ORD((p+2) DIV BlkSize)]^[ORD((p+2) MOD BlkSize)] = "%") THEN
  180. letter := buf[ORD((p+3) DIV BlkSize)]^[ORD((p+3) MOD BlkSize)];
  181. q := p + 4;
  182. WHILE (q + 1 < inputLen)
  183. AND NOT ((buf[ORD(q DIV BlkSize)]^[ORD(q MOD BlkSize)] = "*")
  184. AND (buf[ORD((q+1) DIV BlkSize)]^[ORD((q+1) MOD BlkSize)] = ")")) DO
  185. INC(q)
  186. END;
  187. IF letter = "E" THEN
  188. IF nCond > 0 THEN DEC(nCond) END
  189. ELSE
  190. j := p + 4; k := 0;
  191. WHILE (j < q) AND (k <= HIGH(id)) DO
  192. c := buf[ORD(j DIV BlkSize)]^[ORD(j MOD BlkSize)];
  193. IF CondIdent(c) THEN id[k] := c; INC(k)
  194. ELSIF k > 0 THEN j := q (* end of the name *)
  195. END;
  196. INC(j)
  197. END;
  198. id[k] := CHR(0);
  199. cond := IsDefined(id);
  200. IF letter = "F" THEN cond := NOT cond END;
  201. parentOk := (nCond = 0) OR condStk[nCond - 1];
  202. IF NOT parentOk THEN cond := FALSE END;
  203. IF nCond <= HIGH(condStk) THEN condStk[nCond] := cond; INC(nCond) END
  204. END;
  205. b := p;
  206. WHILE b <= q + 1 DO CondBlank(b); INC(b) END;
  207. p := q + 2
  208. ELSE
  209. active := (nCond = 0) OR condStk[nCond - 1];
  210. IF active THEN INC(p) ELSE CondBlank(p); INC(p) END
  211. END
  212. END
  213. END CondFilter;
  214. PROCEDURE Get (VAR sym: CARDINAL);
  215. VAR
  216. state: CARDINAL;
  217. PROCEDURE Equal (s: ARRAY OF CHAR): BOOLEAN;
  218. VAR
  219. i: CARDINAL;
  220. q: INT32;
  221. BEGIN
  222. IF nextLen # LENGTH(s) THEN RETURN FALSE END;
  223. i := 1; q := bp0; INC(q);
  224. WHILE i < nextLen DO
  225. IF CurrentCh(q) # s[i] THEN RETURN FALSE END;
  226. INC(i); INC(q)
  227. END;
  228. RETURN TRUE
  229. END Equal;
  230. PROCEDURE CheckLiteral;
  231. BEGIN
  232. CASE CurrentCh(bp0) OF
  233. "A": IF Equal("AND") THEN sym := 74;
  234. ELSIF Equal("ARRAY") THEN sym := 28;
  235. END
  236. | "B": IF Equal("BEGIN") THEN sym := 11;
  237. ELSIF Equal("BY") THEN sym := 56;
  238. END
  239. | "C": IF Equal("CASE") THEN sym := 31;
  240. ELSIF Equal("CLASS") THEN sym := 39;
  241. ELSIF Equal("CONST") THEN sym := 41;
  242. END
  243. | "D": IF Equal("DEFINITION") THEN sym := 6;
  244. ELSIF Equal("DIV") THEN sym := 72;
  245. ELSIF Equal("DO") THEN sym := 51;
  246. END
  247. | "E": IF Equal("ELSE") THEN sym := 34;
  248. ELSIF Equal("ELSIF") THEN sym := 49;
  249. ELSIF Equal("END") THEN sym := 9;
  250. ELSIF Equal("EXIT") THEN sym := 45;
  251. ELSIF Equal("EXPORT") THEN sym := 17;
  252. END
  253. | "F": IF Equal("FOR") THEN sym := 55;
  254. ELSIF Equal("FORWARD") THEN sym := 40;
  255. ELSIF Equal("FROM") THEN sym := 19;
  256. END
  257. | "G": IF Equal("GOTO") THEN sym := 44;
  258. END
  259. | "I": IF Equal("IF") THEN sym := 47;
  260. ELSIF Equal("IMPLEMENTATION") THEN sym := 10;
  261. ELSIF Equal("IMPORT") THEN sym := 20;
  262. ELSIF Equal("IN") THEN sym := 43;
  263. ELSIF Equal("INLINE") THEN sym := 12;
  264. ELSIF Equal("IS") THEN sym := 60;
  265. END
  266. | "L": IF Equal("LABEL") THEN sym := 13;
  267. ELSIF Equal("LOOP") THEN sym := 54;
  268. END
  269. | "M": IF Equal("MOD") THEN sym := 73;
  270. ELSIF Equal("MODULE") THEN sym := 7;
  271. END
  272. | "N": IF Equal("NOT") THEN sym := 80;
  273. END
  274. | "O": IF Equal("OF") THEN sym := 29;
  275. ELSIF Equal("OR") THEN sym := 69;
  276. END
  277. | "P": IF Equal("POINTER") THEN sym := 24;
  278. ELSIF Equal("PROCEDURE") THEN sym := 37;
  279. END
  280. | "Q": IF Equal("QUALIFIED") THEN sym := 18;
  281. END
  282. | "R": IF Equal("RECORD") THEN sym := 30;
  283. ELSIF Equal("REPEAT") THEN sym := 52;
  284. ELSIF Equal("RETURN") THEN sym := 57;
  285. END
  286. | "S": IF Equal("SET") THEN sym := 35;
  287. END
  288. | "T": IF Equal("THEN") THEN sym := 48;
  289. ELSIF Equal("TO") THEN sym := 36;
  290. ELSIF Equal("TYPE") THEN sym := 21;
  291. END
  292. | "U": IF Equal("UNTIL") THEN sym := 53;
  293. END
  294. | "V": IF Equal("VAR") THEN sym := 38;
  295. ELSIF Equal("VIRTUAL") THEN sym := 23;
  296. END
  297. | "W": IF Equal("WHILE") THEN sym := 50;
  298. ELSIF Equal("WITH") THEN sym := 58;
  299. END
  300. ELSE
  301. END
  302. END CheckLiteral;
  303. BEGIN (*Get*)
  304. WHILE (ch = ' ') OR
  305. ((ch >= CHR(9)) & (ch <= CHR(13))) DO NextCh END;
  306. IF ((ch = "/") OR (ch = "(")) & Comment() THEN Get(sym); RETURN END;
  307. pos := nextPos; nextPos := bp;
  308. col := nextCol; nextCol := VAL(INTEGER, bp - lineStart);
  309. line := nextLine; nextLine := curLine;
  310. len := nextLen; nextLen := 0;
  311. apx := 0; state := start[ORD(ch)]; bp0 := bp;
  312. LOOP
  313. NextCh; INC(nextLen);
  314. CASE state OF
  315. 1: IF ((ch >= "0") & (ch <= "9") OR
  316. (ch >= "@") & (ch <= "Z") OR
  317. (ch = "_") OR
  318. (ch >= "a") & (ch <= "z")) THEN
  319. ELSE sym := 1; CheckLiteral; RETURN
  320. END;
  321. | 2: IF ((ch >= "0") & (ch <= "9") OR
  322. (ch >= "A") & (ch <= "F") OR
  323. (ch >= "a") & (ch <= "f")) THEN state := 3;
  324. ELSE sym := noSYMB; RETURN
  325. END;
  326. | 3: IF ((ch >= "0") & (ch <= "9") OR
  327. (ch >= "A") & (ch <= "F") OR
  328. (ch >= "a") & (ch <= "f")) THEN
  329. ELSE sym := 2; RETURN
  330. END;
  331. | 4: IF ((ch >= "0") & (ch <= "9") OR
  332. (ch >= "A") & (ch <= "F") OR
  333. (ch >= "a") & (ch <= "f")) THEN state := 5;
  334. ELSE sym := noSYMB; RETURN
  335. END;
  336. | 5: IF ((ch >= "0") & (ch <= "9") OR
  337. (ch >= "A") & (ch <= "F") OR
  338. (ch >= "a") & (ch <= "f")) THEN
  339. ELSE sym := 2; RETURN
  340. END;
  341. | 6: bp := bp - apx - Long1; DEC(nextLen, ORDL(apx)); NextCh; sym := 2; RETURN
  342. | 7: sym := 2; RETURN
  343. | 8: IF ((ch >= "0") & (ch <= "9")) THEN
  344. ELSIF ((ch = "E") OR
  345. (ch = "e")) THEN state := 9;
  346. ELSE sym := 3; RETURN
  347. END;
  348. | 9: IF ((ch >= "0") & (ch <= "9")) THEN state := 11;
  349. ELSIF ((ch = "+") OR
  350. (ch = "-")) THEN state := 10;
  351. ELSE sym := noSYMB; RETURN
  352. END;
  353. | 10: IF ((ch >= "0") & (ch <= "9")) THEN state := 11;
  354. ELSE sym := noSYMB; RETURN
  355. END;
  356. | 11: IF ((ch >= "0") & (ch <= "9")) THEN
  357. ELSE sym := 3; RETURN
  358. END;
  359. | 12: IF ((ch <= CHR(12)) OR
  360. (ch >= CHR(14)) & (ch <= "&") OR
  361. (ch >= "(")) THEN
  362. ELSIF (ch = "'") THEN state := 14;
  363. ELSE sym := noSYMB; RETURN
  364. END;
  365. | 13: IF ((ch <= CHR(12)) OR
  366. (ch >= CHR(14)) & (ch <= "!") OR
  367. (ch >= "#")) THEN
  368. ELSIF (ch = '"') THEN state := 14;
  369. ELSE sym := noSYMB; RETURN
  370. END;
  371. | 14: sym := 4; RETURN
  372. | 15: IF ((ch >= "0") & (ch <= "9")) THEN
  373. ELSIF (ch = "c") THEN state := 17;
  374. ELSIF ((ch = "A") OR
  375. (ch >= "D") & (ch <= "F") OR
  376. (ch = "a") OR
  377. (ch >= "d") & (ch <= "f")) THEN state := 18;
  378. ELSIF (ch = ".") THEN state := 19; INC(apx)
  379. ELSIF (ch = "B") THEN state := 20;
  380. ELSIF (ch = "b") THEN state := 21;
  381. ELSIF ((ch = "H") OR
  382. (ch = "h")) THEN state := 7;
  383. ELSIF (ch = "C") THEN state := 22;
  384. ELSE sym := 2; RETURN
  385. END;
  386. | 16: IF ((ch >= "0") & (ch <= "9")) THEN state := 15;
  387. ELSIF (ch = "c") THEN state := 17;
  388. ELSIF ((ch = "A") OR
  389. (ch >= "D") & (ch <= "F") OR
  390. (ch = "a") OR
  391. (ch >= "d") & (ch <= "f")) THEN state := 18;
  392. ELSIF (ch = ".") THEN state := 19; INC(apx)
  393. ELSIF (ch = "B") THEN state := 20;
  394. ELSIF (ch = "b") THEN state := 21;
  395. ELSIF ((ch = "H") OR
  396. (ch = "h")) THEN state := 7;
  397. ELSIF (ch = "C") THEN state := 22;
  398. ELSIF (ch = "x") THEN state := 2;
  399. ELSIF (ch = "X") THEN state := 4;
  400. ELSE sym := 2; RETURN
  401. END;
  402. | 17: IF (ch = "c") THEN
  403. ELSIF ((ch >= "0") & (ch <= "9") OR
  404. (ch >= "A") & (ch <= "B") OR
  405. (ch >= "D") & (ch <= "F") OR
  406. (ch >= "a") & (ch <= "b") OR
  407. (ch >= "d") & (ch <= "f")) THEN state := 18;
  408. ELSIF ((ch = "H") OR
  409. (ch = "h")) THEN state := 7;
  410. ELSIF (ch = "C") THEN state := 22;
  411. ELSE sym := 2; RETURN
  412. END;
  413. | 18: IF (ch = "c") THEN state := 17;
  414. ELSIF ((ch >= "0") & (ch <= "9") OR
  415. (ch >= "A") & (ch <= "B") OR
  416. (ch >= "D") & (ch <= "F") OR
  417. (ch >= "a") & (ch <= "b") OR
  418. (ch >= "d") & (ch <= "f")) THEN
  419. ELSIF ((ch = "H") OR
  420. (ch = "h")) THEN state := 7;
  421. ELSIF (ch = "C") THEN state := 22;
  422. ELSE sym := noSYMB; RETURN
  423. END;
  424. | 19: IF ((ch >= "0") & (ch <= "9")) THEN state := 8; apx := Long0
  425. ELSIF (ch = ".") THEN state := 6; INC(apx)
  426. ELSIF ((ch = "E") OR
  427. (ch = "e")) THEN state := 9; apx := Long0
  428. ELSE sym := 3; RETURN
  429. END;
  430. | 20: IF (ch = "c") THEN state := 17;
  431. ELSIF ((ch >= "0") & (ch <= "9") OR
  432. (ch >= "A") & (ch <= "B") OR
  433. (ch >= "D") & (ch <= "F") OR
  434. (ch >= "a") & (ch <= "b") OR
  435. (ch >= "d") & (ch <= "f")) THEN state := 18;
  436. ELSIF ((ch = "H") OR
  437. (ch = "h")) THEN state := 7;
  438. ELSIF (ch = "C") THEN state := 22;
  439. ELSE sym := 2; RETURN
  440. END;
  441. | 21: IF (ch = "c") THEN state := 17;
  442. ELSIF ((ch >= "0") & (ch <= "9") OR
  443. (ch >= "A") & (ch <= "B") OR
  444. (ch >= "D") & (ch <= "F") OR
  445. (ch >= "a") & (ch <= "b") OR
  446. (ch >= "d") & (ch <= "f")) THEN state := 18;
  447. ELSIF ((ch = "H") OR
  448. (ch = "h")) THEN state := 7;
  449. ELSIF (ch = "C") THEN state := 22;
  450. ELSE sym := 2; RETURN
  451. END;
  452. | 22: IF (ch = "c") THEN state := 17;
  453. ELSIF ((ch >= "0") & (ch <= "9") OR
  454. (ch >= "A") & (ch <= "B") OR
  455. (ch >= "D") & (ch <= "F") OR
  456. (ch >= "a") & (ch <= "b") OR
  457. (ch >= "d") & (ch <= "f")) THEN state := 18;
  458. ELSIF ((ch = "H") OR
  459. (ch = "h")) THEN state := 7;
  460. ELSIF (ch = "C") THEN
  461. ELSE sym := 2; RETURN
  462. END;
  463. | 23: IF (ch = ".") THEN state := 29;
  464. ELSE sym := 5; RETURN
  465. END;
  466. | 24: sym := 8; RETURN
  467. | 25: sym := 14; RETURN
  468. | 26: sym := 15; RETURN
  469. | 27: sym := 16; RETURN
  470. | 28: sym := 22; RETURN
  471. | 29: sym := 25; RETURN
  472. | 30: sym := 26; RETURN
  473. | 31: sym := 27; RETURN
  474. | 32: IF (ch = ":") THEN state := 34;
  475. ELSIF (ch = "=") THEN state := 36;
  476. ELSE sym := 32; RETURN
  477. END;
  478. | 33: sym := 33; RETURN
  479. | 34: IF (ch = "=") THEN state := 35;
  480. ELSE sym := noSYMB; RETURN
  481. END;
  482. | 35: sym := 42; RETURN
  483. | 36: sym := 46; RETURN
  484. | 37: sym := 59; RETURN
  485. | 38: sym := 61; RETURN
  486. | 39: IF (ch = ">") THEN state := 40;
  487. ELSIF (ch = "=") THEN state := 41;
  488. ELSIF (ch = "<") THEN state := 49;
  489. ELSE sym := 63; RETURN
  490. END;
  491. | 40: sym := 62; RETURN
  492. | 41: sym := 64; RETURN
  493. | 42: IF (ch = "=") THEN state := 43;
  494. ELSIF (ch = ">") THEN state := 50;
  495. ELSE sym := 65; RETURN
  496. END;
  497. | 43: sym := 66; RETURN
  498. | 44: sym := 67; RETURN
  499. | 45: sym := 68; RETURN
  500. | 46: sym := 70; RETURN
  501. | 47: sym := 71; RETURN
  502. | 48: sym := 75; RETURN
  503. | 49: sym := 76; RETURN
  504. | 50: sym := 77; RETURN
  505. | 51: sym := 78; RETURN
  506. | 52: sym := 79; RETURN
  507. | 53: sym := 81; RETURN
  508. | 54: sym := 0; ch := 0C; DEC(bp); RETURN
  509. ELSE sym := noSYMB; RETURN (*NextCh already done*)
  510. END
  511. END
  512. END Get;
  513. PROCEDURE GetString (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  514. VAR
  515. i: CARDINAL;
  516. p: INT32;
  517. BEGIN
  518. IF len > HIGH(s) THEN len := HIGH(s) END;
  519. p := pos; i := 0;
  520. WHILE i < len DO
  521. s[i] := CharAt(p); INC(i); INC(p)
  522. END;
  523. s[len] := CHR(0);
  524. END GetString;
  525. PROCEDURE GetName (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  526. VAR
  527. i: CARDINAL;
  528. p: INT32;
  529. BEGIN
  530. IF len > HIGH(s) THEN len := HIGH(s) END;
  531. p := pos; i := 0;
  532. WHILE i < len DO
  533. s[i] := CurrentCh(p); INC(i); INC(p)
  534. END;
  535. s[len] := CHR(0);
  536. END GetName;
  537. PROCEDURE CharAt (pos: INT32): CHAR;
  538. VAR
  539. ch: CHAR;
  540. BEGIN
  541. IF pos >= inputLen THEN RETURN EOF END;
  542. ch := buf[ORD(pos DIV BlkSize)]^[ORD(pos MOD BlkSize)];
  543. IF ch # eof THEN RETURN ch ELSE RETURN EOF END
  544. END CharAt;
  545. PROCEDURE CapChAt (pos: INT32): CHAR;
  546. VAR
  547. ch: CHAR;
  548. BEGIN
  549. IF pos >= inputLen THEN RETURN EOF END;
  550. ch := CAP(buf[ORD(pos DIV BlkSize)]^[ORD(pos MOD BlkSize)]);
  551. IF ch # eof THEN RETURN ch ELSE RETURN EOF END
  552. END CapChAt;
  553. PROCEDURE Reset;
  554. VAR
  555. i, read: CARDINAL;
  556. BEGIN (*assert: src has been opened*)
  557. i := 0; inputLen := 0;
  558. REPEAT
  559. NEW(buf[i]); (* typed alloc: sets the block descriptor's count *)
  560. read := BlkSize; FileIO.ReadBytes(src, buf[i]^, read);
  561. INC(i); INC(inputLen, VAL(INT32, read))
  562. UNTIL read # BlkSize;
  563. buf[i-1]^[read] := EOF;
  564. CondFilter;
  565. curLine := 1; lineStart := -2; bp := -1;
  566. oldEols := 0; apx := 0; errors := 0;
  567. NextCh;
  568. END Reset;
  569. BEGIN
  570. CurrentCh := CharAt;
  571. start[ 0] := 54; start[ 1] := 55; start[ 2] := 55; start[ 3] := 55;
  572. start[ 4] := 55; start[ 5] := 55; start[ 6] := 55; start[ 7] := 55;
  573. start[ 8] := 55; start[ 9] := 55; start[ 10] := 55; start[ 11] := 55;
  574. start[ 12] := 55; start[ 13] := 55; start[ 14] := 55; start[ 15] := 55;
  575. start[ 16] := 55; start[ 17] := 55; start[ 18] := 55; start[ 19] := 55;
  576. start[ 20] := 55; start[ 21] := 55; start[ 22] := 55; start[ 23] := 55;
  577. start[ 24] := 55; start[ 25] := 55; start[ 26] := 55; start[ 27] := 55;
  578. start[ 28] := 55; start[ 29] := 55; start[ 30] := 55; start[ 31] := 55;
  579. start[ 32] := 55; start[ 33] := 55; start[ 34] := 13; start[ 35] := 38;
  580. start[ 36] := 55; start[ 37] := 55; start[ 38] := 48; start[ 39] := 12;
  581. start[ 40] := 30; start[ 41] := 31; start[ 42] := 46; start[ 43] := 44;
  582. start[ 44] := 25; start[ 45] := 45; start[ 46] := 23; start[ 47] := 47;
  583. start[ 48] := 16; start[ 49] := 15; start[ 50] := 15; start[ 51] := 15;
  584. start[ 52] := 15; start[ 53] := 15; start[ 54] := 15; start[ 55] := 15;
  585. start[ 56] := 15; start[ 57] := 15; start[ 58] := 32; start[ 59] := 24;
  586. start[ 60] := 39; start[ 61] := 28; start[ 62] := 42; start[ 63] := 55;
  587. start[ 64] := 55; start[ 65] := 1; start[ 66] := 1; start[ 67] := 1;
  588. start[ 68] := 1; start[ 69] := 1; start[ 70] := 1; start[ 71] := 1;
  589. start[ 72] := 1; start[ 73] := 1; start[ 74] := 1; start[ 75] := 1;
  590. start[ 76] := 1; start[ 77] := 1; start[ 78] := 1; start[ 79] := 1;
  591. start[ 80] := 1; start[ 81] := 1; start[ 82] := 1; start[ 83] := 1;
  592. start[ 84] := 1; start[ 85] := 1; start[ 86] := 1; start[ 87] := 1;
  593. start[ 88] := 1; start[ 89] := 1; start[ 90] := 1; start[ 91] := 26;
  594. start[ 92] := 55; start[ 93] := 27; start[ 94] := 37; start[ 95] := 1;
  595. start[ 96] := 55; start[ 97] := 1; start[ 98] := 1; start[ 99] := 1;
  596. start[100] := 1; start[101] := 1; start[102] := 1; start[103] := 1;
  597. start[104] := 1; start[105] := 1; start[106] := 1; start[107] := 1;
  598. start[108] := 1; start[109] := 1; start[110] := 1; start[111] := 1;
  599. start[112] := 1; start[113] := 1; start[114] := 1; start[115] := 1;
  600. start[116] := 1; start[117] := 1; start[118] := 1; start[119] := 1;
  601. start[120] := 1; start[121] := 1; start[122] := 1; start[123] := 51;
  602. start[124] := 33; start[125] := 52; start[126] := 53; start[127] := 55;
  603. start[128] := 55; start[129] := 55; start[130] := 55; start[131] := 55;
  604. start[132] := 55; start[133] := 55; start[134] := 55; start[135] := 55;
  605. start[136] := 55; start[137] := 55; start[138] := 55; start[139] := 55;
  606. start[140] := 55; start[141] := 55; start[142] := 55; start[143] := 55;
  607. start[144] := 55; start[145] := 55; start[146] := 55; start[147] := 55;
  608. start[148] := 55; start[149] := 55; start[150] := 55; start[151] := 55;
  609. start[152] := 55; start[153] := 55; start[154] := 55; start[155] := 55;
  610. start[156] := 55; start[157] := 55; start[158] := 55; start[159] := 55;
  611. start[160] := 55; start[161] := 55; start[162] := 55; start[163] := 55;
  612. start[164] := 55; start[165] := 55; start[166] := 55; start[167] := 55;
  613. start[168] := 55; start[169] := 55; start[170] := 55; start[171] := 55;
  614. start[172] := 55; start[173] := 55; start[174] := 55; start[175] := 55;
  615. start[176] := 55; start[177] := 55; start[178] := 55; start[179] := 55;
  616. start[180] := 55; start[181] := 55; start[182] := 55; start[183] := 55;
  617. start[184] := 55; start[185] := 55; start[186] := 55; start[187] := 55;
  618. start[188] := 55; start[189] := 55; start[190] := 55; start[191] := 55;
  619. start[192] := 55; start[193] := 55; start[194] := 55; start[195] := 55;
  620. start[196] := 55; start[197] := 55; start[198] := 55; start[199] := 55;
  621. start[200] := 55; start[201] := 55; start[202] := 55; start[203] := 55;
  622. start[204] := 55; start[205] := 55; start[206] := 55; start[207] := 55;
  623. start[208] := 55; start[209] := 55; start[210] := 55; start[211] := 55;
  624. start[212] := 55; start[213] := 55; start[214] := 55; start[215] := 55;
  625. start[216] := 55; start[217] := 55; start[218] := 55; start[219] := 55;
  626. start[220] := 55; start[221] := 55; start[222] := 55; start[223] := 55;
  627. start[224] := 55; start[225] := 55; start[226] := 55; start[227] := 55;
  628. start[228] := 55; start[229] := 55; start[230] := 55; start[231] := 55;
  629. start[232] := 55; start[233] := 55; start[234] := 55; start[235] := 55;
  630. start[236] := 55; start[237] := 55; start[238] := 55; start[239] := 55;
  631. start[240] := 55; start[241] := 55; start[242] := 55; start[243] := 55;
  632. start[244] := 55; start[245] := 55; start[246] := 55; start[247] := 55;
  633. start[248] := 55; start[249] := 55; start[250] := 55; start[251] := 55;
  634. start[252] := 55; start[253] := 55; start[254] := 55; start[255] := 55;
  635. Error := Err; lastCh := EOF;
  636. END M2S.