IMPLEMENTATION MODULE CRP; (* Parser generated by Coco/R - assuming FileIO library will be available. *) IMPORT FileIO, CRS; IMPORT CRT, CRA, Sets; CONST ident = 0; string = 1; (* symbol kind *) TYPE INT32 = FileIO.INT32; PROCEDURE FixString (VAR name: ARRAY OF CHAR; len: CARDINAL); VAR double, spaces: BOOLEAN; i: CARDINAL; BEGIN IF len = 2 THEN SemError(129); RETURN END; IF CRT.ignoreCase THEN (* force uppercase *) FOR i := 1 TO len - 2 DO name[i] := CAP(name[i]) END END; double := FALSE; spaces := FALSE; FOR i := 1 TO len - 2 DO (* search for interior " or spaces *) IF name[i] = '"' THEN double := TRUE END; IF name[i] <= ' ' THEN spaces := TRUE END; END; IF ~ double THEN (* force delimiters to be " quotes *) name[0] := '"'; name[len-1] := '"' END; IF spaces THEN SemError(124) END; END FixString; PROCEDURE MatchLiteral (sp: INTEGER); (* store string either as token or as literal *) VAR sn, sn1: CRT.SymbolNode; matchedSp: INTEGER; BEGIN CRT.GetSym(sp, sn); CRA.MatchDFA(sn.name, sp, matchedSp); IF matchedSp # CRT.noSym THEN CRT.GetSym(matchedSp, sn1); sn1.struct := CRT.classLitToken; CRT.PutSym(matchedSp, sn1); sn.struct := CRT.litToken ELSE sn.struct := CRT.classToken; END; CRT.PutSym(sp, sn) END MatchLiteral; PROCEDURE SetCtx (gp: INTEGER); (* set transition code to CRT.contextTrans *) VAR gn: CRT.GraphNode; BEGIN WHILE gp > 0 DO CRT.GetNode(gp, gn); IF (gn.typ = CRT.char) OR (gn.typ = CRT.class) THEN gn.p2 := CRT.contextTrans; CRT.PutNode(gp, gn) ELSIF (gn.typ = CRT.opt) OR (gn.typ = CRT.iter) THEN SetCtx(gn.p1) ELSIF gn.typ = CRT.alt THEN SetCtx(gn.p1); SetCtx(gn.p2) END; gp := gn.next END END SetCtx; PROCEDURE SetOption (s: ARRAY OF CHAR); VAR i: CARDINAL; BEGIN i := 1; WHILE s[i] # 0C DO s[i] := CAP(s[i]); IF (s[i] >= "A") AND (s[i] <= "Z") THEN CRT.ddt[s[i]] := TRUE END; INC(i); END; END SetOption; (*--------------------------------------------------------------------*) CONST maxT = 41; maxP = 42; minErrDist = 2; (* minimal distance (good tokens) between two errors *) setsize = 16; (* sets are stored in 16 bits *) TYPE SymbolSet = ARRAY [0 .. maxT DIV setsize] OF BITSET; VAR symSet: ARRAY [0 .. 18] OF SymbolSet; (*symSet[0] = allSyncSyms*) errDist: CARDINAL; (* number of symbols recognized since last error *) sym: CARDINAL; (* current input symbol *) PROCEDURE SemError (errNo: INTEGER); BEGIN IF errDist >= minErrDist THEN CRS.Error(errNo, CRS.line, CRS.col, CRS.pos); END; errDist := 0; END SemError; PROCEDURE SynError (errNo: INTEGER); BEGIN IF errDist >= minErrDist THEN CRS.Error(errNo, CRS.nextLine, CRS.nextCol, CRS.nextPos); END; errDist := 0; END SynError; PROCEDURE Get; VAR s: ARRAY [0 .. 31] OF CHAR; BEGIN REPEAT CRS.Get(sym); IF sym <= maxT THEN INC(errDist); ELSE CASE sym OF 42: CRS.GetName(CRS.nextPos, CRS.nextLen, s); SetOption(s); END; CRS.nextPos := CRS.pos; CRS.nextCol := CRS.col; CRS.nextLine := CRS.line; CRS.nextLen := CRS.len; END; UNTIL sym <= maxT END Get; PROCEDURE In (VAR s: SymbolSet; x: CARDINAL): BOOLEAN; BEGIN RETURN x MOD setsize IN s[x DIV setsize]; END In; PROCEDURE Expect (n: CARDINAL); BEGIN IF sym = n THEN Get ELSE SynError(n) END END Expect; PROCEDURE ExpectWeak (n, follow: CARDINAL); BEGIN IF sym = n THEN Get ELSE SynError(n); WHILE ~ In(symSet[follow], sym) DO Get END END END ExpectWeak; PROCEDURE WeakSeparator (n, syFol, repFol: CARDINAL): BOOLEAN; VAR s: SymbolSet; i: CARDINAL; BEGIN IF sym = n THEN Get; RETURN TRUE ELSIF In(symSet[repFol], sym) THEN RETURN FALSE ELSE i := 0; WHILE i <= maxT DIV setsize DO s[i] := symSet[0, i] + symSet[syFol, i] + symSet[repFol, i]; INC(i) END; SynError(n); WHILE ~ In(s, sym) DO Get END; RETURN In(symSet[syFol], sym) END END WeakSeparator; PROCEDURE LexName (VAR Lex: ARRAY OF CHAR); BEGIN CRS.GetName(CRS.pos, CRS.len, Lex) END LexName; PROCEDURE LexString (VAR Lex: ARRAY OF CHAR); BEGIN CRS.GetString(CRS.pos, CRS.len, Lex) END LexString; PROCEDURE LookAheadName (VAR Lex: ARRAY OF CHAR); BEGIN CRS.GetName(CRS.nextPos, CRS.nextLen, Lex) END LookAheadName; PROCEDURE LookAheadString (VAR Lex: ARRAY OF CHAR); BEGIN CRS.GetString(CRS.nextPos, CRS.nextLen, Lex) END LookAheadString; PROCEDURE Successful (): BOOLEAN; BEGIN RETURN CRS.errors = 0 END Successful; (* ----- FORWARD not needed in multipass compilers PROCEDURE TokenFactor (VAR gL, gR: INTEGER); FORWARD; PROCEDURE TokenTerm (VAR gL, gR: INTEGER); FORWARD; PROCEDURE Factor (VAR gL, gR: INTEGER); FORWARD; PROCEDURE Term (VAR gL, gR: INTEGER); FORWARD; PROCEDURE Symbol (VAR name: CRT.Name; VAR kind: INTEGER); FORWARD; PROCEDURE SingleChar (VAR n: CARDINAL); FORWARD; PROCEDURE SimSet (VAR set: CRT.Set); FORWARD; PROCEDURE Set (VAR set: CRT.Set); FORWARD; PROCEDURE TokenExpr (VAR gL, gR: INTEGER); FORWARD; PROCEDURE NameDecl; FORWARD; PROCEDURE TokenDecl (typ: INTEGER); FORWARD; PROCEDURE SetDecl; FORWARD; PROCEDURE Expression (VAR gL, gR: INTEGER); FORWARD; PROCEDURE SemText (VAR semPos: CRT.Position); FORWARD; PROCEDURE Attribs (VAR attrPos: CRT.Position); FORWARD; PROCEDURE Declaration (VAR startedDFA: BOOLEAN); FORWARD; PROCEDURE Ident (VAR name: CRT.Name); FORWARD; PROCEDURE CR; FORWARD; ----- *) PROCEDURE TokenFactor (VAR gL, gR: INTEGER); VAR kind, c: INTEGER; set: CRT.Set; name: CRT.Name; BEGIN gL :=0; gR := 0; IF (sym = 1) OR (sym = 2) THEN Symbol(name, kind); IF kind = ident THEN c := CRT.ClassWithName(name); IF c < 0 THEN SemError(115); Sets.Clear(set); c := CRT.NewClass(name, set) END; gL := CRT.NewNode(CRT.class, c, 0); gR := gL ELSE (* string *) CRT.StrToGraph(name, gL, gR) END; ELSIF (sym = 25) THEN Get; TokenExpr(gL, gR); Expect(26); ELSIF (sym = 29) THEN Get; TokenExpr(gL, gR); Expect(30); CRT.MakeOption(gL, gR); ELSIF (sym = 31) THEN Get; TokenExpr(gL, gR); Expect(32); CRT.MakeIteration(gL, gR); ELSE SynError(42); END; END TokenFactor; PROCEDURE TokenTerm (VAR gL, gR: INTEGER); VAR gL2, gR2: INTEGER; BEGIN TokenFactor(gL, gR); WHILE (sym = 1) OR (sym = 2) OR (sym = 25) OR (sym = 29) OR (sym = 31) DO TokenFactor(gL2, gR2); CRT.ConcatSeq(gL, gR, gL2, gR2); END; IF (sym = 34) THEN Get; Expect(25); TokenExpr(gL2, gR2); SetCtx(gL2); CRT.ConcatSeq(gL, gR, gL2, gR2); Expect(26); END; END TokenTerm; PROCEDURE Factor (VAR gL, gR: INTEGER); VAR sp, kind: INTEGER; name: CRT.Name; gn: CRT.GraphNode; sn: CRT.SymbolNode; set: CRT.Set; undef, weak: BOOLEAN; pos: CRT.Position; BEGIN gL :=0; gR := 0; weak := FALSE; CASE sym OF 1, 2, 28 : IF (sym = 28) THEN Get; weak := TRUE; END; Symbol(name, kind); sp := CRT.FindSym(name); undef := sp = CRT.noSym; IF undef THEN IF kind = ident THEN (* forward nt *) sp := CRT.NewSym(CRT.nt, name, 0) ELSIF CRT.genScanner THEN sp := CRT.NewSym(CRT.t, name, CRS.line); MatchLiteral(sp) ELSE (* undefined string in production *) SemError(106); sp := 0 END END; CRT.GetSym(sp, sn); IF (sn.typ # CRT.t) & (sn.typ # CRT.nt) THEN SemError(104) END; IF weak THEN IF sn.typ = CRT.t THEN sn.typ := CRT.wt ELSE SemError(123) END END; gL := CRT.NewNode(sn.typ, sp, CRS.line); gR := gL; IF (sym = 35) OR (sym = 37) THEN Attribs(pos); CRT.GetNode(gL, gn); gn.pos := pos; CRT.PutNode(gL, gn); CRT.GetSym(sp, sn); IF sn.typ # CRT.nt THEN SemError(103) END; IF undef THEN sn.attrPos := pos; CRT.PutSym(sp, sn) ELSIF sn.attrPos.beg < FileIO.Long0 THEN SemError(105) END; ELSIF In(symSet[1], sym) THEN CRT.GetSym(sp, sn); IF sn.attrPos.beg >= FileIO.Long0 THEN SemError(105) END; ELSE SynError(43); END; | 25 : Get; Expression(gL, gR); Expect(26); | 29 : Get; Expression(gL, gR); Expect(30); CRT.MakeOption(gL, gR); | 31 : Get; Expression(gL, gR); Expect(32); CRT.MakeIteration(gL, gR); | 39 : SemText(pos); gL := CRT.NewNode(CRT.sem, 0, 0); gR := gL; CRT.GetNode(gL, gn); gn.pos := pos; CRT.PutNode(gL, gn); | 23 : Get; Sets.Fill(set); Sets.Excl(set, CRT.eofSy); gL := CRT.NewNode(CRT.any, CRT.NewSet(set), 0); gR := gL; | 33 : Get; gL := CRT.NewNode(CRT.sync, 0, 0); gR := gL; ELSE SynError(44); END; END Factor; PROCEDURE Term (VAR gL, gR: INTEGER); VAR gL2, gR2: INTEGER; BEGIN gL := 0; gR := 0; IF In(symSet[2], sym) THEN Factor(gL, gR); WHILE In(symSet[2], sym) DO Factor(gL2, gR2); CRT.ConcatSeq(gL, gR, gL2, gR2); END; ELSIF (sym = 8) OR (sym = 26) OR (sym = 27) OR (sym = 30) OR (sym = 32) THEN gL := CRT.NewNode(CRT.eps, 0, 0); gR := gL; ELSE SynError(45); END; END Term; PROCEDURE Symbol (VAR name: CRT.Name; VAR kind: INTEGER); BEGIN IF (sym = 1) THEN Ident(name); kind := ident; ELSIF (sym = 2) THEN Get; CRS.GetName(CRS.pos, CRS.len, name); kind := string; FixString(name, CRS.len); ELSE SynError(46); END; END Symbol; PROCEDURE SingleChar (VAR n: CARDINAL); VAR i: CARDINAL; s: ARRAY [0 .. 127] OF CHAR; BEGIN Expect(24); Expect(25); IF (sym = 4) THEN Get; CRS.GetName(CRS.pos, CRS.len, s); n := 0; i := 0; WHILE s[i] # 0C DO n := 10 * n + ORD(s[i]) - ORD("0"); INC(i) END; IF n > 255 THEN SemError(118); n := n MOD 256 END; IF CRT.ignoreCase THEN n := ORD(CAP(CHR(n))) END; ELSIF (sym = 2) THEN Get; CRS.GetName(CRS.pos, CRS.len, s); IF CRS.len # 3 THEN SemError(118) END; IF CRT.ignoreCase THEN s[1] := CAP(s[1]) END; n := ORD(s[1]);; ELSE SynError(47); END; Expect(26); END SingleChar; PROCEDURE SimSet (VAR set: CRT.Set); VAR i, n1, n2: CARDINAL; c: INTEGER; name: CRT.Name; s: ARRAY [0 .. 127] OF CHAR; BEGIN Sets.Clear(set); IF (sym = 1) THEN Ident(name); c := CRT.ClassWithName(name); IF c < 0 THEN SemError(115) ELSE CRT.GetClass(c, set) END; ELSIF (sym = 2) THEN Get; CRS.GetName(CRS.pos, CRS.len, s); i := 1; WHILE s[i] # s[0] DO IF CRT.ignoreCase THEN s[i] := CAP(s[i]) END; Sets.Incl(set, ORD(s[i])); INC(i) END; ELSIF (sym = 24) THEN SingleChar(n1); Sets.Incl(set, n1); IF (sym = 22) THEN Get; SingleChar(n2); FOR i := n1 TO n2 DO Sets.Incl(set, i) END; END; ELSIF (sym = 23) THEN Get; FOR i := 0 TO 255 DO Sets.Incl(set, i) END; ELSE SynError(48); END; END SimSet; PROCEDURE Set (VAR set: CRT.Set); VAR set2: CRT.Set; BEGIN SimSet(set); WHILE (sym = 20) OR (sym = 21) DO IF (sym = 20) THEN Get; SimSet(set2); Sets.Unite(set, set2); ELSE Get; SimSet(set2); Sets.Differ(set, set2); END; END; END Set; PROCEDURE TokenExpr (VAR gL, gR: INTEGER); VAR gL2, gR2: INTEGER; first: BOOLEAN; BEGIN TokenTerm(gL, gR); first := TRUE; WHILE WeakSeparator(27, 3, 4) DO TokenTerm(gL2, gR2); IF first THEN CRT.MakeFirstAlt(gL, gR); first := FALSE END; CRT.ConcatAlt(gL, gR, gL2, gR2); END; END TokenExpr; PROCEDURE NameDecl; VAR name, str: CRT.Name; BEGIN Ident(name); Expect(7); IF (sym = 1) THEN Get; CRS.GetName(CRS.pos, CRS.len, str); ELSIF (sym = 2) THEN Get; CRS.GetName(CRS.pos, CRS.len, str); FixString(str, CRS.len); ELSE SynError(49); END; CRT.NewName(name, str); Expect(8); END NameDecl; PROCEDURE TokenDecl (typ: INTEGER); VAR kind: INTEGER; name: CRT.Name; pos: CRT.Position; sp, gL, gR: INTEGER; sn: CRT.SymbolNode; BEGIN Symbol(name, kind); IF CRT.FindSym(name) # CRT.noSym THEN SemError(107) ELSE sp := CRT.NewSym(typ, name, CRS.line); CRT.GetSym(sp, sn); sn.struct := CRT.classToken; CRT.PutSym(sp, sn) END; WHILE ~ ( In(symSet[5], sym)) DO SynError(50); Get END; IF (sym = 7) THEN Get; TokenExpr(gL, gR); IF kind # ident THEN SemError(113) END; CRT.CompleteGraph(gR); CRA.ConvertToStates(gL, sp); Expect(8); ELSIF In(symSet[6], sym) THEN IF kind = ident THEN CRT.genScanner := FALSE ELSE MatchLiteral(sp) END; ELSE SynError(51); END; IF (sym = 39) THEN SemText(pos); IF typ = CRT.t THEN SemError(114) END; CRT.GetSym(sp, sn); sn.semPos := pos; CRT.PutSym(sp, sn); END; END TokenDecl; PROCEDURE SetDecl; VAR c: INTEGER; set: CRT.Set; name: CRT.Name; BEGIN Ident(name); c := CRT.ClassWithName(name); IF c >= 0 THEN SemError(107) END; Expect(7); Set(set); IF Sets.Empty(set) THEN SemError(101) END; c := CRT.NewClass(name, set); Expect(8); END SetDecl; PROCEDURE Expression (VAR gL, gR: INTEGER); VAR gL2, gR2: INTEGER; first: BOOLEAN; BEGIN Term(gL, gR); first := TRUE; WHILE WeakSeparator(27, 1, 7) DO Term(gL2, gR2); IF first THEN CRT.MakeFirstAlt(gL, gR); first := FALSE END; CRT.ConcatAlt(gL, gR, gL2, gR2); END; END Expression; PROCEDURE SemText (VAR semPos: CRT.Position); BEGIN Expect(39); semPos.beg := CRS.pos + FileIO.Long2; semPos.col := CRS.col + 2; WHILE In(symSet[8], sym) DO IF In(symSet[9], sym) THEN Get; ELSIF (sym = 3) THEN Get; SemError(102); ELSE Get; SemError(109); END; END; Expect(40); IF CRS.pos - semPos.beg > FileIO.INT(CRT.maxSemLen) THEN SemError(128) END; semPos.len := FileIO.ORDL(CRS.pos - semPos.beg); END SemText; PROCEDURE Attribs (VAR attrPos: CRT.Position); BEGIN IF (sym = 35) THEN Get; attrPos.beg := CRS.pos + FileIO.Long1; attrPos.col := CRS.col + 1; WHILE In(symSet[10], sym) DO IF In(symSet[11], sym) THEN Get; ELSE Get; SemError(102); END; END; Expect(36); attrPos.len := FileIO.INTL(CRS.pos - attrPos.beg); ELSIF (sym = 37) THEN Get; attrPos.beg := CRS.pos + FileIO.Long2; attrPos.col := CRS.col + 2; WHILE In(symSet[12], sym) DO IF In(symSet[13], sym) THEN Get; ELSE Get; SemError(102); END; END; Expect(38); attrPos.len := FileIO.INTL(CRS.pos - attrPos.beg); ELSE SynError(52); END; END Attribs; PROCEDURE Declaration (VAR startedDFA: BOOLEAN); VAR gL1, gR1, gL2, gR2: INTEGER; nested: BOOLEAN; BEGIN CASE sym OF 10 : Get; WHILE (sym = 1) DO SetDecl; END; | 11 : Get; WHILE (sym = 1) OR (sym = 2) DO TokenDecl(CRT.t); END; | 12 : Get; WHILE (sym = 1) DO NameDecl; END; | 13 : Get; WHILE (sym = 1) OR (sym = 2) DO TokenDecl(CRT.pr); END; | 14 : Get; Expect(15); TokenExpr(gL1, gR1); Expect(16); TokenExpr(gL2, gR2); IF (sym = 17) THEN Get; nested := TRUE; ELSIF In(symSet[14], sym) THEN nested := FALSE; ELSE SynError(53); END; CRA.NewComment(gL1, gL2, nested); | 18 : Get; IF (sym = 19) THEN Get; IF startedDFA THEN SemError(130) END; CRT.ignoreCase := TRUE; ELSIF (sym = 1) OR (sym = 2) OR (sym = 23) OR (sym = 24) THEN Set(CRT.ignored); IF Sets.In(CRT.ignored, 0) THEN SemError(119) END;; ELSE SynError(54); END; ELSE SynError(55); END; startedDFA := TRUE; END Declaration; PROCEDURE Ident (VAR name: CRT.Name); BEGIN Expect(1); CRS.GetName(CRS.pos, CRS.len, name); END Ident; PROCEDURE CR; VAR startedDFA, ok, undef, hasAttrs: BOOLEAN; unknownSy, eofSy, gR: INTEGER; gramLine, sp: INTEGER; name, gramName: CRT.Name; sn: CRT.SymbolNode; BEGIN Expect(5); gramLine := CRS.line; eofSy := CRT.NewSym(CRT.t, "EOF", 0); CRT.genScanner := TRUE; CRT.ignoreCase := FALSE; Sets.Clear(CRT.ignored); startedDFA := FALSE;; Ident(gramName); CRT.semDeclPos.beg := CRS.nextPos; WHILE In(symSet[15], sym) DO Get; END; CRT.semDeclPos.len := FileIO.INTL(CRS.nextPos - CRT.semDeclPos.beg); CRT.semDeclPos.col := 0; WHILE In(symSet[16], sym) DO Declaration(startedDFA); END; WHILE ~ ( (sym = 0) OR (sym = 6)) DO SynError(56); Get END; Expect(6); ok := Successful(); IF ok & CRT.genScanner THEN CRA.MakeDeterministic(ok) END; IF ~ ok THEN SemError(127) END; CRT.nNodes := 0; WHILE (sym = 1) DO Ident(name); sp := CRT.FindSym(name); undef := sp = CRT.noSym; IF undef THEN sp := CRT.NewSym(CRT.nt, name, CRS.line); CRT.GetSym(sp, sn); ELSE CRT.GetSym(sp, sn); IF sn.typ = CRT.nt THEN IF sn.struct > 0 THEN SemError(107) END ELSE SemError(108) END; sn.line := CRS.line END; hasAttrs := sn.attrPos.beg >= FileIO.Long0; IF (sym = 35) OR (sym = 37) THEN Attribs(sn.attrPos); IF ~ undef & ~ hasAttrs THEN SemError(105) END; CRT.PutSym(sp, sn); ELSIF (sym = 7) OR (sym = 39) THEN IF ~ undef & hasAttrs THEN SemError(105) END; ELSE SynError(57); END; IF (sym = 39) THEN SemText(sn.semPos); END; ExpectWeak(7, 17); Expression(sn.struct, gR); CRT.CompleteGraph(gR); CRT.PutSym(sp, sn); ExpectWeak(8, 18); END; Expect(9); Ident(name); sp := CRT.FindSym(gramName); IF sp = CRT.noSym THEN SemError(111); ELSE CRT.GetSym(sp, sn); IF sn.attrPos.beg >= FileIO.Long0 THEN SemError(112) END; CRT.root := CRT.NewNode(CRT.nt, sp, gramLine); END; IF FileIO.Compare(name, gramName) # 0 THEN SemError(117) END; Expect(8); unknownSy := CRT.NewSym(CRT.t, "not", 0); END CR; PROCEDURE Parse; BEGIN CRS.Reset; Get; CR; END Parse; BEGIN errDist := minErrDist; symSet[ 0, 0] := BITSET{0, 1, 2, 6, 7, 10, 11, 12, 13, 14}; symSet[ 0, 1] := BITSET{2}; symSet[ 0, 2] := BITSET{7}; symSet[ 1, 0] := BITSET{1, 2, 8}; symSet[ 1, 1] := BITSET{7, 9, 10, 11, 12, 13, 14, 15}; symSet[ 1, 2] := BITSET{0, 1, 7}; symSet[ 2, 0] := BITSET{1, 2}; symSet[ 2, 1] := BITSET{7, 9, 12, 13, 15}; symSet[ 2, 2] := BITSET{1, 7}; symSet[ 3, 0] := BITSET{1, 2}; symSet[ 3, 1] := BITSET{9, 13, 15}; symSet[ 3, 2] := BITSET{}; symSet[ 4, 0] := BITSET{6, 8, 10, 11, 12, 13, 14}; symSet[ 4, 1] := BITSET{0, 1, 2, 10, 14}; symSet[ 4, 2] := BITSET{0}; symSet[ 5, 0] := BITSET{0, 1, 2, 6, 7, 10, 11, 12, 13, 14}; symSet[ 5, 1] := BITSET{2}; symSet[ 5, 2] := BITSET{7}; symSet[ 6, 0] := BITSET{1, 2, 6, 10, 11, 12, 13, 14}; symSet[ 6, 1] := BITSET{2}; symSet[ 6, 2] := BITSET{7}; symSet[ 7, 0] := BITSET{8}; symSet[ 7, 1] := BITSET{10, 14}; symSet[ 7, 2] := BITSET{0}; symSet[ 8, 0] := BITSET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[ 8, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[ 8, 2] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 9}; symSet[ 9, 0] := BITSET{1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[ 9, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[ 9, 2] := BITSET{0, 1, 2, 3, 4, 5, 6, 9}; symSet[10, 0] := BITSET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[10, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[10, 2] := BITSET{0, 1, 2, 3, 5, 6, 7, 8, 9}; symSet[11, 0] := BITSET{1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[11, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[11, 2] := BITSET{0, 1, 2, 3, 5, 6, 7, 8, 9}; symSet[12, 0] := BITSET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[12, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[12, 2] := BITSET{0, 1, 2, 3, 4, 5, 7, 8, 9}; symSet[13, 0] := BITSET{1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[13, 1] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[13, 2] := BITSET{0, 1, 2, 3, 4, 5, 7, 8, 9}; symSet[14, 0] := BITSET{6, 10, 11, 12, 13, 14}; symSet[14, 1] := BITSET{2}; symSet[14, 2] := BITSET{}; symSet[15, 0] := BITSET{1, 2, 3, 4, 5, 7, 8, 9, 15}; symSet[15, 1] := BITSET{0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; symSet[15, 2] := BITSET{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; symSet[16, 0] := BITSET{10, 11, 12, 13, 14}; symSet[16, 1] := BITSET{2}; symSet[16, 2] := BITSET{}; symSet[17, 0] := BITSET{0, 1, 2, 6, 7, 8, 10, 11, 12, 13, 14}; symSet[17, 1] := BITSET{2, 7, 9, 11, 12, 13, 15}; symSet[17, 2] := BITSET{1, 7}; symSet[18, 0] := BITSET{0, 1, 2, 6, 7, 9, 10, 11, 12, 13, 14}; symSet[18, 1] := BITSET{2}; symSet[18, 2] := BITSET{7}; END CRP.