CR.atg 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. $LSC (*$ACFGILMOSXN*)
  2. (* COCO/R for MS-DOS grammar used to generate COCO/R itself
  3. as adapted by P.D. Terry, January 1992
  4. version 1.50 last modified Sat 11-13-99 *)
  5. COMPILER CR
  6. (*---------------------- semantic declarations -----------------------*)
  7. IMPORT CRT, CRA, Sets;
  8. CONST
  9. ident = 0; string = 1; (* symbol kind *)
  10. TYPE
  11. INT32 = FileIO.INT32;
  12. PROCEDURE FixString (VAR name: ARRAY OF CHAR; len: CARDINAL);
  13. VAR
  14. double, spaces: BOOLEAN;
  15. i: CARDINAL;
  16. BEGIN
  17. IF len = 2 THEN SemError(129); RETURN END;
  18. IF CRT.ignoreCase THEN (* force uppercase *)
  19. FOR i := 1 TO len - 2 DO name[i] := CAP(name[i]) END
  20. END;
  21. double := FALSE; spaces := FALSE;
  22. FOR i := 1 TO len - 2 DO (* search for interior " or spaces *)
  23. IF name[i] = '"' THEN double := TRUE END;
  24. IF name[i] <= ' ' THEN spaces := TRUE END;
  25. END;
  26. IF ~ double THEN (* force delimiters to be " quotes *)
  27. name[0] := '"'; name[len-1] := '"'
  28. END;
  29. IF spaces THEN SemError(124) END;
  30. END FixString;
  31. PROCEDURE MatchLiteral (sp: INTEGER);
  32. (* store string either as token or as literal *)
  33. VAR
  34. sn, sn1: CRT.SymbolNode;
  35. matchedSp: INTEGER;
  36. BEGIN
  37. CRT.GetSym(sp, sn);
  38. CRA.MatchDFA(sn.name, sp, matchedSp);
  39. IF matchedSp # CRT.noSym THEN
  40. CRT.GetSym(matchedSp, sn1);
  41. sn1.struct := CRT.classLitToken;
  42. CRT.PutSym(matchedSp, sn1);
  43. sn.struct := CRT.litToken
  44. ELSE sn.struct := CRT.classToken;
  45. END;
  46. CRT.PutSym(sp, sn)
  47. END MatchLiteral;
  48. PROCEDURE SetCtx (gp: INTEGER);
  49. (* set transition code to CRT.contextTrans *)
  50. VAR
  51. gn: CRT.GraphNode;
  52. BEGIN
  53. WHILE gp > 0 DO
  54. CRT.GetNode(gp, gn);
  55. IF (gn.typ = CRT.char) OR (gn.typ = CRT.class) THEN
  56. gn.p2 := CRT.contextTrans; CRT.PutNode(gp, gn)
  57. ELSIF (gn.typ = CRT.opt) OR (gn.typ = CRT.iter) THEN SetCtx(gn.p1)
  58. ELSIF gn.typ = CRT.alt THEN SetCtx(gn.p1); SetCtx(gn.p2)
  59. END;
  60. gp := gn.next
  61. END
  62. END SetCtx;
  63. PROCEDURE SetOption (s: ARRAY OF CHAR);
  64. VAR
  65. i: CARDINAL;
  66. BEGIN
  67. i := 1;
  68. WHILE s[i] # 0C DO
  69. s[i] := CAP(s[i]);
  70. IF (s[i] >= "A") AND (s[i] <= "Z") THEN CRT.ddt[s[i]] := TRUE END;
  71. INC(i);
  72. END;
  73. END SetOption;
  74. (*--------------------------------------------------------------------*)
  75. CHARACTERS
  76. letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_".
  77. digit = "0123456789".
  78. ctrl = CHR(1) .. CHR(31).
  79. tab = CHR(9).
  80. eol = CHR(13).
  81. lf = CHR(10).
  82. noQuote1 = ANY - '"' - ctrl.
  83. noQuote2 = ANY - "'" - ctrl.
  84. IGNORE tab + eol + lf
  85. TOKENS
  86. ident = letter {letter | digit}.
  87. string = '"' {noQuote1} '"' | "'" {noQuote2} "'".
  88. badstring = '"' {noQuote1} (eol | lf) | "'" {noQuote2} (eol | lf).
  89. number = digit {digit}.
  90. PRAGMAS
  91. Options = "$" {letter | digit} .
  92. (.CRS.GetName(CRS.nextPos, CRS.nextLen, s); SetOption(s); .)
  93. COMMENTS FROM "(*" TO "*)" NESTED
  94. COMMENTS FROM "/*" TO "*/"
  95. PRODUCTIONS
  96. CR (. VAR
  97. startedDFA, ok, undef, hasAttrs: BOOLEAN;
  98. unknownSy,
  99. eofSy, gR: INTEGER;
  100. gramLine, sp: INTEGER;
  101. name, gramName: CRT.Name;
  102. sn: CRT.SymbolNode; .)
  103. =
  104. "COMPILER"
  105. (. gramLine := CRS.line;
  106. eofSy := CRT.NewSym(CRT.t, "EOF", 0);
  107. CRT.genScanner := TRUE; CRT.ignoreCase := FALSE;
  108. Sets.Clear(CRT.ignored);
  109. startedDFA := FALSE; .)
  110. Ident <gramName> (. CRT.semDeclPos.beg := CRS.nextPos .)
  111. { ANY } (. CRT.semDeclPos.len := FileIO.INTL(CRS.nextPos - CRT.semDeclPos.beg);
  112. CRT.semDeclPos.col := 0 .)
  113. { Declaration<startedDFA> }
  114. SYNC
  115. "PRODUCTIONS" (. ok := Successful();
  116. IF ok & CRT.genScanner THEN CRA.MakeDeterministic(ok) END;
  117. IF ~ ok THEN SemError(127) END;
  118. CRT.nNodes := 0 .)
  119. { Ident <name> (. sp := CRT.FindSym(name); undef := sp = CRT.noSym;
  120. IF undef THEN
  121. sp := CRT.NewSym(CRT.nt, name, CRS.line);
  122. CRT.GetSym(sp, sn);
  123. ELSE
  124. CRT.GetSym(sp, sn);
  125. IF sn.typ = CRT.nt THEN
  126. IF sn.struct > 0 THEN SemError(107) END
  127. ELSE SemError(108)
  128. END;
  129. sn.line := CRS.line
  130. END;
  131. hasAttrs := sn.attrPos.beg >= FileIO.Long0 .)
  132. ( Attribs <sn.attrPos> (. IF ~ undef & ~ hasAttrs THEN SemError(105) END;
  133. CRT.PutSym(sp, sn) .)
  134. | (. IF ~ undef & hasAttrs THEN SemError(105) END .)
  135. )
  136. [ SemText <sn.semPos>]
  137. WEAK "="
  138. Expression <sn.struct, gR> (. CRT.CompleteGraph(gR); CRT.PutSym(sp, sn) .)
  139. WEAK "."
  140. }
  141. "END" Ident <name> (. sp := CRT.FindSym(gramName);
  142. IF sp = CRT.noSym THEN SemError(111);
  143. ELSE
  144. CRT.GetSym(sp, sn);
  145. IF sn.attrPos.beg >= FileIO.Long0 THEN SemError(112) END;
  146. CRT.root := CRT.NewNode(CRT.nt, sp, gramLine);
  147. END;
  148. IF FileIO.Compare(name, gramName) # 0 THEN
  149. SemError(117)
  150. END .)
  151. "." (. unknownSy := CRT.NewSym(CRT.t, "not", 0) .)
  152. .
  153. (*----------------------------------------------------------------------------*)
  154. Declaration<VAR startedDFA: BOOLEAN>
  155. (. VAR
  156. gL1, gR1, gL2, gR2: INTEGER;
  157. nested: BOOLEAN; .)
  158. = (
  159. "CHARACTERS" { SetDecl }
  160. | "TOKENS" { TokenDecl <CRT.t> }
  161. | "NAMES" { NameDecl }
  162. | "PRAGMAS" { TokenDecl <CRT.pr> }
  163. | "COMMENTS"
  164. "FROM" TokenExpr <gL1, gR1>
  165. "TO" TokenExpr <gL2, gR2>
  166. ( "NESTED" (. nested := TRUE .)
  167. | (. nested := FALSE .)
  168. )
  169. (. CRA.NewComment(gL1, gL2, nested) .)
  170. | "IGNORE"
  171. ( "CASE" (. IF startedDFA THEN SemError(130) END;
  172. CRT.ignoreCase := TRUE .)
  173. | Set <CRT.ignored> (. IF Sets.In(CRT.ignored, 0) THEN SemError(119) END; .)
  174. )
  175. ) (. startedDFA := TRUE .)
  176. .
  177. (*----------------------------------------------------------------------------*)
  178. SetDecl (. VAR
  179. c: INTEGER;
  180. set: CRT.Set;
  181. name: CRT.Name; .)
  182. = Ident <name> (. c := CRT.ClassWithName(name);
  183. IF c >= 0 THEN SemError(107) END .)
  184. "=" Set <set> (. IF Sets.Empty(set) THEN SemError(101) END;
  185. c := CRT.NewClass(name, set) .)
  186. ".".
  187. (*----------------------------------------------------------------------------*)
  188. Set <VAR set: CRT.Set> (. VAR
  189. set2: CRT.Set; .)
  190. = SimSet <set>
  191. { "+" SimSet <set2> (. Sets.Unite(set, set2) .)
  192. | "-" SimSet <set2> (. Sets.Differ(set, set2) .)
  193. }.
  194. (*----------------------------------------------------------------------------*)
  195. SimSet <VAR set: CRT.Set> (. VAR
  196. i, n1, n2: CARDINAL;
  197. c: INTEGER;
  198. name: CRT.Name;
  199. s: ARRAY [0 .. 127] OF CHAR; .)
  200. = (. Sets.Clear(set) .)
  201. ( Ident <name> (. c := CRT.ClassWithName(name);
  202. IF c < 0
  203. THEN SemError(115)
  204. ELSE CRT.GetClass(c, set)
  205. END .)
  206. | string (. CRS.GetName(CRS.pos, CRS.len, s);
  207. i := 1;
  208. WHILE s[i] # s[0] DO
  209. IF CRT.ignoreCase THEN s[i] := CAP(s[i]) END;
  210. Sets.Incl(set, ORD(s[i])); INC(i)
  211. END .)
  212. | SingleChar <n1> (. Sets.Incl(set, n1) .)
  213. [ ".." SingleChar <n2> (. FOR i := n1 TO n2 DO Sets.Incl(set, i) END .)
  214. ]
  215. | "ANY" (. FOR i := 0 TO 255 DO Sets.Incl(set, i) END .)
  216. ) .
  217. (*----------------------------------------------------------------------------*)
  218. SingleChar <VAR n: CARDINAL> (. VAR
  219. i: CARDINAL;
  220. s: ARRAY [0 .. 127] OF CHAR; .)
  221. =
  222. "CHR" "("
  223. ( number (. CRS.GetName(CRS.pos, CRS.len, s);
  224. n := 0; i := 0;
  225. WHILE s[i] # 0C DO
  226. n := 10 * n + ORD(s[i]) - ORD("0"); INC(i)
  227. END;
  228. IF n > 255 THEN SemError(118); n := n MOD 256 END;
  229. IF CRT.ignoreCase THEN n := ORD(CAP(CHR(n))) END .)
  230. | string (. CRS.GetName(CRS.pos, CRS.len, s);
  231. IF CRS.len # 3 THEN SemError(118) END;
  232. IF CRT.ignoreCase THEN s[1] := CAP(s[1]) END;
  233. n := ORD(s[1]); .)
  234. )
  235. ")" .
  236. (*----------------------------------------------------------------------------*)
  237. TokenDecl <typ: INTEGER> (. VAR
  238. kind: INTEGER;
  239. name: CRT.Name;
  240. pos: CRT.Position;
  241. sp, gL, gR: INTEGER;
  242. sn: CRT.SymbolNode; .)
  243. = Symbol <name, kind> (. IF CRT.FindSym(name) # CRT.noSym THEN SemError(107)
  244. ELSE
  245. sp := CRT.NewSym(typ, name, CRS.line);
  246. CRT.GetSym(sp, sn); sn.struct := CRT.classToken;
  247. CRT.PutSym(sp, sn)
  248. END .)
  249. SYNC
  250. ( "="
  251. TokenExpr <gL, gR> (. IF kind # ident THEN SemError(113) END;
  252. CRT.CompleteGraph(gR);
  253. CRA.ConvertToStates(gL, sp) .)
  254. "."
  255. | (. IF kind = ident THEN CRT.genScanner := FALSE
  256. ELSE MatchLiteral(sp)
  257. END .)
  258. )
  259. [ SemText <pos> (. IF typ = CRT.t THEN SemError(114) END;
  260. CRT.GetSym(sp, sn); sn.semPos := pos;
  261. CRT.PutSym(sp, sn) .)
  262. ].
  263. (*----------------------------------------------------------------------------*)
  264. Expression <VAR gL, gR: INTEGER>
  265. (. VAR
  266. gL2, gR2: INTEGER;
  267. first: BOOLEAN; .)
  268. = Term <gL, gR> (. first := TRUE .)
  269. { WEAK "|"
  270. Term <gL2, gR2> (. IF first THEN
  271. CRT.MakeFirstAlt(gL, gR); first := FALSE
  272. END;
  273. CRT.ConcatAlt(gL, gR, gL2, gR2) .)
  274. }
  275. .
  276. (*----------------------------------------------------------------------------*)
  277. Term<VAR gL, gR: INTEGER> (. VAR
  278. gL2, gR2: INTEGER; .)
  279. = (. gL := 0; gR := 0 .)
  280. ( Factor <gL, gR>
  281. { Factor <gL2, gR2> (. CRT.ConcatSeq(gL, gR, gL2, gR2) .)
  282. }
  283. | (. gL := CRT.NewNode(CRT.eps, 0, 0); gR := gL .)
  284. ).
  285. (*----------------------------------------------------------------------------*)
  286. Factor <VAR gL, gR: INTEGER> (. VAR
  287. sp, kind: INTEGER;
  288. name: CRT.Name;
  289. gn: CRT.GraphNode;
  290. sn: CRT.SymbolNode;
  291. set: CRT.Set;
  292. undef, weak: BOOLEAN;
  293. pos: CRT.Position; .)
  294. = (. gL :=0; gR := 0; weak := FALSE .)
  295. ( [ "WEAK" (. weak := TRUE .)
  296. ]
  297. Symbol <name, kind> (. sp := CRT.FindSym(name); undef := sp = CRT.noSym;
  298. IF undef THEN
  299. IF kind = ident THEN (* forward nt *)
  300. sp := CRT.NewSym(CRT.nt, name, 0)
  301. ELSIF CRT.genScanner THEN
  302. sp := CRT.NewSym(CRT.t, name, CRS.line);
  303. MatchLiteral(sp)
  304. ELSE (* undefined string in production *)
  305. SemError(106); sp := 0
  306. END
  307. END;
  308. CRT.GetSym(sp, sn);
  309. IF (sn.typ # CRT.t) & (sn.typ # CRT.nt) THEN SemError(104) END;
  310. IF weak THEN
  311. IF sn.typ = CRT.t THEN sn.typ := CRT.wt
  312. ELSE SemError(123)
  313. END
  314. END;
  315. gL := CRT.NewNode(sn.typ, sp, CRS.line); gR := gL .)
  316. ( Attribs <pos> (. CRT.GetNode(gL, gn); gn.pos := pos;
  317. CRT.PutNode(gL, gn);
  318. CRT.GetSym(sp, sn);
  319. IF sn.typ # CRT.nt THEN SemError(103) END;
  320. IF undef THEN
  321. sn.attrPos := pos; CRT.PutSym(sp, sn)
  322. ELSIF sn.attrPos.beg < FileIO.Long0 THEN SemError(105)
  323. END .)
  324. | (. CRT.GetSym(sp, sn);
  325. IF sn.attrPos.beg >= FileIO.Long0 THEN SemError(105) END .)
  326. )
  327. | "(" Expression <gL, gR> ")"
  328. | "[" Expression <gL, gR> "]" (. CRT.MakeOption(gL, gR) .)
  329. | "{" Expression <gL, gR> "}" (. CRT.MakeIteration(gL, gR) .)
  330. | SemText <pos> (. gL := CRT.NewNode(CRT.sem, 0, 0); gR := gL;
  331. CRT.GetNode(gL, gn);
  332. gn.pos := pos;
  333. CRT.PutNode(gL, gn) .)
  334. | "ANY" (. Sets.Fill(set); Sets.Excl(set, CRT.eofSy);
  335. gL := CRT.NewNode(CRT.any, CRT.NewSet(set), 0); gR := gL .)
  336. | "SYNC" (. gL := CRT.NewNode(CRT.sync, 0, 0); gR := gL .)
  337. ).
  338. (*----------------------------------------------------------------------------*)
  339. TokenExpr <VAR gL, gR: INTEGER>
  340. (. VAR
  341. gL2, gR2: INTEGER;
  342. first: BOOLEAN; .)
  343. = TokenTerm <gL, gR> (. first := TRUE .)
  344. { WEAK "|"
  345. TokenTerm <gL2, gR2> (. IF first THEN
  346. CRT.MakeFirstAlt(gL, gR); first := FALSE
  347. END;
  348. CRT.ConcatAlt(gL, gR, gL2, gR2) .)
  349. }.
  350. (*----------------------------------------------------------------------------*)
  351. TokenTerm <VAR gL, gR: INTEGER>
  352. (. VAR
  353. gL2, gR2: INTEGER; .)
  354. = TokenFactor <gL, gR>
  355. { TokenFactor <gL2, gR2> (. CRT.ConcatSeq(gL, gR, gL2, gR2) .)
  356. }
  357. [ "CONTEXT"
  358. "(" TokenExpr <gL2, gR2> (. SetCtx(gL2); CRT.ConcatSeq(gL, gR, gL2, gR2) .)
  359. ")"
  360. ].
  361. (*----------------------------------------------------------------------------*)
  362. TokenFactor <VAR gL, gR: INTEGER>
  363. (.VAR
  364. kind, c: INTEGER;
  365. set: CRT.Set;
  366. name: CRT.Name; .)
  367. = (. gL :=0; gR := 0 .)
  368. ( Symbol <name, kind> (. IF kind = ident THEN
  369. c := CRT.ClassWithName(name);
  370. IF c < 0 THEN
  371. SemError(115);
  372. Sets.Clear(set); c := CRT.NewClass(name, set)
  373. END;
  374. gL := CRT.NewNode(CRT.class, c, 0); gR := gL
  375. ELSE (* string *)
  376. CRT.StrToGraph(name, gL, gR)
  377. END .)
  378. | "(" TokenExpr <gL, gR> ")"
  379. | "[" TokenExpr <gL, gR> "]" (. CRT.MakeOption(gL, gR) .)
  380. | "{" TokenExpr <gL, gR> "}" (. CRT.MakeIteration(gL, gR) .)
  381. ).
  382. (*----------------------------------------------------------------------------*)
  383. Ident <VAR name: CRT.Name> =
  384. ident (. CRS.GetName(CRS.pos, CRS.len, name) .).
  385. (*----------------------------------------------------------------------------*)
  386. Symbol <VAR name: CRT.Name; VAR kind: INTEGER>
  387. =
  388. ( Ident <name> (. kind := ident .)
  389. | string (. CRS.GetName(CRS.pos, CRS.len, name); kind := string;
  390. FixString(name, CRS.len) .)
  391. ).
  392. (*----------------------------------------------------------------------------*)
  393. Attribs <VAR attrPos: CRT.Position> =
  394. "<" (. attrPos.beg := CRS.pos + FileIO.Long1; attrPos.col := CRS.col + 1 .)
  395. { ANY | badstring (. SemError(102) .)
  396. }
  397. ">" (. attrPos.len := FileIO.INTL(CRS.pos - attrPos.beg) .)
  398. |
  399. "<." (. attrPos.beg := CRS.pos + FileIO.Long2; attrPos.col := CRS.col + 2 .)
  400. { ANY | badstring (. SemError(102) .)
  401. }
  402. ".>" (. attrPos.len := FileIO.INTL(CRS.pos - attrPos.beg) .).
  403. (*----------------------------------------------------------------------------*)
  404. SemText <VAR semPos: CRT.Position> =
  405. "(." (. semPos.beg := CRS.pos + FileIO.Long2; semPos.col := CRS.col + 2 .)
  406. { ANY
  407. | badstring (. SemError(102) .)
  408. | "(." (. SemError(109) .)
  409. }
  410. ".)" (. IF CRS.pos - semPos.beg > FileIO.INT(CRT.maxSemLen) THEN SemError(128) END;
  411. semPos.len := FileIO.ORDL(CRS.pos - semPos.beg) .).
  412. (*----------------------------------------------------------------------------*)
  413. NameDecl (. VAR
  414. name, str: CRT.Name; .)
  415. = Ident <name> "="
  416. ( ident (. CRS.GetName(CRS.pos, CRS.len, str) .)
  417. | string (. CRS.GetName(CRS.pos, CRS.len, str);
  418. FixString(str, CRS.len) .)
  419. ) (. CRT.NewName(name, str) .)
  420. ".".
  421. (*----------------------------------------------------------------------------*)
  422. END CR.