home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / oberon / system1 / cr.atg (.txt) < prev    next >
Oberon Text  |  1977-12-31  |  19KB  |  330 lines

  1. Courier8.Scn.Fnt
  2. Syntax10.Scn.Fnt
  3. COMPILER CR  (*H.Moessenboeck 17.11.93, Coco/R*)
  4. (*---------------------- semantic declarations ----------------------------*)
  5. IMPORT CRT, CRA, CRX, Sets, Texts, Oberon;
  6. CONST
  7.   ident = 0; string = 1; (*symbol kind*)
  8.   str: ARRAY 32 OF CHAR;
  9.   w:   Texts.Writer;
  10.   genScanner: BOOLEAN;
  11. PROCEDURE SemErr(nr: INTEGER);
  12. BEGIN
  13.   CRS.Error(200+nr, CRS.pos);
  14. END SemErr;
  15. PROCEDURE MatchLiteral(sp: INTEGER); (*store string either as token or as literal*)
  16.   VAR sn, sn1: CRT.SymbolNode; matchedSp: INTEGER;
  17. BEGIN
  18.   CRT.GetSym(sp, sn);
  19.   CRA.MatchDFA(sn.name, sp, matchedSp);
  20.   IF matchedSp # CRT.noSym THEN
  21.     CRT.GetSym(matchedSp, sn1); sn1.struct := CRT.classLitToken; CRT.PutSym(matchedSp, sn1);
  22.     sn.struct := CRT.litToken
  23.   ELSE sn.struct := CRT.classToken;
  24.   END;
  25.   CRT.PutSym(sp, sn)
  26. END MatchLiteral;
  27. PROCEDURE SetCtx(gp: INTEGER); (*set transition code to CRT.contextTrans*)
  28.   VAR gn: CRT.GraphNode;
  29. BEGIN
  30.   WHILE gp > 0 DO
  31.     CRT.GetNode(gp, gn);
  32.     IF gn.typ IN {CRT.char, CRT.class} THEN
  33.         gn.p2 := CRT.contextTrans; CRT.PutNode(gp, gn)
  34.     ELSIF gn.typ IN {CRT.opt, CRT.iter} THEN SetCtx(gn.p1)
  35.     ELSIF gn.typ = CRT.alt THEN SetCtx(gn.p1); SetCtx(gn.p2)
  36.     END;
  37.     gp := gn.next
  38.   END
  39. END SetCtx;
  40. PROCEDURE SetDDT(s: ARRAY OF CHAR);
  41.   VAR name: ARRAY 64 OF CHAR; i: INTEGER; ch: CHAR;
  42. BEGIN
  43.   i := 1;
  44.   WHILE s[i] # 0X DO
  45.     ch := s[i]; INC(i);
  46.     IF (ch >= "0") & (ch <= "9") THEN CRT.ddt[ORD(ch)-ORD("0")] := TRUE END
  47.   END
  48. END SetDDT;
  49. PROCEDURE FixString (VAR s: ARRAY OF CHAR; len: INTEGER);
  50.     VAR double: BOOLEAN; i: INTEGER;
  51. BEGIN
  52.     double := FALSE;
  53.     FOR i := 0 TO len-2 DO
  54.         IF s[i] = '"' THEN double := TRUE END
  55.     END;
  56.     IF ~ double THEN s[0] := '"'; s[len-1] := '"' END
  57. END FixString;
  58. (*-------------------------------------------------------------------------*)
  59. CHARACTERS
  60.   letter   = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
  61.   digit    = "0123456789".
  62.   eol      = CHR(13).
  63.   tab      = CHR(9).
  64.   noQuote1 = ANY - '"' - eol.
  65.   noQuote2 = ANY - "'" - eol.
  66. IGNORE eol + tab + CHR(28)
  67. TOKENS
  68.   ident    = letter {letter | digit}.
  69.   string   = '"' {noQuote1} '"' | "'" {noQuote2} "'".
  70.   number   = digit {digit}.
  71. PRAGMAS
  72.   ddtSym   = "$" {digit}.        (. CRS.GetName(CRS.nextPos, CRS.nextLen, str); SetDDT(str) .)
  73. COMMENTS FROM "(*" TO "*)" NESTED
  74. (*-------------------------------------------------------------------------*)
  75. PRODUCTIONS
  76. CR                              (. VAR undef, hasAttrs, ok, ok1: BOOLEAN; eofSy, gR: INTEGER; 
  77.                                        gramLine, sp: INTEGER;
  78.                                        gn: CRT.GraphNode; sn: CRT.SymbolNode; 
  79.                                        name, gramName: CRT.Name; .)
  80.   "COMPILER"                    (. Texts.OpenWriter(w);
  81.                                    CRT.Init; CRX.Init; CRA.Init;
  82.                                    gramLine := CRS.line;
  83.                                    eofSy := CRT.NewSym(CRT.t, "EOF", 0);
  84.                                    genScanner := TRUE;
  85.                                    CRT.ignoreCase := FALSE;
  86.                                    ok := TRUE;
  87.                                    Sets.Clear(CRT.ignored) .) 
  88.   ident                         (. CRS.GetName(CRS.pos, CRS.len, gramName);
  89.                                    CRT.semDeclPos.beg := CRS.nextPos; CRT.importPos.beg := -1; .)
  90.   { "IMPORT"                    (. CRT.importPos.beg := CRS.nextPos .)
  91.     {ANY} ";"                   (. CRT.importPos.len := SHORT(CRS.pos - CRT.importPos.beg);
  92.                                    CRT.importPos.col := 0;
  93.                                    CRT.semDeclPos.beg := CRS.nextPos .)
  94.   | ANY 
  95.   }                             (. CRT.semDeclPos.len := SHORT(CRS.nextPos - CRT.semDeclPos.beg);
  96.                                    CRT.semDeclPos.col := 0 .)
  97.   { Declaration }
  98.                                 SYNC 
  99.   "PRODUCTIONS"                 (. IF genScanner THEN CRA.MakeDeterministic(ok) END;
  100.                                    CRT.nNodes := 0 .)
  101.   { ident                       (. CRS.GetName(CRS.pos, CRS.len, name); 
  102.                                    sp := CRT.FindSym(name); undef := sp = CRT.noSym;
  103.                                    IF undef THEN
  104.                                      sp := CRT.NewSym(CRT.nt, name, CRS.line);
  105.                                      CRT.GetSym(sp, sn);
  106.                                    ELSE
  107.                                      CRT.GetSym(sp, sn);
  108.                                      IF sn.typ = CRT.nt THEN
  109.                                        IF sn.struct > 0 THEN SemErr(7) END
  110.                                      ELSE SemErr(8)
  111.                                      END;
  112.                                      sn.line := CRS.line
  113.                                    END;
  114.                                    hasAttrs := sn.attrPos.beg >= 0 .)
  115.     ( Attribs <sn.attrPos>      (. IF ~undef & ~hasAttrs THEN SemErr(9) END;
  116.                                    CRT.PutSym(sp, sn) .)
  117.     |                           (. IF ~undef & hasAttrs THEN SemErr(10) END .)
  118.     ) 
  119.     [ SemText <sn.semPos>] 
  120.     WEAK "="
  121.     Expression <sn.struct, gR>  (. CRT.CompleteGraph(gR); CRT.PutSym(sp, sn);
  122.                                    IF CRT.ddt[2] THEN CRT.PrintGraph END .) 
  123.     WEAK "."
  124.   }                             (. sp := CRT.FindSym(gramName);
  125.                                    IF sp = CRT.noSym THEN SemErr(11);
  126.                                    ELSE
  127.                                      CRT.GetSym(sp, sn); 
  128.                                      IF sn.attrPos.beg >= 0 THEN SemErr(12) END;
  129.                                      CRT.root := CRT.NewNode(CRT.nt, sp, gramLine);
  130.                                    END .)
  131.   "END" ident                   (. CRS.GetName(CRS.pos, CRS.len, name); 
  132.                                    IF name # gramName THEN SemErr(17) END;
  133.                                    IF CRS.errors = 0 THEN
  134.                                      Texts.WriteString(w, " checking"); Texts.Append(Oberon.Log, w.buf);
  135.                                      CRT.CompSymbolSets;
  136.                                      IF ok THEN CRT.TestCompleteness(ok) END;
  137.                                      IF ok THEN
  138.                                        CRT.TestIfAllNtReached(ok1); CRT.FindCircularProductions(ok)
  139.                                      END;
  140.                                      IF ok THEN CRT.TestIfNtToTerm(ok) END;
  141.                                      IF ok THEN CRT.LL1Test(ok1) END;
  142.                                      IF CRT.ddt[0] THEN CRA.PrintStates END;
  143.                                      IF CRT.ddt[7] THEN CRT.XRef END;
  144.                                      IF ok THEN
  145.                                        Texts.WriteString(w, " +parser");
  146.                                        Texts.Append(Oberon.Log, w.buf);
  147.                                        CRX.GenCompiler;
  148.                                        IF genScanner THEN
  149.                                          Texts.WriteString(w, " +scanner");
  150.                                          Texts.Append(Oberon.Log, w.buf);
  151.                                          CRA.WriteScanner
  152.                                        END;
  153.                                        IF CRT.ddt[8] THEN CRX.WriteStatistics END
  154.                                      END
  155.                                    ELSE ok := FALSE
  156.                                    END;
  157.                                    IF CRT.ddt[6] THEN CRT.PrintSymbolTable END;
  158.                                    IF ok THEN Texts.WriteString(w, " done") END;
  159.                                    Texts.WriteLn(w); Texts.Append(Oberon.Log, w.buf) .)
  160.   ".".
  161. (*------------------------------------------------------------------------------------*)
  162. Declaration                     (. VAR gL1, gR1, gL2, gR2: INTEGER; nested: BOOLEAN; .)
  163.   "CHARACTERS" { SetDecl }
  164. | "TOKENS"     { TokenDecl <CRT.t> }
  165. | "PRAGMAS"    { TokenDecl <CRT.pr> }
  166. | "COMMENTS"
  167.   "FROM" TokenExpr <gL1, gR1>
  168.   "TO" TokenExpr <gL2, gR2>
  169.   ( "NESTED"                    (. nested := TRUE .)
  170.   |                             (. nested := FALSE .)
  171.   )                             (. CRA.NewComment(gL1, gL2, nested) .)
  172. | "IGNORE" 
  173.   ( "CASE"                      (. CRT.ignoreCase := TRUE .)
  174.   | Set <CRT.ignored>
  175. (*------------------------------------------------------------------------------------*)
  176. SetDecl                         (. VAR c: INTEGER; set: CRT.Set; name: CRT.Name; .)
  177.   ident                         (. CRS.GetName(CRS.pos, CRS.len, name);
  178.                                    c := CRT.ClassWithName(name); IF c >= 0 THEN SemErr(7) END .)
  179.   "=" Set <set>                 (. c := CRT.NewClass(name, set) .)
  180.   ".".
  181. (*------------------------------------------------------------------------------------*)
  182. Set <VAR set: CRT.Set>          (. VAR set2: CRT.Set; .)
  183.   SimSet <set>
  184.   { "+" SimSet <set2>           (. Sets.Unite(set, set2) .)
  185.   | "-" SimSet <set2>           (. Sets.Differ(set, set2) .)
  186. (*------------------------------------------------------------------------------------*)
  187. SimSet <VAR set: CRT.Set>       (. VAR c, n, i: INTEGER; name: CRT.Name; s: ARRAY 128 OF CHAR; .)
  188.   ident                         (. CRS.GetName(CRS.pos, CRS.len, name);
  189.                                    c := CRT.ClassWithName(name);
  190.                                    IF c < 0 THEN SemErr(15); Sets.Clear(set)
  191.                                    ELSE CRT.GetClass(c, set)
  192.                                    END .)
  193. | string                        (. CRS.GetName(CRS.pos, CRS.len, s);
  194.                                    Sets.Clear(set); i := 1; 
  195.                                    WHILE s[i] # s[0] DO
  196.                                      Sets.Incl(set, ORD(s[i])); INC(i)
  197.                                    END .)
  198. | "CHR" "(" number              (. CRS.GetName(CRS.pos, CRS.len, name);
  199.                                    n := 0; i := 0;
  200.                                    WHILE name[i] # 0X DO
  201.                                      n := 10 * n + (ORD(name[i]) - ORD("0"));
  202.                                      INC(i)
  203.                                    END;
  204.                                    Sets.Clear(set); Sets.Incl(set, n) .)
  205.   ")"
  206. | "ANY"                         (. Sets.Fill(set) .)
  207. (*------------------------------------------------------------------------------------*)
  208. TokenDecl <typ: INTEGER>        (. VAR sp, kind, gL, gR: INTEGER; sn: CRT.SymbolNode;
  209.                                        pos: CRT.Position; name: CRT.Name; .)
  210.   Symbol <name, kind>           (. IF CRT.FindSym(name) # CRT.noSym THEN SemErr(7)
  211.                                    ELSE 
  212.                                      sp := CRT.NewSym(typ, name, CRS.line);
  213.                                      CRT.GetSym(sp, sn); sn.struct := CRT.classToken;
  214.                                      CRT.PutSym(sp, sn)
  215.                                    END .)
  216.   SYNC
  217.   ( "=" TokenExpr <gL, gR> "."  (. IF kind # ident THEN SemErr(13) END;
  218.                                    CRT.CompleteGraph(gR);
  219.                                    CRA.ConvertToStates(gL, sp) .)
  220.   |                             (. IF kind = ident THEN genScanner := FALSE
  221.                                    ELSE MatchLiteral(sp)
  222.                                    END .)
  223.   [ SemText <pos>               (. IF typ = CRT.t THEN SemErr(14) END;
  224.                                    CRT.GetSym(sp, sn); sn.semPos := pos; CRT.PutSym(sp, sn) .)
  225. (*------------------------------------------------------------------------------------*)
  226. Expression <VAR gL, gR: INTEGER>  (. VAR gL2, gR2: INTEGER; first: BOOLEAN; .)
  227.   Term <gL, gR>                 (. first := TRUE .)
  228.   { WEAK "|"
  229.     Term <gL2, gR2>             (. IF first THEN 
  230.                                      CRT.MakeFirstAlt(gL, gR); first := FALSE
  231.                                    END;
  232.                                    CRT.ConcatAlt(gL, gR, gL2, gR2) .)
  233. (*------------------------------------------------------------------------------------*)
  234. Term<VAR gL, gR: INTEGER>       (. VAR gL2, gR2: INTEGER; .)
  235. =                               (. gL := 0; gR := 0 .)
  236.   ( Factor <gL, gR>
  237.     { Factor <gL2, gR2>         (. CRT.ConcatSeq(gL, gR, gL2, gR2) .)
  238.     }
  239.   |                             (. gL := CRT.NewNode(CRT.eps, 0, 0); gR := gL .)
  240. (*------------------------------------------------------------------------------------*)
  241. Factor <VAR gL, gR: INTEGER>    (. VAR sp, kind, c: INTEGER; name: CRT.Name;
  242.                                        gn: CRT.GraphNode; sn: CRT.SymbolNode;
  243.                                        set: CRT.Set;
  244.                                        undef, weak: BOOLEAN;
  245.                                        pos: CRT.Position; .)
  246.                                 (. gL :=0; gR := 0; weak := FALSE .)
  247. ( [ "WEAK"                      (. weak := TRUE .)
  248.   Symbol <name, kind>           (. sp := CRT.FindSym(name); undef := sp = CRT.noSym;
  249.                                    IF undef THEN
  250.                                      IF kind = ident THEN  (*forward nt*)
  251.                                        sp := CRT.NewSym(CRT.nt, name, 0)
  252.                                      ELSE  (*undefined string in production*)
  253.                                        sp := CRT.NewSym(CRT.t, name, CRS.line);
  254.                                        MatchLiteral(sp)
  255.                                      END
  256.                                    END;
  257.                                    CRT.GetSym(sp, sn);
  258.                                    IF ~(sn.typ IN {CRT.t,CRT.nt}) THEN SemErr(4) END;
  259.                                    IF weak THEN 
  260.                                      IF sn.typ = CRT.t THEN sn.typ := CRT.wt ELSE SemErr(23) END
  261.                                    END;
  262.                                    gL := CRT.NewNode(sn.typ, sp, CRS.line); gR := gL .)
  263.                                 
  264.   ( Attribs <pos>               (. CRT.GetNode(gL, gn); gn.pos := pos; CRT.PutNode(gL, gn);
  265.                                    CRT.GetSym(sp, sn);
  266.                                    IF undef THEN 
  267.                                      sn.attrPos := pos; CRT.PutSym(sp, sn)
  268.                                    ELSIF sn.attrPos.beg < 0 THEN SemErr(5)
  269.                                    END;
  270.                                    IF kind # ident THEN SemErr(3) END .)
  271.   |                             (. CRT.GetSym(sp, sn);
  272.                                    IF sn.attrPos.beg >= 0 THEN SemErr(6) END .)
  273. | "(" Expression <gL, gR> ")"
  274. | "[" Expression <gL, gR> "]"   (. CRT.MakeOption(gL, gR) .)
  275. | "{" Expression <gL, gR> "}"   (. CRT.MakeIteration(gL, gR) .)
  276. | SemText <pos>                 (. gL := CRT.NewNode(CRT.sem, 0, 0); 
  277.                                    gR := gL;
  278.                                    CRT.GetNode(gL, gn); gn.pos := pos; CRT.PutNode(gL, gn) .)
  279. | "ANY"                         (. Sets.Fill(set); Sets.Excl(set, CRT.eofSy);
  280.                                    gL := CRT.NewNode(CRT.any, CRT.NewSet(set), 0); gR := gL .)
  281. | "SYNC"                        (. gL := CRT.NewNode(CRT.sync, 0, 0); gR := gL .)
  282. (*------------------------------------------------------------------------------------*)
  283. TokenExpr <VAR gL, gR: INTEGER> (. VAR gL2, gR2: INTEGER; first: BOOLEAN; .)
  284.   TokenTerm <gL, gR>            (. first := TRUE .)
  285.   { WEAK "|"
  286.     TokenTerm <gL2, gR2>        (. IF first THEN 
  287.                                      CRT.MakeFirstAlt(gL, gR); first := FALSE
  288.                                    END;
  289.                                    CRT.ConcatAlt(gL, gR, gL2, gR2) .)
  290. (*------------------------------------------------------------------------------------*)
  291. TokenTerm <VAR gL, gR: INTEGER> (. VAR gL2, gR2: INTEGER; .)
  292.   TokenFactor <gL, gR>
  293.   { TokenFactor <gL2, gR2>      (. CRT.ConcatSeq(gL, gR, gL2, gR2) .)
  294.   [ "CONTEXT"
  295.     "(" TokenExpr <gL2, gR2>    (. SetCtx(gL2); CRT.ConcatSeq(gL, gR, gL2, gR2) .)
  296.     ")"
  297. (*------------------------------------------------------------------------------------*)
  298. TokenFactor <VAR gL, gR: INTEGER> (. VAR kind, c: INTEGER; set: CRT.Set; name: CRT.Name; .)
  299.                                 (. gL :=0; gR := 0 .)
  300. ( Symbol <name, kind>           (. IF kind = ident THEN
  301.                                      c := CRT.ClassWithName(name);
  302.                                      IF c < 0 THEN
  303.                                        SemErr(15); 
  304.                                        Sets.Clear(set); c := CRT.NewClass(name, set)
  305.                                      END;
  306.                                      gL := CRT.NewNode(CRT.class, c, 0); gR := gL
  307.                                    ELSE (*string*)
  308.                                      CRT.StrToGraph(name, gL, gR)
  309.                                    END .)
  310. | "(" TokenExpr <gL, gR> ")"
  311. | "[" TokenExpr <gL, gR> "]"    (. CRT.MakeOption(gL, gR) .)
  312. | "{" TokenExpr <gL, gR> "}"    (. CRT.MakeIteration(gL, gR) .)
  313. (*------------------------------------------------------------------------------------*)
  314. Symbol <VAR name: CRT.Name; VAR kind: INTEGER> = 
  315.   ( ident                       (. kind := ident .)
  316.   | string                      (. kind := string .)
  317.   )                             (. CRS.GetName(CRS.pos, CRS.len, name);
  318.                                    IF kind = string THEN FixString(name, CRS.len) END .) .
  319. (*------------------------------------------------------------------------------------*)
  320. Attribs <VAR attrPos: CRT.Position> = 
  321.   "<"                           (. attrPos.beg := CRS.nextPos; attrPos.col := CRS.nextCol .)
  322.   { ANY }
  323.   ">"                           (. attrPos.len := SHORT(CRS.pos - attrPos.beg) .).
  324. (*------------------------------------------------------------------------------------*)
  325. SemText <VAR semPos: CRT.Position> = 
  326.   "(."                          (. semPos.beg := CRS.nextPos; semPos.col := CRS.nextCol .)
  327.   { ANY }
  328.   ".)"                          (. semPos.len := SHORT(CRS.pos - semPos.beg) .).
  329. END CR.
  330.