-- 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 <> 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_1], 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..