home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1987-07-16 | 6.8 KB | 271 lines |
- IMPLEMENTATION MODULE -->modulenamelex;
-
- FROM Files IMPORT
- ReadNBytes;
- FROM SYSTEM IMPORT
- ADR;
- FROM FileIO IMPORT
- con, WriteString;
-
- CONST
- buffersize = 2048; (*input buffer size*)
- idmax = 4980; (*max.length of identifier-list*)
- htmax = 599; (*max.length of hash table*)
- CR = 15C;
- LF = 12C;
- EF = 4C;
-
- -->declarations
- TYPE
- Buffer = ARRAY[0..buffersize-1] OF CHAR;
- Charset = ARRAY[0..7] OF BITSET;
- Class = ARRAY[0..classes-1] OF RECORD
- set: Charset;
- END;
- Starttable = ARRAY[0..127] OF CARDINAL;
-
- VAR
- ch: CHAR; (*current input character*)
- col: CARDINAL; (*current input columns*)
- state: CARDINAL; (*current state*)
- apx: CARDINAL; (*length of appendix*)
-
- VAR
- class: Class; (*generated character classes*)
- comstart: Charset; (*set of comment start symbols*)
- ignored: Charset; (*set of ignored characters in start state*)
- starttab: Starttable; (*start state for every character*)
- attr: CARDINAL; (*attribute value*)
- filled: BOOLEAN; (*TRUE if attr is filled*)
-
- VAR
- inbuffer: Buffer;
- ip: CARDINAL; (*ptr to next character in input buffer*)
- ipmax: CARDINAL; (*ptr to last character in input buffer*)
-
- VAR
- id: ARRAY[0..idmax+20] OF CHAR; (*identifiers*)
- idact: CARDINAL; (*last character IN id*)
- idp: CARDINAL; (*last character of new token*)
- keys: CARDINAL; (*position OF last keyword IN id*)
- ht: ARRAY[0..htmax] OF INTEGER; (*hash table*)
-
- VAR
- oldch: ARRAY[0..160] OF CHAR; (*delayed input*)
- oldcol: ARRAY[0..160] OF CARDINAL; (*columns of delayed input*)
- oldip: CARDINAL; (*length of delayed input*)
- eols: CARDINAL; (*nr.of EOLs in a comment*)
- i: CARDINAL;
-
-
- PROCEDURE Comment(): BOOLEAN;
- VAR
- level: CARDINAL;
- och: CHAR;
- ocol: CARDINAL;
-
- PROCEDURE RememberEols;
- BEGIN
- IF eols>0 THEN
- IF ch<>LF THEN PushInput(ch); END;
- WHILE eols>0 DO PushInput(LF); PushInput(CR); DEC(eols); END;
- NextCh;
- END;
- END RememberEols;
-
- BEGIN (*Comment*)
- level:=1; eols:=0;
- -->comment
- END Comment;
-
-
- PROCEDURE CutAppendix;
- BEGIN
- PushInput(ch);
- WHILE apx>0 DO
- PushInput(id[idp]); DEC(idp); DEC(apx);
- END;
- NextCh;
- END CutAppendix;
-
-
- PROCEDURE Element(x:CARDINAL; set:Charset): BOOLEAN;
- BEGIN RETURN (x MOD 16) IN set[x DIV 16]; END Element;
-
-
- PROCEDURE GetSy(VAR token:CARDINAL);
- VAR typ,column,spix: CARDINAL;
-
- PROCEDURE Error;
- BEGIN typ:=errortoken; END Error;
-
- BEGIN (*GetSy*)
- IF filled (*attribute available*)
- THEN token:=attr; filled:=FALSE;
- ELSE
- -->GetSy1
- column:=col; idp:=idact;
- IF Element(ORD(ch),ignored)
- THEN ShiftIgnore(starttab[ORD(ch)]);
- ELSE Shift(starttab[ORD(ch)]);
- END;
- LOOP
- CASE state OF
- 1:
- -->GetSy2
- ELSE Error; NextCh; EXIT;
- END; (*CASE*)
- END; (*LOOP*)
- token:=256*typ+column;
- END;
- END GetSy;
-
-
- PROCEDURE GetVal(spix:CARDINAL;VAR name:ARRAY OF CHAR;VAR l:CARDINAL);
- VAR i: CARDINAL;
- BEGIN
- i:=spix; l:=0;
- WHILE (id[i]<>0C) AND (l<=HIGH(name)) DO
- name[l]:=id[i]; INC(i); INC(l);
- END;
- END GetVal;
-
-
- PROCEDURE Hash(VAR spix: CARDINAL);
- VAR
- h,l: CARDINAL;
- d: INTEGER;
-
- PROCEDURE Equal(x,y,l:CARDINAL):BOOLEAN;
- VAR i: CARDINAL;
- BEGIN
- i:=0;
- WHILE (i<l) AND (id[x+i]=id[y+i]) DO INC(i); END;
- RETURN i=l;
- END Equal;
-
- BEGIN (*Hash*)
- INC(idp); id[idp]:=0C;
- l:=idp-idact; spix:=idact+1;
- h:=(ORD(id[spix])*7 + ORD(id[spix+1]) + l) * 17 MOD htmax;
- d:= -htmax;
- LOOP
- IF ht[h]=0 THEN (*new identifier*)
- ht[h]:=spix; idact:=idp;
- EXIT;
- ELSIF Equal(ht[h],spix,l) THEN (*old identifier*)
- spix:=ht[h]; EXIT;
- ELSE (*collision*)
- d:=d+2;
- IF d=htmax THEN
- WriteString(con,"$--- Hash table full$"); HALT;
- END;
- h:=(h+CARDINAL(ABS(d))) MOD htmax;
- END;
- END; (*LOOP*)
- IF idp>idmax THEN
- WriteString(con,"$--- Name list full$"); HALT;
- END;
- END Hash;
-
-
- PROCEDURE InitClass(nr,x1,x2,x3,x4,x5,x6,x7,x8:CARDINAL);
- BEGIN
- WITH class[nr] DO
- set[0]:=BITSET(x1); set[1]:=BITSET(x2);
- set[2]:=BITSET(x3); set[3]:=BITSET(x4);
- set[4]:=BITSET(x5); set[5]:=BITSET(x6);
- set[6]:=BITSET(x7); set[7]:=BITSET(x8);
- END;
- END InitClass;
-
-
- PROCEDURE InitIgnored(x1,x2,x3,x4,x5,x6,x7,x8:CARDINAL);
- BEGIN
- ignored[0]:=BITSET(x1); ignored[1]:=BITSET(x2);
- ignored[2]:=BITSET(x3); ignored[3]:=BITSET(x4);
- ignored[4]:=BITSET(x5); ignored[5]:=BITSET(x6);
- ignored[6]:=BITSET(x7); ignored[7]:=BITSET(x8);
- END InitIgnored;
-
-
- PROCEDURE InitStartTab(base,x1,x2,x3,x4,x5,x6,x7,x8:CARDINAL);
- BEGIN
- starttab[base]:=x1; starttab[base+1]:=x2;
- starttab[base+2]:=x3; starttab[base+3]:=x4;
- starttab[base+4]:=x5; starttab[base+5]:=x6;
- starttab[base+6]:=x7; starttab[base+7]:=x8;
- END InitStartTab;
-
-
- PROCEDURE Keyword(spix:CARDINAL; VAR keynr:CARDINAL): BOOLEAN;
- BEGIN
- IF spix<=keys
- THEN keynr:=ORD(id[spix-1]); RETURN TRUE;
- ELSE RETURN FALSE;
- END;
- END Keyword;
-
-
- PROCEDURE NewKey(sy:CARDINAL; key:ARRAY OF CHAR);
- VAR i: CARDINAL;
- BEGIN
- INC(idact); id[idact]:=CHR(sy); idp:=idact;
- FOR i:=0 TO HIGH(key) DO INC(idp); id[idp]:=key[i]; END;
- Hash(keys); (*keys contains the last keyword spix at any time*)
- END NewKey;
-
-
- PROCEDURE NextCh; (*return global variable ch*)
- BEGIN
- IF oldip>0
- THEN
- DEC(oldip); ch:=oldch[oldip]; col:=oldcol[oldip];
- ELSE
- IF ip>=ipmax THEN
- ipmax := ReadNBytes(src,ADR(inbuffer),buffersize);
- IF ipmax=0 THEN inbuffer[0]:=EF; END;
- ip:=0;
- END;
- ch:=inbuffer[ip]; INC(ip);
- IF ch=LF THEN col:=0; INC(eols); ELSE INC(col); END;
- END;
- END NextCh;
-
-
- PROCEDURE PushInput(ch:CHAR);
- BEGIN
- oldch[oldip]:=ch; oldcol[oldip]:=col; INC(oldip);
- END PushInput;
-
-
- PROCEDURE Shift(s:CARDINAL);
- BEGIN
- INC(idp); id[idp]:=ch; apx:=0; NextCh;
- state:=s;
- END Shift;
-
-
- PROCEDURE ShiftIgnore(s:CARDINAL);
- BEGIN
- apx:=0; NextCh;
- state:=s;
- END ShiftIgnore;
-
-
- PROCEDURE ShiftLA(s:CARDINAL);
- BEGIN
- INC(idp); id[idp]:=ch; INC(apx); NextCh;
- state:=s;
- END ShiftLA;
-
-
- BEGIN (*Scanner*)
- ip:=buffersize; ipmax:=ip; oldip:=0; (*init input*)
- col:=0; ch:=" "; eols:=0;
- filled:=FALSE;
- FOR i:=0 TO htmax-1 DO ht[i]:=0; END; (*init name list*)
- idact:=0;
- -->initializations
- END -->modulenamelex.