|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 35328 (0x8a00) Types: TextFile Names: »xfortran4tx «
└─⟦01e83a425⟧ Bits:30008166 Bånd med SW8010 og SW8500 source code └─⟦75ff9bef3⟧ └─⟦this⟧ »xfortran4tx «
xfortran = algol index.no begin <* bobs-system parser *> <* algol6 - version *> <* rewritten from pascal *> <* october 76 *> message version id: 88 10 10, 4; integer linemax, <* max line length *> stackmax, <* parse stack size *> bufmax, <* max no of chars in name and consts *> lrmax, <* size of lr-tables *> lxmax, <* size of lexical tables *> errorval, <* *> nameval, <* internal value of name *> constval, <* - - - const *> stringval, <* - - - string *> stringch, <* stringescape char *> curchclass, <* class of curch *> filemax, <* max no of files allowed to be defined *> fpmax, <* max size of call of compiler *> errormax; <* max no of marked errors*> zone productions(128,1,stderror); zone parsetables(128,1,stderror); zone xref(128,1,stderror); integer field f2,f4,f6,f8,f10,f12,f14,f16,f18; f2:=2; f4:=4; f6:=6; f8:=8; f10:=10; f12:=12; f14:=14; f16:=16; f18:=18; linemax := 150; fpmax:=60; stackmax := 60; bufmax := 12; errormax := 10; filemax := 5; open(productions,4,<:productions:>,0); open(parsetables,4,<:parsetables:>,0); inrec6(parsetables,18); lrmax:=parsetables.f6; lxmax:=parsetables.f8; errorval:=parsetables.f10; nameval:=parsetables.f12; constval:=parsetables.f14; stringval:=parsetables.f16; stringch:=parsetables.f18; begin integer array lrchain,lrnext,lr(0:lrmax); <* lr(.) bit 0 - 2 kind bit 3 - 11 symb/rs bit 12 - 23 lb/prd (if kind=5 then this field is 0) *> integer kind, symb; integer startinx; <* start of current state in lr *> integer array stack(0:stackmax); <* parse stack *> integer stacktop, newtop; integer array entry(1:4,32:127); <* entry(1,.) - np (0:lxmax) entry(2,.) - hp ( - ) entry(3,.) - tv (0:symbmax) entry(4,.) - ch4 ( charvalue ) *> integer np,tv,hp,ch4; integer array lx(1:4,0:lxmax); <* lexical tables *> <* the entries are as above *> integer newsymb, <* current terminal symbol *> curch; <* current char *> integer array name(1:bufmax), <* current name in chars *> konst,konstbuf(0:bufmax); <* current const in chars *> integer nameno, konstno; integer stringescape, lineinx; <* pos in line of current char *> boolean letterordigit, <* true if current char is letter or digit *> ok, <* false when parsing has to be stopped *> moreinput; <* false when input is exhausted *> integer array errormark(1:2,0:errormax); <* errormark(1,.) - errornous lineno - (2,.) - errornous char pos. *> integer array line1,line2,ltype1,ltype2(0:linemax); <* line buffer and type *> integer errorcount,linecount1,linecount2,lineno ; <* index to line *> integer linecount3; boolean newline, <* newline char (local) *> firsttime , <* used to handle output *> more, <* true as long as more input in buffer2 *> anything_left, commentline; <* false when input line is skipped *> integer startexp,konstlimit,s1,new1,i,j; boolean readexp; <* true if read statement *> integer endexp, <* pointer to exp in special read-write *> startio, <* start of io list *> fileinx; <* no of defined files *> boolean firstdefine ,format; integer array unit(1:2,1:filemax), <* unit no in define file *> assvar(1:6,1:filemax), <* the associated variable *> conv(0:225) , <* converted prod number *> recsize(1:filemax), <* the recordsize *> cheat(1:3),tcheat(1:3); <* used to avoid parsing formats *> zone outfile(128,1,stderror); <* the zone name used to outputfile *> integer array tail(1:20),fp(1:fpmax); <* tail of entry, fp-stack *> real array workfile,fpparam(1:2); <* parameters to system-procedure *> real array sourcename(1:2); <* filename for input to normal fortran *> integer fpinx,sourceinx,paramno; integer array rem(1:20), <* array to remember pos of dots *> testword(1:10); <* contains some operators *> integer reminx; <* index to rem *> boolean dot, <* true if dots in line *> random1, <* true if random access *> xfortrantest, <* true if test-output *> crossref; <* true if crossref of prg *> procedure outfilno(inx); value inx; integer inx; begin integer i; for i:=1,2 do if unit(i,inx)=32 then i := 10000 else outchar(outfile, unit(i,inx)); end; procedure outassvar(inx); value inx; integer inx; begin integer i; for i:=1 step 1 until 6 do if assvar(i,inx)=32 then i := 10000 else outchar(outfile,assvar(i,inx)); end; procedure outfiledef(inx); value inx; integer inx; begin integer i; if firstdefine then begin firstdefine := false; lineno := lineno+1; write(outfile, <: logical setposition:>, newline, 1); end; write(outfile, <: zone fil:>); outfilno(inx); write(outfile, <:(:>, <<ddd>, 128*recsize(inx), <:, 1, stderror):>, newline, 1, <: integer :>); outassvar(inx); write(outfile, newline, 1); lineno := lineno + 2; write(outfile, <: common/comfil:>); outfilno(inx); write(outfile, <:/fil:>); outfilno(inx); write(outfile, <:/comass:>); outfilno(inx); write(outfile, <:/:>); outassvar(inx); write(outfile, newline, 1); lineno := lineno + 1; end; procedure code(prodno); value prodno; integer prodno; begin integer ii; if xfortrantest then write(productions,<<dddd>,prodno); if conv(prodno)=0 then goto exitcode; case conv(prodno) of begin <* -1- <simple statement> ::= <rewind> konst / <endfile> konst *> begin lineno:=lineno+1; for i:=1 step 1 until 6 do outchar(outfile,line1(i)); if prodno=130 then begin <* rewind *> write(outfile,<:call setposition(fil:>); for i:=1 step 1 until konstno do outchar(outfile,konst(i)); write(outfile,<:, 0, 0):>,newline,1); end else begin <* endfile *> write(outfile,<:call close(fil:>); for i:=1 step 1 until konstno do outchar(outfile,konst(i)); write(outfile,<:, .true.):>,newline,1); end end; <* -2- <rewind> ::= rewind <endfile>::= endfile *> commentline := true; <* -3- <special read statem> ::= read ( <fileno> ' <special write statem>::= write ( <fileno> ' *> begin if prodno = 174 then readexp:=true else readexp:=false; commentline := true; end; <* -4- <special read write> ::= <special read statem> <expr> ) / <special write statem> <expr> ) *> begin for ii:=1 step 1 until fileinx do if unit(1,ii)=konstbuf(1) and unit(2,ii)=konstbuf(2) then goto found; markerror; ii:=1; found : if random1 then <* random access *> begin lineno:=lineno+1; write(outfile,<: call setposition(fil:>); outchar(outfile,konstbuf(1)); outchar(outfile,konstbuf(2)); write(outfile,<:, 0, (:>); for i:=1 step 1 until endexp do outchar(outfile,rem(i)); write(outfile,<: - 1)*:>,<<ddd>,recsize(ii),<:):>,newline,1); end; lineno:=lineno+1; write(outfile,<: :>,if readexp then <:read:> else <:write:>, <:(fil:>); for i:=1 step 1 until konstlimit do outchar(outfile,konstbuf(i)); write(outfile,<:) :>); for i:=startio step 1 until linecount1-1 do outchar(outfile,line1(i)); <* associated variable *> write(outfile,newline,1); lineno:=lineno+1; for i:=1 step 1 until 6 do outchar(outfile,line1(i)); outassvar(ii); write(outfile,<: = 1 + :>); for i:=1 step 1 until endexp do outchar(outfile,rem(i)); write(outfile,newline,1); startexp:=0; end; <* -5- <expr> ::= <prim5> *> if startexp>0 then begin startio:=lineinx; if line1(startexp)<48 then startexp:=startexp+1; for i:=startexp step 1 until lineinx-2 do rem(i-startexp+1):=line1(i); endexp:=lineinx-1-startexp; end; <* -6- <unit> ::= konst *> begin commentline := true; if fileinx < filemax then fileinx := fileinx+1 else stop(4); unit(1,fileinx) := konst(1); unit(2,fileinx) := if konstno=1 then 32 else konst(2); end; <* -7- <noofrec> ::= konst *> begin <* this is not used in this version *> end; <* -8- <max> ::= konst *> begin j:=0; for i:=1 step 1 until konstno do j:=j*10+konst(i)-48; recsize(fileinx):=if j mod 256=0 then j/256 else j/256+1;; end; <* -9-<program start> ::= <prg> name <sep> <firstpart> / <prg> name <sep> *> begin for i:=1 step 1 until fileinx do begin lineno:=lineno+1; write(outfile,<: call open(fil:>); outfilno(i); write(outfile,<:, 4, 'fil:>); outfilno(i); write(outfile,<:', 0):>,newline,1,<: :>); lineno:=lineno+1; outassvar(i); write(outfile,<: = 1 :>,newline,1); end; end; <* -10- <filedef> ::= <unit> ( <noofrec>,<max>,name,name ) *> begin if nameno>6 then nameno:=6; for i:=1 step 1 until nameno do assvar(i,fileinx):=name(i); for i:=nameno+1 step 1 until 6 do assvar(i,fileinx):=32; outfiledef(fileinx); end; <* -11- <f> ::= format / formato *> begin format :=true; for i := i while true do begin lineno:=lineno+1; j:=if linecount1>=72 then 72 else linecount1-1; for i:=1 step 1 until j do outchar(outfile,line1(i)); write(outfile,newline,1); if line1(linecount1)=59 then <* format statement terminated *> begin <* copy cheat line into linebuf *> j:=if curch=32 then lineinx+1 else lineinx; for i:=j step 1 until j+2 do begin line1(i):=cheat(i-j+1); ltype1(i):=tcheat(i-j+1); end; linecount1:=j+2; goto exit; end; nextline; end while; exit : end; <* -12- <fileno> ::= konst *> begin konstbuf(1):=konst(1); konstbuf(2):=if konstno=1 then 32 else konst(2); startexp:=lineinx; konstlimit:=konstno; end; <* -13- <statement> ::= <f> ( <format field> ) *> format := false; <* -14- <leftside> ::= <variable> = <if> ::= if *> begin if reminx=0 then checkpoint; if line1(linecount1)<>59 then dot:=true; end; <* -15- <simple statement> ::= <leftside> <expr> <cond statement> ::= <if> ( <expr> ) <simple statement> / <if> ( <expr> ) konst, konst, konst *> begin dot := false; reminx:=0; end; <* -16- <sub-name> ::= name *> begin <*used in crossref *> i:=-1; write(xref,newline,1,i,nameno,<: :>); for i:=1 step 1 until nameno do outchar(xref,name(i)); end; <* -17- <prg> ::= program *> begin <*used in crossref *> i:=-1; j:=4; write(xref,newline,1,i,j,<: main:>); end; <* -18- <pause> ::= pause <find> ::= find *> begin commentline:= true; lineno:=lineno+1; for i:=1 step 1 until 6 do outchar(outfile,line1(i)); write(outfile,<:continue:>,newline,1); end; <* -19- <program-unit> ::= <program-start> <statement-part> end / < do > end <procedure> ::= <procedure start> < do > end / < do > end *> ; <* empty *> <* -20- <proceduredecl> ::= subroutine <sub-name> (separator> / subroutine <sub-name> ( <formalparameters> ) <separator> / function <sub-name> ( <formalparameters> ) <separator> / <type> function <sub-name> ( <formalparameters> ) <separator> *> begin integer fileno; firstdefine := true; for fileno := 1 step 1 until fileinx do outfiledef(fileno); end; end case ; exitcode : end proc code; procedure checkpoint; <* the routine makes some lexical work removing . around some relational operators (because of lr-problems) *> begin integer i,k,t1; reminx:=0; i:=7; for i:=i while i< linecount1 do if line1(i)=46 <* . *> then begin k:=i; i:=i+1; for i:=i while line1(i)=32 do i:=i+1; if (ltype1(i)=6 and ltype1(i+1)=6) then <* . followed by at least two letters *> begin t1:= (line1(i) shift 16); t1:=t1 add (line1(i+1) shift 8); t1:=t1 add (if ltype1(i+2)<>6 then 32 else line1(i+2)); i:=i+1; for j:=1 step 1 until 9 do if t1=testword(j) then goto found; j:=0; found : if j<> 0 then begin reminx:=reminx+1; rem(reminx):=k; line1(k):=32; ltype1(k):=7; <* find the belonging . *> for i:=i while line1(i)<>46 do i:=i+1; reminx:=reminx+1; rem(reminx):=i; line1(i):=32; ltype1(i):=7; i:=i+1; end; end; end else i:=i+1; end proc checkpoint ; procedure markerror; <* syntax errors are remembered by a call of this routine. furthermore if the error recovery algorithm has problems with loops this avoided by a call of lexical. *> begin if (new1=newsymb) and (s1=startinx) then lexical; new1:=newsymb; s1:=startinx; if (errorcount<errormax) and errormark(1,errorcount) <> lineno then begin errorcount := errorcount+1; errormark(1,errorcount) := lineno; errormark(2,errorcount) := lineinx; end; end proc errormark; procedure unpackfp; begin integer k,l; write(productions,newline,2); i:=1; for i:=i while i<fpinx do begin j:=fp(i) extract 12; k:=fp(i) shift (-12); write(productions,k,<: shift 12 + :>,j,newline,1); if j=0 then goto exit else if j=4 then begin i:=i+1; write(productions,fp(i),newline,1); end else if j=10 then begin for k:=1 step 1 until 4 do for j:=2 step -1 until 0 do begin l:=fp(i+k) shift (-8*j); outchar(productions,l); end; write(productions,newline,1); i:=i+4; end; i:=i+1; end; exit : end unpackfp; procedure packfp(del); <* the fp-stack is changed. repacking is done here *> value del; integer del; begin integer l, nextdel; real array nextparam(1:2); l:=del extract 12; if l=10 then j:=4 else j:=1; if (fpinx+j)>fpmax then stop(5); fpinx:=fpinx+1; fp(fpinx):=del; if l=4 then fp(fpinx+1):=fpparam(1) <* integer *> else begin <* name *> nextdel := system(4,paramno+1,nextparam); if nextdel=8 shift 12 + 10 and fpparam(1) = real <:xfort:> and nextparam(1) = real <:test:> then begin xfortrantest := true; j := -1; paramno := paramno + 1; <* skip the compound parameter *> end else if nextdel=8 shift 12 + 10 and fpparam(1)=real <:xref:> then begin <* the param xref.yes or xref.no appear *> paramno:=paramno+1; i:=system(4,paramno,fpparam); if fpparam(1)=real <:yes:> then crossref:=true; j:=-1; end else if nextdel=8 shift 12 + 10 and fpparam(1)= real <:rand:> then begin <* the parameter rand.yes or no appear *> paramno:=paramno+1; i:=system(4,paramno,fpparam); if fpparam(1)=real <:yes:> then random1:=true; j:=-1; end else if nextdel=8 shift 12 + 10 and fpparam(1)= real <:text:> then begin paramno := paramno+1; for i:=1,2 do sourcename(i) := nextparam(i); j := -1; end else begin <* pack name *> l:=1; for i:=1,2 do begin if i=2 then l:=3; fp(fpinx+l):=fpparam(i) shift (-24) extract 24; fp(fpinx+l+1):=fpparam(i) extract 24; end; end; end; fpinx:=fpinx+j; end packfp; procedure stop(n); value n; integer n; begin write(out,newline,2); case n of begin write(out,<: *** parse stack overflow (stackmax) :>); write(out,<: *** end of file encountered :>); begin for i:=1 step 1 until errorcount do write(out,newline,1,<: syntax in line :>,<<dddd>,errormark(1,i), <: char.no. :>,<<dd>,errormark(2,i)); end case 3; write(out,<: *** too many file definitions (filemax) :>); write(out,<: *** parameter list too small (fpmax) :>); write(out,<: *** line too long (linemax) :>); end case ; if n<>3 then write(out, <: in line:>, lineno); write(out,newline,1); if n<>3 then goto exitprg; end proc stop; procedure initialize; <* variables and tables are initialized in this routine *> begin ok:=moreinput:=firstdefine:=firsttime:=more:=anything_left:=true; format:=commentline:=false; konstno:=nameno:=stacktop:=lineinx:=errorcount:=fileinx:=linecount1:=linecount2:=0; stack(0):=0; curch:=32; lineno:=1; startexp:=0; <* initialization only concerning the algol 6 version : *> np := 1; hp := 2; ch4 := 4; tv := 3; newline := false add 10; conv(0):=0; for i:=1 step 1 until 180 do conv(i):=case i of (0,0,0,0,19,19,0,0,19,19, 0,0,20,20,20,20,0,0,0,0, 0,0,0,0,9,9,17,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,10,6,7,8,0, 0,0,13,0,0,16,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,11,11,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,15,0,0, 0,0,0,0,0,0,0,0,0,1, 1,0,0,0,15,15,14,0,5,0, 0,0,0,0,18,0,0,0,2,2, 2,18,0,0,0,0,0,0,0,0, 14,0,0,0,0,0,0,0,0,0, 0,4,4,3,3,12,0,0,0,0); for i:=181 step 1 until 225 do conv(i):=0; cheat(1):=120; cheat(2):=41; cheat(3):=59; tcheat(1):=6; tcheat(2):=7; tcheat(3):=7; reminx:=0; dot :=false; for i:=1 step 1 until 9 do testword(i):= long (case i of (<:lt :>,<:ge :>,<:eq :>,<:le :>, <:ne :>,<:gt :>,<:and:>,<:or :>,<:shi:>)) shift (-24) extract 24; for i:=1 step 1 until 63 do begin inrec6(parsetables,8); j:=parsetables.f2; if (j>64) and (j<94) then j:=j+32; entry(ch4,j):=j; entry(np,j):=parsetables.f4; entry(hp,j):=parsetables.f6; entry(tv,j):=parsetables.f8; end init entry; for i:=0 step 1 until lxmax do begin inrec6(parsetables,8); j:=parsetables.f2; if (j>64) and (j<94) then lx(ch4,i):=j+32 else lx(ch4,i):=j; lx(np,i):=parsetables.f4; lx(hp,i):=parsetables.f6; lx(tv,i):=parsetables.f8; end; stringescape:= entry(tv,stringch); for i:=0 step 1 until lrmax do begin inrec6(parsetables,8); lrchain(i):=parsetables.f2; lrnext(i):=parsetables.f4; kind:=parsetables.f6; symb:=parsetables.f8; if kind<>5 then begin inrec6(parsetables,2); j:=parsetables.f2; end; if kind = 5 then lr(i) := (symb shift 3) add 5 else lr(i) := (j shift 12) add (symb shift 3) add kind; end init lr; close(parsetables,true); end proc initialize; procedure readaline(line,ltype,linecount); <* the procedure reads the next line, comments are skipped *> integer linecount; integer array line,ltype; begin linecount := 0; more := anything_left; if more then begin nextsymbol: linecount := linecount + 1; if linecount > linemax then stop(6); ltype(linecount) := readchar(in,j); if 64<j and j<94 then j := j+32; <* convert to small letters *> if j=25 then begin <* end medium *> repeatchar(in); more := false; end; line(linecount) := j; if j <> 10 and j <> 25 then goto nextsymbol; if line(1) = 47 then begin anything_left := false; ltype(1) := 6; <* simulate letter *> end; linecount := linecount - 1; end; end; <* proc readaline *> procedure nextline; begin own integer char73; if firsttime then begin firsttime := false; readaline(line1,ltype1,linecount1); readaline(line2,ltype2,linecount2); end else begin for i:=1 step 1 until reminx do line1(rem(i)):=46; <* . *> if commentline then <* lines which are transformed to comments *> begin if firstdefine or (line2(6)=32) then commentline:=false; line1(1):=99; <* c *> line1(2):=42; <* * *> end; if -, format then <* if format the line is written elsewhere *> begin repline : if line1(linecount3)<>59 then linecount3:=linecount3+1; line1(linecount3):=10; line1(73):=char73; for i:=1 step 1 until linecount3 do outchar(outfile,line1(i)); if linecount3>7 then lineno := lineno+1; end; for i:=1 step 1 until linecount2 do begin line1(i):=line2(i); ltype1(i):=ltype2(i); end; linecount1:=linecount2; readaline(line2,ltype2,linecount2); if -, more then <* end of program *> begin linecount1:=linecount1+1; line1(linecount1):=59; ltype1(linecount1):=7; linecount1:=linecount1+1; if linecount1<7 then linecount1:=7; line1(linecount1):=25; <*em*> ltype1(linecount1):=8; linecount1:=linecount1+1; end; end; <* if cardmode (72 signif. chars) *> char73 := line1(73); linecount3:=linecount1; if ltype1(1) = 6 then goto repline; <* comment line in source text *> if linecount1>72 then linecount1:=72; if more and linecount1<=7 then goto repline; if dot then checkpoint; <* check points if cont. or if *> if more and (ltype2(1)=6 <* commentline *> or line2(6)=32 or linecount2<=6) then <* if not continuation line set seperator *> begin linecount1:=linecount1+1; line1(linecount1):=59; ltype1(linecount1):=7; end; end proc nextline; procedure lexical; <* returns the next terminal in newsymb *> begin integer bufi, newi, oldch ; integer array buf(1:bufmax), lxnode(1:4); boolean oldchclass; procedure inchar; <* the procedure reads the next character from the line- buffer,if possible, else the linebuffer is changed and the character is read from the new buffer. furthermore some lexical work is done here. *> begin if lineinx>= linecount1 and more then begin <*change buffer*> nextline; lineinx:=6; end; lineinx :=lineinx+1; curch := line1(lineinx); curchclass:=ltype1(lineinx); if curch=25 then begin moreinput:=false; line1(linecount1-2):=10; if linecount1>9 then for i:=1 step 1 until linecount1-2 do outchar(outfile,line1(i)); end; letterordigit := (curchclass=2) or (curchclass=6); end; <*proc inchar *> procedure packname; <* the current name (identifier) is packed here *> begin newsymb := nameval; if bufi>bufmax then bufi:=bufmax; for i:=1 step 1 until bufi do name(i):=buf(i); nameno:=bufi; if xfortrantest then begin write(productions,newline,1,<: name :>); for i:=1 step 1 until nameno do outchar(productions,name(i)); end; write(xref,newline,1,lineno,nameno,<: :>); for i:=1 step 1 until nameno do outchar(xref,name(i)); end proc packname; procedure packstring; <* the current string is read here *> begin for i:=i while true do begin if curch = stringch then begin inchar; if curch <> stringch then goto exitloop; end; inchar; end for; exitloop: newsymb := stringval; end proc packstring; <* body of lexical *> for i:=i while (curch=32) or (curch = 10) do inchar; <* spaces and nl's are skipped *> if -, moreinput then begin if newsymb = 0 then <* third *> stop(2) else if newsymb = 1 then <* second *> newsymb := 0 else <* first *> newsymb := 1; end else if curchclass = 2 then <* charclass is digit *> begin for konstno := 1,konstno+1 while letterordigit do begin if konstno <= bufmax then konst(konstno) := curch; inchar; end; konstno :=konstno-1; newsymb := constval; if xfortrantest then begin write(productions,newline,1,<: konst :>); for i:=1 step 1 until konstno do outchar(productions,konst(i)); end; end else begin <* not constant - search in termtree *> bufi := 1; buf(1) := curch; for i:= 1 step 1 until 4 do lxnode(i):= entry(i,curch); newi:= lxnode(hp); inchar; for i :=i while newi <> 0 do begin if lx(ch4,newi) = curch then begin if bufi<bufmax then begin bufi:=bufi+1; buf(bufi):=curch; end; if (bufi=10) and buf(2) =113 then inchar; <* if equivalence then skip last e *> for i := 1 step 1 until 4 do lxnode(i) := lx(i,newi); newi := lxnode(hp); inchar; end else newi := lx(np,newi); end for i; oldch := buf(bufi); oldchclass := (oldch>96)and(oldch<=125)or(oldch>47)and(oldch<58); if oldchclass and letterordigit then begin for bufi:=bufi+1,bufi+1 while letterordigit do begin if bufi<=bufmax then buf(bufi) := curch; inchar; end; bufi:=bufi-1; packname; end else if lxnode(tv)>0 then <* valid terminal *> begin newsymb := lxnode(tv); if newsymb= stringescape then packstring; end else if oldchclass then packname else markerror; end; if xfortrantest then write(productions,newline,1,<: newsymb :>,newsymb); end proc lexical; procedure parse; <* the parsing algorithm *> begin integer lri,li,si,i; procedure syntaxerror; begin integer stackp,chainp; <* the error is tried to be repaired by a stack-recovery algorithm *> markerror; if xfortrantest then write(productions,newline,1,<: error :>,startinx,newsymb); shiftstack; if -, moreinput then ok := false; for i:=i while moreinput do begin stackp := stacktop; for i:=i while stackp>0 do begin chainp := stack(stackp); for i:=i while chainp<>0 do begin if (lr(chainp) shift (-3) extract 9)=errorval then begin startinx:= stack(stackp); stacktop:= stackp-1; goto endrecover; end; chainp := lrchain(chainp); end; stackp:=stackp-1; end stackp>0; markerror; lexical; end moreinput; endrecover: end proc syntaxerror; procedure shiftstack; begin stacktop := stacktop+1; if stacktop > stackmax then stop(1); stack(stacktop) := startinx; end proc shiftstack; <* body of parse *> startinx := 1; lexical; for i:=i while ok do begin lri := startinx; i := case lr(lri) extract 3 +1 of (1,2,3,4,3,5,3); case i of begin <* 1 stop *> ok := false; <* 2 shift *> begin for i:=i while (lr(lri) shift (-3)) extract 9 <> newsymb do begin li := lrchain(lri); if li = 0 then begin syntaxerror; goto endshift; end; lri:=li; end for i; shiftstack; lexical; startinx:=lrnext(lri); endshift: end shift case2; <* 3 shift lookahead or reduce empty *> begin for i:=i while ((lr(lri) shift (-3)) extract 9)<>newsymb do begin li :=lrchain(lri); if li=0 then goto exitloop; lri := li; end; exitloop: kind := lr(lri) extract 3; if kind=2 then begin shiftstack; lexical; end else if kind = 6 then begin shiftstack; newtop := stacktop; code(lr(lri) shift (-12)); end; startinx:= lrnext(lri); end case 3; <* 4 reduce *> begin newtop := stacktop-(lr(lri) shift (-3) extract 9); i :=lr(lri) shift (-12); if conv(i) <> 0 then code(i); stacktop := newtop; startinx := lrnext(lri); end; <* 5 lookback *> begin si := stack(stacktop); for i:=i while (lr(lri) shift (-3)) <> si do begin li := lrchain(lri); if li = 0 then goto exlookback; lri := li; end; exlookback: startinx := lrnext(lri); end end case; end while; end proc parse; <* m-a-i-n p-r-o-g-r-a-m *> <* the most of the following contains code for changing the fp-stack. *> fpinx:=0; random1:=xfortrantest:=crossref:=false; paramno:=1; sourcename(1) := real <::>; i:=system(4,paramno,fpparam); if i=6 shift 12+10 then <*leftside exists *> begin i:=system(4,0,fpparam); packfp(i); i:=system(4,paramno,fpparam); end else begin <* no leftside *> i:=system(4,0,fpparam); paramno:=0; end; <* the parameter should be xfortran *> fpinx:=fpinx+1; fp(fpinx):=i; for j:=1 step 1 until 4 do fp(fpinx+j) :=long (case j of (<:for:>,<:tra:>,<:n:>,<::>)) shift (-24) extract 24; fpinx:=fpinx+4; paramno:=paramno+1; <* next parameter should be source file if any *> fpinx:=fpinx+1; fp(fpinx):=4 shift 12 + 10; sourceinx := fpinx; fpinx:=fpinx+4; i:=system(4,paramno,fpparam); j:=system(4,paramno+1,workfile); if j shift (-12) <> 4 then packfp(i); <* no source file *> paramno:=paramno+1; i:=system(4,paramno,fpparam); for i:=i while i<>0 do begin packfp(i); paramno:=paramno+1; i:=system(4,paramno,fpparam); end; i:=1; open(outfile, 4, string sourcename(increase(i)), 0); if if monitor(52) create area process:(outfile, 0, tail) = 0 then monitor( 8) reserve process :(outfile, 0 , tail) <> 0 else true then begin <* file did not exist or was not allowed for writing *> tail(1) := 42; <* size *> tail(2) := 1; <* disc preferred *> for i:=3 step 1 until 10 do tail(i) := 0; monitor(40) create entry:(outfile, 0, tail); end; tail(1):=42; tail(2):=1; for i:=3 step 1 until 10 do tail(i):=0; open(xref,4,<::>,0); monitor(40) create entry:(xref,0,tail); getzone6(xref,tail); if crossref then begin <* make call of crossref program *> fpinx:=fpinx+1; fp(fpinx):=2 shift 12 + 10; for i:=1 step 1 until 4 do fp(fpinx+i):=long (case i of(<:cro:>,<:ssr:>,<:ef:>,<::>)) shift (-24) extract 24; fpinx:=fpinx+5; fp(fpinx):=4 shift 12 +10; for i:=1 step 1 until 4 do fp(fpinx+i):=tail(i+1); fpinx:=fpinx+4; end; initialize; parse; write(outfile,false add 25 ,1); getzone6(outfile, tail); <* tail 2-5 contains the areaname for input to fortran *> for i:= 1 step 1 until 4 do fp(sourceinx+i) := tail(i+1); close(outfile,true); i:=0; write(xref,newline,1,i,i,newline,1); close(xref,true); if -, crossref then monitor(48) remove entry:(xref,0,tail); if xfortrantest then begin unpackfp; write(productions,false add 25,1); close(productions,true); stop(3); <* write out possible errormessages *> end; fpexecute(fp,fpinx*2); exitprg : end inner block; end ▶EOF◀