ListHandler.mod 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. MODULE ListHandler;
  2. (* ------------------- Source Listing and Error handler -------------- *)
  3. IMPORT FIO, Storage, SYSTEM;
  4. IMPORT CharAt, ATGFileName, IDE, errors, INT32;
  5. TYPE
  6. Err = POINTER TO ErrDesc;
  7. ErrDesc = RECORD
  8. nr, line, col: INTEGER;
  9. next: Err
  10. END;
  11. CONST
  12. tab = 11C;
  13. VAR
  14. firstErr, lastErr: Err;
  15. Extra: INTEGER;
  16. PROCEDURE StoreError (nr, line, col: INTEGER; pos: INT32);
  17. (* Store an error message for later printing *)
  18. VAR
  19. nextErr: Err;
  20. BEGIN
  21. (*Storage.ALLOCATE(nextErr, SYSTEM.TSIZE(ErrDesc));*)
  22. nextErr^.nr := nr; nextErr^.line := line; nextErr^.col := col;
  23. nextErr^.next := NIL;
  24. IF firstErr = NIL
  25. THEN firstErr := nextErr
  26. ELSE lastErr^.next := nextErr
  27. END;
  28. lastErr := nextErr;
  29. INC(errors)
  30. END StoreError;
  31. PROCEDURE GetLine (VAR pos: INT32;
  32. VAR line: ARRAY OF CHAR;
  33. VAR eof: BOOLEAN);
  34. (* Read a source line. Return empty line if eof *)
  35. VAR
  36. ch: CHAR;
  37. i: CARDINAL;
  38. BEGIN
  39. (* i := 0; eof := FALSE; ch := CharAt(pos); INC(pos);
  40. WHILE (ch # CR) & (ch # LF) & (ch # EOF) DO
  41. line[i] := ch; INC(i); ch := CharAt(pos); INC(pos);
  42. END;
  43. eof := (i = 0) & (ch = EOF); line[i] := 0C;
  44. IF ch = CR THEN (* check for MsDos *)
  45. ch := CharAt(pos);
  46. IF ch = LF THEN INC(pos); Extra := 0 END
  47. END*)
  48. END GetLine;
  49. PROCEDURE PrintErr (line: ARRAY OF CHAR; nr, col: INTEGER);
  50. (* Print an error message *)
  51. PROCEDURE Msg (s: ARRAY OF CHAR);
  52. BEGIN
  53. FIO.WriteString(FIO.File, s)
  54. END Msg;
  55. PROCEDURE Pointer;
  56. VAR
  57. i: INTEGER;
  58. BEGIN
  59. FIO.WriteString(FIO.File, "***** ");
  60. i := 0;
  61. WHILE i < col + Extra - 2 DO
  62. IF line[i] = tab
  63. THEN FIO.Write(FIO.File, tab)
  64. ELSE FIO.Write(FIO.File, ' ')
  65. END;
  66. INC(i)
  67. END;
  68. FIO.WriteString(FIO.File, "^ ")
  69. END Pointer;
  70. BEGIN
  71. IF ~ IDE THEN Pointer END;
  72. CASE nr OF
  73. 0: Msg("EOF expected")
  74. | 1: Msg("ident expected")
  75. | 2: Msg("string expected")
  76. | 3: Msg("badstring expected")
  77. | 4: Msg("number expected")
  78. | 5: Msg("'COMPILER' expected")
  79. | 6: Msg("'PRODUCTIONS' expected")
  80. | 7: Msg("'=' expected")
  81. | 8: Msg("'.' expected")
  82. | 9: Msg("'END' expected")
  83. | 10: Msg("'CHARACTERS' expected")
  84. | 11: Msg("'TOKENS' expected")
  85. | 12: Msg("'NAMES' expected")
  86. | 13: Msg("'PRAGMAS' expected")
  87. | 14: Msg("'COMMENTS' expected")
  88. | 15: Msg("'FROM' expected")
  89. | 16: Msg("'TO' expected")
  90. | 17: Msg("'NESTED' expected")
  91. | 18: Msg("'IGNORE' expected")
  92. | 19: Msg("'CASE' expected")
  93. | 20: Msg("'+' expected")
  94. | 21: Msg("'-' expected")
  95. | 22: Msg("'..' expected")
  96. | 23: Msg("'ANY' expected")
  97. | 24: Msg("'CHR' expected")
  98. | 25: Msg("'(' expected")
  99. | 26: Msg("')' expected")
  100. | 27: Msg("'|' expected")
  101. | 28: Msg("'WEAK' expected")
  102. | 29: Msg("'[' expected")
  103. | 30: Msg("']' expected")
  104. | 31: Msg("'{' expected")
  105. | 32: Msg("'}' expected")
  106. | 33: Msg("'SYNC' expected")
  107. | 34: Msg("'CONTEXT' expected")
  108. | 35: Msg("'<' expected")
  109. | 36: Msg("'>' expected")
  110. | 37: Msg("'<.' expected")
  111. | 38: Msg("'.>' expected")
  112. | 39: Msg("'(.' expected")
  113. | 40: Msg("'.)' expected")
  114. | 41: Msg("not expected")
  115. | 42: Msg("invalid TokenFactor")
  116. | 43: Msg("invalid Factor")
  117. | 44: Msg("invalid Factor")
  118. | 45: Msg("invalid Term")
  119. | 46: Msg("invalid Symbol")
  120. | 47: Msg("invalid SingleChar")
  121. | 48: Msg("invalid SimSet")
  122. | 49: Msg("invalid NameDecl")
  123. | 50: Msg("this symbol not expected in TokenDecl")
  124. | 51: Msg("invalid TokenDecl")
  125. | 52: Msg("invalid Attribs")
  126. | 53: Msg("invalid Declaration")
  127. | 54: Msg("invalid Declaration")
  128. | 55: Msg("invalid Declaration")
  129. | 56: Msg("this symbol not expected in CR")
  130. | 57: Msg("invalid CR")
  131. | 101: Msg("character set may not be empty")
  132. | 102: Msg("string literal may not extend over line end")
  133. | 103: Msg("a literal must not have attributes")
  134. | 104: Msg("this symbol kind not allowed in production")
  135. | 105: Msg("attribute mismatch between declaration and use")
  136. | 106: Msg("undefined string in production")
  137. | 107: Msg("name declared twice")
  138. | 108: Msg("this type not allowed on left side of production")
  139. | 109: Msg("earlier semantic action was not terminated")
  140. | 111: Msg("no production found for grammar name")
  141. | 112: Msg("grammar symbol must not have attributes")
  142. | 113: Msg("a literal must not be declared with a structure")
  143. | 114: Msg("semantic action not allowed here")
  144. | 115: Msg("undefined name")
  145. | 116: Msg("attributes not allowed in token declaration")
  146. | 117: Msg("name does not match grammar name")
  147. | 118: Msg("unacceptable constant value")
  148. | 119: Msg("may not ignore CHR(0)")
  149. | 120: Msg("token might be empty")
  150. | 121: Msg("token must not start with an iteration")
  151. | 122: Msg("comment delimiters may not be structured")
  152. | 123: Msg("only terminals may be weak")
  153. | 124: Msg("literal tokens may not contain white space")
  154. | 125: Msg("comment delimiter must be 1 or 2 characters long")
  155. | 126: Msg("character set contains more than one character")
  156. | 127: Msg("could not make deterministic automaton")
  157. | 128: Msg("semantic action text too long - please split it")
  158. | 129: Msg("literal tokens may not be empty")
  159. | 130: Msg("IGNORE CASE must appear earlier")
  160. ELSE Msg("Error: "); FIO.WriteInt(FIO.File, nr, 1);
  161. END;
  162. FIO.WriteLn(FIO.File)
  163. END PrintErr;
  164. PROCEDURE PrintListing;
  165. (* Print a source listing with error messages *)
  166. VAR
  167. nextErr: Err;
  168. eof: BOOLEAN;
  169. lnr, errC: INTEGER;
  170. srcPos: INT32;
  171. line: ARRAY [0 .. 255] OF CHAR;
  172. BEGIN
  173. IF ~ IDE THEN
  174. FIO.WriteString(FIO.File, "Listing:");
  175. FIO.WriteLn(FIO.File); FIO.WriteLn(FIO.File);
  176. END;
  177. srcPos := 0; nextErr := firstErr;
  178. GetLine(srcPos, line, eof); lnr := 1; errC := 0;
  179. WHILE ~ eof DO
  180. IF ~ IDE THEN
  181. FIO.WriteInt(FIO.File, lnr, 5); FIO.WriteString(FIO.File, " ");
  182. FIO.WriteString(FIO.File, line); FIO.WriteLn(FIO.File)
  183. END;
  184. WHILE (nextErr # NIL) & (nextErr^.line = lnr) DO
  185. IF IDE THEN
  186. FIO.WriteString(FIO.File, ATGFileName);
  187. FIO.WriteString(FIO.File, " (");
  188. FIO.WriteCard(FIO.File, lnr, 1);
  189. FIO.WriteString(FIO.File, ",");
  190. FIO.WriteCard(FIO.File, nextErr^.col-1, 0);
  191. FIO.WriteString(FIO.File, ") ")
  192. END;
  193. PrintErr(line, nextErr^.nr, nextErr^.col); INC(errC);
  194. nextErr := nextErr^.next
  195. END;
  196. GetLine(srcPos, line, eof); INC(lnr);
  197. END;
  198. IF nextErr # NIL THEN
  199. IF ~ IDE THEN FIO.WriteInt(FIO.File, lnr, 5); FIO.WriteLn(FIO.File) END;
  200. WHILE nextErr # NIL DO
  201. IF IDE THEN
  202. FIO.WriteString(FIO.File, ATGFileName);
  203. FIO.WriteString(FIO.File, " (");
  204. FIO.WriteCard(FIO.File, lnr, 1);
  205. FIO.WriteString(FIO.File, ",");
  206. FIO.WriteCard(FIO.File, nextErr^.col-1, 0);
  207. FIO.WriteString(FIO.File, ") ")
  208. END;
  209. PrintErr(line, nextErr^.nr, nextErr^.col); INC(errC);
  210. nextErr := nextErr^.next
  211. END
  212. END;
  213. IF ~ IDE AND (errC > 0) THEN
  214. FIO.WriteLn(FIO.File);
  215. FIO.WriteInt(FIO.File, errC, 5); FIO.WriteString(FIO.File, " error");
  216. IF errC # 1 THEN FIO.Write(FIO.File, "s") END;
  217. FIO.WriteLn(FIO.File); FIO.WriteLn(FIO.File); FIO.WriteLn(FIO.File);
  218. END
  219. END PrintListing;
  220. BEGIN
  221. firstErr := NIL; Extra := 1;
  222. END ListHandler.