⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cr.atg

📁 一个Modula-2语言分析器
💻 ATG
📖 第 1 页 / 共 2 页
字号:
$LSC (*$ACFGILMOSXN*)
(* COCO/R for MS-DOS grammar used to generate COCO/R itself
   as adapted by P.D. Terry, January 1992
   version 1.48 last modified Mon  11-16-98 *)

COMPILER CR

(*---------------------- semantic declarations -----------------------*)

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;

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

CHARACTERS

  letter   = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_".
  digit    = "0123456789".
  ctrl     = CHR(1) .. CHR(31).
  tab      = CHR(9).
  eol      = CHR(13).
  lf       = CHR(10).
  noQuote1 = ANY - '"' - ctrl.
  noQuote2 = ANY - "'" - ctrl.

IGNORE tab + eol + lf

TOKENS

  ident     = letter {letter | digit}.
  string    = '"' {noQuote1} '"' | "'" {noQuote2} "'".
  badstring = '"' {noQuote1} (eol | lf) | "'" {noQuote2} (eol | lf).
  number    = digit {digit}.

PRAGMAS

  Options = "$" {letter | digit} .
                (.CRS.GetName(CRS.nextPos, CRS.nextLen, s); SetOption(s);  .)

COMMENTS FROM "(*" TO "*)" NESTED
COMMENTS FROM "/*" TO "*/"

PRODUCTIONS

CR                            (. VAR
                                   ok, undef, hasAttrs: BOOLEAN;
                                   unknownSy,
                                   eofSy, gR:       INTEGER;
                                   gramLine, sp:    INTEGER;
                                   name, gramName:  CRT.Name;
                                   sn:              CRT.SymbolNode; .)
=
"COMPILER"
                              (. 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 .)
{ ANY }                       (. CRT.semDeclPos.len := FileIO.INTL(CRS.nextPos - CRT.semDeclPos.beg);
                                 CRT.semDeclPos.col := 0 .)
{ Declaration }
SYNC
"PRODUCTIONS"                 (. ok := Successful();
                                 IF ok & CRT.genScanner THEN CRA.MakeDeterministic(ok) END;
                                 IF ~ ok THEN SemError(127) END;
                                 CRT.nNodes := 0 .)
{ 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 .)
  ( Attribs <sn.attrPos>      (. IF ~ undef & ~ hasAttrs THEN SemError(105) END;
                                 CRT.PutSym(sp, sn) .)
  |                           (. IF ~ undef & hasAttrs THEN SemError(105) END .)
  )
  [ SemText <sn.semPos>]
  WEAK "="
  Expression <sn.struct, gR>  (. CRT.CompleteGraph(gR); CRT.PutSym(sp, sn) .)
  WEAK "."
  }
"END" 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 .)
"."                           (. unknownSy := CRT.NewSym(CRT.t, "not", 0) .)

.

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

Declaration                   (. VAR
                                   gL1, gR1, gL2, gR2: INTEGER;
                                   nested:             BOOLEAN; .)
= "CHARACTERS" { SetDecl }
| "TOKENS"     { TokenDecl <CRT.t> }
| "NAMES"      { NameDecl }
| "PRAGMAS"    { TokenDecl <CRT.pr> }
| "COMMENTS"
  "FROM" TokenExpr <gL1, gR1>
  "TO" TokenExpr <gL2, gR2>
  ( "NESTED"                  (. nested := TRUE .)
    |                         (. nested := FALSE .)
  )
                              (. CRA.NewComment(gL1, gL2, nested) .)
| "IGNORE"
  ( "CASE"                    (. CRT.ignoreCase := TRUE .)
  | Set <CRT.ignored>         (. IF Sets.In(CRT.ignored, 0) THEN SemError(119) END .)
  )
.


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

SetDecl                       (. VAR
                                   c:    INTEGER;
                                   set:  CRT.Set;
                                   name: CRT.Name; .)
= Ident <name>                (. c := CRT.ClassWithName(name);
                                 IF c >= 0 THEN SemError(107) END .)
  "=" Set <set>               (. c := CRT.NewClass(name, set) .)
  ".".

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

Set <VAR set: CRT.Set>        (. VAR
                                   set2: CRT.Set; .)
= SimSet <set>
  { "+" SimSet <set2>         (. Sets.Unite(set, set2) .)
  | "-" SimSet <set2>         (. Sets.Differ(set, set2) .)
  }.

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

SimSet <VAR set: CRT.Set>     (. VAR
                                   i, n1, n2: CARDINAL;
                                   c:         INTEGER;
                                   name:      CRT.Name;
                                   s:         ARRAY [0 .. 127] OF CHAR; .)
= Ident <name>                (. c := CRT.ClassWithName(name);
                                 IF c < 0 THEN SemError(115); Sets.Clear(set)
                                   ELSE CRT.GetClass(c, set)
                                 END .)
| string                      (. 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 .)
| SingleChar <n1>
                              (. Sets.Clear(set); Sets.Incl(set, n1) .)

⌨️ 快捷键说明

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