| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- (* Release 3.10 *)
- (*-------------------------------------------------------------------------*
- * *
- * SCANNER.MOD - COMMS Toolkit script file scanner *
- * *
- * COPYRIGHT (C) 1988..1992 Clarion Software Corporation. *
- * All Rights Reserved *
- * *
- *--------------------------------------------------------------------------*)
- (*# check(range=>off,overflow=>off,index=>off)*)
- IMPLEMENTATION MODULE Scanner;
- IMPORT Lib,Str,IO,Window;
- FROM Window IMPORT Color;
- CONST
- MaxResWords = 70;
- TAB = 11C;
- ErrWin = Window.WinDef(5,5,74,19,White,Red,TRUE,FALSE,FALSE,TRUE,Window.SingleFrame,White,Red);
- TYPE
- LineBuff = ARRAY[0..255] OF CHAR;
- ResWordRec = RECORD
- WordId : ARRAY[0..20] OF CHAR;
- RSy : Symbols;
- END;
- VAR
- Ch : CHAR;
- FirstSymOnLine : BOOLEAN;
- Stdwords,Lnth,Max : CARDINAL;
- TokenPos,LineLength,
- LineIndex,LineNumber: CARDINAL;
- History : ARRAY[0..3] OF LineBuff;
- CurrentLine : LineBuff;
- Reswords : ARRAY[0..MaxResWords-1] OF ResWordRec;
- (*................................................*)
- PROCEDURE ShowTokenPos;
- VAR
- i : CARDINAL;
- Blank : LineBuff;
- BEGIN
- FOR i:=0 TO 3 DO
- IO.WrStr(History[i]);
- IO.WrLn;
- END;
- IF TokenPos<=80 THEN
- CurrentLine[LineLength] := 0C;
- IO.WrStr(CurrentLine);
- IO.WrLn;
- IF TokenPos>0 THEN
- Lib.Fill(ADR(Blank),TokenPos,' ');
- END;
- Blank[TokenPos]:='^';
- Blank[TokenPos+1]:=0C;
- IO.WrStr(Blank);
- IO.WrLn;
- END;
- END ShowTokenPos;
- (*................................................*)
- PROCEDURE WriteCard(c:CARDINAL);
- BEGIN
- IF c>9 THEN
- WriteCard(c DIV 10);
- END;
- IO.WrChar(CHR((c MOD 10)+48));
- END WriteCard;
- (*................................................*)
- PROCEDURE Error(Errnum:CARDINAL);
- VAR
- Ch : CHAR;
- Err : Window.WinType;
- s : ARRAY[0..79] OF CHAR;
- BEGIN
- IF GotError THEN
- RETURN;
- END;
- Err := Window.Open(ErrWin);
- Window.GotoXY(1,2);
- ShowTokenPos;
- IO.WrLn;
- IO.WrStr('Error ');
- WriteCard(Errnum);
- IO.WrStr(': ');
- CASE Errnum OF
- 1 : s:='String constant must not exceed source line';|
- 2 : s:='Illegal char in text'; |
- 3 : s:='This Symbol not expected here'; |
- 4 : s:='Value too large! (max 255)'; |
- 5 : s:='String variable expected'; |
- 6 : s:='String or String variable expected'; |
- 7 : s:='Value out of range'; |
- 8 : s:='Parameter Missing'; |
- 9 : s:='DIAL command not supported.'; |
- 10 : s:='Unknown File Protocol'; |
- 11 : s:='Label already defined!'; |
- 12 : s:='Label or Statement expected'; |
- 13 : s:='Label name expected'; |
- 14 : s:='Switch statement must have only one default!';|
- 15 : s:='Could not open Script file.'; |
- ELSE
- s:='Unknown error (program bug)';
- END;
- IO.WrStr(s);
- IO.WrLn;
- IO.WrLn;
- IO.WrStr('Press any key...');
- Ch:=IO.RdKey();
- Window.Close(Err);
- GotError := TRUE;
- END Error;
- (*................................................*)
- PROCEDURE StrCompare(VAR S1,S2:ARRAY OF CHAR):INTEGER;
- VAR
- i,Chrs,Lnth1,Lnth2,
- diff : INTEGER;
- Ch1,Ch2 : CHAR;
- BEGIN
- Lnth1:=Str.Length(S1);
- Lnth2:=Str.Length(S2);
- IF Lnth1>8 THEN
- Lnth1:=8;
- END;
- IF Lnth2>8 THEN
- Lnth2:=8;
- END;
- diff := Lnth1-Lnth2;
- IF Lnth1<Lnth2 THEN
- Chrs:=Lnth1;
- ELSE
- Chrs:=Lnth2;
- END;
- i:=0;
- WHILE i<Chrs DO
- Ch1:=CAP(S1[i]);
- Ch2:=CAP(S2[i]);
- IF Ch1<>Ch2 THEN
- RETURN INTEGER(ORD(Ch1))-INTEGER(ORD(Ch2));
- END;
- INC(i);
- END;
- RETURN diff;
- END StrCompare;
- (*.................................................*)
- PROCEDURE InitSymbolTable;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- PROCEDURE Symbol(Tipe:Symbols; Name:ARRAY OF CHAR);
- BEGIN
- WITH Reswords[Stdwords] DO
- Lib.Move(ADR(Name),ADR(WordId),Str.Length(Name)+1);
- RSy:=Tipe;
- END;
- INC(Stdwords);
- END Symbol;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- BEGIN (* InitSymbolTable *)
- Stdwords := 0;
- (* NOTE: because I was too lazy to include a sort procedure to be *)
- (* used once only, the words in this reserved word table have been *)
- (* manually entered in alphabetical order. Be careful when adding *)
- (* new words! *)
- Symbol(AlarmSy,'ALARM');
- Symbol(FTAscii,'ASCII');
- Symbol(AssignSy,'ASSIGN');
- Symbol(BreakSy,'BREAK');
- Symbol(FTBYmodem,'BYMODEM');
- Symbol(CaseSy,'CASE');
- Symbol(ChDirSy,'CHDIR');
- Symbol(ClearSy,'CLEAR');
- Symbol(CloseSy,'CLOSE');
- Symbol(ConnectSy,'CONNECTED');
- Symbol(CWhenSy,'CWHEN');
- Symbol(DefaultSy,'DEFAULT');
- Symbol(DialSy,'DIAL');
- Symbol(DosSy,'DOS');
- Symbol(ElseSy,'ELSE');
- Symbol(EmulateSy,'EMULATE');
- Symbol(EndCaseSy,'ENDCASE');
- Symbol(EndifSy,'ENDIF');
- Symbol(EndSwitchSy,'ENDSWITCH');
- Symbol(ExecuteSy,'EXECUTE');
- Symbol(ExitSy,'EXIT');
- Symbol(FailureSy,'FAILURE');
- Symbol(FindSy,'FIND');
- Symbol(FoundSy,'FOUND');
- Symbol(GetSy,'GET');
- Symbol(GetFileSy,'GETFILE');
- Symbol(GosubSy,'GOSUB');
- Symbol(GotoSy,'GOTO');
- Symbol(HangupSy,'HANGUP');
- Symbol(HostSy,'HOST');
- Symbol(IfSy,'IF');
- Symbol(IsFileSy,'ISFILE');
- Symbol(FTKermit,'KERMIT');
- Symbol(KermServSy,'KERMSERV');
- Symbol(KFlushSy,'KFLUSH');
- Symbol(LinkedSy,'LINKED');
- Symbol(LocateSy,'LOCATE');
- Symbol(LogSy,'LOG');
- Symbol(MacroSy,'MACRO');
- Symbol(MessageSy,'MESSAGE');
- Symbol(MGetSy,'MGET');
- Symbol(MLoadSy,'MLOAD');
- Symbol(NotSy,'NOT');
- Symbol(OffSy,'OFF');
- Symbol(OnSy,'ON');
- Symbol(OpenSy,'OPEN');
- Symbol(PauseSy,'PAUSE');
- Symbol(PrinterSy,'PRINTER');
- Symbol(QuitSy,'QUIT');
- Symbol(ResumeSy,'RESUME');
- Symbol(ReturnSy,'RETURN');
- Symbol(RFlushSy,'RFLUSH');
- Symbol(RGetSy,'RGET');
- Symbol(RunSy,'RUN');
- Symbol(SendFileSy,'SENDFILE');
- Symbol(SetSy,'SET');
- Symbol(SnapshotSy,'SNAPSHOT');
- Symbol(SuccessSy,'SUCCESS');
- Symbol(SuspendSy,'SUSPEND');
- Symbol(SwitchSy,'SWITCH');
- Symbol(TraceSy,'TRACE');
- Symbol(TransmitSy,'TRANSMIT');
- Symbol(WaitSy,'WAIT');
- Symbol(WaitForSy,'WAITFOR');
- Symbol(WhenSy,'WHEN');
- Symbol(FTWXmodem,'WXMODEM');
- Symbol(FTXmodem,'XMODEM');
- Symbol(FTYmodem,'YMODEM');
- END InitSymbolTable;
- (*.................................................*)
- PROCEDURE InitScanner;
- VAR
- i : CARDINAL;
- BEGIN
- FOR i:=0 TO 3 DO
- History[i,0] := 0C;
- END;
- CurrentLine[0] := 0C;
- Stdwords := 0;
- InitSymbolTable;
- LineLength := 0;
- LineNumber := 0;
- LineIndex := 0FFFFH;
- FirstSymOnLine := TRUE;
- GotError := FALSE;
- END InitScanner;
- (*................................................*)
- PROCEDURE GetChar(VAR Ch:CHAR);
- VAR
- i : CARDINAL;
- BEGIN
- IF LineIndex>LineLength THEN
- IF FIO.EOF THEN
- Ch:=0C;
- LineIndex:=0FFFFH;
- LineLength:=0;
- RETURN
- END;
- FOR i:=0 TO 2 DO
- History[i] := History[i+1];
- END;
- History[3] := CurrentLine;
- History[3,LineLength] := 0C;
- FIO.RdStr(infile,CurrentLine);
- IF FIO.EOF THEN
- Ch := 0C;
- RETURN;
- END; (*IF*)
- INC(LineNumber);
- LineLength := Str.Length(CurrentLine);
- CurrentLine[LineLength] := CHR(13);
- LineIndex := Lib.ScanNeR(ADR(CurrentLine),LineLength,' ');
- FirstSymOnLine := TRUE;
- END;
- Ch := CurrentLine[LineIndex];
- INC(LineIndex);
- END GetChar;
- (*................................................*)
- PROCEDURE PushBack;
- BEGIN
- IF LineIndex>0 THEN
- DEC(LineIndex);
- END;
- END PushBack;
- (*................................................*)
- PROCEDURE GetSym;
- VAR
- GotSym : BOOLEAN;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- PROCEDURE AddChar(VAR S:ARRAY OF CHAR; Ch:CHAR);
- BEGIN
- IF Lnth<Max THEN
- S[Lnth]:=Ch;
- INC(Lnth);
- S[Lnth]:=0C;
- END;
- END AddChar;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- PROCEDURE CopyString;
- VAR
- QuoteChar : CHAR;
- BEGIN
- QuoteChar:=Ch;
- Lnth:=0;
- Max:=255;
- Sy:=StringConst;
- REPEAT
- GetChar(Ch);
- IF (Ch=0C) OR (Ch=CHR(13)) THEN
- Error(1);
- END;
- IF Ch<>QuoteChar THEN
- AddChar(LastStringConst,Ch);
- END;
- UNTIL Ch=QuoteChar;
- END CopyString;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- PROCEDURE Number;
- BEGIN
- LastNumConst:='';
- Lnth:=0;
- Max:=MaxSymLnth;
- Sy:=IntConst;
- REPEAT
- AddChar(LastNumConst,Ch);
- GetChar(Ch);
- UNTIL (Ch<'0') OR (Ch>'9');
- PushBack;
- END Number;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- PROCEDURE Identifier;
- (*. . . . . . . . . . . . . . . . .*)
- PROCEDURE CheckResWords;
- VAR
- Result,K,L,R : INTEGER;
- BEGIN
- L:=0;
- R:=Stdwords-1;
- REPEAT
- K := (L+R) DIV 2;
- Result := StrCompare(Id,Reswords[K].WordId);
- IF Result<=0 THEN
- R:=K-1;
- END;
- IF Result>=0 THEN
- L:=K+1;
- END;
- UNTIL R<L;
- IF L-R>1 THEN
- Sy := Reswords[K].RSy;
- END;
- END CheckResWords;
- (*. . . . . . . . . . . . . . . . .*)
- BEGIN (* Identifier *)
- Sy:=Ident;
- Lnth:=0;
- Max:=MaxSymLnth;
- LOOP
- CASE Ch OF
- '_',
- 'a'..'z',
- '0'..'9',
- 'A'..'Z' : AddChar(Id,CAP(Ch));
- GetChar(Ch) |
- ELSE
- EXIT;
- END;
- END;
- PushBack;
- CheckResWords;
- END Identifier;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- PROCEDURE Comment;
- BEGIN
- (* Throw away remainder of line *)
- LineIndex := LineLength+1;
- END Comment;
- (*. . . . . . . . . . . . . . . . . . . . . . . . .*)
- BEGIN (* GetSym *)
- REPEAT
- Sy:=Other;
- GotSym:=TRUE;
- REPEAT
- GetChar(Ch);
- UNTIL (Ch=0C) OR ((Ch>' ') AND (Ch<=CHR(126)));
- TokenPos := LineIndex-1;
- CASE Ch OF
- 0C : Sy:=EndOfFile; |
- '"' : CopyString; |
- '0'..'9' : Number; |
- 'A'..'Z',
- 'a'..'z' : Identifier; |
- ';' : Comment;
- GotSym := FALSE; |
- ',' : Sy := Comma;
- GotSym := FALSE; |
- ':' : Sy := Colon; |
- ELSE
- Error(2)
- END; (* cases *)
- FirstSymOnLine := FALSE;
- UNTIL GotSym;
- END GetSym;
- (*................................................*)
- END Scanner.
|