crp.mod

来自「一个Modula-2语言分析器」· MOD 代码 · 共 816 行 · 第 1/2 页

MOD
816
字号
      c := CRT.ClassWithName(name);
      IF c < 0 THEN SemError(115); 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
        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.Clear(set); 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;
      Sets.Fill(set);
    ELSE SynError(47);
    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(48);
    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(49); 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(50);
    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);
    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(51);
    END;
  END Attribs;

PROCEDURE Declaration;
  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(52);
        END;
        CRA.NewComment(gL1, gL2, nested);
    | 18 :
        Get;
        IF (sym = 19) THEN
          Get;
          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(53);
        END;
    ELSE SynError(54);
    END;
  END Declaration;

PROCEDURE Ident (VAR name: CRT.Name);
  BEGIN
    Expect(1);
    CRS.GetName(CRS.pos, CRS.len, name);
  END Ident;

PROCEDURE CR;
  VAR
    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);
    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;
    END;
    WHILE ~ ( (sym = 0) OR (sym = 6)) DO SynError(55); 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(56);
      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.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?