CRP.mod 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. IMPLEMENTATION MODULE CRP;
  2. (* Parser generated by Coco/R - assuming FileIO library will be available. *)
  3. IMPORT FileIO, CRS;
  4. IMPORT CRT, CRA, Sets;
  5. CONST
  6. ident = 0; string = 1; (* symbol kind *)
  7. TYPE
  8. INT32 = FileIO.INT32;
  9. PROCEDURE FixString (VAR name: ARRAY OF CHAR; len: CARDINAL);
  10. VAR
  11. double, spaces: BOOLEAN;
  12. i: CARDINAL;
  13. BEGIN
  14. IF len = 2 THEN SemError(129); RETURN END;
  15. IF CRT.ignoreCase THEN (* force uppercase *)
  16. FOR i := 1 TO len - 2 DO name[i] := CAP(name[i]) END
  17. END;
  18. double := FALSE; spaces := FALSE;
  19. FOR i := 1 TO len - 2 DO (* search for interior " or spaces *)
  20. IF name[i] = '"' THEN double := TRUE END;
  21. IF name[i] <= ' ' THEN spaces := TRUE END;
  22. END;
  23. IF ~ double THEN (* force delimiters to be " quotes *)
  24. name[0] := '"'; name[len-1] := '"'
  25. END;
  26. IF spaces THEN SemError(124) END;
  27. END FixString;
  28. PROCEDURE MatchLiteral (sp: INTEGER);
  29. (* store string either as token or as literal *)
  30. VAR
  31. sn, sn1: CRT.SymbolNode;
  32. matchedSp: INTEGER;
  33. BEGIN
  34. CRT.GetSym(sp, sn);
  35. CRA.MatchDFA(sn.name, sp, matchedSp);
  36. IF matchedSp # CRT.noSym THEN
  37. CRT.GetSym(matchedSp, sn1);
  38. sn1.struct := CRT.classLitToken;
  39. CRT.PutSym(matchedSp, sn1);
  40. sn.struct := CRT.litToken
  41. ELSE sn.struct := CRT.classToken;
  42. END;
  43. CRT.PutSym(sp, sn)
  44. END MatchLiteral;
  45. PROCEDURE SetCtx (gp: INTEGER);
  46. (* set transition code to CRT.contextTrans *)
  47. VAR
  48. gn: CRT.GraphNode;
  49. BEGIN
  50. WHILE gp > 0 DO
  51. CRT.GetNode(gp, gn);
  52. IF (gn.typ = CRT.char) OR (gn.typ = CRT.class) THEN
  53. gn.p2 := CRT.contextTrans; CRT.PutNode(gp, gn)
  54. ELSIF (gn.typ = CRT.opt) OR (gn.typ = CRT.iter) THEN SetCtx(gn.p1)
  55. ELSIF gn.typ = CRT.alt THEN SetCtx(gn.p1); SetCtx(gn.p2)
  56. END;
  57. gp := gn.next
  58. END
  59. END SetCtx;
  60. PROCEDURE SetOption (s: ARRAY OF CHAR);
  61. VAR
  62. i: CARDINAL;
  63. BEGIN
  64. i := 1;
  65. WHILE s[i] # 0C DO
  66. s[i] := CAP(s[i]);
  67. IF (s[i] >= "A") AND (s[i] <= "Z") THEN CRT.ddt[s[i]] := TRUE END;
  68. INC(i);
  69. END;
  70. END SetOption;
  71. (*--------------------------------------------------------------------*)
  72. CONST
  73. maxT = 41;
  74. maxP = 42;
  75. minErrDist = 2; (* minimal distance (good tokens) between two errors *)
  76. setsize = 16; (* sets are stored in 16 bits *)
  77. TYPE
  78. SymbolSet = ARRAY [0 .. maxT DIV setsize] OF BITSET;
  79. VAR
  80. symSet: ARRAY [0 .. 18] OF SymbolSet; (*symSet[0] = allSyncSyms*)
  81. errDist: CARDINAL; (* number of symbols recognized since last error *)
  82. sym: CARDINAL; (* current input symbol *)
  83. PROCEDURE SemError (errNo: INTEGER);
  84. BEGIN
  85. IF errDist >= minErrDist THEN
  86. CRS.Error(errNo, CRS.line, CRS.col, CRS.pos);
  87. END;
  88. errDist := 0;
  89. END SemError;
  90. PROCEDURE SynError (errNo: INTEGER);
  91. BEGIN
  92. IF errDist >= minErrDist THEN
  93. CRS.Error(errNo, CRS.nextLine, CRS.nextCol, CRS.nextPos);
  94. END;
  95. errDist := 0;
  96. END SynError;
  97. PROCEDURE Get;
  98. VAR
  99. s: ARRAY [0 .. 31] OF CHAR;
  100. BEGIN
  101. REPEAT
  102. CRS.Get(sym);
  103. IF sym <= maxT THEN
  104. INC(errDist);
  105. ELSE
  106. CASE sym OF
  107. 42: CRS.GetName(CRS.nextPos, CRS.nextLen, s); SetOption(s);
  108. END;
  109. CRS.nextPos := CRS.pos;
  110. CRS.nextCol := CRS.col;
  111. CRS.nextLine := CRS.line;
  112. CRS.nextLen := CRS.len;
  113. END;
  114. UNTIL sym <= maxT
  115. END Get;
  116. PROCEDURE In (VAR s: SymbolSet; x: CARDINAL): BOOLEAN;
  117. BEGIN
  118. RETURN x MOD setsize IN s[x DIV setsize];
  119. END In;
  120. PROCEDURE Expect (n: CARDINAL);
  121. BEGIN
  122. IF sym = n THEN Get ELSE SynError(n) END
  123. END Expect;
  124. PROCEDURE ExpectWeak (n, follow: CARDINAL);
  125. BEGIN
  126. IF sym = n
  127. THEN Get
  128. ELSE SynError(n); WHILE ~ In(symSet[follow], sym) DO Get END
  129. END
  130. END ExpectWeak;
  131. PROCEDURE WeakSeparator (n, syFol, repFol: CARDINAL): BOOLEAN;
  132. VAR
  133. s: SymbolSet;
  134. i: CARDINAL;
  135. BEGIN
  136. IF sym = n
  137. THEN Get; RETURN TRUE
  138. ELSIF In(symSet[repFol], sym) THEN RETURN FALSE
  139. ELSE
  140. i := 0;
  141. WHILE i <= maxT DIV setsize DO
  142. s[i] := symSet[0, i] + symSet[syFol, i] + symSet[repFol, i]; INC(i)
  143. END;
  144. SynError(n); WHILE ~ In(s, sym) DO Get END;
  145. RETURN In(symSet[syFol], sym)
  146. END
  147. END WeakSeparator;
  148. PROCEDURE LexName (VAR Lex: ARRAY OF CHAR);
  149. BEGIN
  150. CRS.GetName(CRS.pos, CRS.len, Lex)
  151. END LexName;
  152. PROCEDURE LexString (VAR Lex: ARRAY OF CHAR);
  153. BEGIN
  154. CRS.GetString(CRS.pos, CRS.len, Lex)
  155. END LexString;
  156. PROCEDURE LookAheadName (VAR Lex: ARRAY OF CHAR);
  157. BEGIN
  158. CRS.GetName(CRS.nextPos, CRS.nextLen, Lex)
  159. END LookAheadName;
  160. PROCEDURE LookAheadString (VAR Lex: ARRAY OF CHAR);
  161. BEGIN
  162. CRS.GetString(CRS.nextPos, CRS.nextLen, Lex)
  163. END LookAheadString;
  164. PROCEDURE Successful (): BOOLEAN;
  165. BEGIN
  166. RETURN CRS.errors = 0
  167. END Successful;
  168. (* ----- FORWARD not needed in multipass compilers
  169. PROCEDURE TokenFactor (VAR gL, gR: INTEGER); FORWARD;
  170. PROCEDURE TokenTerm (VAR gL, gR: INTEGER); FORWARD;
  171. PROCEDURE Factor (VAR gL, gR: INTEGER); FORWARD;
  172. PROCEDURE Term (VAR gL, gR: INTEGER); FORWARD;
  173. PROCEDURE Symbol (VAR name: CRT.Name; VAR kind: INTEGER); FORWARD;
  174. PROCEDURE SingleChar (VAR n: CARDINAL); FORWARD;
  175. PROCEDURE SimSet (VAR set: CRT.Set); FORWARD;
  176. PROCEDURE Set (VAR set: CRT.Set); FORWARD;
  177. PROCEDURE TokenExpr (VAR gL, gR: INTEGER); FORWARD;
  178. PROCEDURE NameDecl; FORWARD;
  179. PROCEDURE TokenDecl (typ: INTEGER); FORWARD;
  180. PROCEDURE SetDecl; FORWARD;
  181. PROCEDURE Expression (VAR gL, gR: INTEGER); FORWARD;
  182. PROCEDURE SemText (VAR semPos: CRT.Position); FORWARD;
  183. PROCEDURE Attribs (VAR attrPos: CRT.Position); FORWARD;
  184. PROCEDURE Declaration (VAR startedDFA: BOOLEAN); FORWARD;
  185. PROCEDURE Ident (VAR name: CRT.Name); FORWARD;
  186. PROCEDURE CR; FORWARD;
  187. ----- *)
  188. PROCEDURE TokenFactor (VAR gL, gR: INTEGER);
  189. VAR
  190. kind, c: INTEGER;
  191. set: CRT.Set;
  192. name: CRT.Name;
  193. BEGIN
  194. gL :=0; gR := 0;
  195. IF (sym = 1) OR (sym = 2) THEN
  196. Symbol(name, kind);
  197. IF kind = ident THEN
  198. c := CRT.ClassWithName(name);
  199. IF c < 0 THEN
  200. SemError(115);
  201. Sets.Clear(set); c := CRT.NewClass(name, set)
  202. END;
  203. gL := CRT.NewNode(CRT.class, c, 0); gR := gL
  204. ELSE (* string *)
  205. CRT.StrToGraph(name, gL, gR)
  206. END;
  207. ELSIF (sym = 25) THEN
  208. Get;
  209. TokenExpr(gL, gR);
  210. Expect(26);
  211. ELSIF (sym = 29) THEN
  212. Get;
  213. TokenExpr(gL, gR);
  214. Expect(30);
  215. CRT.MakeOption(gL, gR);
  216. ELSIF (sym = 31) THEN
  217. Get;
  218. TokenExpr(gL, gR);
  219. Expect(32);
  220. CRT.MakeIteration(gL, gR);
  221. ELSE SynError(42);
  222. END;
  223. END TokenFactor;
  224. PROCEDURE TokenTerm (VAR gL, gR: INTEGER);
  225. VAR
  226. gL2, gR2: INTEGER;
  227. BEGIN
  228. TokenFactor(gL, gR);
  229. WHILE (sym = 1) OR (sym = 2) OR (sym = 25) OR (sym = 29) OR (sym = 31) DO
  230. TokenFactor(gL2, gR2);
  231. CRT.ConcatSeq(gL, gR, gL2, gR2);
  232. END;
  233. IF (sym = 34) THEN
  234. Get;
  235. Expect(25);
  236. TokenExpr(gL2, gR2);
  237. SetCtx(gL2); CRT.ConcatSeq(gL, gR, gL2, gR2);
  238. Expect(26);
  239. END;
  240. END TokenTerm;
  241. PROCEDURE Factor (VAR gL, gR: INTEGER);
  242. VAR
  243. sp, kind: INTEGER;
  244. name: CRT.Name;
  245. gn: CRT.GraphNode;
  246. sn: CRT.SymbolNode;
  247. set: CRT.Set;
  248. undef, weak: BOOLEAN;
  249. pos: CRT.Position;
  250. BEGIN
  251. gL :=0; gR := 0; weak := FALSE;
  252. CASE sym OF
  253. 1, 2, 28 :
  254. IF (sym = 28) THEN
  255. Get;
  256. weak := TRUE;
  257. END;
  258. Symbol(name, kind);
  259. sp := CRT.FindSym(name); undef := sp = CRT.noSym;
  260. IF undef THEN
  261. IF kind = ident THEN (* forward nt *)
  262. sp := CRT.NewSym(CRT.nt, name, 0)
  263. ELSIF CRT.genScanner THEN
  264. sp := CRT.NewSym(CRT.t, name, CRS.line);
  265. MatchLiteral(sp)
  266. ELSE (* undefined string in production *)
  267. SemError(106); sp := 0
  268. END
  269. END;
  270. CRT.GetSym(sp, sn);
  271. IF (sn.typ # CRT.t) & (sn.typ # CRT.nt) THEN SemError(104) END;
  272. IF weak THEN
  273. IF sn.typ = CRT.t THEN sn.typ := CRT.wt
  274. ELSE SemError(123)
  275. END
  276. END;
  277. gL := CRT.NewNode(sn.typ, sp, CRS.line); gR := gL;
  278. IF (sym = 35) OR (sym = 37) THEN
  279. Attribs(pos);
  280. CRT.GetNode(gL, gn); gn.pos := pos;
  281. CRT.PutNode(gL, gn);
  282. CRT.GetSym(sp, sn);
  283. IF sn.typ # CRT.nt THEN SemError(103) END;
  284. IF undef THEN
  285. sn.attrPos := pos; CRT.PutSym(sp, sn)
  286. ELSIF sn.attrPos.beg < FileIO.Long0 THEN SemError(105)
  287. END;
  288. ELSIF In(symSet[1], sym) THEN
  289. CRT.GetSym(sp, sn);
  290. IF sn.attrPos.beg >= FileIO.Long0 THEN SemError(105) END;
  291. ELSE SynError(43);
  292. END;
  293. | 25 :
  294. Get;
  295. Expression(gL, gR);
  296. Expect(26);
  297. | 29 :
  298. Get;
  299. Expression(gL, gR);
  300. Expect(30);
  301. CRT.MakeOption(gL, gR);
  302. | 31 :
  303. Get;
  304. Expression(gL, gR);
  305. Expect(32);
  306. CRT.MakeIteration(gL, gR);
  307. | 39 :
  308. SemText(pos);
  309. gL := CRT.NewNode(CRT.sem, 0, 0); gR := gL;
  310. CRT.GetNode(gL, gn);
  311. gn.pos := pos;
  312. CRT.PutNode(gL, gn);
  313. | 23 :
  314. Get;
  315. Sets.Fill(set); Sets.Excl(set, CRT.eofSy);
  316. gL := CRT.NewNode(CRT.any, CRT.NewSet(set), 0); gR := gL;
  317. | 33 :
  318. Get;
  319. gL := CRT.NewNode(CRT.sync, 0, 0); gR := gL;
  320. ELSE SynError(44);
  321. END;
  322. END Factor;
  323. PROCEDURE Term (VAR gL, gR: INTEGER);
  324. VAR
  325. gL2, gR2: INTEGER;
  326. BEGIN
  327. gL := 0; gR := 0;
  328. IF In(symSet[2], sym) THEN
  329. Factor(gL, gR);
  330. WHILE In(symSet[2], sym) DO
  331. Factor(gL2, gR2);
  332. CRT.ConcatSeq(gL, gR, gL2, gR2);
  333. END;
  334. ELSIF (sym = 8) OR (sym = 26) OR (sym = 27) OR (sym = 30) OR (sym = 32) THEN
  335. gL := CRT.NewNode(CRT.eps, 0, 0); gR := gL;
  336. ELSE SynError(45);
  337. END;
  338. END Term;
  339. PROCEDURE Symbol (VAR name: CRT.Name; VAR kind: INTEGER);
  340. BEGIN
  341. IF (sym = 1) THEN
  342. Ident(name);
  343. kind := ident;
  344. ELSIF (sym = 2) THEN
  345. Get;
  346. CRS.GetName(CRS.pos, CRS.len, name); kind := string;
  347. FixString(name, CRS.len);
  348. ELSE SynError(46);
  349. END;
  350. END Symbol;
  351. PROCEDURE SingleChar (VAR n: CARDINAL);
  352. VAR
  353. i: CARDINAL;
  354. s: ARRAY [0 .. 127] OF CHAR;
  355. BEGIN
  356. Expect(24);
  357. Expect(25);
  358. IF (sym = 4) THEN
  359. Get;
  360. CRS.GetName(CRS.pos, CRS.len, s);
  361. n := 0; i := 0;
  362. WHILE s[i] # 0C DO
  363. n := 10 * n + ORD(s[i]) - ORD("0"); INC(i)
  364. END;
  365. IF n > 255 THEN SemError(118); n := n MOD 256 END;
  366. IF CRT.ignoreCase THEN n := ORD(CAP(CHR(n))) END;
  367. ELSIF (sym = 2) THEN
  368. Get;
  369. CRS.GetName(CRS.pos, CRS.len, s);
  370. IF CRS.len # 3 THEN SemError(118) END;
  371. IF CRT.ignoreCase THEN s[1] := CAP(s[1]) END;
  372. n := ORD(s[1]);;
  373. ELSE SynError(47);
  374. END;
  375. Expect(26);
  376. END SingleChar;
  377. PROCEDURE SimSet (VAR set: CRT.Set);
  378. VAR
  379. i, n1, n2: CARDINAL;
  380. c: INTEGER;
  381. name: CRT.Name;
  382. s: ARRAY [0 .. 127] OF CHAR;
  383. BEGIN
  384. Sets.Clear(set);
  385. IF (sym = 1) THEN
  386. Ident(name);
  387. c := CRT.ClassWithName(name);
  388. IF c < 0
  389. THEN SemError(115)
  390. ELSE CRT.GetClass(c, set)
  391. END;
  392. ELSIF (sym = 2) THEN
  393. Get;
  394. CRS.GetName(CRS.pos, CRS.len, s);
  395. i := 1;
  396. WHILE s[i] # s[0] DO
  397. IF CRT.ignoreCase THEN s[i] := CAP(s[i]) END;
  398. Sets.Incl(set, ORD(s[i])); INC(i)
  399. END;
  400. ELSIF (sym = 24) THEN
  401. SingleChar(n1);
  402. Sets.Incl(set, n1);
  403. IF (sym = 22) THEN
  404. Get;
  405. SingleChar(n2);
  406. FOR i := n1 TO n2 DO Sets.Incl(set, i) END;
  407. END;
  408. ELSIF (sym = 23) THEN
  409. Get;
  410. FOR i := 0 TO 255 DO Sets.Incl(set, i) END;
  411. ELSE SynError(48);
  412. END;
  413. END SimSet;
  414. PROCEDURE Set (VAR set: CRT.Set);
  415. VAR
  416. set2: CRT.Set;
  417. BEGIN
  418. SimSet(set);
  419. WHILE (sym = 20) OR (sym = 21) DO
  420. IF (sym = 20) THEN
  421. Get;
  422. SimSet(set2);
  423. Sets.Unite(set, set2);
  424. ELSE
  425. Get;
  426. SimSet(set2);
  427. Sets.Differ(set, set2);
  428. END;
  429. END;
  430. END Set;
  431. PROCEDURE TokenExpr (VAR gL, gR: INTEGER);
  432. VAR
  433. gL2, gR2: INTEGER;
  434. first: BOOLEAN;
  435. BEGIN
  436. TokenTerm(gL, gR);
  437. first := TRUE;
  438. WHILE WeakSeparator(27, 3, 4) DO
  439. TokenTerm(gL2, gR2);
  440. IF first THEN
  441. CRT.MakeFirstAlt(gL, gR); first := FALSE
  442. END;
  443. CRT.ConcatAlt(gL, gR, gL2, gR2);
  444. END;
  445. END TokenExpr;
  446. PROCEDURE NameDecl;
  447. VAR
  448. name, str: CRT.Name;
  449. BEGIN
  450. Ident(name);
  451. Expect(7);
  452. IF (sym = 1) THEN
  453. Get;
  454. CRS.GetName(CRS.pos, CRS.len, str);
  455. ELSIF (sym = 2) THEN
  456. Get;
  457. CRS.GetName(CRS.pos, CRS.len, str);
  458. FixString(str, CRS.len);
  459. ELSE SynError(49);
  460. END;
  461. CRT.NewName(name, str);
  462. Expect(8);
  463. END NameDecl;
  464. PROCEDURE TokenDecl (typ: INTEGER);
  465. VAR
  466. kind: INTEGER;
  467. name: CRT.Name;
  468. pos: CRT.Position;
  469. sp, gL, gR: INTEGER;
  470. sn: CRT.SymbolNode;
  471. BEGIN
  472. Symbol(name, kind);
  473. IF CRT.FindSym(name) # CRT.noSym THEN SemError(107)
  474. ELSE
  475. sp := CRT.NewSym(typ, name, CRS.line);
  476. CRT.GetSym(sp, sn); sn.struct := CRT.classToken;
  477. CRT.PutSym(sp, sn)
  478. END;
  479. WHILE ~ ( In(symSet[5], sym)) DO SynError(50); Get END;
  480. IF (sym = 7) THEN
  481. Get;
  482. TokenExpr(gL, gR);
  483. IF kind # ident THEN SemError(113) END;
  484. CRT.CompleteGraph(gR);
  485. CRA.ConvertToStates(gL, sp);
  486. Expect(8);
  487. ELSIF In(symSet[6], sym) THEN
  488. IF kind = ident THEN CRT.genScanner := FALSE
  489. ELSE MatchLiteral(sp)
  490. END;
  491. ELSE SynError(51);
  492. END;
  493. IF (sym = 39) THEN
  494. SemText(pos);
  495. IF typ = CRT.t THEN SemError(114) END;
  496. CRT.GetSym(sp, sn); sn.semPos := pos;
  497. CRT.PutSym(sp, sn);
  498. END;
  499. END TokenDecl;
  500. PROCEDURE SetDecl;
  501. VAR
  502. c: INTEGER;
  503. set: CRT.Set;
  504. name: CRT.Name;
  505. BEGIN
  506. Ident(name);
  507. c := CRT.ClassWithName(name);
  508. IF c >= 0 THEN SemError(107) END;
  509. Expect(7);
  510. Set(set);
  511. IF Sets.Empty(set) THEN SemError(101) END;
  512. c := CRT.NewClass(name, set);
  513. Expect(8);
  514. END SetDecl;
  515. PROCEDURE Expression (VAR gL, gR: INTEGER);
  516. VAR
  517. gL2, gR2: INTEGER;
  518. first: BOOLEAN;
  519. BEGIN
  520. Term(gL, gR);
  521. first := TRUE;
  522. WHILE WeakSeparator(27, 1, 7) DO
  523. Term(gL2, gR2);
  524. IF first THEN
  525. CRT.MakeFirstAlt(gL, gR); first := FALSE
  526. END;
  527. CRT.ConcatAlt(gL, gR, gL2, gR2);
  528. END;
  529. END Expression;
  530. PROCEDURE SemText (VAR semPos: CRT.Position);
  531. BEGIN
  532. Expect(39);
  533. semPos.beg := CRS.pos + FileIO.Long2; semPos.col := CRS.col + 2;
  534. WHILE In(symSet[8], sym) DO
  535. IF In(symSet[9], sym) THEN
  536. Get;
  537. ELSIF (sym = 3) THEN
  538. Get;
  539. SemError(102);
  540. ELSE
  541. Get;
  542. SemError(109);
  543. END;
  544. END;
  545. Expect(40);
  546. IF CRS.pos - semPos.beg > FileIO.INT(CRT.maxSemLen) THEN SemError(128) END;
  547. semPos.len := FileIO.ORDL(CRS.pos - semPos.beg);
  548. END SemText;
  549. PROCEDURE Attribs (VAR attrPos: CRT.Position);
  550. BEGIN
  551. IF (sym = 35) THEN
  552. Get;
  553. attrPos.beg := CRS.pos + FileIO.Long1; attrPos.col := CRS.col + 1;
  554. WHILE In(symSet[10], sym) DO
  555. IF In(symSet[11], sym) THEN
  556. Get;
  557. ELSE
  558. Get;
  559. SemError(102);
  560. END;
  561. END;
  562. Expect(36);
  563. attrPos.len := FileIO.INTL(CRS.pos - attrPos.beg);
  564. ELSIF (sym = 37) THEN
  565. Get;
  566. attrPos.beg := CRS.pos + FileIO.Long2; attrPos.col := CRS.col + 2;
  567. WHILE In(symSet[12], sym) DO
  568. IF In(symSet[13], sym) THEN
  569. Get;
  570. ELSE
  571. Get;
  572. SemError(102);
  573. END;
  574. END;
  575. Expect(38);
  576. attrPos.len := FileIO.INTL(CRS.pos - attrPos.beg);
  577. ELSE SynError(52);
  578. END;
  579. END Attribs;
  580. PROCEDURE Declaration (VAR startedDFA: BOOLEAN);
  581. VAR
  582. gL1, gR1, gL2, gR2: INTEGER;
  583. nested: BOOLEAN;
  584. BEGIN
  585. CASE sym OF
  586. 10 :
  587. Get;
  588. WHILE (sym = 1) DO
  589. SetDecl;
  590. END;
  591. | 11 :
  592. Get;
  593. WHILE (sym = 1) OR (sym = 2) DO
  594. TokenDecl(CRT.t);
  595. END;
  596. | 12 :
  597. Get;
  598. WHILE (sym = 1) DO
  599. NameDecl;
  600. END;
  601. | 13 :
  602. Get;
  603. WHILE (sym = 1) OR (sym = 2) DO
  604. TokenDecl(CRT.pr);
  605. END;
  606. | 14 :
  607. Get;
  608. Expect(15);
  609. TokenExpr(gL1, gR1);
  610. Expect(16);
  611. TokenExpr(gL2, gR2);
  612. IF (sym = 17) THEN
  613. Get;
  614. nested := TRUE;
  615. ELSIF In(symSet[14], sym) THEN
  616. nested := FALSE;
  617. ELSE SynError(53);
  618. END;
  619. CRA.NewComment(gL1, gL2, nested);
  620. | 18 :
  621. Get;
  622. IF (sym = 19) THEN
  623. Get;
  624. IF startedDFA THEN SemError(130) END;
  625. CRT.ignoreCase := TRUE;
  626. ELSIF (sym = 1) OR (sym = 2) OR (sym = 23) OR (sym = 24) THEN
  627. Set(CRT.ignored);
  628. IF Sets.In(CRT.ignored, 0) THEN SemError(119) END;;
  629. ELSE SynError(54);
  630. END;
  631. ELSE SynError(55);
  632. END;
  633. startedDFA := TRUE;
  634. END Declaration;
  635. PROCEDURE Ident (VAR name: CRT.Name);
  636. BEGIN
  637. Expect(1);
  638. CRS.GetName(CRS.pos, CRS.len, name);
  639. END Ident;
  640. PROCEDURE CR;
  641. VAR
  642. startedDFA, ok, undef, hasAttrs: BOOLEAN;
  643. unknownSy,
  644. eofSy, gR: INTEGER;
  645. gramLine, sp: INTEGER;
  646. name, gramName: CRT.Name;
  647. sn: CRT.SymbolNode;
  648. BEGIN
  649. Expect(5);
  650. gramLine := CRS.line;
  651. eofSy := CRT.NewSym(CRT.t, "EOF", 0);
  652. CRT.genScanner := TRUE; CRT.ignoreCase := FALSE;
  653. Sets.Clear(CRT.ignored);
  654. startedDFA := FALSE;;
  655. Ident(gramName);
  656. CRT.semDeclPos.beg := CRS.nextPos;
  657. WHILE In(symSet[15], sym) DO
  658. Get;
  659. END;
  660. CRT.semDeclPos.len := FileIO.INTL(CRS.nextPos - CRT.semDeclPos.beg);
  661. CRT.semDeclPos.col := 0;
  662. WHILE In(symSet[16], sym) DO
  663. Declaration(startedDFA);
  664. END;
  665. WHILE ~ ( (sym = 0) OR (sym = 6)) DO SynError(56); Get END;
  666. Expect(6);
  667. ok := Successful();
  668. IF ok & CRT.genScanner THEN CRA.MakeDeterministic(ok) END;
  669. IF ~ ok THEN SemError(127) END;
  670. CRT.nNodes := 0;
  671. WHILE (sym = 1) DO
  672. Ident(name);
  673. sp := CRT.FindSym(name); undef := sp = CRT.noSym;
  674. IF undef THEN
  675. sp := CRT.NewSym(CRT.nt, name, CRS.line);
  676. CRT.GetSym(sp, sn);
  677. ELSE
  678. CRT.GetSym(sp, sn);
  679. IF sn.typ = CRT.nt THEN
  680. IF sn.struct > 0 THEN SemError(107) END
  681. ELSE SemError(108)
  682. END;
  683. sn.line := CRS.line
  684. END;
  685. hasAttrs := sn.attrPos.beg >= FileIO.Long0;
  686. IF (sym = 35) OR (sym = 37) THEN
  687. Attribs(sn.attrPos);
  688. IF ~ undef & ~ hasAttrs THEN SemError(105) END;
  689. CRT.PutSym(sp, sn);
  690. ELSIF (sym = 7) OR (sym = 39) THEN
  691. IF ~ undef & hasAttrs THEN SemError(105) END;
  692. ELSE SynError(57);
  693. END;
  694. IF (sym = 39) THEN
  695. SemText(sn.semPos);
  696. END;
  697. ExpectWeak(7, 17);
  698. Expression(sn.struct, gR);
  699. CRT.CompleteGraph(gR); CRT.PutSym(sp, sn);
  700. ExpectWeak(8, 18);
  701. END;
  702. Expect(9);
  703. Ident(name);
  704. sp := CRT.FindSym(gramName);
  705. IF sp = CRT.noSym THEN SemError(111);
  706. ELSE
  707. CRT.GetSym(sp, sn);
  708. IF sn.attrPos.beg >= FileIO.Long0 THEN SemError(112) END;
  709. CRT.root := CRT.NewNode(CRT.nt, sp, gramLine);
  710. END;
  711. IF FileIO.Compare(name, gramName) # 0 THEN
  712. SemError(117)
  713. END;
  714. Expect(8);
  715. unknownSy := CRT.NewSym(CRT.t, "not", 0);
  716. END CR;
  717. PROCEDURE Parse;
  718. BEGIN
  719. CRS.Reset; Get;
  720. CR;
  721. END Parse;
  722. BEGIN
  723. errDist := minErrDist;
  724. symSet[ 0, 0] := BITSET{0, 1, 2, 6, 7, 10, 11, 12, 13, 14};
  725. symSet[ 0, 1] := BITSET{2};
  726. symSet[ 0, 2] := BITSET{7};
  727. symSet[ 1, 0] := BITSET{1, 2, 8};
  728. symSet[ 1, 1] := BITSET{7, 9, 10, 11, 12, 13, 14, 15};
  729. symSet[ 1, 2] := BITSET{0, 1, 7};
  730. symSet[ 2, 0] := BITSET{1, 2};
  731. symSet[ 2, 1] := BITSET{7, 9, 12, 13, 15};
  732. symSet[ 2, 2] := BITSET{1, 7};
  733. symSet[ 3, 0] := BITSET{1, 2};
  734. symSet[ 3, 1] := BITSET{9, 13, 15};
  735. symSet[ 3, 2] := BITSET{};
  736. symSet[ 4, 0] := BITSET{6, 8, 10, 11, 12, 13, 14};
  737. symSet[ 4, 1] := BITSET{0, 1, 2, 10, 14};
  738. symSet[ 4, 2] := BITSET{0};
  739. symSet[ 5, 0] := BITSET{0, 1, 2, 6, 7, 10, 11, 12, 13, 14};
  740. symSet[ 5, 1] := BITSET{2};
  741. symSet[ 5, 2] := BITSET{7};
  742. symSet[ 6, 0] := BITSET{1, 2, 6, 10, 11, 12, 13, 14};
  743. symSet[ 6, 1] := BITSET{2};
  744. symSet[ 6, 2] := BITSET{7};
  745. symSet[ 7, 0] := BITSET{8};
  746. symSet[ 7, 1] := BITSET{10, 14};
  747. symSet[ 7, 2] := BITSET{0};
  748. symSet[ 8, 0] := BITSET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  749. symSet[ 8, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  750. symSet[ 8, 2] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 9};
  751. symSet[ 9, 0] := BITSET{1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  752. symSet[ 9, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  753. symSet[ 9, 2] := BITSET{0, 1, 2, 3, 4, 5, 6, 9};
  754. symSet[10, 0] := BITSET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  755. symSet[10, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  756. symSet[10, 2] := BITSET{0, 1, 2, 3, 5, 6, 7, 8, 9};
  757. symSet[11, 0] := BITSET{1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  758. symSet[11, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  759. symSet[11, 2] := BITSET{0, 1, 2, 3, 5, 6, 7, 8, 9};
  760. symSet[12, 0] := BITSET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  761. symSet[12, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  762. symSet[12, 2] := BITSET{0, 1, 2, 3, 4, 5, 7, 8, 9};
  763. symSet[13, 0] := BITSET{1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  764. symSet[13, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  765. symSet[13, 2] := BITSET{0, 1, 2, 3, 4, 5, 7, 8, 9};
  766. symSet[14, 0] := BITSET{6, 10, 11, 12, 13, 14};
  767. symSet[14, 1] := BITSET{2};
  768. symSet[14, 2] := BITSET{};
  769. symSet[15, 0] := BITSET{1, 2, 3, 4, 5, 7, 8, 9, 15};
  770. symSet[15, 1] := BITSET{0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  771. symSet[15, 2] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  772. symSet[16, 0] := BITSET{10, 11, 12, 13, 14};
  773. symSet[16, 1] := BITSET{2};
  774. symSet[16, 2] := BITSET{};
  775. symSet[17, 0] := BITSET{0, 1, 2, 6, 7, 8, 10, 11, 12, 13, 14};
  776. symSet[17, 1] := BITSET{2, 7, 9, 11, 12, 13, 15};
  777. symSet[17, 2] := BITSET{1, 7};
  778. symSet[18, 0] := BITSET{0, 1, 2, 6, 7, 9, 10, 11, 12, 13, 14};
  779. symSet[18, 1] := BITSET{2};
  780. symSet[18, 2] := BITSET{7};
  781. END CRP.