Scanner.mod 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. IMPLEMENTATION MODULE Scanner; (* gf 01.06.89 (pl0) *)
  2. FROM CharacterInput IMPORT ch, GetCh, EOF,
  3. endOfInput, currLine, currCol,
  4. InitInput;
  5. FROM StringTable IMPORT InitStringTable, EnterKeyWord,
  6. InsertIdent, IdKind;
  7. FROM ErrorHandling IMPORT PrintError1;
  8. FROM InOut IMPORT Write, WriteInt, WriteLn;
  9. IMPORT SYSTEM;
  10. CONST maxCard = 177777B;
  11. maxLine = 120;
  12. LF = 12C;
  13. HT = 11C;
  14. VAR string : ARRAY[0..200] OF CHAR;
  15. PROCEDURE Identifier;
  16. VAR k : CARDINAL;
  17. BEGIN
  18. k := 0;
  19. REPEAT
  20. string[k] := ch; INC(k);
  21. GetCh
  22. UNTIL (ch < "0") OR ("9" < ch) & (CAP(ch) < "A") OR ("Z" < CAP(ch));
  23. string[k] := 0C;
  24. id := InsertIdent(string);
  25. sym := IdKind(id);
  26. END Identifier;
  27. PROCEDURE Number;
  28. VAR i, j, k, d : CARDINAL;
  29. dig : ARRAY[0..31] OF CHAR;
  30. BEGIN
  31. sym := sNumber; i := 0;
  32. REPEAT
  33. dig[i] := ch; i := i + 1; GetCh;
  34. UNTIL (ch < "0") OR ("9" < ch) & (CAP(ch) < "A") OR ("Z" < CAP(ch));
  35. j := 0; k := 0;
  36. REPEAT
  37. d := ORD(dig[j]) - 60B;
  38. IF (d < 10) & ((maxCard - d) DIV 10 >= k) THEN
  39. k := 10 * k + d
  40. ELSE
  41. pos.line := currLine;
  42. pos.column := currCol;
  43. PrintError1(58, pos);
  44. k := 0
  45. END;
  46. INC(j)
  47. UNTIL j = i;
  48. num := k
  49. END Number;
  50. PROCEDURE GetSymbol;
  51. PROCEDURE Comment;
  52. BEGIN
  53. GetCh;
  54. IF ch = '$' THEN
  55. GetCh;
  56. IF ch = 'C' THEN
  57. GetCh; printCode := ch = '+'
  58. ELSIF ch = 'T' THEN
  59. GetCh; traceParser := ch = '+'
  60. ELSIF ch = 'L' THEN
  61. GetCh; printListing := ch = '+'
  62. ELSIF ch = 'O' THEN
  63. GetCh; optimize := ch = '+'
  64. END
  65. END;
  66. REPEAT
  67. WHILE (ch # "*") AND NOT endOfInput DO GetCh END;
  68. GetCh
  69. UNTIL (ch = ")") OR endOfInput;
  70. GetCh
  71. END Comment;
  72. BEGIN
  73. LOOP
  74. (* ignore control characters *)
  75. IF ch = EOF THEN
  76. EXIT
  77. ELSIF ch <= " " THEN
  78. GetCh
  79. ELSIF ch >= 177C THEN
  80. GetCh
  81. ELSE EXIT
  82. END
  83. END;
  84. pos.line := currLine; pos.column := currCol;
  85. CASE ch OF (* " " <= ch < 177C *)
  86. EOF : sym := sEof;
  87. | "!" : sym := sWrite; GetCh
  88. | '"' : sym := sNull; GetCh
  89. | "#" : sym := sNE; GetCh
  90. | "$" : sym := sNull; GetCh
  91. | "%" : sym := sNull; GetCh
  92. | "&" : sym := sNull; GetCh
  93. | "(" : GetCh;
  94. IF ch = "*" THEN
  95. Comment; GetSymbol
  96. ELSE
  97. sym := sLParen
  98. END
  99. | ")" : sym := sRParen; GetCh
  100. | "*" : sym := sTimes; GetCh
  101. | "+" : sym := sPlus; GetCh
  102. | "," : sym := sComma; GetCh
  103. | "-" : sym := sMinus; GetCh
  104. | "." : sym := sPeriod; GetCh
  105. | "/" : sym := sDiv; GetCh
  106. | "0".."9" :
  107. Number
  108. | ":" : GetCh;
  109. IF ch = "=" THEN
  110. GetCh; sym := sBecomes
  111. ELSE
  112. sym := sColon
  113. END
  114. | ";" : sym := sSemicolon; GetCh
  115. | "<" : GetCh;
  116. IF ch = "=" THEN
  117. GetCh; sym := sLE
  118. ELSE
  119. sym := sLT
  120. END
  121. | "=" : sym := sEQ; GetCh
  122. | ">" : GetCh;
  123. IF ch = "=" THEN
  124. GetCh; sym := sGE
  125. ELSE
  126. sym := sGT
  127. END
  128. | "?" : sym := sRead; GetCh
  129. | "@" : sym := sNull; GetCh
  130. | "A".."Z": Identifier
  131. | "a".."z": Identifier
  132. | "[" : sym := sLBracket; GetCh
  133. | "]" : sym := sRBracket; GetCh
  134. ELSE
  135. sym := sNull; GetCh
  136. END;
  137. Write("<"); WriteInt(ORD(sym), 1); Write('>'); WriteLn;
  138. END GetSymbol;
  139. PROCEDURE ResetOptions;
  140. BEGIN
  141. printCode := FALSE;
  142. traceParser := FALSE;
  143. optimize := FALSE;
  144. printListing := TRUE
  145. END ResetOptions;
  146. PROCEDURE InitScanner;
  147. BEGIN
  148. InitInput;
  149. ch := " ";
  150. ResetOptions;
  151. InitStringTable;
  152. EnterKeyWord (sDo, "DO");
  153. EnterKeyWord (sIf, "IF");
  154. (* EnterKeyWord (sOf, "OF"); *)
  155. EnterKeyWord (sOr, "OR");
  156. EnterKeyWord (sAnd, "AND");
  157. EnterKeyWord (sEnd, "END");
  158. EnterKeyWord (sNot, "NOT");
  159. EnterKeyWord (sOdd, "ODD");
  160. EnterKeyWord (sVar, "VAR");
  161. EnterKeyWord (sCall, "CALL");
  162. EnterKeyWord (sElse, "ELSE");
  163. EnterKeyWord (sThen, "THEN");
  164. (* EnterKeyWord (sType, "TYPE"); *)
  165. (* EnterKeyWord (sArray, "ARRAY"); *)
  166. EnterKeyWord (sBegin, "BEGIN");
  167. EnterKeyWord (sConst, "CONST");
  168. EnterKeyWord (sElsif, "ELSIF");
  169. EnterKeyWord (sWhile, "WHILE");
  170. EnterKeyWord (sProcedure, "PROCEDURE");
  171. END InitScanner;
  172. BEGIN
  173. dummyPosition.line := 0;
  174. dummyPosition.column := 0;
  175. END Scanner.