ucscompiler.pas

来自「本Delphi项目文件为本人在一个Pascal-s(子集)源代码基础上完成的。本」· PAS 代码 · 共 1,455 行 · 第 1/5 页

PAS
1,455
字号
                            then CCLex.Insymbol
                            else begin
                                CCLex.error(12);
                                if CCLex.sy = rparent then CCLex.Insymbol
                            end;
                            if CCLex.sy = ofsy then CCLex.Insymbol else CCLex.error(8);
                            typ(fsys,eltp,elrf,elsz)
                        end;
                        with atab[aref] do
                        begin
                            arsz:= (high - low +1)*elsz; size:= arsz;
                            eltyp := eltp; elref := elrf; elsize := elsz
                        end;
                    end;//arraytyp

            begin {typ}
                tp := notyp; rf:= 0; sz:= 0;
                test(typebegsys,fsys,10);
                if CCLex.sy in typebegsys
                then begin
                    if CCLex.sy = ident
                    then begin
                        x:= loc(id);
                        if x<> 0
                        then with tab[x] do
                            if obj<>typel
                            then    CCLex.error(29)

                            else begin
                                tp:= typ; rf:= ref; sz:= adr;
                                if tp= notyp then CCLex.error(30)//
                            end;
                        CCLex.Insymbol
                    end else if CCLex.sy = arraysy
                            then begin
                                CCLex.Insymbol;
                                if CCLex.sy= lbrack
                                then CCLex.Insymbol
                                else begin
                                    CCLex.error(11);
                                    if CCLex.sy=lparent
                                    then CCLex.Insymbol
                                end;
                                tp:= arrays;   arraytyp(rf,sz)
                            end else begin {records}
                            CCLex.Insymbol;
                            enterblock;
                            tp := records; rf:= b;
                            if level= lmax then CCLex.fatal(5);
                            level := level + 1;  display[level]:= b; offset := 0;
                            while not (CCLex.sy in fsys-[semicolon,comma,ident]+[endsy])  do
                            begin {field section}
                                if CCLex.sy= ident
                                then begin
                                    t0:= t; entervariable;
                                    while CCLex.sy = comma do
                                    begin
                                        CCLex.Insymbol; entervariable
                                    end;
                                    if CCLex.sy =colon then CCLex.Insymbol else CCLex.error(5);
                                    t1:= t;
                                    typ(fsys+[semicolon,endsy,comma,ident],eltp,elrf,elsz);
                                    while t0<t1 do
                                    begin
                                        t0:= t0+1;
                                        with tab[t0] do
                                        begin
                                            typ:= eltp;
                                            ref:= elrf;
                                            normal := true;
                                            adr:= offset;
                                            offset:= offset + elsz;//add;
                                        end
                                    end
                                end;{CCLex.sy=ident}
                                if CCLex.sy<>endsy
                                    then begin
                                    if CCLex.sy =semicolon
                                    then CCLex.Insymbol
                                    else begin
                                        CCLex.error(14);
                                        if CCLex.sy= comma then CCLex.Insymbol
                                    end;
                                        test([ident,endsy,semicolon],fsys,6)
                                    end
                                end;{field section}
                                btab[rf].vsize := offset; sz:= offset;
                                btab[rf].psize := 0;
                                CCLex.Insymbol;   level:= level -1;
                            end;{records}
                    test(fsys,[],6);
                    end
            end;//typ
            procedure parameterlist;
            var tp:types;
                valpar: boolean;
                rf,sz,x,t0:integer;
            begin
                CCLex.Insymbol;
                tp := notyp; rf:=0; sz:= 0;
                test([ident,varsy],fsys+[rparent],7);
                while CCLex.sy in [ident ,varsy] do
                begin
                    if CCLex.sy<>varsy
                    then valpar:=true
                    else begin
                        CCLex.Insymbol;
                        valpar:= false
                    end;
                    t0:= t; entervariable;
                    while CCLex.sy=comma do
                    begin
                        CCLex.Insymbol; entervariable;
                    end;
                    if CCLex.sy=colon
                    then begin
                      CCLex.Insymbol;
                      if CCLex.sy<> ident
                      then CCLex.error(2)
                      else begin
                         x:= loc(id); CCLex.Insymbol;
                         if x<>0
                         then with tab[x] do
                                if obj<>typel
                                then CCLex.error(29)
                                else begin
                                    tp:= typ; rf:= ref;
                                    if valpar then sz:= adr else sz:=1
                                end;
                         end;
                      test([semicolon,rparent],[comma,ident]+fsys,14)
                    end else CCLex.error(5);
                    while t0< t do
                    begin
                     t0:= t0+1;
                     with  tab[t0] do
                     begin
                        typ:= tp; ref:= rf;
                        adr:= dx; lev:= level;
                        normal := valpar;
                        dx := dx+sz
                     end
                    end;
                    if CCLex.sy <> rparent
                    then begin
                     if CCLex.sy= semicolon
                     then CCLex.Insymbol
                     else begin
                        CCLex.error(14);
                        if CCLex.sy=comma then CCLex.Insymbol
                     end;
                     test([ident,varsy],[rparent]+fsys,6)
                    end
                end;//while
                if CCLex.sy =rparent
                then begin
                 CCLex.Insymbol;
                 test([semicolon,colon],fsys,6)
                end else CCLex.error(4)
            end;//parameterlist

            PROCEDURE  constdec;
            var c:conrec;
            begin
                CCLex.Insymbol;
                test([ident],blockbegsys,2);
                while CCLex.sy = ident do
                begin
                    enter(id,konstant); CCLex.Insymbol;
                    if CCLex.sy = eql
                    then CCLex.Insymbol
                    else begin
                        CCLex.error(16);
                        if CCLex.sy= becomes then CCLex.Insymbol
                    end;
                    constant([semicolon,comma,ident]+fsys,c);
                    tab[t].typ := c.tp;
                    tab[t].ref:=0;
                    if c.tp=reals
                    then begin
                        enterreal(c.r); tab[t].adr:= c1;
                    end else tab[t].adr:= c.i;
                    testsemicolon
                end
            end;//constdec

            procedure typedeclaration;
            var    tp:types;
                rf,sz,t1: integer;
            begin
                CCLex.Insymbol;
                test([ident],blockbegsys,2);
                while CCLex.sy= ident do
                begin
                    enter(id,typel);
                    t1:= t; CCLex.Insymbol;
                    if CCLex.sy=eql
                    then CCLex.Insymbol
                    else begin
                        CCLex.error(16);
                        if CCLex.sy=becomes then CCLex.Insymbol
                    end;
                    typ([semicolon,comma,ident]+fsys,tp,rf,sz);
                    with tab[t1] do
                    begin
                        typ:=tp; ref := rf; adr := sz;
                    end;
                    testsemicolon
                end
            end;//typedeclaration

            procedure variabledeclaration;
            var     tp:types;
                t0,t1,rf,sz:integer;
            begin
                CCLex.Insymbol;
                while CCLex.sy=ident do
                begin
                    t0:= t; entervariable;
                    while CCLex.sy=comma do
                    begin
                        CCLex.Insymbol; entervariable;
                    end;
                    if CCLex.sy= colon then CCLex.Insymbol else CCLex.error(5);
                    t1:= t;
                    typ([semicolon,comma,ident]+fsys,tp,rf,sz);
                    while t0< t1 do
                    begin
                        t0:= t0+1;
                        with tab[t0] do
                        begin
                            typ := tp; ref:= rf;
                            lev := level; adr:= dx;
                            normal:= true;
                            dx:= dx+sz;
                        end
                    end;
                    testsemicolon
                end
                end;//variabledeclaration

                procedure procdeclaration;
                var isfun:boolean;
                begin
                    isfun:= sy= funcsy;
                    CCLex.Insymbol;
                    if sy<>ident
                    then begin
                        CCLex.error(2); id:='          ';
                    end;
                    if isfun then
                        enter(id,funktion)
                    else
                        enter(id,prozedure);
                    tab[t].normal := true;
                    CCLex.Insymbol;
                    block([semicolon]+fsys,isfun,level+1);
                    if sy=semicolon then CCLex.Insymbol else CCLex.error(14);
                    emit(32+ord(isfun));//exit
                end;//proceduredeclaration

                procedure statement(fsys:symset);
                var i:integer;
                    x: item;
                    procedure expression(fsys:symset;var x: item);forward;

                        procedure selector(fsys:symset;var v:item);
                        var x: item;
                            a,j: integer;
                        begin
                            repeat
                                if sy=period
                                then begin
                                    CCLex.Insymbol;//field selector
                                    if sy<>ident
                                    then CCLex.error(2)
                                    else begin
                                        if v.typ<>records
                                        then CCLex.error(31)
                                    else begin//search field identifier
                                        j:= btab[v.ref].last;
                                        tab[0].name:= id;
                                        while tab[j].name <>id do j:= tab[j].link;
                                        if j=0 then CCLex.error(0);
                                        v.typ:= tab[j].typ;
                                        v.ref:= tab[j].ref;
                                        a:= tab[j].adr;
                                        if a<>0 then emit1(9,a);
                                        end;
                                        CCLex.Insymbol
                                        end

⌨️ 快捷键说明

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