scanner.frm 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. IMPLEMENTATION MODULE -->modulename;
  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 = -->unknownsym; (*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. -->commentRETURN FALSE;
  59. END Comment;
  60. (* ---- TopSpeed conditional compilation: (*%T cond*) / (*%F cond*) /
  61. (*%E*) ---- Blank the inactive regions of the source buffer (CR/LF
  62. kept, so line numbers survive) before scanning. Conditions are
  63. evaluated against a small define set (see InitDefs); an unknown
  64. symbol is 'undefined'. *)
  65. PROCEDURE CopyStr (s: ARRAY OF CHAR; VAR t: ARRAY OF CHAR);
  66. VAR i: CARDINAL;
  67. BEGIN
  68. i := 0;
  69. WHILE (i <= HIGH(t)) AND (i <= HIGH(s)) AND (s[i] # CHR(0)) DO
  70. t[i] := s[i]; INC(i)
  71. END;
  72. IF i <= HIGH(t) THEN t[i] := CHR(0) END
  73. END CopyStr;
  74. PROCEDURE Same (a, b: ARRAY OF CHAR): BOOLEAN;
  75. VAR i: CARDINAL;
  76. BEGIN
  77. i := 0;
  78. WHILE (a[i] # CHR(0)) AND (b[i] # CHR(0)) AND (a[i] = b[i]) DO INC(i) END;
  79. RETURN a[i] = b[i]
  80. END Same;
  81. PROCEDURE AddDef (s: ARRAY OF CHAR);
  82. BEGIN
  83. IF nDefs <= HIGH(defs) THEN CopyStr(s, defs[nDefs]); INC(nDefs) END
  84. END AddDef;
  85. PROCEDURE InitDefs;
  86. (* Define set used to select conditional branches. Tuned for the
  87. TS-V3 corpus: the "_fdata"/"_mthread" variants are the plain,
  88. parseable ones; "_OS2"/"_fcall"/... are left undefined so the
  89. non-OS2 branches are taken. *)
  90. BEGIN
  91. nDefs := 0;
  92. (* DEFINES:BEGIN *)
  93. AddDef("_fdata");
  94. AddDef("_mthread");
  95. AddDef("_fptr");
  96. AddDef("_fcall");
  97. (* DEFINES:END *)
  98. END InitDefs;
  99. PROCEDURE IsDefined (id: ARRAY OF CHAR): BOOLEAN;
  100. VAR k: CARDINAL;
  101. BEGIN
  102. k := 0;
  103. WHILE k < nDefs DO
  104. IF Same(id, defs[k]) THEN RETURN TRUE END;
  105. INC(k)
  106. END;
  107. RETURN FALSE
  108. END IsDefined;
  109. PROCEDURE CondIdent (c: CHAR): BOOLEAN;
  110. BEGIN
  111. RETURN ((c >= "A") AND (c <= "Z")) OR ((c >= "a") AND (c <= "z"))
  112. OR ((c >= "0") AND (c <= "9")) OR (c = "_")
  113. END CondIdent;
  114. PROCEDURE CondBlank (p: INT32);
  115. VAR c: CHAR;
  116. BEGIN
  117. IF (p < 0) OR (p >= inputLen) THEN RETURN END;
  118. c := buf[ORD(p DIV BlkSize)]^[ORD(p MOD BlkSize)];
  119. IF (c # CR) AND (c # LF) THEN
  120. buf[ORD(p DIV BlkSize)]^[ORD(p MOD BlkSize)] := " "
  121. END
  122. END CondBlank;
  123. PROCEDURE CondFilter;
  124. VAR p, q, j, b: INT32;
  125. c, letter: CHAR;
  126. id: ARRAY [0 .. 31] OF CHAR;
  127. k: CARDINAL;
  128. parentOk, cond, active: BOOLEAN;
  129. BEGIN
  130. IF NOT defsInit THEN InitDefs; defsInit := TRUE END;
  131. nCond := 0;
  132. p := 0;
  133. WHILE p < inputLen DO
  134. c := buf[ORD(p DIV BlkSize)]^[ORD(p MOD BlkSize)];
  135. IF (c = "(") AND (p + 3 < inputLen)
  136. AND (buf[ORD((p+1) DIV BlkSize)]^[ORD((p+1) MOD BlkSize)] = "*")
  137. AND (buf[ORD((p+2) DIV BlkSize)]^[ORD((p+2) MOD BlkSize)] = "%") THEN
  138. letter := buf[ORD((p+3) DIV BlkSize)]^[ORD((p+3) MOD BlkSize)];
  139. q := p + 4;
  140. WHILE (q + 1 < inputLen)
  141. AND NOT ((buf[ORD(q DIV BlkSize)]^[ORD(q MOD BlkSize)] = "*")
  142. AND (buf[ORD((q+1) DIV BlkSize)]^[ORD((q+1) MOD BlkSize)] = ")")) DO
  143. INC(q)
  144. END;
  145. IF letter = "E" THEN
  146. IF nCond > 0 THEN DEC(nCond) END
  147. ELSE
  148. j := p + 4; k := 0;
  149. WHILE (j < q) AND (k <= HIGH(id)) DO
  150. c := buf[ORD(j DIV BlkSize)]^[ORD(j MOD BlkSize)];
  151. IF CondIdent(c) THEN id[k] := c; INC(k)
  152. ELSIF k > 0 THEN j := q (* end of the name *)
  153. END;
  154. INC(j)
  155. END;
  156. id[k] := CHR(0);
  157. cond := IsDefined(id);
  158. IF letter = "F" THEN cond := NOT cond END;
  159. parentOk := (nCond = 0) OR condStk[nCond - 1];
  160. IF NOT parentOk THEN cond := FALSE END;
  161. IF nCond <= HIGH(condStk) THEN condStk[nCond] := cond; INC(nCond) END
  162. END;
  163. b := p;
  164. WHILE b <= q + 1 DO CondBlank(b); INC(b) END;
  165. p := q + 2
  166. ELSE
  167. active := (nCond = 0) OR condStk[nCond - 1];
  168. IF active THEN INC(p) ELSE CondBlank(p); INC(p) END
  169. END
  170. END
  171. END CondFilter;
  172. PROCEDURE Get (VAR sym: CARDINAL);
  173. VAR
  174. state: CARDINAL;
  175. PROCEDURE Equal (s: ARRAY OF CHAR): BOOLEAN;
  176. VAR
  177. i: CARDINAL;
  178. q: INT32;
  179. BEGIN
  180. IF nextLen # LENGTH(s) THEN RETURN FALSE END;
  181. i := 1; q := bp0; INC(q);
  182. WHILE i < nextLen DO
  183. IF CurrentCh(q) # s[i] THEN RETURN FALSE END;
  184. INC(i); INC(q)
  185. END;
  186. RETURN TRUE
  187. END Equal;
  188. PROCEDURE CheckLiteral;
  189. BEGIN
  190. -->literals
  191. END CheckLiteral;
  192. BEGIN (*Get*)
  193. -->GetSy1
  194. pos := nextPos; nextPos := bp;
  195. col := nextCol; nextCol := VAL(INTEGER, bp - lineStart);
  196. line := nextLine; nextLine := curLine;
  197. len := nextLen; nextLen := 0;
  198. apx := 0; state := start[ORD(ch)]; bp0 := bp;
  199. LOOP
  200. NextCh; INC(nextLen);
  201. CASE state OF
  202. -->GetSy2
  203. ELSE sym := noSYMB; RETURN (*NextCh already done*)
  204. END
  205. END
  206. END Get;
  207. PROCEDURE GetString (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  208. VAR
  209. i: CARDINAL;
  210. p: INT32;
  211. BEGIN
  212. IF len > HIGH(s) THEN len := HIGH(s) END;
  213. p := pos; i := 0;
  214. WHILE i < len DO
  215. s[i] := CharAt(p); INC(i); INC(p)
  216. END;
  217. s[len] := CHR(0);
  218. END GetString;
  219. PROCEDURE GetName (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  220. VAR
  221. i: CARDINAL;
  222. p: INT32;
  223. BEGIN
  224. IF len > HIGH(s) THEN len := HIGH(s) END;
  225. p := pos; i := 0;
  226. WHILE i < len DO
  227. s[i] := CurrentCh(p); INC(i); INC(p)
  228. END;
  229. s[len] := CHR(0);
  230. END GetName;
  231. PROCEDURE CharAt (pos: INT32): CHAR;
  232. VAR
  233. ch: CHAR;
  234. BEGIN
  235. IF pos >= inputLen THEN RETURN EOF END;
  236. ch := buf[ORD(pos DIV BlkSize)]^[ORD(pos MOD BlkSize)];
  237. IF ch # eof THEN RETURN ch ELSE RETURN EOF END
  238. END CharAt;
  239. PROCEDURE CapChAt (pos: INT32): CHAR;
  240. VAR
  241. ch: CHAR;
  242. BEGIN
  243. IF pos >= inputLen THEN RETURN EOF END;
  244. ch := CAP(buf[ORD(pos DIV BlkSize)]^[ORD(pos MOD BlkSize)]);
  245. IF ch # eof THEN RETURN ch ELSE RETURN EOF END
  246. END CapChAt;
  247. PROCEDURE Reset;
  248. VAR
  249. i, read: CARDINAL;
  250. BEGIN (*assert: src has been opened*)
  251. i := 0; inputLen := 0;
  252. REPEAT
  253. NEW(buf[i]); (* typed alloc: sets the block descriptor's count *)
  254. read := BlkSize; FileIO.ReadBytes(src, buf[i]^, read);
  255. INC(i); INC(inputLen, VAL(INT32, read))
  256. UNTIL read # BlkSize;
  257. buf[i-1]^[read] := EOF;
  258. CondFilter;
  259. curLine := 1; lineStart := -2; bp := -1;
  260. oldEols := 0; apx := 0; errors := 0;
  261. NextCh;
  262. END Reset;
  263. BEGIN
  264. -->initializations
  265. Error := Err; lastCh := EOF;
  266. END -->modulename.
  267. -->definitionDEFINITION MODULE -->modulename;
  268. (* Scanner generated by Coco/R - using the FileIO library supplied with this project. *)
  269. IMPORT FileIO;
  270. TYPE
  271. INT32 = FileIO.INT32 (* need 32 bit integers *);
  272. VAR
  273. src, lst: FileIO.File;(*source/list files. To be opened by the main pgm*)
  274. directory: ARRAY [0 .. 255] OF CHAR (*of source file*);
  275. line, col: INTEGER; (*line and column of current symbol*)
  276. len: CARDINAL; (*length of current symbol*)
  277. pos: INT32; (*file position of current symbol*)
  278. nextLine: INTEGER; (*line of lookahead symbol*)
  279. nextCol: INTEGER; (*column of lookahead symbol*)
  280. nextLen: CARDINAL; (*length of lookahead symbol*)
  281. nextPos: INT32; (*file position of lookahead symbol*)
  282. errors: INTEGER; (*number of detected errors*)
  283. Error: PROCEDURE ((*nr*)INTEGER, (*line*)INTEGER, (*col*)INTEGER,
  284. (*pos*)INT32);
  285. PROCEDURE Get (VAR sym: CARDINAL);
  286. (* Gets next symbol from source file *)
  287. PROCEDURE GetString (pos: INT32; len: CARDINAL; VAR name: ARRAY OF CHAR);
  288. (* Retrieves exact string of max length len from position pos in source file *)
  289. PROCEDURE GetName (pos: INT32; len: CARDINAL; VAR name: ARRAY OF CHAR);
  290. (* Retrieves name of symbol of length len at position pos in source file *)
  291. PROCEDURE CharAt (pos: INT32): CHAR;
  292. (* Returns exact character at position pos in source file *)
  293. PROCEDURE Reset;
  294. (* Reads and stores source file internally *)
  295. END -->modulename.