-- DemoOneCasaba.mesa, March 13, 1986 10:48:58 am PST
-- Sturgis, April 9, 1986 10:38:33 am PST
DIRECTORY
Commander USING[CommandProc, Register],
FS USING[StreamOpen],
IO USING[Close, EndOfStream, GetCedarTokenRope, GetTokenRope, IDProc, int, PutF, RIS, rope, STREAM, TokenKind],
OneCasabaParser USING[BuildParserTableFromKipperedStream, GetReportStream, Parse, ParserTable],
Rope USING[Cat, Length, ROPE];
DemoOneCasaba: CEDAR PROGRAM IMPORTS Commander, FS, IO, OneCasabaParser, Rope =
BEGIN OPEN Commander, FS, IO, OneCasabaParser, Rope;
DemoOneCasaba: CommandProc =
BEGIN
commandLineStream: STREAM ← RIS[cmd.commandLine];
rootName: ROPE;
sourceStream: STREAM;
tableStream: STREAM ← FS.StreamOpen["OneCasabaFormat.kipperedParseTables"];
table: ParserTable ← BuildParserTableFromKipperedStream[tableStream];
Close[tableStream];
rootName ← GetTokenRope[commandLineStream, IDProc
! EndOfStream => {rootName ← NIL; CONTINUE}].token;
Close[commandLineStream];
sourceStream ← FS.StreamOpen[Rope.Cat[rootName, ".oneCasaba"]];
DemoTheParse[table, sourceStream, cmd.out];
END;
DemoTheParse: PROC[table: ParserTable, source: STREAM, out: STREAM] =
BEGIN
textPosition: INT ← 0;
SupplySourceToken: PROC RETURNS[tokenKind: TokenKind, tokenText: ROPE, position: INT] =
BEGIN
charsSkipped: INT;
WHILE TRUE DO
[tokenKind, tokenText, charsSkipped] ← GetCedarTokenRope[source, FALSE
! IO.EndOfStream => {tokenKind ← tokenEOF; tokenText ← ""; charsSkipped ← 0; CONTINUE}];
textPosition ← textPosition + charsSkipped;
position ← textPosition;
textPosition ← textPosition + Length[tokenText];
IF tokenKind # tokenCOMMENT THEN RETURN[tokenKind, tokenText, position];
ENDLOOP;
END;
SeeNonGenericShift: PROC[text: ROPE, firstCharPosition: INT] =
BEGIN
IO.PutF[out, "\Nsee nongeneric token: %g at %g", IO.rope[text], IO.int[firstCharPosition]];
END;
SeeGenericShift: PROC[code: CARDINAL, kind: TokenKind, text: ROPE, firstCharPosition: INT] =
BEGIN
IO.PutF[out, "\Nsee generic token: %g at %g", IO.rope[text], IO.int[firstCharPosition]];
END;
SeeReduce: PROC[rule: CARDINAL, firstCharPosition: INT, length: INT] =
BEGIN
IO.PutF[out, "\Nsee production: %g at %g with length %g", IO.rope[ProdName[rule]], IO.int[firstCharPosition], IO.int[length]];
END;
IF Parse[table, SupplySourceToken, SeeReduce, SeeGenericShift, SeeNonGenericShift
! GetReportStream => RESUME[out]]
THEN PutF[out, "\Nsource was accepted\N"] ELSE PutF[out, "\Nsource NOT accepted\N"];
END;
ProdName: ARRAY [0..16] OF ROPE = ["MainGoal", "Blocka", "Blockb", "ItemSeqone", "ItemSeqmore", "ItemsimpleTkns", "ItemgenericTkn", "ItemnonTerminal", "Itemprod", "RopeSeqone", "RopeSeqmany", "ProdNameone", "ProdNametwo", "RightSideSeqemtpy", "RightSideSeqnonEmpty", "RightSideItemsimpleToken", "RightSideItemidentifier"];
-- The following is a sketch of a simple value computation in which we compute the number of tokens in the text
this declaration text was produced by GenOneCasabaParser
ProductionNames: TYPE = {MainGoal, Blocka, Blockb, ItemSeqone, ItemSeqmore, ItemsimpleTkns, ItemgenericTkn, ItemnonTerminal, Itemprod, RopeSeqone, RopeSeqmany, ProdNameone, ProdNametwo, RightSideSeqemtpy, RightSideSeqnonEmpty, RightSideItemsimpleToken, RightSideItemidentifier};
DemoAComputation: PROC[table: ParserTable, source: STREAM, out: STREAM] =
BEGIN
textPosition: INT ← 0;
partialValues: LIST OF REF ANY ← NIL;
SupplySourceToken: PROC RETURNS[tokenKind: TokenKind, tokenText: ROPE, position: INT];
SeeGenericShift: PROC[code: CARDINAL, kind: TokenKind, text: ROPE, firstCharPosition: INT] =
{partialValues ← CONS[NEW[INT𡤁], partialValues]};
SeeReduce: PROC[rule: CARDINAL, firstCharPosition: INT, length: INT] =
BEGIN
SELECT ProductionNames[VAL[rule]] FROM
MainGoal => NULL; -- we need do no computation in this case
Blocka =>
BEGIN
itemSeqSize: INT ← NARROW[partialValues.first, REF INT]^;
partialValues ← CONS[NEW[INT←(3+itemSeqSize)], partialValues.rest];
END;
Blockb =>
BEGIN
itemSeqSize: INT ← NARROW[partialValues.first, REF INT]^;
partialValues ← CONS[NEW[INT←(4+itemSeqSize)], partialValues.rest];
END;
ItemSeqone => NULL; -- we need do no computation in this case
ItemSeqmore =>
BEGIN
-- note that we pop two values off of the list and push one on.
itemSeqSize: INT ← NARROW[partialValues.first, REF INT]^;
itemSize: INT ← NARROW[partialValues.rest.first, REF INT]^;
partialValues ← CONS[NEW[INT←(1+itemSeqSize+itemSize)], partialValues.rest.rest];
END;
-- we skip showing the other cases.
ENDCASE => ERROR;
END;
[] ← Parse[table, SupplySourceToken, SeeReduce, SeeGenericShift, NIL
! GetReportStream => RESUME[out]];
END;
-- main code
Register["DemoOneCasaba", DemoOneCasaba];
END..