<<>> <> <> <> <> <> <> <> <<>> DIRECTORY BasicTime USING [GMT, Now, nullGMT, ToPupTime], NPGSCommandUtil USING [KeyValue, ListLength, PairList, SetExtension], FS USING [ComponentPositions, Error, ExpandName, GetInfo, OpenFileFromStream, StreamOpen], IO USING [Close, EndOf, EndOfStream, GetChar, GetIndex, Put, PutChar, PutRope, SetIndex, STREAM, time, UnsafeGetBlock, UnsafePutBlock], NPGS1 USING [InstallParseTable, Parse], NPGSConDefs USING [Format, LALRGen, OutModule, PrintGrammar, TabGen], NPGSOps USING [NPGSPhase], NPGSTypes, PBasics USING [BITOR], Rope USING [Concat, Equal, Fetch, Length, Replace, ROPE, Substr], TimeStamp USING [Stamp]; NPGSControl: CEDAR PROGRAM IMPORTS BasicTime, NPGSCommandUtil, FS, IO, NPGS1, NPGSConDefs, PBasics, Rope EXPORTS NPGSConDefs, NPGSOps = { eofMark: PUBLIC CARDINAL; totalTokens, numProd, numRules, nextAlias: PUBLIC CARDINAL; warningsLogged: PUBLIC BOOL; flags: PUBLIC ARRAY NPGSTypes.Options OF BOOL _ ALL[FALSE]; symTab: PUBLIC NPGSTypes.SymTab; symInfo: PUBLIC NPGSTypes.SymInfo; aliases: PUBLIC NPGSTypes.Aliases; tokenInfo: PUBLIC NPGSTypes.TokenInfo; prodInfo: PUBLIC NPGSTypes.ProdInfo; rhsChar: PUBLIC NPGSTypes.RhsChar; sLim, tEntries, ntEntries: PUBLIC CARDINAL; bitstrSize: PUBLIC CARDINAL; NPGSFail: PUBLIC ERROR = CODE; outStream: IO.STREAM; outeol: PUBLIC PROC[n: INTEGER] = { THROUGH [1..n] DO outStream.PutChar['\n] ENDLOOP; }; outchar: PUBLIC PROC [c: CHAR, n: INTEGER] = { IF n < 1 THEN RETURN; -- workaround for compiler bug THROUGH [1..n] DO outStream.PutChar[c] ENDLOOP; }; outstring: PUBLIC PROC [string: Rope.ROPE] = { outStream.PutRope[string]; }; outtab: PUBLIC PROC = {outStream.PutChar['\t]}; DivMod: PROC [num, den: CARD16] RETURNS [quotient, remainder: CARD16] = { quotient _ num/den; remainder _ num MOD den }; outnum: PUBLIC PROC [val: INTEGER, cols: NAT, signChar: CHAR_'-] = { i: CARDINAL; power, digits: CARDINAL _ 1; num: CARDINAL _ ABS[val]; sign: CARDINAL = IF val<0 THEN 1 ELSE 0; WHILE (i_power*10)<=num DO power _ i; digits _ digits+1 ENDLOOP; outchar[' , INTEGER[cols]-INTEGER[digits]-INTEGER[sign]]; IF sign#0 THEN outStream.PutChar[signChar]; UNTIL power < 1 DO [i,num] _ --Basics.--DivMod[num,power]; outStream.PutChar[VAL['0.ORD+i]]; power _ power/10; ENDLOOP }; startTime: BasicTime.GMT _ BasicTime.nullGMT; outtime: PUBLIC PROC = {outStream.Put[IO.time[startTime]]}; <> MakeSymTab: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.SymTab] ~ { new _ NEW[NPGSTypes.SymTabSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ 0C; ENDLOOP; }; MakeSymInfo: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.SymInfo] ~ { new _ NEW[NPGSTypes.SymInfoSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullSymTabEntry; ENDLOOP; }; MakeAliases: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.Aliases] ~ { new _ NEW[NPGSTypes.AliasesSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullAliasEntry ENDLOOP; }; MakeTokenInfo: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.TokenInfo] ~ { new _ NEW[NPGSTypes.TokenInfoSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullTokenEntry ENDLOOP; }; MakeProdInfo: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.ProdInfo] ~ { new _ NEW[NPGSTypes.ProdInfoSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullProdEntry ENDLOOP; }; MakeCardinals: PROC [length: CARDINAL] RETURNS [new: NPGSTypes.Cardinals] ~ { new _ NEW[NPGSTypes.CardinalsSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ 0; ENDLOOP; }; MakeRhsChar: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.RhsChar] ~ { new _ MakeCardinals[length] }; MakeStateInfo: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.StateInfo] ~ { new _ NEW[NPGSTypes.StateInfoSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullStateInfoRec ENDLOOP; }; MakeTable: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.Table] ~ { new _ NEW[NPGSTypes.TableSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullItemRec ENDLOOP; }; MakeBackChain: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.BackChain] ~ { new _ NEW[NPGSTypes.BackChainSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullChainRec ENDLOOP; }; MakeStack: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.Stack] ~ { new _ MakeCardinals[length]; }; MakeBitsInfo: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.BitsInfo] ~ { new _ NEW[NPGSTypes.BitsInfoSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullContextRec ENDLOOP; }; MakeBitString: PUBLIC PROC [length, width: CARDINAL] RETURNS [new: NPGSTypes.BitString] ~ { size: CARDINAL ~ length*width; new _ NEW[NPGSTypes.BitStringSeq[size]]; new.length _ length; new.width _ width; FOR i: CARDINAL IN[0..size) DO new[i] _ 0 ENDLOOP; }; MakeAttrVec: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.AttrVec] ~ { new _ MakeCardinals[length]; }; MakeHashTab: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.HashTab] ~ { new _ NEW[NPGSTypes.HashTabSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullHashTabRec ENDLOOP; }; MakeTab: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.Tab] ~ { new _ NEW[NPGSTypes.TabSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullTabRec ENDLOOP; }; MakeColumn: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.Column] ~ { new _ NEW[NPGSTypes.ColumnSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullColumnRec ENDLOOP; }; MakeStateData: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.StateData] ~ { new _ NEW[NPGSTypes.StateDataSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullStateDataRec ENDLOOP; }; MakeNTDefaults: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.NTDefaults] ~ { new _ NEW[NPGSTypes.NTDefaultsSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullNTDefaultRec ENDLOOP; }; MakeRenumber: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.Renumber] ~ { new _ MakeCardinals[length]; }; MakeVocabIndex: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.VocabIndex] ~ { new _ MakeCardinals[length]; }; MakeSInfo: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.SInfo] ~ { new _ NEW[NPGSTypes.SInfoSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullSInfoRec ENDLOOP; }; MakePInfo: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.PInfo] ~ { new _ NEW[NPGSTypes.PInfoSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ NPGSTypes.nullPInfoRec ENDLOOP; }; <<>> MakeTokenSeq: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.TokensUsed] ~ { new _ NEW[NPGSTypes.TokenSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ no ENDLOOP; }; <<>> MakeErrSeq: PUBLIC PROC [length: CARDINAL] RETURNS [new: NPGSTypes.ErrorMsg] ~ { new _ NEW[NPGSTypes.ErrSeq[length]]; FOR i: CARDINAL IN[0..length) DO new[i] _ MAgg ENDLOOP; }; <<>> ExpandSymTab: PUBLIC PROC [old: NPGSTypes.SymTab, ext: CARDINAL] RETURNS [new: NPGSTypes.SymTab] ~ { newLen: NAT _ old.length+ext; new _ NEW[NPGSTypes.SymTabSeq[newLen]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i]; ENDLOOP; FOR i: CARDINAL IN [old.length..newLen) DO new[i] _ 0C; ENDLOOP; }; ExpandSymInfo: PUBLIC PROC [old: NPGSTypes.SymInfo, ext: CARDINAL] RETURNS [new: NPGSTypes.SymInfo] ~ { new _ NEW[NPGSTypes.SymInfoSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i]; ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ NPGSTypes.nullSymTabEntry; ENDLOOP; }; ExpandAliases: PUBLIC PROC [old: NPGSTypes.Aliases, ext: CARDINAL] RETURNS [new: NPGSTypes.Aliases] ~ { new _ NEW[NPGSTypes.AliasesSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ NPGSTypes.nullAliasEntry ENDLOOP; }; ExpandProdInfo: PUBLIC PROC [old: NPGSTypes.ProdInfo, ext: CARDINAL] RETURNS [new: NPGSTypes.ProdInfo] ~ { new _ NEW[NPGSTypes.ProdInfoSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ NPGSTypes.nullProdEntry ENDLOOP; }; ExpandCardinals: PROC [old: NPGSTypes.Cardinals, ext: CARDINAL] RETURNS [new: NPGSTypes.Cardinals] ~ { new _ NEW[NPGSTypes.CardinalsSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ 0 ENDLOOP; }; ExpandRhsChar: PUBLIC PROC [old: NPGSTypes.RhsChar, ext: CARDINAL] RETURNS [new: NPGSTypes.RhsChar] ~ { new _ ExpandCardinals[old, ext]; }; ExpandStateInfo: PUBLIC PROC [old: NPGSTypes.StateInfo, ext: CARDINAL] RETURNS [new: NPGSTypes.StateInfo] ~ { new _ NEW[NPGSTypes.StateInfoSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ NPGSTypes.nullStateInfoRec ENDLOOP; }; ExpandStack: PUBLIC PROC [old: NPGSTypes.Stack, ext: CARDINAL] RETURNS [new: NPGSTypes.Stack] ~ { new _ ExpandCardinals[old, ext]; }; ExpandBitsInfo: PUBLIC PROC [old: NPGSTypes.BitsInfo, ext: CARDINAL] RETURNS [new: NPGSTypes.BitsInfo] ~ { new _ NEW[NPGSTypes.BitsInfoSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ NPGSTypes.nullContextRec ENDLOOP; }; ExpandBitString: PUBLIC PROC [old: NPGSTypes.BitString, ext: CARDINAL] RETURNS [new: NPGSTypes.BitString] ~ { size: CARDINAL ~ (old.length+ext)*old.width; new _ NEW[NPGSTypes.BitStringSeq[size]]; new.length _ old.length+ext; new.width _ old.width; FOR i: CARDINAL IN [0..old.size) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.size..new.size) DO new[i] _ 0 ENDLOOP; }; ExpandSInfo: PUBLIC PROC [old: NPGSTypes.SInfo, ext: CARDINAL] RETURNS [new: NPGSTypes.SInfo] ~ { new _ NEW[NPGSTypes.SInfoSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ NPGSTypes.nullSInfoRec ENDLOOP; }; ExpandPInfo: PUBLIC PROC [old: NPGSTypes.PInfo, ext: CARDINAL] RETURNS [new: NPGSTypes.PInfo] ~ { new _ NEW[NPGSTypes.PInfoSeq[old.length+ext]]; FOR i: CARDINAL IN [0..old.length) DO new[i] _ old[i] ENDLOOP; FOR i: CARDINAL IN [old.length..new.length) DO new[i] _ NPGSTypes.nullPInfoRec ENDLOOP; }; orCount: PUBLIC CARDINAL _ 0; OrBits: PUBLIC PROC [source: NPGSTypes.BitString, sourceI: CARDINAL, sink: NPGSTypes.BitString, sinkI: CARDINAL] = { sourceBase: CARDINAL ~ sourceI*source.width; sinkBase: CARDINAL ~ sinkI*sink.width; IF source.width#sink.width THEN ERROR; FOR i: CARDINAL IN [0..source.width) DO sink[sinkBase+i] _ PBasics.BITOR[sink[sinkBase+i], source[sourceBase+i]]; ENDLOOP; orCount _ orCount+1; }; <> sourceStream: PUBLIC IO.STREAM _ NIL; errStream: PUBLIC IO.STREAM _ NIL; tabStream: PUBLIC IO.STREAM _ NIL; defsRoot: PUBLIC Rope.ROPE _ NIL; implRoot: PUBLIC Rope.ROPE _ NIL; typeName: PUBLIC Rope.ROPE _ NIL; modName: PUBLIC Rope.ROPE _ NIL; sourceName: PUBLIC Rope.ROPE _ NIL; sourceVersion: PUBLIC TimeStamp.Stamp; objectName: Rope.ROPE _ NIL; defsName: Rope.ROPE _ NIL; implName: Rope.ROPE _ NIL; gfName: Rope.ROPE _ NIL; CreateTime: PROC [s: IO.STREAM] RETURNS [LONG CARDINAL] = { RETURN [BasicTime.ToPupTime[FS.GetInfo[FS.OpenFileFromStream[s]].created]]; }; getstream: PROC [dotstring: Rope.ROPE] RETURNS [IO.STREAM] = { RETURN [FS.StreamOpen[Rope.Concat[rootName, dotstring], $create]]; }; seterrstream: PUBLIC PROC = { IF errStream = NIL THEN { outStream _ errStream _ getstream[".errlog"]; outstring["Cedar NPGS of "]; outtime[]; outstring[" -- "]; outstring[rootName]; outstring[".errlog"]; outeol[2]; } ELSE outStream _ errStream; }; closeerrstream: PROC = { IF errStream # NIL THEN {IO.Close[errStream]; errStream _ NIL}; }; setoutstream: PUBLIC PROC [dotstring: Rope.ROPE] = { outStream _ tabStream _ getstream[dotstring]; }; resetoutstream: PUBLIC PROC = {outStream _ tabStream}; closeoutstream: PUBLIC PROC = { IF tabStream # NIL THEN {IO.Close[tabStream]; tabStream _ NIL}; }; cleanupstreams: PUBLIC PROC = {NULL}; -- used for checkout openwordstream: PUBLIC PROC [scratch: BOOL] = { tabStream _ FS.StreamOpen[objectName, $create]; }; closewordstream: PUBLIC PROC = {closeoutstream[]}; bpw: NAT ~ BYTES[WORD]; inword: PUBLIC PROC RETURNS [n: CARDINAL] = TRUSTED { -- note: reads from tabStream! base: LONG POINTER ~ @n; IF tabStream.UnsafeGetBlock[[base: base, count: bpw]]=bpw THEN RETURN [n] ELSE ERROR IO.EndOfStream[tabStream] }; outword: PUBLIC PROC [n: CARDINAL] = TRUSTED { base: LONG POINTER ~ @n; tabStream.UnsafePutBlock[[base: base, count: bpw]]; }; inchar: PUBLIC PROC RETURNS [c: CHAR, end: BOOL] = { IF (end _ sourceStream.EndOf[]) THEN c _ '\000 ELSE c _ sourceStream.GetChar[]; }; <> Logger: PROC [proc: PROC [log: IO.STREAM]] = { seterrstream[]; proc[outStream]; resetoutstream[]; }; <> StreamIndex: TYPE = INT; -- FileStream.FileByteIndex sourceOrigin: StreamIndex _ 0; getindex: PUBLIC PROC RETURNS [CARDINAL] = { RETURN [sourceStream.GetIndex[]-sourceOrigin]; }; setindex: PUBLIC PROC [index: CARDINAL] = { sourceStream.SetIndex[sourceOrigin+index]; }; <> rootName: Rope.ROPE _ NIL; GetRoot: PROC [fileName: Rope.ROPE] RETURNS [Rope.ROPE] ~ { fullFName: Rope.ROPE; cp: FS.ComponentPositions; [fullFName: fullFName, cp: cp] _ FS.ExpandName[name: fileName]; RETURN [fullFName.Substr[cp.base.start, cp.base.length]]; }; SetRoot: PROC [s: Rope.ROPE] = {rootName _ GetRoot[s]}; SetFileName: PROC [fileName, default, extension: Rope.ROPE] RETURNS [Rope.ROPE] = { root: Rope.ROPE = IF fileName = NIL THEN default ELSE fileName; RETURN [NPGSCommandUtil.SetExtension[root, extension]]; }; TestExtension: PROC [fileName, extension: Rope.ROPE] RETURNS [BOOL] = { fullFName, ext: Rope.ROPE; cp: FS.ComponentPositions; [fullFName: fullFName, cp: cp] _ FS.ExpandName[name: fileName]; ext _ fullFName.Substr[cp.ext.start, cp.ext.length]; RETURN [Rope.Equal[ext, extension, FALSE]]; }; ReplaceExtension: PROC [fileName, extension: Rope.ROPE] RETURNS [Rope.ROPE] = { fullFName: Rope.ROPE; cp: FS.ComponentPositions; [fullFName: fullFName, cp: cp] _ FS.ExpandName[name: fileName]; RETURN [fullFName.Replace[cp.ext.start, cp.ext.length, extension]]; }; KeyVal: PROC [list: NPGSCommandUtil.PairList, key: Rope.ROPE, delete: BOOL_TRUE] RETURNS [Rope.ROPE] = INLINE { RETURN [NPGSCommandUtil.KeyValue[key, list, delete]]; }; <<* * * * * * HERE IT BEGINS * * * * * *>> NoSource: PUBLIC ERROR = CODE; LockedSource: PUBLIC ERROR = CODE; BadSemantics: PUBLIC ERROR = CODE; Generate: PUBLIC PROC [ source: Rope.ROPE, args, results: NPGSCommandUtil.PairList, switches: Rope.ROPE, startPhase: PROC [NPGSOps.NPGSPhase] RETURNS [BOOL], princOps: BOOL] RETURNS [success, warnings: BOOL] = { printGrammar: BOOL _ TRUE; cedar: BOOL _ TRUE; mesa: BOOL _ FALSE; cusp: BOOL _ FALSE; scratchExists: BOOL _ FALSE; tableId: Rope.ROPE _ NIL; exportId: Rope.ROPE _ NIL; sourceName _ source; typeName _ objectName _ gfName _ NIL; <> { nR: CARDINAL _ NPGSCommandUtil.ListLength[results]; IF (defsName _ KeyVal[results, "defs"]) # NIL THEN nR _ nR - 1; IF (gfName _ KeyVal[results, "grammar"]) # NIL THEN nR _ nR - 1; IF nR # 0 THEN GO TO badSemantics; }; SetRoot[IF objectName # NIL THEN objectName ELSE sourceName]; IF switches # NIL THEN { sense: BOOL _ TRUE; FOR i: INT IN [0 .. switches.Length[]) DO SELECT switches.Fetch[i] FROM '-, '~ => {sense _ ~sense; LOOP}; 'g, 'G => printGrammar _ sense; 'm, 'M => mesa _ sense; 'c, 'C => cusp _ sense; ENDCASE; sense _ TRUE; ENDLOOP; }; cedar _ ~mesa; startTime _ BasicTime.Now[]; warningsLogged _ warnings _ FALSE; sourceName _ NPGSCommandUtil.SetExtension[sourceName, "pgs"]; IF sourceName.Fetch[sourceName.Length[]-1] = '. THEN sourceName _ Rope.Substr[sourceName, 0, sourceName.Length[]-1]; IF TestExtension[sourceName, "pgs"] THEN { inputName: Rope.ROPE ~ sourceName; sourceName _ Rope.Concat[GetRoot[inputName], ".mesa"]; [] _ startPhase[$format]; sourceStream _ FS.StreamOpen[inputName, $read ! FS.Error => IF error.group=lock THEN GOTO lockedSource ELSE GOTO noSource]; outStream _ tabStream _ FS.StreamOpen[sourceName, $create]; [table: tableId, type: typeName, export: exportId] _ NPGSConDefs.Format[ ! NPGSFail => {GOTO formatFailed}]; <> <> sourceVersion _ [net: 0, host: 0, time: CreateTime[tabStream]]; closeoutstream[]; IO.Close[sourceStream]; sourceStream _ NIL; <<>> <> gfName _ IF printGrammar THEN SetFileName[gfName, IF tableId.Length[] # 0 THEN tableId ELSE rootName, "grammar"] ELSE "pgs.scratch$"; outStream _ tabStream _ FS.StreamOpen[gfName, $create]; NPGSConDefs.PrintGrammar[]; closeoutstream[]; IF ~printGrammar THEN scratchExists _ TRUE; <<>> <> sourceStream _ FS.StreamOpen[gfName, $read]; <<>> <> IF typeName.Length[] = 0 AND defsName # NIL THEN typeName _ GetRoot[defsName]; EXITS formatFailed => { closeoutstream[]; closeerrstream[]; seterrstream[]; outstring["\nDirectives incorrect or out of sequence\n"]; GO TO fail } } ELSE { sourceStream _ FS.StreamOpen[sourceName, $read ! FS.Error => {GO TO noSource}]; sourceVersion _ [net: 0, host: 0, time: CreateTime[sourceStream]]; IF objectName = NIL THEN objectName _ rootName; <<>> <> typeName _ Rope.Concat[rootName, "NPGSTable"]; }; IF defsName = NIL THEN { IF typeName.Length[] # 0 THEN defsName _ typeName ELSE defsName _ Rope.Concat[rootName, "NPGSTableType"]; }; defsRoot _ defsName; implRoot _ Rope.Concat[defsRoot, "Impl"]; implName _ NPGSCommandUtil.SetExtension[implRoot, "mesa"]; defsName _ NPGSCommandUtil.SetExtension[defsName, "mesa"]; objectName _ "NPGS.scratch$"; <> tabStream _ errStream _ NIL; sourceOrigin _ IO.GetIndex[sourceStream]; modName _ defsName; <> [] _ startPhase[$lalr]; success _ NPGS1.Parse[sourceStream, Logger, TRUE, cusp].nErrors = 0; IO.Close[sourceStream]; closeoutstream[]; <> IF success AND (flags[lists] OR flags[printLALR] OR flags[printLR]) THEN { success _ NPGSConDefs.LALRGen[cusp ! NPGSFail => {success _ FALSE; CONTINUE}]; IF success AND flags[lists] THEN { closeoutstream[]; -- flush output from LALRGen tabStream _ FS.StreamOpen[objectName]; -- for reinput objectName _ implName; success _ NPGSConDefs.TabGen[cedar, cusp]; IF ~success THEN closewordstream[] ELSE { closeoutstream[]; -- flush tabgen output outStream _ tabStream _ FS.StreamOpen[defsName, $create]; NPGSConDefs.OutModule[cedar, cusp]; closeoutstream[]; }; }; }; closeerrstream[]; warnings _ warningsLogged; EXITS badSemantics => ERROR BadSemantics; noSource => ERROR NoSource; lockedSource => ERROR LockedSource; fail => {closeerrstream[]; success _ FALSE} }; <> NPGS1.InstallParseTable[]; }.