-- 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.. @this declaration text was produced by GenOneCasabaParser ʘJ˜5J˜)J˜˜ Jšœ'˜'J˜J˜oJ˜_J˜—J˜šœO˜OJšœ4˜4J˜˜J˜J˜1J˜J˜JšœK˜KJšœE˜EJ˜Jšœ˜J˜˜1J˜3—J˜J˜?J˜J˜+J˜J˜—J˜šœE˜EJ˜J˜J˜˜WJ˜J˜˜ šœAÏk˜FJšœX˜X—Jšœ+˜+J˜J˜0JšœH˜HJ˜—J˜—J˜˜>J˜J˜[J˜—J˜˜\J˜J˜XJ˜—J˜˜FJ˜J˜~J˜—J˜˜QJšœ!˜!JšœT˜T—J˜—J˜JšœÂ˜ÂJ˜J˜J˜J˜J˜J˜o˜J™8—Jšœ–˜–J˜šœI˜IJ˜J˜J˜%J˜J˜VJ˜˜\J˜2—J˜˜FJ˜šœ&˜&Jšœ;˜;šœ ˜ Jšœ˜J˜9J˜CJšœ˜—šœ ˜ Jšœ˜J˜9J˜CJšœ˜—Jšœ=˜=šœ˜Jšœ˜J˜?J˜9J˜;J˜QJšœ˜—J˜#J˜—J˜—J˜˜DJšœ"˜"—J˜—J˜J˜ J˜J˜)J˜——…—üY