CRQ.mod 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. (* CR Main Module of Coco/R
  2. == =====================
  3. This is a compiler generator that produces a scanner and a parser
  4. from an attributed grammar, and optionally a complete small compiler.
  5. Original code in Oberon by Hanspeter Moessenboeck, ETH Zurich
  6. Ported at ETH to Apple Modula, and thence to JPI-2 Modula.
  7. Usage:
  8. COCOR [-options] GrammarName[.atg] [$options]
  9. Input:
  10. attributed grammar input grammar
  11. scanner.frm frame file
  12. parser.frm frame file
  13. compiler.frm frame file (optional)
  14. (Frame files must be in the sme directory as the grammar, or may be
  15. found on a path specified by environment variable CRFRAMES).
  16. Output:
  17. <GrammarName>S.def + mod generated scanner
  18. <GrammarName>P.def + mod generated parser
  19. <GrammarName>.err error numbers and corresponding error messages
  20. <GrammarName>.lst source listing with error messages and trace output
  21. Optionally
  22. <GrammarName>G.def + mod generated symbolic names
  23. <GrammarName>.mod generated compiler main module
  24. Implementation restrictions
  25. 1 too many nodes in graph (>1500) CRT.NewNode
  26. 2 too many symbols (>500) CRT.NewSym, MovePragmas
  27. 3 too many sets (>256 ANY-syms or SYNC syms) CRT.NewSet,
  28. 4 too many character classes (>250) CRT.NewClass
  29. 5 too many conditions in generated code (>100) CRX.NewCondSet
  30. 6 too many token names in "NAMES" (>100) CRT.NewName
  31. 7 too many states in automata (>500) CRA.NewState
  32. Trace output
  33. (To activate a trace switch, write "${letter}" in the input grammar, or
  34. invoke Coco with a second command line parameter)
  35. A Prints states of automaton
  36. C Generates complete compiler module
  37. D Suppresses Def Mod generation
  38. F Prints start symbols and followers of nonterminals.
  39. G Prints the top-down graph.
  40. I Trace of start symbol set computation.
  41. L Forces a listing (otherwise a listing is only printed if errors are found).
  42. M Suppresses FORWARD declarations in parser (for multipass compilers).
  43. N Uses default names for symbol value constants. This generates an
  44. extra module <grammar name>G, and corresponding import statements
  45. using constant names instead of numbers for symbols in parser and
  46. scanner.
  47. The constants are used unqualified and hence all needed constants
  48. have to be imported; so a complete import list for these constants
  49. is generated.
  50. There is no decision whether a constant is actually needed.
  51. The default conventions are (only terminals or pragmas can have names):
  52. single character --> <ASCII name (lowercase)>Sym
  53. eg. "+" --> plusSym
  54. character string --> <string>Sym
  55. eg. "PROGRAM" --> PROGRAMSym
  56. scanner token --> <token name>Sym
  57. eg. ident --> identSym
  58. O Trace of follow set computation (not yet implemented).
  59. P Generates parser only
  60. S Prints the symbol list.
  61. T Suppresses generation of def and mod files (grammar tests only).
  62. X Prints a cross reference list.
  63. ==========================================================================*)
  64. MODULE CR;
  65. FROM CRS IMPORT lst, src, errors, directory, Error, CharAt;
  66. FROM CRP IMPORT Parse;
  67. IMPORT CRC, CRT, CRA, CRP, CRS, CRX, FIO;
  68. IMPORT Storage;
  69. IMPORT SYSTEM (* for TSIZE only *);
  70. IMPORT FileIO, FIO;
  71. CONST
  72. ATGExt = ".atg";
  73. LSTExt = ".lst";
  74. Version = "1.53q";
  75. ReleaseDate = "2025";
  76. EOF = 0C; (* FileIO.Read returns EOF when eof is reached. *)
  77. EOL = 36C; (* FileIO.Read maps line marks onto EOL
  78. FileIO.Write maps EOL onto cr, lf, or cr/lf
  79. as appropriate for filing system. *)
  80. ESC = 33C; (* Standard ASCII escape. *)
  81. CR = 15C; (* Standard ASCII carriage return. *)
  82. LF = 12C; (* Standard ASCII line feed. *)
  83. BS = 10C; (* Standard ASCII backspace. *)
  84. DEL = 177C; (* Standard ASCII DEL (rub-out). *)
  85. TYPE
  86. INT32 = CARDINAL;
  87. VAR
  88. Options,
  89. GrammarName,
  90. ATGFileName,
  91. lstFileName: ARRAY [0 .. 63] OF CHAR;
  92. ll1: BOOLEAN; (* TRUE, if grammar is LL(1) *)
  93. IDE,
  94. ok: BOOLEAN; (* TRUE, if grammar tests ok so far *)
  95. MODULE ListHandler;
  96. (* ------------------- Source Listing and Error handler -------------- *)
  97. IMPORT FIO, Storage, SYSTEM;
  98. IMPORT lst, CharAt, ATGFileName, IDE, errors, INT32;
  99. EXPORT StoreError, PrintListing;
  100. TYPE
  101. Err = POINTER TO ErrDesc;
  102. ErrDesc = RECORD
  103. nr, line, col: INTEGER;
  104. next: Err
  105. END;
  106. CONST
  107. tab = 11C;
  108. VAR
  109. firstErr, lastErr: Err;
  110. Extra: INTEGER;
  111. PROCEDURE StoreError (nr, line, col: INTEGER; pos: INT32);
  112. (* Store an error message for later printing *)
  113. VAR
  114. nextErr: Err;
  115. BEGIN
  116. (*Storage.ALLOCATE(nextErr, SYSTEM.TSIZE(ErrDesc));*)
  117. nextErr^.nr := nr; nextErr^.line := line; nextErr^.col := col;
  118. nextErr^.next := NIL;
  119. IF firstErr = NIL
  120. THEN firstErr := nextErr
  121. ELSE lastErr^.next := nextErr
  122. END;
  123. lastErr := nextErr;
  124. INC(errors)
  125. END StoreError;
  126. PROCEDURE GetLine (VAR pos: INT32;
  127. VAR line: ARRAY OF CHAR;
  128. VAR eof: BOOLEAN);
  129. (* Read a source line. Return empty line if eof *)
  130. VAR
  131. ch: CHAR;
  132. i: CARDINAL;
  133. BEGIN
  134. (* i := 0; eof := FALSE; ch := CharAt(pos); INC(pos);
  135. WHILE (ch # CR) & (ch # LF) & (ch # EOF) DO
  136. line[i] := ch; INC(i); ch := CharAt(pos); INC(pos);
  137. END;
  138. eof := (i = 0) & (ch = EOF); line[i] := 0C;
  139. IF ch = CR THEN (* check for MsDos *)
  140. ch := CharAt(pos);
  141. IF ch = LF THEN INC(pos); Extra := 0 END
  142. END*)
  143. END GetLine;
  144. PROCEDURE PrintErr (line: ARRAY OF CHAR; nr, col: INTEGER);
  145. (* Print an error message *)
  146. PROCEDURE Msg (s: ARRAY OF CHAR);
  147. BEGIN
  148. FIO.WriteString(lst, s)
  149. END Msg;
  150. PROCEDURE Pointer;
  151. VAR
  152. i: INTEGER;
  153. BEGIN
  154. FIO.WriteString(lst, "***** ");
  155. i := 0;
  156. WHILE i < col + Extra - 2 DO
  157. IF line[i] = tab
  158. THEN FIO.Write(lst, tab)
  159. ELSE FIO.Write(lst, ' ')
  160. END;
  161. INC(i)
  162. END;
  163. FIO.WriteString(lst, "^ ")
  164. END Pointer;
  165. BEGIN
  166. IF ~ IDE THEN Pointer END;
  167. CASE nr OF
  168. 0: Msg("EOF expected")
  169. | 1: Msg("ident expected")
  170. | 2: Msg("string expected")
  171. | 3: Msg("badstring expected")
  172. | 4: Msg("number expected")
  173. | 5: Msg("'COMPILER' expected")
  174. | 6: Msg("'PRODUCTIONS' expected")
  175. | 7: Msg("'=' expected")
  176. | 8: Msg("'.' expected")
  177. | 9: Msg("'END' expected")
  178. | 10: Msg("'CHARACTERS' expected")
  179. | 11: Msg("'TOKENS' expected")
  180. | 12: Msg("'NAMES' expected")
  181. | 13: Msg("'PRAGMAS' expected")
  182. | 14: Msg("'COMMENTS' expected")
  183. | 15: Msg("'FROM' expected")
  184. | 16: Msg("'TO' expected")
  185. | 17: Msg("'NESTED' expected")
  186. | 18: Msg("'IGNORE' expected")
  187. | 19: Msg("'CASE' expected")
  188. | 20: Msg("'+' expected")
  189. | 21: Msg("'-' expected")
  190. | 22: Msg("'..' expected")
  191. | 23: Msg("'ANY' expected")
  192. | 24: Msg("'CHR' expected")
  193. | 25: Msg("'(' expected")
  194. | 26: Msg("')' expected")
  195. | 27: Msg("'|' expected")
  196. | 28: Msg("'WEAK' expected")
  197. | 29: Msg("'[' expected")
  198. | 30: Msg("']' expected")
  199. | 31: Msg("'{' expected")
  200. | 32: Msg("'}' expected")
  201. | 33: Msg("'SYNC' expected")
  202. | 34: Msg("'CONTEXT' expected")
  203. | 35: Msg("'<' expected")
  204. | 36: Msg("'>' expected")
  205. | 37: Msg("'<.' expected")
  206. | 38: Msg("'.>' expected")
  207. | 39: Msg("'(.' expected")
  208. | 40: Msg("'.)' expected")
  209. | 41: Msg("not expected")
  210. | 42: Msg("invalid TokenFactor")
  211. | 43: Msg("invalid Factor")
  212. | 44: Msg("invalid Factor")
  213. | 45: Msg("invalid Term")
  214. | 46: Msg("invalid Symbol")
  215. | 47: Msg("invalid SingleChar")
  216. | 48: Msg("invalid SimSet")
  217. | 49: Msg("invalid NameDecl")
  218. | 50: Msg("this symbol not expected in TokenDecl")
  219. | 51: Msg("invalid TokenDecl")
  220. | 52: Msg("invalid Attribs")
  221. | 53: Msg("invalid Declaration")
  222. | 54: Msg("invalid Declaration")
  223. | 55: Msg("invalid Declaration")
  224. | 56: Msg("this symbol not expected in CR")
  225. | 57: Msg("invalid CR")
  226. | 101: Msg("character set may not be empty")
  227. | 102: Msg("string literal may not extend over line end")
  228. | 103: Msg("a literal must not have attributes")
  229. | 104: Msg("this symbol kind not allowed in production")
  230. | 105: Msg("attribute mismatch between declaration and use")
  231. | 106: Msg("undefined string in production")
  232. | 107: Msg("name declared twice")
  233. | 108: Msg("this type not allowed on left side of production")
  234. | 109: Msg("earlier semantic action was not terminated")
  235. | 111: Msg("no production found for grammar name")
  236. | 112: Msg("grammar symbol must not have attributes")
  237. | 113: Msg("a literal must not be declared with a structure")
  238. | 114: Msg("semantic action not allowed here")
  239. | 115: Msg("undefined name")
  240. | 116: Msg("attributes not allowed in token declaration")
  241. | 117: Msg("name does not match grammar name")
  242. | 118: Msg("unacceptable constant value")
  243. | 119: Msg("may not ignore CHR(0)")
  244. | 120: Msg("token might be empty")
  245. | 121: Msg("token must not start with an iteration")
  246. | 122: Msg("comment delimiters may not be structured")
  247. | 123: Msg("only terminals may be weak")
  248. | 124: Msg("literal tokens may not contain white space")
  249. | 125: Msg("comment delimiter must be 1 or 2 characters long")
  250. | 126: Msg("character set contains more than one character")
  251. | 127: Msg("could not make deterministic automaton")
  252. | 128: Msg("semantic action text too long - please split it")
  253. | 129: Msg("literal tokens may not be empty")
  254. | 130: Msg("IGNORE CASE must appear earlier")
  255. ELSE Msg("Error: "); FIO.WriteInt(lst, nr, 1);
  256. END;
  257. FIO.WriteLn(lst)
  258. END PrintErr;
  259. PROCEDURE PrintListing;
  260. (* Print a source listing with error messages *)
  261. VAR
  262. nextErr: Err;
  263. eof: BOOLEAN;
  264. lnr, errC: INTEGER;
  265. srcPos: INT32;
  266. line: ARRAY [0 .. 255] OF CHAR;
  267. BEGIN
  268. IF ~ IDE THEN
  269. FIO.WriteString(lst, "Listing:");
  270. FIO.WriteLn(lst); FIO.WriteLn(lst);
  271. END;
  272. srcPos := 0; nextErr := firstErr;
  273. GetLine(srcPos, line, eof); lnr := 1; errC := 0;
  274. WHILE ~ eof DO
  275. IF ~ IDE THEN
  276. FIO.WriteInt(lst, lnr, 5); FIO.WriteString(lst, " ");
  277. FIO.WriteString(lst, line); FIO.WriteLn(lst)
  278. END;
  279. WHILE (nextErr # NIL) & (nextErr^.line = lnr) DO
  280. IF IDE THEN
  281. FIO.WriteString(lst, ATGFileName);
  282. FIO.WriteString(lst, " (");
  283. FIO.WriteCard(lst, lnr, 1);
  284. FIO.WriteString(lst, ",");
  285. FIO.WriteCard(lst, nextErr^.col-1, 0);
  286. FIO.WriteString(lst, ") ")
  287. END;
  288. PrintErr(line, nextErr^.nr, nextErr^.col); INC(errC);
  289. nextErr := nextErr^.next
  290. END;
  291. GetLine(srcPos, line, eof); INC(lnr);
  292. END;
  293. IF nextErr # NIL THEN
  294. IF ~ IDE THEN FIO.WriteInt(lst, lnr, 5); FIO.WriteLn(lst) END;
  295. WHILE nextErr # NIL DO
  296. IF IDE THEN
  297. FIO.WriteString(lst, ATGFileName);
  298. FIO.WriteString(lst, " (");
  299. FIO.WriteCard(lst, lnr, 1);
  300. FIO.WriteString(lst, ",");
  301. FIO.WriteCard(lst, nextErr^.col-1, 0);
  302. FIO.WriteString(lst, ") ")
  303. END;
  304. PrintErr(line, nextErr^.nr, nextErr^.col); INC(errC);
  305. nextErr := nextErr^.next
  306. END
  307. END;
  308. IF ~ IDE AND (errC > 0) THEN
  309. FIO.WriteLn(lst);
  310. FIO.WriteInt(lst, errC, 5); FIO.WriteString(lst, " error");
  311. IF errC # 1 THEN FIO.Write(lst, "s") END;
  312. FIO.WriteLn(lst); FIO.WriteLn(lst); FIO.WriteLn(lst);
  313. END
  314. END PrintListing;
  315. BEGIN
  316. firstErr := NIL; Extra := 1;
  317. END ListHandler;
  318. PROCEDURE SetOption (s: ARRAY OF CHAR);
  319. (* Set compiler options *)
  320. VAR
  321. i: CARDINAL;
  322. BEGIN
  323. i := 1;
  324. WHILE s[i] # 0C DO
  325. s[i] := CAP(s[i]);
  326. IF (s[i] >= "A") AND (s[i] <= "Z") THEN CRT.ddt[s[i]] := TRUE END;
  327. INC(i);
  328. END;
  329. END SetOption;
  330. PROCEDURE Msg (S: ARRAY OF CHAR);
  331. BEGIN
  332. FIO.WriteString(FIO.StdOut, S); FIO.WriteLn(FIO.StdOut);
  333. END Msg;
  334. (* --------------------------- Help ------------------------------- *)
  335. PROCEDURE Help;
  336. BEGIN
  337. Msg("Usage: COCOR [-Options] [Grammar[.atg]] [-Options]");
  338. Msg("Example: COCOR -mcs Test");
  339. Msg("");
  340. Msg("Options are");
  341. Msg("a - Trace automaton");
  342. Msg("c - Generate compiler module");
  343. Msg("d - Suppress generation of Definition Modules");
  344. Msg("f - Give Start and Follower sets");
  345. Msg("g - Print top-down graph");
  346. Msg("i - Trace start set computations");
  347. Msg("l - Force listing");
  348. Msg("m - (Multipass) Suppress FORWARD declarations");
  349. Msg("n - Generate symbolic names");
  350. Msg("p - Generate parser only");
  351. Msg("q - Generate error messages to interface with editor");
  352. Msg("s - Print symbol table");
  353. Msg("t - Grammar tests only - no code generated");
  354. Msg("x - Print cross reference list");
  355. Msg("COMPILER.FRM, SCANNER.FRM and PARSER.FRM must be in the working directory,");
  356. Msg("or on the path specified by the environment variable CRFRAMES");
  357. END Help;
  358. BEGIN (* CR *)
  359. FIO.WriteString(FIO.StdOut, "Coco/R (WinTel) - Compiler-Compiler V");
  360. FIO.WriteString(FIO.StdOut, Version);
  361. FIO.WriteLn(FIO.StdOut);
  362. FIO.WriteString(FIO.StdOut, "Released by Pat Terry ");
  363. FIO.WriteString(FIO.StdOut, ReleaseDate);
  364. FIO.WriteLn(FIO.StdOut);
  365. FIO.NextParameter(GrammarName);
  366. IF (GrammarName[0] = "?")
  367. OR (GrammarName[0] = "/") AND (GrammarName[1] = "?") THEN
  368. Help; FIO.QuitExecution
  369. END;
  370. IF GrammarName[0] = 0C THEN
  371. FIO.WriteString(FIO.StdOut, "(COCOR ? gives short help screen)");
  372. FIO.WriteLn(FIO.StdOut);
  373. END;
  374. WHILE (GrammarName[0] = "-") OR (GrammarName[0] = "/") DO
  375. (* accept options before filename *)
  376. SetOption(GrammarName); FIO.NextParameter(GrammarName)
  377. END;
  378. ok := GrammarName[0] # 0C;
  379. REPEAT
  380. IF ~ ok THEN
  381. FIO.WriteString(FIO.StdOut, "Grammar[.atg] ? : ");
  382. FIO.ReadString(FIO.StdIn, GrammarName);
  383. IF ~ FIO.IsNoError(FIO.StdIn) THEN FIO.QuitExecution END;
  384. FIO.ReadLn(FIO.StdIn);
  385. END;
  386. FIO.AppendExtension(GrammarName, ATGExt, ATGFileName);
  387. GrammarName := ATGFileName;
  388. FIO.Open(src, GrammarName, FALSE);
  389. ok := FIO.IsNoError(src);
  390. IF ~ ok THEN
  391. FIO.WriteString(FIO.StdOut, "File <");
  392. FIO.WriteString(FIO.StdOut, GrammarName);
  393. FIO.WriteString(FIO.StdOut, "> not found.");
  394. FIO.WriteLn(FIO.StdOut);
  395. END
  396. UNTIL ok;
  397. FIO.NextParameter(Options);
  398. IF Options[0] # 0C THEN SetOption(Options) END;
  399. IDE := CRT.ddt["Q"];
  400. FIO.ExtractDirectory(GrammarName, directory);
  401. FIO.ChangeExtension(GrammarName, LSTExt, lstFileName);
  402. IF IDE
  403. THEN
  404. lst := FIO.StdOut
  405. ELSE
  406. FIO.Open(lst, lstFileName, TRUE);
  407. FIO.WriteString(lst, "Coco/R - Compiler-Compiler V");
  408. FIO.WriteString(lst, Version);
  409. FIO.WriteLn(lst);
  410. FIO.WriteString(lst, "Released by Pat Terry ");
  411. FIO.WriteString(lst, ReleaseDate);
  412. FIO.WriteLn(lst);
  413. FIO.WriteString(lst, "Source file: ");
  414. FIO.WriteString(lst, GrammarName);
  415. FIO.WriteLn(lst); FIO.WriteLn(lst);
  416. FIO.WriteLn(FIO.StdOut);
  417. FIO.WriteString(FIO.StdOut, "parsing file ");
  418. FIO.WriteString(FIO.StdOut, GrammarName);
  419. FIO.WriteLn(FIO.StdOut);
  420. END;
  421. CRS.Error := StoreError;
  422. CRP.Parse;
  423. (*
  424. IF ~ IDE THEN
  425. FIO.WriteLn(FIO.StdOut); FIO.WriteElapsedTime(FIO.StdOut)
  426. END;
  427. *)
  428. IF errors = 0 THEN
  429. IF ~ IDE
  430. THEN
  431. Msg("testing grammar");
  432. FIO.WriteString(lst, "Grammar Tests:");
  433. FIO.WriteLn(lst); FIO.WriteLn(lst)
  434. ELSE
  435. FIO.WriteLn(lst); FIO.WriteString(lst, ATGFileName);
  436. FIO.WriteString(lst, " (0, 0) Grammar tests"); FIO.WriteLn(lst)
  437. END;
  438. CRT.CompSymbolSets;
  439. IF IDE THEN
  440. FIO.WriteLn(lst); FIO.WriteString(lst, ATGFileName);
  441. FIO.WriteString(lst, " (0, 0) Undefined tests"); FIO.WriteLn(lst)
  442. END;
  443. CRT.TestCompleteness(ok);
  444. IF ok
  445. THEN
  446. IF IDE THEN
  447. FIO.WriteLn(lst); FIO.WriteString(lst, ATGFileName);
  448. FIO.WriteString(lst, " (0, 0) Unreachable tests"); FIO.WriteLn(lst)
  449. END;
  450. CRT.TestIfAllNtReached(ok)
  451. END;
  452. IF ok THEN
  453. IF IDE THEN
  454. FIO.WriteLn(lst); FIO.WriteString(lst, ATGFileName);
  455. FIO.WriteString(lst, " (0, 0) Circular tests"); FIO.WriteLn(lst)
  456. END;
  457. CRT.FindCircularProductions(ok)
  458. END;
  459. IF ok THEN
  460. IF IDE THEN
  461. FIO.WriteLn(lst); FIO.WriteString(lst, ATGFileName);
  462. FIO.WriteString(lst, " (0, 0) Underivable tests"); FIO.WriteLn(lst)
  463. END;
  464. CRT.TestIfNtToTerm(ok)
  465. END;
  466. IF ok THEN
  467. IF IDE THEN
  468. FIO.WriteLn(lst); FIO.WriteString(lst, ATGFileName);
  469. FIO.WriteString(lst, " (0, 0) LL(1) tests"); FIO.WriteLn(lst)
  470. END;
  471. CRT.LL1Test(ll1)
  472. END;
  473. (*
  474. IF ~ IDE THEN
  475. FIO.WriteLn(FIO.StdOut); FIO.WriteElapsedTime(FIO.StdOut);
  476. FIO.WriteLn(lst)
  477. END;
  478. *)
  479. IF ~ ok OR ~ ll1 OR CRT.ddt["L"] OR CRT.ddt["X"] THEN
  480. IF ~ IDE THEN Msg("listing") END;
  481. PrintListing; IF CRT.ddt["X"] THEN CRT.XRef; END;
  482. (*
  483. IF ~ IDE THEN
  484. FIO.WriteLn(FIO.StdOut); FIO.WriteElapsedTime(FIO.StdOut)
  485. END;
  486. *)
  487. END;
  488. IF CRT.ddt["N"] OR CRT.symNames THEN
  489. IF ~ IDE THEN Msg("symbol name assignment") END;
  490. CRT.AssignSymNames(CRT.ddt["N"], CRT.symNames);
  491. END;
  492. IF ok AND ~ CRT.ddt["T"] THEN
  493. IF ~ IDE THEN Msg("generating parser") END;
  494. CRX.GenCompiler;
  495. (*
  496. IF ~ IDE THEN
  497. FIO.WriteLn(FIO.StdOut); FIO.WriteElapsedTime(FIO.StdOut)
  498. END;
  499. *)
  500. IF CRT.genScanner AND ~ CRT.ddt["P"] THEN
  501. IF ~ IDE THEN Msg("generating scanner") END;
  502. CRA.WriteScanner(ok);
  503. IF CRT.ddt["A"] THEN CRA.PrintStates END;
  504. (*
  505. IF ~ IDE THEN
  506. FIO.WriteLn(FIO.StdOut); FIO.WriteElapsedTime(FIO.StdOut)
  507. END;
  508. *)
  509. END;
  510. IF CRT.ddt["C"] THEN
  511. IF ~ IDE THEN Msg("generating compiler") END;
  512. CRC.WriteDriver;
  513. (*
  514. IF ~ IDE THEN
  515. FIO.WriteLn(FIO.StdOut); FIO.WriteElapsedTime(FIO.StdOut);
  516. END;
  517. *)
  518. END;
  519. IF ~ IDE THEN CRX.WriteStatistics END;
  520. END;
  521. IF ~ ok THEN
  522. FIO.WriteLn(FIO.StdOut);
  523. IF IDE THEN
  524. FIO.WriteString(lst, ATGFileName);
  525. FIO.WriteString(lst, " (0, 0) ")
  526. END;
  527. FIO.WriteString(FIO.StdOut, "Compilation ended with errors in grammar tests.");
  528. ELSIF ~ ll1 THEN
  529. FIO.WriteLn(FIO.StdOut);
  530. IF IDE THEN
  531. FIO.WriteString(lst, ATGFileName);
  532. FIO.WriteString(lst, " (0, 0) ")
  533. END;
  534. FIO.WriteString(FIO.StdOut, "Compilation ended with LL(1) errors.");
  535. ELSE
  536. Msg("Compilation completed. No errors detected.");
  537. END;
  538. ELSE
  539. IF ~ IDE THEN Msg("listing") END;
  540. PrintListing; IF CRT.ddt["X"] THEN CRT.XRef END;
  541. IF ~ IDE THEN Msg("*** errors detected ***") END;
  542. END;
  543. FIO.WriteLn(FIO.StdOut);
  544. IF CRT.ddt["G"] THEN CRT.PrintGraph END;
  545. IF CRT.ddt["S"] THEN CRT.PrintSymbolTable END;
  546. FIO.Close(lst); FIO.Close(src);
  547. (*
  548. IF ~ IDE THEN
  549. FIO.WriteLn(FIO.StdOut); FIO.WriteExecutionTime(FIO.StdOut)
  550. END
  551. *)
  552. END CR.