SCANNER.MOD 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * SCANNER.MOD - COMMS Toolkit script file scanner *
  5. * *
  6. * COPYRIGHT (C) 1988..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. (*# check(range=>off,overflow=>off,index=>off)*)
  11. IMPLEMENTATION MODULE Scanner;
  12. IMPORT Lib,Str,IO,Window;
  13. FROM Window IMPORT Color;
  14. CONST
  15. MaxResWords = 70;
  16. TAB = 11C;
  17. ErrWin = Window.WinDef(5,5,74,19,White,Red,TRUE,FALSE,FALSE,TRUE,Window.SingleFrame,White,Red);
  18. TYPE
  19. LineBuff = ARRAY[0..255] OF CHAR;
  20. ResWordRec = RECORD
  21. WordId : ARRAY[0..20] OF CHAR;
  22. RSy : Symbols;
  23. END;
  24. VAR
  25. Ch : CHAR;
  26. FirstSymOnLine : BOOLEAN;
  27. Stdwords,Lnth,Max : CARDINAL;
  28. TokenPos,LineLength,
  29. LineIndex,LineNumber: CARDINAL;
  30. History : ARRAY[0..3] OF LineBuff;
  31. CurrentLine : LineBuff;
  32. Reswords : ARRAY[0..MaxResWords-1] OF ResWordRec;
  33. (*................................................*)
  34. PROCEDURE ShowTokenPos;
  35. VAR
  36. i : CARDINAL;
  37. Blank : LineBuff;
  38. BEGIN
  39. FOR i:=0 TO 3 DO
  40. IO.WrStr(History[i]);
  41. IO.WrLn;
  42. END;
  43. IF TokenPos<=80 THEN
  44. CurrentLine[LineLength] := 0C;
  45. IO.WrStr(CurrentLine);
  46. IO.WrLn;
  47. IF TokenPos>0 THEN
  48. Lib.Fill(ADR(Blank),TokenPos,' ');
  49. END;
  50. Blank[TokenPos]:='^';
  51. Blank[TokenPos+1]:=0C;
  52. IO.WrStr(Blank);
  53. IO.WrLn;
  54. END;
  55. END ShowTokenPos;
  56. (*................................................*)
  57. PROCEDURE WriteCard(c:CARDINAL);
  58. BEGIN
  59. IF c>9 THEN
  60. WriteCard(c DIV 10);
  61. END;
  62. IO.WrChar(CHR((c MOD 10)+48));
  63. END WriteCard;
  64. (*................................................*)
  65. PROCEDURE Error(Errnum:CARDINAL);
  66. VAR
  67. Ch : CHAR;
  68. Err : Window.WinType;
  69. s : ARRAY[0..79] OF CHAR;
  70. BEGIN
  71. IF GotError THEN
  72. RETURN;
  73. END;
  74. Err := Window.Open(ErrWin);
  75. Window.GotoXY(1,2);
  76. ShowTokenPos;
  77. IO.WrLn;
  78. IO.WrStr('Error ');
  79. WriteCard(Errnum);
  80. IO.WrStr(': ');
  81. CASE Errnum OF
  82. 1 : s:='String constant must not exceed source line';|
  83. 2 : s:='Illegal char in text'; |
  84. 3 : s:='This Symbol not expected here'; |
  85. 4 : s:='Value too large! (max 255)'; |
  86. 5 : s:='String variable expected'; |
  87. 6 : s:='String or String variable expected'; |
  88. 7 : s:='Value out of range'; |
  89. 8 : s:='Parameter Missing'; |
  90. 9 : s:='DIAL command not supported.'; |
  91. 10 : s:='Unknown File Protocol'; |
  92. 11 : s:='Label already defined!'; |
  93. 12 : s:='Label or Statement expected'; |
  94. 13 : s:='Label name expected'; |
  95. 14 : s:='Switch statement must have only one default!';|
  96. 15 : s:='Could not open Script file.'; |
  97. ELSE
  98. s:='Unknown error (program bug)';
  99. END;
  100. IO.WrStr(s);
  101. IO.WrLn;
  102. IO.WrLn;
  103. IO.WrStr('Press any key...');
  104. Ch:=IO.RdKey();
  105. Window.Close(Err);
  106. GotError := TRUE;
  107. END Error;
  108. (*................................................*)
  109. PROCEDURE StrCompare(VAR S1,S2:ARRAY OF CHAR):INTEGER;
  110. VAR
  111. i,Chrs,Lnth1,Lnth2,
  112. diff : INTEGER;
  113. Ch1,Ch2 : CHAR;
  114. BEGIN
  115. Lnth1:=Str.Length(S1);
  116. Lnth2:=Str.Length(S2);
  117. IF Lnth1>8 THEN
  118. Lnth1:=8;
  119. END;
  120. IF Lnth2>8 THEN
  121. Lnth2:=8;
  122. END;
  123. diff := Lnth1-Lnth2;
  124. IF Lnth1<Lnth2 THEN
  125. Chrs:=Lnth1;
  126. ELSE
  127. Chrs:=Lnth2;
  128. END;
  129. i:=0;
  130. WHILE i<Chrs DO
  131. Ch1:=CAP(S1[i]);
  132. Ch2:=CAP(S2[i]);
  133. IF Ch1<>Ch2 THEN
  134. RETURN INTEGER(ORD(Ch1))-INTEGER(ORD(Ch2));
  135. END;
  136. INC(i);
  137. END;
  138. RETURN diff;
  139. END StrCompare;
  140. (*.................................................*)
  141. PROCEDURE InitSymbolTable;
  142. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  143. PROCEDURE Symbol(Tipe:Symbols; Name:ARRAY OF CHAR);
  144. BEGIN
  145. WITH Reswords[Stdwords] DO
  146. Lib.Move(ADR(Name),ADR(WordId),Str.Length(Name)+1);
  147. RSy:=Tipe;
  148. END;
  149. INC(Stdwords);
  150. END Symbol;
  151. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  152. BEGIN (* InitSymbolTable *)
  153. Stdwords := 0;
  154. (* NOTE: because I was too lazy to include a sort procedure to be *)
  155. (* used once only, the words in this reserved word table have been *)
  156. (* manually entered in alphabetical order. Be careful when adding *)
  157. (* new words! *)
  158. Symbol(AlarmSy,'ALARM');
  159. Symbol(FTAscii,'ASCII');
  160. Symbol(AssignSy,'ASSIGN');
  161. Symbol(BreakSy,'BREAK');
  162. Symbol(FTBYmodem,'BYMODEM');
  163. Symbol(CaseSy,'CASE');
  164. Symbol(ChDirSy,'CHDIR');
  165. Symbol(ClearSy,'CLEAR');
  166. Symbol(CloseSy,'CLOSE');
  167. Symbol(ConnectSy,'CONNECTED');
  168. Symbol(CWhenSy,'CWHEN');
  169. Symbol(DefaultSy,'DEFAULT');
  170. Symbol(DialSy,'DIAL');
  171. Symbol(DosSy,'DOS');
  172. Symbol(ElseSy,'ELSE');
  173. Symbol(EmulateSy,'EMULATE');
  174. Symbol(EndCaseSy,'ENDCASE');
  175. Symbol(EndifSy,'ENDIF');
  176. Symbol(EndSwitchSy,'ENDSWITCH');
  177. Symbol(ExecuteSy,'EXECUTE');
  178. Symbol(ExitSy,'EXIT');
  179. Symbol(FailureSy,'FAILURE');
  180. Symbol(FindSy,'FIND');
  181. Symbol(FoundSy,'FOUND');
  182. Symbol(GetSy,'GET');
  183. Symbol(GetFileSy,'GETFILE');
  184. Symbol(GosubSy,'GOSUB');
  185. Symbol(GotoSy,'GOTO');
  186. Symbol(HangupSy,'HANGUP');
  187. Symbol(HostSy,'HOST');
  188. Symbol(IfSy,'IF');
  189. Symbol(IsFileSy,'ISFILE');
  190. Symbol(FTKermit,'KERMIT');
  191. Symbol(KermServSy,'KERMSERV');
  192. Symbol(KFlushSy,'KFLUSH');
  193. Symbol(LinkedSy,'LINKED');
  194. Symbol(LocateSy,'LOCATE');
  195. Symbol(LogSy,'LOG');
  196. Symbol(MacroSy,'MACRO');
  197. Symbol(MessageSy,'MESSAGE');
  198. Symbol(MGetSy,'MGET');
  199. Symbol(MLoadSy,'MLOAD');
  200. Symbol(NotSy,'NOT');
  201. Symbol(OffSy,'OFF');
  202. Symbol(OnSy,'ON');
  203. Symbol(OpenSy,'OPEN');
  204. Symbol(PauseSy,'PAUSE');
  205. Symbol(PrinterSy,'PRINTER');
  206. Symbol(QuitSy,'QUIT');
  207. Symbol(ResumeSy,'RESUME');
  208. Symbol(ReturnSy,'RETURN');
  209. Symbol(RFlushSy,'RFLUSH');
  210. Symbol(RGetSy,'RGET');
  211. Symbol(RunSy,'RUN');
  212. Symbol(SendFileSy,'SENDFILE');
  213. Symbol(SetSy,'SET');
  214. Symbol(SnapshotSy,'SNAPSHOT');
  215. Symbol(SuccessSy,'SUCCESS');
  216. Symbol(SuspendSy,'SUSPEND');
  217. Symbol(SwitchSy,'SWITCH');
  218. Symbol(TraceSy,'TRACE');
  219. Symbol(TransmitSy,'TRANSMIT');
  220. Symbol(WaitSy,'WAIT');
  221. Symbol(WaitForSy,'WAITFOR');
  222. Symbol(WhenSy,'WHEN');
  223. Symbol(FTWXmodem,'WXMODEM');
  224. Symbol(FTXmodem,'XMODEM');
  225. Symbol(FTYmodem,'YMODEM');
  226. END InitSymbolTable;
  227. (*.................................................*)
  228. PROCEDURE InitScanner;
  229. VAR
  230. i : CARDINAL;
  231. BEGIN
  232. FOR i:=0 TO 3 DO
  233. History[i,0] := 0C;
  234. END;
  235. CurrentLine[0] := 0C;
  236. Stdwords := 0;
  237. InitSymbolTable;
  238. LineLength := 0;
  239. LineNumber := 0;
  240. LineIndex := 0FFFFH;
  241. FirstSymOnLine := TRUE;
  242. GotError := FALSE;
  243. END InitScanner;
  244. (*................................................*)
  245. PROCEDURE GetChar(VAR Ch:CHAR);
  246. VAR
  247. i : CARDINAL;
  248. BEGIN
  249. IF LineIndex>LineLength THEN
  250. IF FIO.EOF THEN
  251. Ch:=0C;
  252. LineIndex:=0FFFFH;
  253. LineLength:=0;
  254. RETURN
  255. END;
  256. FOR i:=0 TO 2 DO
  257. History[i] := History[i+1];
  258. END;
  259. History[3] := CurrentLine;
  260. History[3,LineLength] := 0C;
  261. FIO.RdStr(infile,CurrentLine);
  262. IF FIO.EOF THEN
  263. Ch := 0C;
  264. RETURN;
  265. END; (*IF*)
  266. INC(LineNumber);
  267. LineLength := Str.Length(CurrentLine);
  268. CurrentLine[LineLength] := CHR(13);
  269. LineIndex := Lib.ScanNeR(ADR(CurrentLine),LineLength,' ');
  270. FirstSymOnLine := TRUE;
  271. END;
  272. Ch := CurrentLine[LineIndex];
  273. INC(LineIndex);
  274. END GetChar;
  275. (*................................................*)
  276. PROCEDURE PushBack;
  277. BEGIN
  278. IF LineIndex>0 THEN
  279. DEC(LineIndex);
  280. END;
  281. END PushBack;
  282. (*................................................*)
  283. PROCEDURE GetSym;
  284. VAR
  285. GotSym : BOOLEAN;
  286. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  287. PROCEDURE AddChar(VAR S:ARRAY OF CHAR; Ch:CHAR);
  288. BEGIN
  289. IF Lnth<Max THEN
  290. S[Lnth]:=Ch;
  291. INC(Lnth);
  292. S[Lnth]:=0C;
  293. END;
  294. END AddChar;
  295. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  296. PROCEDURE CopyString;
  297. VAR
  298. QuoteChar : CHAR;
  299. BEGIN
  300. QuoteChar:=Ch;
  301. Lnth:=0;
  302. Max:=255;
  303. Sy:=StringConst;
  304. REPEAT
  305. GetChar(Ch);
  306. IF (Ch=0C) OR (Ch=CHR(13)) THEN
  307. Error(1);
  308. END;
  309. IF Ch<>QuoteChar THEN
  310. AddChar(LastStringConst,Ch);
  311. END;
  312. UNTIL Ch=QuoteChar;
  313. END CopyString;
  314. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  315. PROCEDURE Number;
  316. BEGIN
  317. LastNumConst:='';
  318. Lnth:=0;
  319. Max:=MaxSymLnth;
  320. Sy:=IntConst;
  321. REPEAT
  322. AddChar(LastNumConst,Ch);
  323. GetChar(Ch);
  324. UNTIL (Ch<'0') OR (Ch>'9');
  325. PushBack;
  326. END Number;
  327. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  328. PROCEDURE Identifier;
  329. (*. . . . . . . . . . . . . . . . .*)
  330. PROCEDURE CheckResWords;
  331. VAR
  332. Result,K,L,R : INTEGER;
  333. BEGIN
  334. L:=0;
  335. R:=Stdwords-1;
  336. REPEAT
  337. K := (L+R) DIV 2;
  338. Result := StrCompare(Id,Reswords[K].WordId);
  339. IF Result<=0 THEN
  340. R:=K-1;
  341. END;
  342. IF Result>=0 THEN
  343. L:=K+1;
  344. END;
  345. UNTIL R<L;
  346. IF L-R>1 THEN
  347. Sy := Reswords[K].RSy;
  348. END;
  349. END CheckResWords;
  350. (*. . . . . . . . . . . . . . . . .*)
  351. BEGIN (* Identifier *)
  352. Sy:=Ident;
  353. Lnth:=0;
  354. Max:=MaxSymLnth;
  355. LOOP
  356. CASE Ch OF
  357. '_',
  358. 'a'..'z',
  359. '0'..'9',
  360. 'A'..'Z' : AddChar(Id,CAP(Ch));
  361. GetChar(Ch) |
  362. ELSE
  363. EXIT;
  364. END;
  365. END;
  366. PushBack;
  367. CheckResWords;
  368. END Identifier;
  369. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  370. PROCEDURE Comment;
  371. BEGIN
  372. (* Throw away remainder of line *)
  373. LineIndex := LineLength+1;
  374. END Comment;
  375. (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
  376. BEGIN (* GetSym *)
  377. REPEAT
  378. Sy:=Other;
  379. GotSym:=TRUE;
  380. REPEAT
  381. GetChar(Ch);
  382. UNTIL (Ch=0C) OR ((Ch>' ') AND (Ch<=CHR(126)));
  383. TokenPos := LineIndex-1;
  384. CASE Ch OF
  385. 0C : Sy:=EndOfFile; |
  386. '"' : CopyString; |
  387. '0'..'9' : Number; |
  388. 'A'..'Z',
  389. 'a'..'z' : Identifier; |
  390. ';' : Comment;
  391. GotSym := FALSE; |
  392. ',' : Sy := Comma;
  393. GotSym := FALSE; |
  394. ':' : Sy := Colon; |
  395. ELSE
  396. Error(2)
  397. END; (* cases *)
  398. FirstSymOnLine := FALSE;
  399. UNTIL GotSym;
  400. END GetSym;
  401. (*................................................*)
  402. END Scanner.
  403.