DIRECTORY BasicTime USING [Now], ConvertUnsafe USING [ToRope], IO USING [Put, PutChar, PutF, PutF1, PutRope, STREAM], NPGSConDefs, NPGSTypes USING [Column, ErrorType, HashTab, HashTabRec, ItemRec, NTab, NTDefaults, nullItemRec, nullProdEntry, ProdEntry, Renumber, StateData, StateDataRec, TTab, VocabIndex], Rope USING [ROPE]; NPGSTab: CEDAR PROGRAM IMPORTS BasicTime, ConvertUnsafe, IO, NPGSConDefs EXPORTS NPGSConDefs = { ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; linewidth, hashval, lastntstate, vocabspace, nlim, tlim: CARDINAL _ 0; hashtab: NPGSTypes.HashTab; ttab: NPGSTypes.TTab; ntab: NPGSTypes.NTab; statedata: NPGSTypes.StateData; ntdefaults: NPGSTypes.NTDefaults; column: NPGSTypes.Column; renumber: NPGSTypes.Renumber; vocabindex: NPGSTypes.VocabIndex; scantab: REF ScanTabArray _ NIL; ScanTabArray: TYPE = ARRAY ScanTabIndex OF CARDINAL; ScanTabIndex: TYPE = [40b..177b]; errMsgStr: ARRAY NPGSTypes.ErrorType OF ROPE = ["MAgg", "MCalled", "MDotLB", "MExpr", "MId", "MOpd", "MOptn", "MRArrow", "MThe", "MTxt", "MTypeId", "MFieldTypeId", "CloseIconExpr", "CopyIconExpr", "MoveIconExpr", "SelectIconExpr", "IconExpr", "Stmt", "MSecs", "tl"]; WordPtr: TYPE = LONG POINTER TO WORD; splitTrigger: NAT _ 500; OutString: PROC [s: LONG STRING] = { NPGSConDefs.outstring[ConvertUnsafe.ToRope[s]]; }; TabGen: PUBLIC PROC [cedar: BOOL, cusp: BOOL] RETURNS [success: BOOL_TRUE] = { Error: PROC [sel: CARDINAL] = { OutString["\nFAIL - "]; OutString[SELECT sel FROM 1 => "more than 255 terminal symbols", 2 => "more than 254 nonterminal symbols", 3 => "more than 2047 states or productions", 4 => "more than 15 symbols in a production right part", ENDCASE => "NPGS error"]; NPGSConDefs.outeol[1]; success _ FALSE; }; PrefixItem: PROC [init: CARDINAL, nItems: CARDINAL] = { IO.PutF1[st, " i: CARDINAL _ %d;\n", [cardinal[init]] ]; IO.PutRope[st, " dup: PROC = {tab[i] _ tab[i-1]; i _ i + 1};\n"]; IO.PutRope[st, " app0: PROC [transition: CARDINAL] = {\n"]; IO.PutRope[st, " tab[i] _ [[FALSE, 0], transition];\n"]; IO.PutRope[st, " i _ i + 1;\n"]; IO.PutRope[st, " };\n"]; IO.PutRope[st, " app1: PROC [pLength: CARDINAL, transition: CARDINAL] = {\n"]; IO.PutRope[st, " tab[i] _ [[FALSE, pLength], transition];\n"]; IO.PutRope[st, " i _ i + 1;\n"]; IO.PutRope[st, " };\n"]; IO.PutRope[st, " app1t: PROC [transition: CARDINAL] = {\n"]; IO.PutRope[st, " tab[i] _ [[FALSE, 1], transition];\n"]; IO.PutRope[st, " i _ i + 1;\n"]; IO.PutRope[st, " };\n"]; IO.PutRope[st, " app2: PROC [pLength: CARDINAL, transition: CARDINAL] = {\n"]; IO.PutRope[st, " tab[i] _ [[TRUE, pLength], transition];\n"]; IO.PutRope[st, " i _ i + 1;\n"]; IO.PutRope[st, " };\n"]; lagItem _ NPGSTypes.nullItemRec; needSplits _ nItems >= splitTrigger; splitNum _ 0; }; PutItem: PROC [i: CARDINAL, item: NPGSTypes.ItemRec, first: CARDINAL] = { IF (i MOD 5) = 0 OR i = first THEN { IF needSplits THEN IF i = first OR sinceSplit >= splitTrigger THEN { IF splitNum # 0 THEN IO.PutRope[st, "\n };"]; IO.PutF1[st, "\n split%d: PROC = {", [cardinal[splitNum]]]; sinceSplit _ 0; splitNum _ splitNum + 1; }; IO.PutRope[st, "\n"]; }; IF needSplits THEN IO.PutRope[st, " "] ELSE IO.PutRope[st, " "]; IF (i MOD 20) = 0 THEN { IO.PutF1[st, "-- %d\n", [cardinal[i]] ]; IF needSplits THEN IO.PutRope[st, " "] ELSE IO.PutRope[st, " "]; }; SELECT TRUE FROM item = NPGSTypes.nullItemRec => IO.PutRope[st, "i _ i + 1;"]; item = lagItem => IO.PutRope[st, "dup[];"]; ENDCASE => SELECT item.tag FROM 0 => IO.PutF1[st, "app0[%d];", [cardinal[item.pss]] ]; 1 => IF item.jf = 1 THEN IO.PutF1[st, "app1t[%d];", [cardinal[item.pss]] ] ELSE IO.PutF[st, "app1[%d, %d];", [cardinal[item.jf]], [cardinal[item.pss]] ]; 2 => IO.PutF[st, "app2[%d, %d];", [cardinal[item.jf]], [cardinal[item.pss]] ]; ENDCASE => ERROR; lagItem _ item; sinceSplit _ sinceSplit + 1; }; PostfixItem: PROC = { IF needSplits THEN { IO.PutRope[st, "\n };"]; FOR i: NAT IN [0..splitNum) DO IO.PutF1[st, "\n split%d[];", [cardinal[i]]]; ENDLOOP; }; IO.PutRope[st, "\n RETURN [tab];\n };\n"]; }; PutProc: PROC [type: ROPE] = { IO.PutRope[st, "\nInit"]; IO.PutRope[st, type]; IF cedar THEN IO.PutRope[st, ": PUBLIC PROC RETURNS ["] ELSE IO.PutRope[st, ": PUBLIC PROC [uz: UNCOUNTED ZONE] RETURNS ["]; IO.PutRope[st, type]; IO.PutRope[st, "Ref] = {\n"]; }; PutAlloc: PROC [type: ROPE, cons: BOOL _ FALSE, count: CARDINAL _ 0, all: ROPE _ NIL] = { IO.PutF[st, " tab: %gRef _ %gNEW[%g", [rope[type]], [rope[zone]], [rope[type]] ]; IF cons THEN { IO.PutRope[st, " _ [\n"]; IF count # 0 THEN IO.PutF1[st, " -- %d entries\n", [cardinal[count]] ]; RETURN; }; IF all = NIL THEN { IF count # 0 THEN IO.PutF1[st, "[%d]", [cardinal[count]] ]; IO.PutRope[st, "];\n"]; } ELSE { IO.PutF1[st, " _ ALL[%g]];\n", [rope[all]] ]; IF count # 0 THEN IO.PutF1[st, " -- %d entries\n", [cardinal[count]] ]; }; }; PutRtn: PROC [cons: BOOL _ TRUE] = { IF cons THEN IO.PutRope[st, "]];\n"]; IO.PutRope[st, " RETURN [tab];\n };\n"]; }; PutWord: PROC [i: CARDINAL, w: WORD] = { IF i # 0 THEN IO.PutChar[st, ',]; IF (i MOD 10) = 0 THEN IO.PutF1[st, "\n -- %d\n ", [cardinal[i]]] ELSE IO.PutChar[st, ' ]; IO.Put[st, [cardinal[w]]]; }; PutErrorMsg: PROC [i: CARDINAL, e: NPGSTypes.ErrorType] = { IF i # 0 THEN IO.PutChar[st, ',]; IF (i MOD 10) = 0 THEN IO.PutF1[st, "\n -- %d\n ", [cardinal[i]]] ELSE IO.PutChar[st, ' ]; IO.PutRope[st, errMsgStr[e]]; }; st: IO.STREAM; defaultLim: CARDINAL; lagItem: NPGSTypes.ItemRec; needSplits: BOOL _ FALSE; sinceSplit: CARDINAL _ 0; splitNum: CARDINAL _ 0; zone: ROPE _ IF cedar THEN NIL ELSE "uz."; IF NPGSConDefs.eofMark > 255 THEN Error[1]; defaultLim _ NPGSConDefs.totalTokens-NPGSConDefs.eofMark+1; IF defaultLim > 255 THEN Error[2]; IF NPGSConDefs.pssLim > 2047 THEN Error[3]; IF NPGSConDefs.rhsLim > 15 THEN Error[4]; IF ~success THEN RETURN [success]; ntab _ NPGSConDefs.MakeTab[NPGSConDefs.ntEntries]; ttab _ NPGSConDefs.MakeTab[NPGSConDefs.tEntries]; statedata _ NPGSConDefs.MakeStateData[NPGSConDefs.sLim]; ntdefaults _ NPGSConDefs.MakeNTDefaults[defaultLim+1]; column _ NPGSConDefs.MakeColumn[NPGSConDefs.ntEntries+1]; TableSetup[]; NPGSConDefs.closewordstream[]; SquashNTab[]; OutString["\nParse Table Data\n"]; IF NPGSConDefs.flags[printLALR] THEN {PrintNDef[]; TableOverlays[]}; vocabindex _ NPGSConDefs.MakeVocabIndex[NPGSConDefs.eofMark+1]; hashval _ 3*NPGSConDefs.eofMark/2; hashval _ MIN[251, IF hashval MOD 2 = 0 THEN hashval+1 ELSE hashval]; hashtab _ NPGSConDefs.MakeHashTab[hashval+1]; HashTabSetup[]; NPGSConDefs.openwordstream[scratch: FALSE]; st _ NPGSConDefs.tabStream; IO.PutF1[st, "-- %gImpl.mesa\n", [rope[NPGSConDefs.typeName]] ]; IO.PutF[st, " -- an NPGS production from %g, %g.\n\n", [rope[NPGSConDefs.sourceName]], [time[BasicTime.Now[]]] ]; IO.PutF1[st, "DIRECTORY %g;\n\n", [rope[NPGSConDefs.typeName]] ]; IO.PutF1[st, "%gImpl: ", [rope[NPGSConDefs.typeName]]]; IF cedar THEN IO.PutF1[st, "CEDAR "]; IO.PutF1[st, "PROGRAM\n EXPORTS %g\n", [rope[NPGSConDefs.typeName]] ]; IO.PutF1[st, " = { OPEN %g;\n", [rope[NPGSConDefs.typeName]] ]; StatePartition[]; -- compute lastntstate PutProc["ScanTable"]; PutAlloc[type: "ScanTable", count: ScanTabIndex.LAST-ScanTabIndex.FIRST-1, all: "0"]; FOR i: ScanTabIndex IN ScanTabIndex DO w: WORD _ scantab[i]; IF w # 0 THEN IO.PutF[st, " tab[%bC] _ %d;\n", [cardinal[i]], [cardinal[w]]]; ENDLOOP; PutRtn[FALSE]; PutProc["HashTable"]; IO.PutRope[st, " null: VocabHashEntry = [0, 0];\n"]; PutAlloc[type: "HashTable", count: hashval+1, all: "null"]; FOR i: CARDINAL IN [0..hashval] DO w: NPGSTypes.HashTabRec _ hashtab[i]; IF w # [0, 0] THEN IO.PutF[st, " tab[%d] _ [%d, %d];\n", [cardinal[i]], [cardinal[w.symPtr]], [cardinal[w.link]]]; ENDLOOP; PutRtn[FALSE]; PutProc["IndexTable"]; PutAlloc[type: "IndexTable", cons: TRUE, count: NPGSConDefs.eofMark+1]; IO.PutF1[st, " %d", [cardinal[vocabindex[0]]]]; FOR i: CARDINAL IN [1..NPGSConDefs.eofMark] DO w: WORD _ vocabindex[i]; PutWord[i, w]; ENDLOOP; PutRtn[]; PutProc["Vocabulary"]; IO.PutRope[st, " i: CARDINAL _ 0;\n"]; IF cedar THEN IO.PutRope[st, " appText: PROC [r: REF TEXT] = {\n"] ELSE IO.PutRope[st, " appText: PROC [r: STRING] = {\n"]; IO.PutRope[st, " FOR k: NAT IN [0..r.length) DO tab[i+k] _ r[k]; ENDLOOP;\n"]; IO.PutRope[st, " i _ i + r.length;\n"]; IO.PutRope[st, " };\n"]; PutAlloc[type: "Vocabulary", count: vocabspace]; IO.PutF1[st, " -- %d chars\n", [cardinal[vocabspace]]]; FOR i: CARDINAL IN [0..vocabspace) DO c: CHAR _ NPGSConDefs.symTab[i]; IF (i MOD 50) = 0 THEN { IF i # 0 THEN IO.PutRope[st, "\"];\n"]; IO.PutF1[st, " -- %d\n", [cardinal[i]]]; IO.PutRope[st, " appText[\""]; }; SELECT c FROM < 10C => IO.PutF1[st, "\\00%b", [cardinal[c.ORD]]]; < 40C => IO.PutF1[st, "\\0%b", [cardinal[c.ORD]]]; < 177C => IO.PutChar[st, c]; ENDCASE => IO.PutF1[st, "\\%b", [cardinal[c.ORD]]]; ENDLOOP; IO.PutRope[st, "\"];\n tab.length _ i;\n"]; PutRtn[FALSE]; hashtab _ NIL; vocabindex _ NIL; NPGSConDefs.symInfo _ NIL; renumber _ NPGSConDefs.MakeRenumber[NPGSConDefs.sLim]; StateRenumber[cusp]; PutProc["ProdData"]; IO.PutRope[st, " i: CARDINAL _ 1;\n"]; IO.PutRope[st, " lag: ProductionInfo _ [0, 0];\n"]; IO.PutRope[st, " dup: PROC = {tab[i] _ lag; i _ i + 1};\n"]; IO.PutRope[st, " appR: PROC [r: CARDINAL] = {lag.rule _ r; tab[i] _ lag; i _ i + 1};\n"]; IO.PutRope[st, " appL: PROC [lhs: CARDINAL] = {lag.lhs _ lhs; tab[i] _ lag; i _ i + 1};\n"]; IO.PutRope[st, " appRL: PROC [r, lhs: CARDINAL] = {tab[i] _ lag _ [r, lhs]; i _ i + 1};\n"]; PutAlloc[type: "ProdData", count: NPGSConDefs.numProd+1, all: "lag"]; IO.PutRope[st, " "]; { lag: NPGSTypes.ProdEntry _ NPGSTypes.nullProdEntry; FOR i: CARDINAL IN [1..NPGSConDefs.numProd] DO w: NPGSTypes.ProdEntry = NPGSConDefs.prodInfo[i]; wr: CARDINAL _ w.rule; wl: CARDINAL _ w.lhs-NPGSConDefs.eofMark+1; IF i MOD 5 = 0 THEN IO.PutF1[st, "\n -- %d\n ", [cardinal[i]] ]; SELECT TRUE FROM lag.rule # w.rule AND lag.lhs # w.lhs => IO.PutF[st, " appRL[%d, %d];", [cardinal[wr]], [cardinal[wl]] ]; lag.rule # w.rule => IO.PutF1[st, " appR[%d];", [cardinal[wr]] ]; lag.lhs # w.lhs => IO.PutF1[st, " appL[%d];", [cardinal[wl]] ]; ENDCASE => IO.PutRope[st, " dup[];"]; lag _ w; ENDLOOP; }; PutRtn[FALSE]; PutProc["NStarts"]; PutAlloc[type: "NStarts", cons: TRUE, count: lastntstate+1]; IO.PutF1[st, " %d", [cardinal[0]]]; FOR i: CARDINAL IN [1..lastntstate] DO w: WORD = statedata[i].ntIndex; PutWord[i, w]; ENDLOOP; PutRtn[]; PutProc["NLengths"]; PutAlloc[type: "NLengths", cons: TRUE, count: lastntstate+1]; IO.PutF1[st, " %d", [cardinal[0]] ]; FOR i: CARDINAL IN [1..lastntstate] DO w: WORD = statedata[i].ntLink; PutWord[i, w]; ENDLOOP; PutRtn[]; PutProc["NSymbols"]; PutAlloc[type: "NSymbols", cons: TRUE, count: nlim]; IO.PutF1[st, " %d", [cardinal[ntab[0].symbol]]]; FOR i: CARDINAL IN [1..nlim) DO w: WORD _ ntab[i].symbol; PutWord[i, w]; ENDLOOP; PutRtn[]; PutProc["NActions"]; PrefixItem[0, nlim]; IO.PutRope[st, " null: ActionEntry _ [[FALSE, 0], 0];\n"]; PutAlloc[type: "NActions", count: nlim, all: "null"]; FOR i: CARDINAL IN [0..nlim) DO PutItem[i, ntab[i].item, 0]; ENDLOOP; PostfixItem[]; PutProc["NTDefaults"]; PrefixItem[2, defaultLim+1]; IO.PutRope[st, " null: ActionEntry _ [[FALSE, 0], 0];\n"]; PutAlloc[type: "NTDefaults", count: defaultLim+1, all: "null"]; <> FOR i: CARDINAL IN [2..defaultLim] DO PutItem[i, ntdefaults[i].item, 2]; ENDLOOP; PostfixItem[]; PutProc["TStarts"]; PutAlloc[type: "TStarts", cons: TRUE, count: NPGSConDefs.sLim]; IO.PutRope[st, " 0"]; FOR i: CARDINAL IN [1..NPGSConDefs.sLim) DO w: WORD _ statedata[i].tIndex; PutWord[i, w]; ENDLOOP; PutRtn[]; PutProc["TLengths"]; PutAlloc[type: "TLengths", cons: TRUE, count: NPGSConDefs.sLim]; IO.PutRope[st, " 0"]; FOR i: CARDINAL IN [1..NPGSConDefs.sLim) DO w: WORD _ statedata[i].tLink; PutWord[i, w]; ENDLOOP; PutRtn[]; -- new for CUSP IF cusp THEN { PutProc["ErrorMsgs"]; PutAlloc[type: "ErrorMsgs", cons: TRUE, count: NPGSConDefs.sLim]; IO.PutRope[st, " tl"]; FOR i: CARDINAL IN [1..NPGSConDefs.sLim) DO e: NPGSTypes.ErrorType _ NPGSConDefs.CuspPreGetErrorMsg[i]; PutErrorMsg[i, e]; ENDLOOP; NPGSConDefs.CuspPreClearErrorMsgArray[]; PutRtn[]; }; -- end of CUSP additions PutProc["TSymbols"]; PutAlloc[type: "TSymbols", cons: TRUE, count: tlim]; IO.PutF1[st, " %d", [cardinal[ttab[0].symbol]]]; FOR i: CARDINAL IN [1..tlim) DO w: WORD _ ttab[i].symbol; PutWord[i, w]; ENDLOOP; PutRtn[]; PutProc["TActions"]; PrefixItem[0, tlim]; IO.PutRope[st, " null: ActionEntry _ [[FALSE, 0], 0];\n"]; PutAlloc[type: "TActions", count: tlim, all: "null"]; FOR i: CARDINAL IN [0..tlim) DO PutItem[i, ttab[i].item, 0]; ENDLOOP; PostfixItem[]; IO.PutRope[st, "\n}.\n"]; NPGSConDefs.prodInfo _ NIL; ntab _ NIL; ntdefaults _ NIL; renumber _ NIL; statedata _ NIL; ttab _ NIL; scantab _ NIL; }; TableSetup: PROC = { defaultitem, item: NPGSTypes.ItemRec; defaultprod, i, j, k, symbol, ttix, ntix, six, index, ptr: CARDINAL; ColumnEntry: PROC = { j: INTEGER; lastptr: CARDINAL _ 0; ptr _ ntdefaults[symbol].count; DO IF ptr=0 THEN GOTO insert; j _ item.jf-column[ptr].item.jf; IF j=0 THEN j _ item.pss-column[ptr].item.pss; IF j=0 THEN GOTO countup; IF j<0 THEN GOTO insert; lastptr _ ptr; ptr _ column[ptr].link; REPEAT countup => column[ptr].count _ column[ptr].count+1; insert => { column[index].item _ item; IF lastptr=0 THEN { --head of list for column "symbol" column[index].link _ ntdefaults[symbol].count; ntdefaults[symbol].count _ index } ELSE { column[index].link _ column[lastptr].link; column[lastptr].link _ index }; index _ index+1 }; ENDLOOP }; ntix _ ttix _ 0; index _ 1; statedata[1] _ [0,0,0,0]; FOR six IN [1..NPGSConDefs.sLim) DO defaultprod _ NPGSConDefs.inword[]; statedata[six] _ [ttix,ntix,0,0]; THROUGH [1..NPGSConDefs.inword[]] DO --set up entries for state six in ttab and ntab symbol _ NPGSConDefs.inword[]; k _ NPGSConDefs.inword[]; item _ [k MOD 4, k/4, NPGSConDefs.inword[]]; IF item.tag=2 AND item.pss=defaultprod THEN defaultitem _ item ELSE IF symbol<=NPGSConDefs.eofMark THEN {ttab[ttix] _ [symbol, item]; ttix _ ttix+1} ELSE { symbol _ symbol-NPGSConDefs.eofMark+1; ntab[ntix] _ [symbol, item]; ntix _ ntix+1; ColumnEntry[] }; ENDLOOP; IF defaultprod # 0 THEN { ttab[ttix] _ [NPGSConDefs.defaultMarker, defaultitem]; ttix _ ttix+1 }; statedata[six].tLink _ ttix-statedata[six].tIndex; --length statedata[six].ntLink _ ntix-statedata[six].ntIndex; --length FOR i IN [1..six) DO k _ statedata[six].tIndex-statedata[i].tIndex; IF statedata[six].tLink=statedata[i].tLink THEN -- same length FOR j IN [statedata[i].tIndex..statedata[i].tIndex+statedata[i].tLink) DO IF ttab[j]#ttab[j+k] THEN EXIT; REPEAT FINISHED => { --there is a matching set of entries statedata[six].tLink _ -i; -- point state six at state i ttix _ statedata[six].tIndex; -- back up index EXIT }; ENDLOOP; ENDLOOP; ENDLOOP; tlim _ ttix; FOR symbol IN [0..NPGSConDefs.totalTokens-NPGSConDefs.eofMark+1] DO IF (ptr _ ntdefaults[symbol].count)=0 THEN LOOP; k _ 0; ntdefaults[symbol].item _ column[ptr].item; WHILE ptr#0 DO IF column[ptr].count>k THEN { k _ column[ptr].count; ntdefaults[symbol].item _ column[ptr].item }; ptr _ column[ptr].link; ENDLOOP; ntdefaults[symbol].count _ k; ENDLOOP }; SquashNTab: PROC = { nlim _ 0; FOR six: CARDINAL IN [1..NPGSConDefs.sLim) DO k: CARDINAL _ nlim; FOR ntix: CARDINAL IN [statedata[six].ntIndex..statedata[six].ntIndex+statedata[six].ntLink) DO IF ntab[ntix].item # ntdefaults[ntab[ntix].symbol].item THEN { ntab[nlim] _ ntab[ntix]; nlim _ nlim+1; }; ENDLOOP; statedata[six].ntIndex _ k; k _ nlim-k; statedata[six].ntLink _ k; IF k # 0 THEN FOR i: CARDINAL IN [1..six) DO --do these entries match those of an existing state k _ statedata[six].ntIndex-statedata[i].ntIndex; IF statedata[six].ntLink=statedata[i].ntLink THEN -- same length FOR j: CARDINAL IN [statedata[i].ntIndex..statedata[i].ntIndex+statedata[i].ntLink) DO IF ntab[j]#ntab[j+k] THEN EXIT; REPEAT FINISHED => { --there is a matching set of entries statedata[six].ntLink _ -i; -- point state six at state i nlim _ statedata[six].ntIndex; -- back up index EXIT; }; ENDLOOP; ENDLOOP; ENDLOOP; }; PrintNDef: PROC = { j: CARDINAL _ 0; item: NPGSTypes.ItemRec; OutString["\nNonterminal Default Actions\n"]; linewidth _ 0; FOR i: CARDINAL IN [2..NPGSConDefs.totalTokens-NPGSConDefs.eofMark+1] DO IF (linewidth _ linewidth+NPGSConDefs.tokenSize+8)>NPGSConDefs.outbufLim THEN { NPGSConDefs.outeol[1]; linewidth _ NPGSConDefs.tokenSize+8; }; item _ ntdefaults[i].item; j _ j+ntdefaults[i].count; NPGSConDefs.outnum[IF item.tag=0 THEN item.pss ELSE -item.pss, 5]; NPGSConDefs.outchar[' ,1]; NPGSConDefs.outchar[' , NPGSConDefs.tokenSize+2-NPGSConDefs.OutToken[i+NPGSConDefs.eofMark-1]]; ENDLOOP; OutString["\nEntries removed = "]; NPGSConDefs.outnum[j,5]; NPGSConDefs.outeol[1]; }; TableOverlays: PROC = { j, k: INTEGER; OutString["\nTable Overlays\n row ttab ntab\n"]; FOR i: CARDINAL IN [1..NPGSConDefs.sLim) DO j _ statedata[i].tLink; k _ statedata[i].ntLink; IF j<0 OR k<0 THEN { NPGSConDefs.outnum[i,4]; IF j<0 THEN NPGSConDefs.outnum[-j, 5] ELSE NPGSConDefs.outchar[' ,5]; IF k<0 THEN NPGSConDefs.outnum[-k, 5]; NPGSConDefs.outeol[1] }; ENDLOOP }; HashTabSetup: PROC = { i, j, k, h, p, count, freeptr, code: CARDINAL; null: CHAR = '\000; OutString["\nScanner hashtable probe counts (terminal symbol, probecount, hashcode)\n"]; vocabspace _ vocabindex[0] _ 0; freeptr _ hashval; linewidth _ 0; scantab _ NEW[ScanTabArray _ ALL[0]]; FOR i IN [1..NPGSConDefs.eofMark] DO -- strip quotes, Repack, build vocabindex, scantab and hashtab p _ i*NPGSConDefs.tokenSize; k _ NPGSConDefs.symInfo[i].length; IF k=2 AND NPGSConDefs.symTab[p]='' THEN {p _ p+1; k _ 1} ELSE IF k>2 AND NPGSConDefs.symTab[p]='" AND NPGSConDefs.symTab[p+k-1]='" THEN {p_p+1; k_k-2}; IF k=1 AND ~(NPGSConDefs.symTab[p] IN ['a..'z] OR NPGSConDefs.symTab[p] IN ['A..'Z]) THEN { scantab[CARDINAL[NPGSConDefs.symTab[p]-null]] _ i; NPGSConDefs.symTab[vocabspace] _ NPGSConDefs.symTab[p]; vocabspace _ vocabspace+1; vocabindex[i] _ vocabspace } ELSE { FOR j IN [0..k) DO NPGSConDefs.symTab[vocabspace] _ NPGSConDefs.symTab[p+j]; vocabspace _ vocabspace+1; ENDLOOP; vocabindex[i] _ vocabspace; IF i=NPGSConDefs.eofMark THEN LOOP; count _ 1; code _ h _ (((NPGSConDefs.symTab[p]-null)*127+(NPGSConDefs.symTab[p+k-1]-null)) MOD hashval) + 1; IF hashtab[h].symPtr#0 THEN { WHILE h#0 DO j _ h; h _ hashtab[h].link; count _ count+1 ENDLOOP; WHILE hashtab[freeptr].symPtr#0 DO freeptr _ freeptr-1 ENDLOOP; hashtab[j].link _ h _ freeptr }; hashtab[h].symPtr _ i; IF (linewidth _ linewidth+NPGSConDefs.tokenSize+8)>NPGSConDefs.outbufLim THEN { NPGSConDefs.outeol[1]; linewidth _ NPGSConDefs.tokenSize+8 }; FOR j IN [vocabindex[i-1]..vocabindex[i]) DO NPGSConDefs.outchar[NPGSConDefs.symTab[j],1] ENDLOOP; NPGSConDefs.outchar[' ,NPGSConDefs.tokenSize-k]; NPGSConDefs.outnum[count,2]; NPGSConDefs.outnum[code,4]; NPGSConDefs.outchar[' ,2] }; ENDLOOP; IF (j _ vocabspace MOD NPGSConDefs.cpw)#0 THEN -- pad to word boundary THROUGH [j..NPGSConDefs.cpw) DO NPGSConDefs.symTab[vocabspace] _ null ENDLOOP; NPGSConDefs.outeol[1]; }; StatePartition: PROC = { i: CARDINAL _ 2; j: CARDINAL _ NPGSConDefs.sLim-1; DO WHILE statedata[j].ntLink=0 AND i<=j DO j_j-1 ENDLOOP; -- j indexes an ntstate WHILE statedata[i].ntLink#0 AND i=j IF i>=j THEN EXIT ELSE {i_i+1; j_j-1}; -- simulate renumbering ENDLOOP; lastntstate_j; }; StateRenumber: PROC [cusp: BOOL] = { i: CARDINAL _ 2; j: CARDINAL _ NPGSConDefs.sLim-1; k: INTEGER; swaprec: NPGSTypes.StateDataRec; DO WHILE statedata[j].ntLink=0 AND i<=j DO j_j-1 ENDLOOP; -- j indexes an ntstate WHILE statedata[i].ntLink#0 AND i=j IF i>=j THEN EXIT; renumber[i]_j; renumber[j]_i; i_i+1; j_j-1; ENDLOOP; IF lastntstate # j THEN ERROR; FOR i IN [0..tlim) DO IF ttab[i].item.tag=0 AND (j_renumber[ttab[i].item.pss])#0 THEN ttab[i].item.pss_j; ENDLOOP; FOR i IN [0..nlim) DO IF ntab[i].item.tag=0 AND (j_renumber[ntab[i].item.pss])#0 THEN ntab[i].item.pss_j; ENDLOOP; FOR i IN [2..NPGSConDefs.totalTokens-NPGSConDefs.eofMark+1] DO IF ntdefaults[i].item.tag=0 AND (j_renumber[ntdefaults[i].item.pss])#0 THEN ntdefaults[i].item.pss_j; ENDLOOP; FOR i IN [1..NPGSConDefs.sLim) DO k _ statedata[i].tLink; IF k<0 THEN { statedata[i].tLink _ statedata[-k].tLink; statedata[i].tIndex _ statedata[-k].tIndex }; k _ statedata[i].ntLink; IF k<0 THEN { statedata[i].ntLink _ statedata[-k].ntLink; statedata[i].ntIndex _ statedata[-k].ntIndex }; ENDLOOP; FOR i IN [2..lastntstate] DO IF (j_renumber[i])#0 THEN { swaprec _ statedata[i]; statedata[i] _ statedata[j]; statedata[j] _ swaprec }; ENDLOOP; IF cusp THEN NPGSConDefs.CuspPreRenumber[lastntstate, renumber]; -- new for CUSP IF NPGSConDefs.flags[printLALR] THEN { OutString["\nRenumbered States\n"]; FOR i IN [2..lastntstate] DO IF renumber[i]#0 THEN { NPGSConDefs.outnum[i,4]; OutString[" swapped with"]; NPGSConDefs.outnum[renumber[i],4]; NPGSConDefs.outeol[1] }; ENDLOOP } }; OutModule: PUBLIC PROC [cedar: BOOL, cusp: BOOL] = { i,j,k: CARDINAL; OutCuspErrorType: PROC = { OutString[" ErrorType: TYPE = {MAgg, MCalled, MDotLB, MExpr, MId, MOpd,\n"]; OutString[" MOptn, MRArrow, MThe, MTxt, MTypeId, MFieldTypeId, CloseIconExpr,\n"]; OutString[" CopyIconExpr, MoveIconExpr, SelectIconExpr, IconExpr,\n"]; OutString[" Stmt, MSecs, tl};\n"]; }; OutRange: PROC [id, cover: Rope.ROPE, ulim: CARDINAL] = { NPGSConDefs.outchar[' ,2]; NPGSConDefs.outstring[id]; OutString[": TYPE = "]; IF cover = NIL THEN OutString["CARDINAL"] ELSE NPGSConDefs.outstring[cover]; OutString["[0.."]; NPGSConDefs.outnum[ulim,1]; OutString["];\n"]; }; OutArray: PROC [id, index, range: Rope.ROPE] = { NPGSConDefs.outchar[' ,2]; NPGSConDefs.outstring[id]; OutString[": TYPE = ARRAY "]; NPGSConDefs.outstring[index]; OutString[" OF "]; NPGSConDefs.outstring[range]; NPGSConDefs.outchar[';,1]; NPGSConDefs.outeol[1]; }; OutRefProc: PROC [referent: Rope.ROPE] = { NPGSConDefs.outchar[' ,2]; NPGSConDefs.outstring[referent]; IF cedar THEN OutString["Ref: TYPE = REF "] ELSE OutString["Ref: TYPE = LONG POINTER TO "]; NPGSConDefs.outstring[referent]; OutString[";"]; NPGSConDefs.outeol[1]; NPGSConDefs.outchar[' ,2]; OutString["Init"]; NPGSConDefs.outstring[referent]; IF cedar THEN OutString[": PROC RETURNS ["] ELSE OutString[": PROC [uz: UNCOUNTED ZONE] RETURNS ["]; NPGSConDefs.outstring[referent]; OutString["Ref];"]; NPGSConDefs.outeol[2]; }; OutString["-- "]; NPGSConDefs.outstring[NPGSConDefs.modName]; NPGSConDefs.outeol[1]; OutString["-- an NPGS production from "]; NPGSConDefs.outstring[NPGSConDefs.sourceName]; OutString[", "]; NPGSConDefs.outtime[]; NPGSConDefs.outeol[2]; NPGSConDefs.outstring[NPGSConDefs.typeName]; IF cedar THEN OutString[": CEDAR DEFINITIONS = {\n\n"] ELSE OutString[": DEFINITIONS = {\n\n"]; OutRange["Symbol", NIL, NPGSConDefs.maxSymbolIndex]; OutRange["TSymbol", "Symbol", NPGSConDefs.eofMark]; OutRange["NTSymbol", "Symbol", NPGSConDefs.totalTokens-NPGSConDefs.eofMark+1]; OutString["\n-- Token indices for the scanner and parser\n"]; FOR i IN [0..NPGSConDefs.nextAlias) DO NPGSConDefs.outchar[' ,2]; k _ NPGSConDefs.aliases[i].alias*NPGSConDefs.tokenSize; FOR j IN [k..k+NPGSConDefs.tokenSize) WHILE NPGSConDefs.symTab[j]#0c DO NPGSConDefs.outchar[NPGSConDefs.symTab[j],1] ENDLOOP; OutString[": TSymbol ="]; NPGSConDefs.outnum[NPGSConDefs.aliases[i].terminal,3]; NPGSConDefs.outchar[';,1]; NPGSConDefs.outeol[1]; ENDLOOP; NPGSConDefs.symTab _ NIL; NPGSConDefs.aliases _ NIL; OutString["\n defaultMarker: TSymbol = TSymbol.FIRST;"]; OutString["\n endMarker: TSymbol = TSymbol.LAST;"]; NPGSConDefs.outeol[2]; OutRange["HashIndex", NIL, hashval]; OutRange["VIndex", NIL, vocabspace-1]; NPGSConDefs.outeol[1]; OutString["\n VocabHashEntry: TYPE = RECORD ["]; OutString["\n symbol: TSymbol, -- symbol index"]; OutString["\n link: HashIndex]; -- link to next entry"]; NPGSConDefs.outeol[2]; OutRange["State", NIL, NPGSConDefs.sLim-1]; OutRange["NTState", "State", lastntstate]; OutRange["TIndex", NIL, tlim-1]; OutRange["NTIndex", NIL, nlim-1]; OutRange["Production", NIL, NPGSConDefs.numProd]; OutRange["Rule", NIL, NPGSConDefs.numRules]; IF cusp THEN OutCuspErrorType[]; -- New for CUSP OutString["\n ActionTag: TYPE = RECORD ["]; OutString["\n reduce: BOOL, -- TRUE iff reduce entry"]; OutString["\n pLength: [0..15]]; -- number of symbols in production rhs\n"]; OutString["\n ActionEntry: TYPE = RECORD ["]; OutString["\n tag: ActionTag, -- [FALSE,0] if a shift entry"]; OutString["\n transition: [0..2047]]; -- production number / next state\n"]; OutString["\n ProductionInfo: TYPE = RECORD ["]; OutString["\n rule: Rule, -- reduction rule"]; OutString["\n lhs: NTSymbol]; -- production lhs symbol\n\n"]; OutArray["ScanTable", "CHAR['\\040..'\\177]", "TSymbol"]; OutArray["HashTable", "HashIndex", "VocabHashEntry"]; OutArray["IndexTable", "TSymbol", "CARDINAL"]; OutString[" Vocabulary: TYPE = TEXT;\n"]; OutArray["ProdData","Production","ProductionInfo"]; OutArray["NStarts", "NTState", "NTIndex"]; OutArray["NLengths", "NTState", "CARDINAL"]; OutArray["NSymbols", "NTIndex", "NTSymbol"]; OutArray["NActions", "NTIndex", "ActionEntry"]; OutArray["NTDefaults", "NTSymbol", "ActionEntry"]; OutArray["TStarts", "State", "TIndex"]; OutArray["TLengths", "State", "CARDINAL"]; IF cusp THEN OutArray["ErrorMsgs", "State", "ErrorType"]; OutArray["TSymbols", "TIndex", "TSymbol"]; OutArray["TActions", "TIndex", "ActionEntry"]; NPGSConDefs.outeol[1]; OutString[" initialState: State = "]; NPGSConDefs.outnum[1,1]; NPGSConDefs.outchar[';,1]; NPGSConDefs.outeol[1]; OutString[" finalState: State = "]; NPGSConDefs.outnum[0,1]; NPGSConDefs.outchar[';,1]; NPGSConDefs.outeol[2]; OutRefProc["ScanTable"]; OutRefProc["HashTable"]; OutRefProc["IndexTable"]; OutRefProc["Vocabulary"]; OutRefProc["ProdData"]; OutRefProc["NStarts"]; OutRefProc["NLengths"]; OutRefProc["NSymbols"]; OutRefProc["NActions"]; OutRefProc["NTDefaults"]; OutRefProc["TStarts"]; OutRefProc["TLengths"]; IF cusp THEN OutRefProc["ErrorMsgs"]; OutRefProc["TSymbols"]; OutRefProc["TActions"]; OutString["\n}.\n"]; }; }. ‚ NPGSTab.mesa Copyright Σ 1985, 1988 by Xerox Corporation. All rights reserved. Satterthwaite, October 18, 1985 10:24:14 am PDT Maxwell, August 10, 1983 10:39 am Wyatt, March 20, 1984 4:48:28 pm PST Russ Atkinson (RRA) March 28, 1988 5:08:41 pm PST JKF February 6, 1989 3:44:47 pm PST start output file Output header of the implementation file now see if these terminal entries match those of an existing state ttab contains terminal entries; statedata[i].tindex indexes state i entries if statedata[i].link>0, otherwise statedata[-statedata[i].link].tindex indexes them. the following code leaves the most frequently occurring item in column "symbol" of the lalr tables in the appropriate entry of ntdefaults the next two statements are redundant, they keep the new tables identical to the old if j˜@šœ5˜7J˜:—Jšœ?˜AJšœ5˜7Jšœœœ˜%JšœE˜GJšœ>˜@J˜JšœΟc˜)J˜J˜Jšœ0œœ˜Ušœœ˜&Jšœœ˜Jšœœœ>˜NJšœ˜—Jšœœ˜J˜J˜Jšœ3˜5J˜;šœœœ˜"J˜%Jšœ ˜šœ$˜&J˜9—Jšœ˜—Jšœœ˜J˜J˜Jšœ#œ ˜GJšœ0˜2šœœœ˜.Jšœœ˜J˜Jšœ˜—J˜ J˜J˜Jšœ%˜'Jšœ˜Jšœœ3˜:Jšœœ2˜9JšœQ˜SJšœ*˜,Jšœ˜J˜0Jšœ6˜8šœœœ˜%Jšœœ˜ šœœ œ˜Jšœœœ˜'Jšœ'˜)Jšœ˜J˜—šœ˜ Jšœ œ!œ˜3Jšœ œ œ˜2Jšœ œ˜Jšœœœ˜3—Jšœ˜—Jšœ*˜,Jšœœ˜J˜Jšœ œ˜Jšœ œ˜Jšœœ˜J˜J˜6J˜J˜J˜Jšœ%˜'Jšœ2˜4Jšœ;˜=JšœX˜ZJšœ[˜]Jšœ[˜]J˜EJšœ˜˜J˜3šœœœ˜.J˜1Jšœœ ˜Jšœœ˜+Jšœœ˜Jšœ+˜-šœœ˜Jšœœ˜(Jšœ>˜@J˜Jšœ*˜,J˜Jšœ*˜,Jšœ˜ —Jšœ˜J˜Jšœ˜—J˜—Jšœœ˜J˜J˜Jšœ œ˜šœœœ˜%J˜"Jšœ˜—J˜J˜J˜Jšœ œ˜?Jšœ˜šœœœ˜+Jšœœ˜J˜Jšœ˜—J˜ J˜J˜Jšœ!œ˜@Jšœ˜šœœœ˜+Jšœœ˜J˜Jšœ˜—J˜ J˜J˜J˜˜J˜Jšœ"œ˜AJšœ˜šœœœ˜+Jšœ8˜;J˜Jšœ˜—Jšœ(˜(J˜ J˜—J˜J˜J˜J˜Jšœ!œ˜4Jšœ1˜3šœœœ ˜Jšœœ˜J˜Jšœ˜—J˜ J˜J˜J˜Jšœ9˜;J˜5šœœœ ˜J˜Jšœ˜—J˜J˜Jšœ˜J˜Jšœœ œ˜'Jšœ œ œ˜!Jšœ œ œ˜Jšœ œ˜J˜—J˜šž œœ˜J˜%Jšœ;œ˜DJ˜šž œœ˜Jšœœ˜ Jšœ œ˜J˜š˜Jšœœœ˜J˜ Jšœœ#˜.Jšœœœ ˜Jšœœœ˜J˜&Jš˜J˜3˜ J˜šœ œŸ"˜6J˜.J˜ J˜—šœ˜J˜*J˜J˜—J˜J˜—Jš˜—J˜—J˜J˜5šœœ˜#J˜EšœœŸ/˜UJ˜8Jšœ œ˜,šœ œœ˜CJšœœ-˜P—šœ˜J˜RJ˜ J˜—Jšœ˜—šœœ˜J˜DJ˜—Jšœ3Ÿ˜;Jšœ5Ÿ˜=JšœB™Bšœœ ˜J˜.Jšœ)œŸ˜?šœœ?˜IJšœœœ˜šœœŸ$˜9JšœŸ˜8JšœŸ˜.Jš˜J˜—Jšœ˜—Jšœ˜—Jšœ˜—J˜ JšœN™NJšœQ™QJ˜JšœO™OJšœ9™9šœœ4˜CJšœ$œœ˜0J˜2šœ˜šœœ˜J˜AJ˜—J˜Jšœ˜—J˜Jš˜—J˜—J˜šž œœ˜J˜ šœœœ˜-Jšœœ˜šœœœH˜_šœ6œ˜>J˜J˜J˜—Jšœ˜—J˜J˜ J˜Jšœ˜ š œœœ œŸ3˜RJ˜0Jšœ+œŸ˜AšœœœB˜VJšœœœ˜šœœŸ$˜9JšœŸ˜9JšœŸ˜/Jšœ˜J˜—Jšœ˜—Jšœ˜—Jšœ˜—J˜—J˜J˜šž œœ˜Jšœœ˜J˜J˜-J˜šœœœ4˜HšœGœ˜OJ˜J˜$J˜—J˜5Jšœœ œ œ*˜]J˜_Jšœ˜—J˜"J˜J˜J˜—J˜šž œœ˜Jšœœ˜J˜0šœœœ˜+J˜0šœœœ˜J˜Jšœœœ˜EJšœœ˜&J˜J˜—Jš˜—J˜—J˜šž œœ˜Jšœ%œ˜.Jšœœ ˜J˜XJ˜AJšœ œœ˜%šœœœŸ>˜cJ˜?Jšœœ˜#Jšœ˜Jš œœœœœ˜^š œœœ œœ œ˜[Jšœœ"˜2JšœT™TJ˜R˜J˜——šœ˜šœœ˜J˜TJšœ˜—J˜Jšœœœ˜#J˜ JšœPœ˜ašœœ˜Jšœœ.œ˜BJšœœœ˜?J˜J˜—J˜šœGœ˜OJ˜:J˜—Jšœœ"œ.œ˜bJ˜MJ˜5J˜—Jšœ˜—šœœœŸ˜FJšœœ'œ˜N—J˜J˜—J˜šžœœ˜Jšœœ˜Jšœœ˜!š˜Jš œœœœŸ˜NJš œœœœŸ˜PJšœœ˜JšœŸ˜,Jšœ˜—J˜J˜—J˜šž œœœ˜$Jšœœ˜Jšœœ˜!Jšœœ˜ J˜ š˜Jš œœœœŸ˜NJš œœœœŸ˜PJšœœœ˜J˜J˜J˜J˜Jšœ+™+Jšœ˜—Jšœœœ˜J˜Jšœ™šœœ ˜Jšœœ"œ˜SJšœ˜—šœœ ˜Jšœœ"œ˜SJšœ˜—šœœ4˜>šœœ(˜KJ˜—Jšœ˜—J˜Jšœ ™ šœœ˜!J˜šœœ˜ J˜)J˜*J˜—J˜šœœ˜ J˜+J˜,J˜—Jšœ˜—šœœ˜šœœ˜J˜KJ˜—Jšœ˜—Jšœœ5Ÿ˜Pšœœ˜&J˜#šœœ˜šœœ˜J˜mJ˜—Jš˜—J˜—J˜—J˜š ž œœœ œœ˜5Jšœœ˜J˜šžœœ˜JšœM˜MJšœU˜UJšœI˜IJšœ%˜%J˜J˜—šžœœœœ˜9J˜MJšœ œœœ˜LJ˜AJ˜—J˜šžœœœ˜0J˜SJ˜NJ˜1J˜—J˜šž œœœ˜*Jšœ!™!J˜J˜ Jšœ˜Jšœ˜"Jšœ+˜/J˜ J˜J˜J˜Jšœ6™6J˜J˜J˜ Jšœ˜Jšœ˜"Jšœ4˜8J˜ J˜J˜J˜—J˜Jšœ%™%J˜J˜+J˜J˜)J˜.J˜J˜J˜J˜J˜,Jšœ˜Jšœ)˜-Jšœ$˜(J˜Jšœœ˜4J˜3J˜NJ˜J˜=šœœ˜&J˜RJš œœœœ.œ˜~J˜‚Jšœ˜—Jšœœœ˜4J˜J˜9J˜4J˜J˜Jšœœ ˜$Jšœœ˜&J˜J˜J˜1J˜7J˜>J˜J˜Jšœœ˜+J˜*Jšœœ ˜ Jšœœ ˜!Jšœœ˜1Jšœœ˜,J˜JšœœŸ˜0J˜J˜,J˜AJ˜SJ˜.J˜JJ˜QJ˜1J˜8J˜@J˜J˜9J˜5J˜.J˜*J˜J˜3J˜J˜*J˜,J˜,J˜/J˜2J˜J˜'J˜*J˜9J˜*J˜.J˜J˜J˜ZJ˜J˜XJ˜J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜%J˜J˜J˜J˜J˜—J˜J˜—Jšœ1™1Jšœ<™