NPGSControl.mesa
Copyright Ó 1985, 1987, 1988, 1990, 1992 by Xerox Corporation. All rights reserved.
Satterthwaite, October 18, 1985 10:20:39 am PDT
Maxwell, August 9, 1983 9:14 am
Russ Atkinson (RRA) March 25, 1988 7:42:51 pm PST
Doug Wyatt, January 21, 1987 5:33:45 pm PST
JKF May 24, 1990 10:42:19 am PDT
Michael Plass, December 10, 1992 10:01 pm PST
DIRECTORY
BasicTime USING [GMT, Now, nullGMT, ToPupTime],
NPGSCommandUtil USING [KeyValue, ListLength, PairList, SetExtension],
FS USING [ComponentPositions, Error, ExpandName, GetInfo, OpenFileFromStream, StreamOpen],
IO,
NPGS1 USING [InstallParseTable, Parse],
NPGSConDefs USING [Format, LALRGen, OutModule, PrintGrammar, TabGen],
NPGSOps USING [NPGSPhase],
NPGSTypes,
Basics USING [BITOR],
Rope USING [Concat, Equal, Fetch, Length, Replace, ROPE, Substr],
TimeStamp USING [Stamp];
NPGSControl: CEDAR PROGRAM
IMPORTS BasicTime, NPGSCommandUtil, FS, IO, NPGS1, NPGSConDefs, Basics, 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.Put1[IO.time[startTime]]};
storage allocation for NPGSscan, NPGSlalr, NPGStab
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] ¬ Basics.BITOR[sink[sinkBase+i], source[sourceBase+i]];
ENDLOOP;
orCount ¬ orCount+1;
};
streams and files
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[];
};
message logging
Logger: PROC [proc: PROC [log: IO.STREAM]] = {
seterrstream[]; proc[outStream]; resetoutstream[];
};
I/O operations
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];
};
processing options
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;
collect output specifications
{
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=user THEN GOTO noSource ELSE GOTO lockedSource];
outStream ¬ tabStream ¬ FS.StreamOpen[sourceName, $create];
[table: tableId, type: typeName, export: exportId] ¬ NPGSConDefs.Format[
! NPGSFail => {GOTO formatFailed}];
input from inputName (sourceStream), modified input to sourceName (tabStream),
sets up data for PrintGrammar
sourceVersion ¬ [net: 0, host: 0, time: CreateTime[tabStream]];
closeoutstream[]; IO.Close[sourceStream]; sourceStream ¬ NIL;
output grammar to summary file (or scratch)
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;
connect pgs.scratch to input stream and fix sourceNames
sourceStream ¬ FS.StreamOpen[gfName, $read];
derive missing type id (compatibility feature)
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;
derive type name
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$";
objectName ← Rope.Concat[SystemNames.LocalDir[subDirs: "Temp", option: $releaseOmitted], "NPGS.scratch$"];
tabStream ¬ errStream ¬ NIL;
sourceOrigin ¬ IO.GetIndex[sourceStream];
modName ¬ defsName;
load table and call first pass here
[] ¬ startPhase[$lalr];
success ¬ NPGS1.Parse[sourceStream, Logger, TRUE, cusp].nErrors = 0;
IO.Close[sourceStream];
closeoutstream[];
now if no errors generate the tables then package them on request
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}
};
start code
NPGS1.InstallParseTable[];
}.