(* parser module generated by Coco-R *)
MODULE CRP; 

IMPORT CRS, CRT, CRA, CRX, Sets, Texts := CmdlnTexts, Oberon;

CONST 
  maxP        = 39;
  maxT        = 38;
  nrSets = 18;

  setSize = 32;  nSets = (maxT DIV setSize) + 1;

TYPE
  SymbolSet = ARRAY nSets OF SET;

VAR
  sym:     INTEGER;   (* current input symbol *)
  symSet:  ARRAY nrSets OF SymbolSet;

CONST
  ident = 0; string = 1; (*symbol kind*)
  
VAR 
  str: ARRAY 32 OF CHAR;
  w:   Texts.Writer;
  genScanner: BOOLEAN;


PROCEDURE SemErr(nr: INTEGER);
BEGIN
  CRS.Error(200+nr, CRS.pos);
END SemErr;

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 IN {CRT.char, CRT.class} THEN
        gn.p2 := CRT.contextTrans; CRT.PutNode(gp, gn)
    ELSIF gn.typ IN {CRT.opt, 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 SetDDT(s: ARRAY OF CHAR);
  VAR name: ARRAY 64 OF CHAR; i: INTEGER; ch: CHAR;
BEGIN
  i := 1;
  WHILE s[i] # 0X DO
    ch := s[i]; INC(i);
    IF (ch >= "0") & (ch <= "9") THEN CRT.ddt[ORD(ch)-ORD("0")] := TRUE END
  END
END SetDDT;

PROCEDURE FixString (VAR s: ARRAY OF CHAR; len: INTEGER);
  VAR double: BOOLEAN; i: INTEGER;
BEGIN
  double := FALSE;
  FOR i := 0 TO len-2 DO
    IF s[i] = '"' THEN double := TRUE END
  END;
  IF ~ double THEN s[0] := '"'; s[len-1] := '"' END
END FixString;

(*-------------------------------------------------------------------------*)


PROCEDURE Error (n: INTEGER);
BEGIN CRS.Error(n, CRS.nextPos)
END Error;

PROCEDURE Get;
BEGIN
  LOOP CRS.Get(sym);
    IF sym > maxT THEN
      IF sym = 39 THEN
         CRS.GetName(CRS.nextPos, CRS.nextLen, str); SetDDT(str) 
      END;
      CRS.nextPos := CRS.pos;
      CRS.nextCol := CRS.col;
      CRS.nextLine := CRS.line;
      CRS.nextLen := CRS.len;
    ELSE EXIT
    END
END

END Get;

PROCEDURE Expect(n: INTEGER);
BEGIN IF sym = n THEN Get ELSE Error(n) END
END Expect;

PROCEDURE StartOf(s: INTEGER): BOOLEAN;
BEGIN RETURN (sym MOD setSize) IN symSet[s, sym DIV setSize]
END StartOf;

PROCEDURE ExpectWeak(n, follow: INTEGER);
BEGIN
  IF sym = n THEN Get
  ELSE Error(n); WHILE ~ StartOf(follow) DO Get END
  END
END ExpectWeak;

PROCEDURE WeakSeparator(n, syFol, repFol: INTEGER): BOOLEAN;
  VAR s: SymbolSet; i: INTEGER;
BEGIN
  IF sym = n THEN Get; RETURN TRUE
  ELSIF StartOf(repFol) THEN RETURN FALSE
  ELSE
    i := 0; WHILE i < nSets DO s[i] := symSet[syFol, i] + symSet[repFol, i] + symSet[0, i]; INC(i) END;
    Error(n); WHILE ~ ((sym MOD setSize) IN s[sym DIV setSize]) DO Get END;
    RETURN StartOf(syFol)
  END
END WeakSeparator;

PROCEDURE ^TokenFactor(VAR gL, gR: INTEGER);
PROCEDURE ^TokenTerm(VAR gL, gR: INTEGER);
PROCEDURE ^Factor(VAR gL, gR: INTEGER);
PROCEDURE ^Term(VAR gL, gR: INTEGER);
PROCEDURE ^Symbol(VAR name: CRT.Name; VAR kind: INTEGER);
PROCEDURE ^SimSet(VAR set: CRT.Set);
PROCEDURE ^Set(VAR set: CRT.Set);
PROCEDURE ^TokenExpr(VAR gL, gR: INTEGER);
PROCEDURE ^TokenDecl(typ: INTEGER);
PROCEDURE ^SetDecl;
PROCEDURE ^Expression(VAR gL, gR: INTEGER);
PROCEDURE ^SemText(VAR semPos: CRT.Position);
PROCEDURE ^Attribs(VAR attrPos: CRT.Position);
PROCEDURE ^Declaration;
PROCEDURE ^CR;

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
        SemErr(15); 
        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 = 23) THEN
    Get;
    TokenExpr(gL, gR);
    Expect(24);
  ELSIF (sym = 28) THEN
    Get;
    TokenExpr(gL, gR);
    Expect(29);
    CRT.MakeOption(gL, gR) ;
  ELSIF (sym = 30) THEN
    Get;
    TokenExpr(gL, gR);
    Expect(31);
    CRT.MakeIteration(gL, gR) ;
  ELSE Error(39)
  END;
END TokenFactor;

PROCEDURE TokenTerm(VAR gL, gR: INTEGER);
  VAR gL2, gR2: INTEGER;  
BEGIN
  TokenFactor(gL, gR);
  WHILE StartOf(1)  DO
    TokenFactor(gL2, gR2);
    CRT.ConcatSeq(gL, gR, gL2, gR2) ;
  END;
  IF (sym = 33) THEN
    Get;
    Expect(23);
    TokenExpr(gL2, gR2);
    SetCtx(gL2); CRT.ConcatSeq(gL, gR, gL2, gR2) ;
    Expect(24);
  END;
END TokenTerm;

PROCEDURE Factor(VAR gL, gR: INTEGER);
  VAR sp, kind, c: 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,27:     IF (sym = 27) 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)
      ELSE  (*undefined string in production*)
        sp := CRT.NewSym(CRT.t, name, CRS.line);
        MatchLiteral(sp)
      END
    END;
    CRT.GetSym(sp, sn);
    IF ~(sn.typ IN {CRT.t,CRT.nt}) THEN SemErr(4) END;
    IF weak THEN 
      IF sn.typ = CRT.t THEN sn.typ := CRT.wt ELSE SemErr(23) END
    END;
    gL := CRT.NewNode(sn.typ, sp, CRS.line); gR := gL ;
    IF (sym = 34) THEN
      Attribs(pos);
      CRT.GetNode(gL, gn); gn.pos := pos; CRT.PutNode(gL, gn);
      CRT.GetSym(sp, sn);
      IF undef THEN 
        sn.attrPos := pos; CRT.PutSym(sp, sn)
      ELSIF sn.attrPos.beg < 0 THEN SemErr(5)
      END;
      IF kind # ident THEN SemErr(3) END ;
    ELSIF StartOf(2)  THEN
      CRT.GetSym(sp, sn);
      IF sn.attrPos.beg >= 0 THEN SemErr(6) END ;
    ELSE Error(40)
    END;
  | 23:     Get;
    Expression(gL, gR);
    Expect(24);
  | 28:     Get;
    Expression(gL, gR);
    Expect(29);
    CRT.MakeOption(gL, gR) ;
  | 30:     Get;
    Expression(gL, gR);
    Expect(31);
    CRT.MakeIteration(gL, gR) ;
  | 36:     SemText(pos);
    gL := CRT.NewNode(CRT.sem, 0, 0); 
    gR := gL;
    CRT.GetNode(gL, gn); gn.pos := pos; CRT.PutNode(gL, gn) ;
  | 25:     Get;
    Sets.Fill(set); Sets.Excl(set, CRT.eofSy);
    gL := CRT.NewNode(CRT.any, CRT.NewSet(set), 0); gR := gL ;
  | 32:     Get;
    gL := CRT.NewNode(CRT.sync, 0, 0); gR := gL ;
  ELSE Error(41)
  END;
END Factor;

PROCEDURE Term(VAR gL, gR: INTEGER);
  VAR gL2, gR2: INTEGER;  
BEGIN
  gL := 0; gR := 0 ;
  IF StartOf(3)  THEN
    Factor(gL, gR);
    WHILE StartOf(3)  DO
      Factor(gL2, gR2);
      CRT.ConcatSeq(gL, gR, gL2, gR2) ;
    END;
  ELSIF StartOf(4)  THEN
    gL := CRT.NewNode(CRT.eps, 0, 0); gR := gL ;
  ELSE Error(42)
  END;
END Term;

PROCEDURE Symbol(VAR name: CRT.Name; VAR kind: INTEGER);
BEGIN
  IF (sym = 1) THEN
    Get;
    kind := ident ;
  ELSIF (sym = 2) THEN
    Get;
    kind := string ;
  ELSE Error(43)
  END;
  CRS.GetName(CRS.pos, CRS.len, name);
  IF kind = string THEN FixString(name, CRS.len) END ;
END Symbol;

PROCEDURE SimSet(VAR set: CRT.Set);
  VAR c, n, i: INTEGER; name: CRT.Name; s: ARRAY 128 OF CHAR;  
BEGIN
  IF (sym = 1) THEN
    Get;
    CRS.GetName(CRS.pos, CRS.len, name);
    c := CRT.ClassWithName(name);
    IF c < 0 THEN SemErr(15); Sets.Clear(set)
    ELSE CRT.GetClass(c, set)
    END ;
  ELSIF (sym = 2) THEN
    Get;
    CRS.GetName(CRS.pos, CRS.len, s);
    Sets.Clear(set); i := 1; 
    WHILE s[i] # s[0] DO
      Sets.Incl(set, ORD(s[i])); INC(i)
    END ;
  ELSIF (sym = 22) THEN
    Get;
    Expect(23);
    Expect(3);
    CRS.GetName(CRS.pos, CRS.len, name);
    n := 0; i := 0;
    WHILE name[i] # 0X DO
      n := 10 * n + (ORD(name[i]) - ORD("0"));
      INC(i)
    END;
    Sets.Clear(set); Sets.Incl(set, n) ;
    Expect(24);
  ELSIF (sym = 25) THEN
    Get;
    Sets.Fill(set) ;
  ELSE Error(44)
  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(26, 1, 5)  DO
    TokenTerm(gL2, gR2);
    IF first THEN 
      CRT.MakeFirstAlt(gL, gR); first := FALSE
    END;
    CRT.ConcatAlt(gL, gR, gL2, gR2) ;
  END;
END TokenExpr;

PROCEDURE TokenDecl(typ: INTEGER);
  VAR sp, kind, gL, gR: INTEGER; sn: CRT.SymbolNode;
      pos: CRT.Position; name: CRT.Name;  
BEGIN
  Symbol(name, kind);
  IF CRT.FindSym(name) # CRT.noSym THEN SemErr(7)
  ELSE 
    sp := CRT.NewSym(typ, name, CRS.line);
    CRT.GetSym(sp, sn); sn.struct := CRT.classToken;
    CRT.PutSym(sp, sn)
  END ;
  WHILE ~( StartOf(6) ) DO Error(45); Get END;
  IF (sym = 8) THEN
    Get;
    TokenExpr(gL, gR);
    Expect(9);
    IF kind # ident THEN SemErr(13) END;
    CRT.CompleteGraph(gR);
    CRA.ConvertToStates(gL, sp) ;
  ELSIF StartOf(7)  THEN
    IF kind = ident THEN genScanner := FALSE
    ELSE MatchLiteral(sp)
    END ;
  ELSE Error(46)
  END;
  IF (sym = 36) THEN
    SemText(pos);
    IF typ = CRT.t THEN SemErr(14) 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
  Expect(1);
  CRS.GetName(CRS.pos, CRS.len, name);
  c := CRT.ClassWithName(name); IF c >= 0 THEN SemErr(7) END ;
  Expect(8);
  Set(set);
  c := CRT.NewClass(name, set) ;
  Expect(9);
END SetDecl;

PROCEDURE Expression(VAR gL, gR: INTEGER);
  VAR gL2, gR2: INTEGER; first: BOOLEAN;  
BEGIN
  Term(gL, gR);
  first := TRUE ;
  WHILE WeakSeparator(26, 2, 8)  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(36);
  semPos.beg := CRS.nextPos; semPos.col := CRS.nextCol ;
  WHILE StartOf(9)  DO
    Get;
  END;
  Expect(37);
  semPos.len := SHORT(CRS.pos - semPos.beg) ;
END SemText;

PROCEDURE Attribs(VAR attrPos: CRT.Position);
BEGIN
  Expect(34);
  attrPos.beg := CRS.nextPos; attrPos.col := CRS.nextCol ;
  WHILE StartOf(10)  DO
    Get;
  END;
  Expect(35);
  attrPos.len := SHORT(CRS.pos - attrPos.beg) ;
END Attribs;

PROCEDURE Declaration;
  VAR gL1, gR1, gL2, gR2: INTEGER; nested: BOOLEAN;  
BEGIN
  IF (sym = 11) THEN
    Get;
    WHILE (sym = 1) DO
      SetDecl;
    END;
  ELSIF (sym = 12) THEN
    Get;
    WHILE (sym = 1) OR (sym = 2) DO
      TokenDecl(CRT.t);
    END;
  ELSIF (sym = 13) THEN
    Get;
    WHILE (sym = 1) OR (sym = 2) DO
      TokenDecl(CRT.pr);
    END;
  ELSIF (sym = 14) THEN
    Get;
    Expect(15);
    TokenExpr(gL1, gR1);
    Expect(16);
    TokenExpr(gL2, gR2);
    IF (sym = 17) THEN
      Get;
      nested := TRUE ;
    ELSIF StartOf(11)  THEN
      nested := FALSE ;
    ELSE Error(47)
    END;
    CRA.NewComment(gL1, gL2, nested) ;
  ELSIF (sym = 18) THEN
    Get;
    IF (sym = 19) THEN
      Get;
      CRT.ignoreCase := TRUE ;
    ELSIF StartOf(12)  THEN
      Set(CRT.ignored);
    ELSE Error(48)
    END;
  ELSE Error(49)
  END;
END Declaration;

PROCEDURE CR;
  VAR undef, hasAttrs, ok, ok1: BOOLEAN; eofSy, gR: INTEGER; 
      gramLine, sp: INTEGER;
      gn: CRT.GraphNode; sn: CRT.SymbolNode; 
      name, gramName: CRT.Name;  
BEGIN
  Expect(4);
  Texts.OpenWriter(w);
  CRT.Init; CRX.Init; CRA.Init;
  gramLine := CRS.line;
  eofSy := CRT.NewSym(CRT.t, "EOF", 0);
  genScanner := TRUE;
  CRT.ignoreCase := FALSE;
  ok := TRUE;
  Sets.Clear(CRT.ignored) ;
  Expect(1);
  CRS.GetName(CRS.pos, CRS.len, gramName);
  CRT.semDeclPos.beg := CRS.nextPos; CRT.importPos.beg := -1; ;
  WHILE StartOf(13)  DO
    IF (sym = 5) THEN
      Get;
      CRT.importPos.beg := CRS.nextPos ;
      WHILE StartOf(14)  DO
        Get;
      END;
      Expect(6);
      CRT.importPos.len := SHORT(CRS.pos - CRT.importPos.beg);
      CRT.importPos.col := 0;
      CRT.semDeclPos.beg := CRS.nextPos ;
    ELSE
      Get;
    END;
  END;
  CRT.semDeclPos.len := SHORT(CRS.nextPos - CRT.semDeclPos.beg);
  CRT.semDeclPos.col := 0 ;
  WHILE StartOf(15)  DO
    Declaration;
  END;
  WHILE ~( (sym = 0) OR (sym = 7)) DO Error(50); Get END;
  Expect(7);
  IF genScanner THEN CRA.MakeDeterministic(ok) END;
  CRT.nNodes := 0 ;
  WHILE (sym = 1) DO
    Get;
    CRS.GetName(CRS.pos, CRS.len, 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 SemErr(7) END
      ELSE SemErr(8)
      END;
      sn.line := CRS.line
    END;
    hasAttrs := sn.attrPos.beg >= 0 ;
    IF (sym = 34) THEN
      Attribs(sn.attrPos);
      IF ~undef & ~hasAttrs THEN SemErr(9) END;
      CRT.PutSym(sp, sn) ;
    ELSIF (sym = 8) OR (sym = 36) THEN
      IF ~undef & hasAttrs THEN SemErr(10) END ;
    ELSE Error(51)
    END;
    IF (sym = 36) THEN
      SemText(sn.semPos);
    END;
    ExpectWeak(8, 16);
    Expression(sn.struct, gR);
    CRT.CompleteGraph(gR); CRT.PutSym(sp, sn);
    IF CRT.ddt[2] THEN CRT.PrintGraph END ;
    ExpectWeak(9, 17);
  END;
  sp := CRT.FindSym(gramName);
  IF sp = CRT.noSym THEN SemErr(11);
  ELSE
    CRT.GetSym(sp, sn); 
    IF sn.attrPos.beg >= 0 THEN SemErr(12) END;
    CRT.root := CRT.NewNode(CRT.nt, sp, gramLine);
  END ;
  Expect(10);
  Expect(1);
  CRS.GetName(CRS.pos, CRS.len, name); 
  IF name # gramName THEN SemErr(17) END;
  IF CRS.errors = 0 THEN
    Texts.WriteString(w, " checking"); Texts.Append(Oberon.Log, w.buf);
    CRT.CompSymbolSets;
    IF ok THEN CRT.TestCompleteness(ok) END;
    IF ok THEN
      CRT.TestIfAllNtReached(ok1); CRT.FindCircularProductions(ok)
    END;
    IF ok THEN CRT.TestIfNtToTerm(ok) END;
    IF ok THEN CRT.LL1Test(ok1) END;
    IF CRT.ddt[0] THEN CRA.PrintStates END;
    IF CRT.ddt[7] THEN CRT.XRef END;
    IF ok THEN
      Texts.WriteString(w, " +parser");
      Texts.Append(Oberon.Log, w.buf);
      CRX.GenCompiler;
      IF genScanner THEN
        Texts.WriteString(w, " +scanner");
        Texts.Append(Oberon.Log, w.buf);
        CRA.WriteScanner
      END;
      IF CRT.ddt[8] THEN CRX.WriteStatistics END
    END
  ELSE ok := FALSE
  END;
  IF CRT.ddt[6] THEN CRT.PrintSymbolTable END;
  IF ok THEN Texts.WriteString(w, " done") END;
  Texts.WriteLn(w); Texts.Append(Oberon.Log, w.buf) ;
  Expect(9);
END CR;



PROCEDURE Parse*;
BEGIN
  Get;
  CR;

END Parse;

BEGIN
  symSet[0, 0] := {0,1,2,7,8,11,12,13,14,18};
  symSet[0, 1] := {4};
  symSet[1, 0] := {1,2,23,28,30};
  symSet[1, 1] := {};
  symSet[2, 0] := {1,2,9,23,24,25,26,27,28,29,30,31};
  symSet[2, 1] := {0,4};
  symSet[3, 0] := {1,2,23,25,27,28,30};
  symSet[3, 1] := {0,4};
  symSet[4, 0] := {9,24,26,29,31};
  symSet[4, 1] := {};
  symSet[5, 0] := {7,9,11,12,13,14,16,17,18,24,29,31};
  symSet[5, 1] := {};
  symSet[6, 0] := {0,1,2,7,8,11,12,13,14,18};
  symSet[6, 1] := {4};
  symSet[7, 0] := {1,2,7,11,12,13,14,18};
  symSet[7, 1] := {4};
  symSet[8, 0] := {9,24,29,31};
  symSet[8, 1] := {};
  symSet[9, 0] := {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[9, 1] := {0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[10, 0] := {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[10, 1] := {0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[11, 0] := {7,11,12,13,14,18};
  symSet[11, 1] := {};
  symSet[12, 0] := {1,2,22,25};
  symSet[12, 1] := {};
  symSet[13, 0] := {1,2,3,4,5,6,8,9,10,15,16,17,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[13, 1] := {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[14, 0] := {1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[14, 1] := {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  symSet[15, 0] := {11,12,13,14,18};
  symSet[15, 1] := {};
  symSet[16, 0] := {0,1,2,7,8,9,11,12,13,14,18,23,25,26,27,28,30};
  symSet[16, 1] := {0,4};
  symSet[17, 0] := {0,1,2,7,8,10,11,12,13,14,18};
  symSet[17, 1] := {4};

END CRP.
  |  0: Msg("EOF expected")
  |  1: Msg("ident expected")
  |  2: Msg("string expected")
  |  3: Msg("number expected")
  |  4: Msg("'COMPILER' expected")
  |  5: Msg("'IMPORT' expected")
  |  6: Msg("';' expected")
  |  7: Msg("'PRODUCTIONS' expected")
  |  8: Msg("'=' expected")
  |  9: Msg("'.' expected")
  | 10: Msg("'END' expected")
  | 11: Msg("'CHARACTERS' expected")
  | 12: Msg("'TOKENS' expected")
  | 13: Msg("'PRAGMAS' expected")
  | 14: Msg("'COMMENTS' expected")
  | 15: Msg("'FROM' expected")
  | 16: Msg("'TO' expected")
  | 17: Msg("'NESTED' expected")
  | 18: Msg("'IGNORE' expected")
  | 19: Msg("'CASE' expected")
  | 20: Msg("'+' expected")
  | 21: Msg("'-' expected")
  | 22: Msg("'CHR' expected")
  | 23: Msg("'(' expected")
  | 24: Msg("')' expected")
  | 25: Msg("'ANY' expected")
  | 26: Msg("'|' expected")
  | 27: Msg("'WEAK' expected")
  | 28: Msg("'[' expected")
  | 29: Msg("']' expected")
  | 30: Msg("'{' expected")
  | 31: Msg("'}' expected")
  | 32: Msg("'SYNC' expected")
  | 33: Msg("'CONTEXT' expected")
  | 34: Msg("'<' expected")
  | 35: Msg("'>' expected")
  | 36: Msg("'(.' expected")
  | 37: Msg("'.)' expected")
  | 38: Msg("??? expected")
  | 39: Msg("invalid TokenFactor")
  | 40: Msg("invalid Factor")
  | 41: Msg("invalid Factor")
  | 42: Msg("invalid Term")
  | 43: Msg("invalid Symbol")
  | 44: Msg("invalid SimSet")
  | 45: Msg("this symbol not expected in TokenDecl")
  | 46: Msg("invalid TokenDecl")
  | 47: Msg("invalid Declaration")
  | 48: Msg("invalid Declaration")
  | 49: Msg("invalid Declaration")
  | 50: Msg("this symbol not expected in CR")
  | 51: Msg("invalid CR")
