-- ParserDisplayImpl.mesa -- last edit November 2, 1984 2:17:16 pm PST -- Sturgis, April 1, 1986 2:54:05 pm PST DIRECTORY GrammarBasic USING[GenAllSymbols, GenCanBeFirst, GenProductions, GenTerminalSymbols, GetLeftSideSymbol, GetLength, GetNTerminalSymbols, GetProductionIndex, GetRightSideSymbol, GetSymbolText, Grammar, Production, Symbol, TestCanProduceEmpty, TestIfTerminal], IO USING [card, CR, int, PutChar, PutF, PutRope, rope, STREAM], LR0Items USING[GetProductionAndPosition], LR0ItemSetsBasic USING[GenItemsInLR0ItemSet, LR0Item, LR0ItemSet, NarrowLR0ItemSet], LR1ItemSetsBasic USING[GenerateSubsetsFromLR1ItemSet, LR1Item, LR1ItemSet, LR1ItemSubset, NarrowLR1ItemSet], ParserDisplay USING[], ParserGraphAlgorithms USING[TestConsistencyOfNode, GenerateParseActions], ParserGraphs USING[GenerateAllNodes, GenerateArcs, GetAssociatedSet, GetBaseNode, GetClass, GetGraph, GetNodeIndex, GetRingNumber, GetStartNode, Graph, GraphClass, Node], Rope USING[ROPE], TerminalSequences USING[GenTerminalSeqsFromSet, GetSymbolFromTerminalSeq, TerminalSeq, TerminalSeqSet]; ParserDisplayImpl: CEDAR PROGRAM IMPORTS GrammarBasic, IO, LR0Items, LR0ItemSetsBasic, LR1ItemSetsBasic, ParserGraphAlgorithms, ParserGraphs, TerminalSequences EXPORTS ParserDisplay = BEGIN OPEN GrammarBasic, IO, LR0Items, LR0ItemSetsBasic, LR1ItemSetsBasic, ParserGraphAlgorithms, ParserGraphs, Rope, TerminalSequences; ShowGrammar: PUBLIC PROC[on: STREAM, grammar: Grammar] = BEGIN ShowOneProduction: PROC[production: Production] = BEGIN PutF[on, "(%g) ", card[GetProductionIndex[production]]]; PutRope[on, GetSymbolText[GetLeftSideSymbol[production]]]; PutRope[on, " _ "]; FOR I: CARDINAL IN [0..GetLength[production]) DO PutRope[on, GetSymbolText[GetRightSideSymbol[production, I]]]; IF I+1 # GetLength[production] THEN PutRope[on, " "]; ENDLOOP; PutChar[on, CR]; END; ShowOneTerminal: PROC[s: Symbol] = {PutF[on, " %g\N", rope[GetSymbolText[s]]]}; ShowOneNonTerminal: PROC[s: Symbol] = BEGIN ShowOneFirst: PROC[first: Symbol] = {PutF[on, " %g\N", rope[GetSymbolText[first]]]}; IF NOT TestIfTerminal[s] THEN BEGIN PutF[on, " %g%g\N", rope[GetSymbolText[s]], rope[IF TestCanProduceEmpty[s] THEN " (can produce empty)" ELSE ""]]; GenCanBeFirst[s, ShowOneFirst]; END; END; PutChar[on, CR]; GenProductions[grammar, ShowOneProduction]; PutF[on, "\N\NnTerminals = %g\N", card[GetNTerminalSymbols[grammar]]]; GenTerminalSymbols[grammar, ShowOneTerminal]; PutF[on, "\N\NNon Terminals\N"]; GenAllSymbols[grammar, ShowOneNonTerminal]; END; ShowTerminalSeqSet: PUBLIC PROC[on: STREAM, offset: CARDINAL, set: TerminalSeqSet] = BEGIN first: BOOLEAN _ TRUE; ShowOneSeq: PROC[seq: TerminalSeq] = BEGIN IF NOT first THEN PutRope[on, ", "]; first _ FALSE; ShowTerminalSeq[on, 0, seq]; END; Offset[on, offset]; GenTerminalSeqsFromSet[set, ShowOneSeq]; END; ShowLR0Item: PUBLIC PROC[on: STREAM, offset: CARDINAL, item: LR0Item] = BEGIN Offset[on, offset]; PutRope[on, "[ "]; ShowLR0ItemInner[on, item]; PutRope[on, " ]"]; END; ShowLR0ItemInner: PROC[on: STREAM, item: LR0Item] = BEGIN production: Production; position: CARDINAL; [production, position] _ GetProductionAndPosition[item]; PutRope[on, GetSymbolText[GetLeftSideSymbol[production]]]; PutRope[on, " _ "]; FOR I: CARDINAL IN [0..GetLength[production]) DO IF I = position THEN IO.PutF[on, " %l%g%l", IO.rope["i"], IO.rope[GetSymbolText[GetRightSideSymbol[production, I]]], IO.rope[" "]] ELSE IO.PutF[on, " %g", IO.rope[GetSymbolText[GetRightSideSymbol[production, I]]]]; ENDLOOP; END; ShowLR1Item: PUBLIC PROC[on: STREAM, offset: CARDINAL, item: LR1Item] = BEGIN Offset[on, offset]; PutRope[on, "[ "]; ShowLR0ItemInner[on, item.lr0Item]; PutRope[on, " | "]; ShowTerminalSeq[on, 0, item.terminalSeq]; PutRope[on, " ]"]; END; ShowLR0ItemSet: PUBLIC PROC[on: STREAM, offset: CARDINAL, set: REF ANY] = BEGIN lr0ItemSet: LR0ItemSet _ NarrowLR0ItemSet[set]; ShowOneItem: PROC[item: LR0Item] = BEGIN Offset[on, offset]; ShowLR0Item[on, offset, item]; PutRope[on, "\N"]; END; GenItemsInLR0ItemSet[lr0ItemSet, ShowOneItem]; END; ShowNode: PUBLIC PROC[on: STREAM, offset: CARDINAL, node: Node] = BEGIN ring: CARDINAL; baseNodeIndex: CARDINAL; consistent: BOOLEAN; graph: Graph _ GetGraph[node]; startNode: Node _ GetStartNode[graph]; graphClass: GraphClass _ GetClass[graph]; showAssociatedSet: PROC[STREAM, CARDINAL, REF ANY]; ShowOneArc: PROC[s: Symbol, target: Node] RETURNS[BOOLEAN] = BEGIN Offset[on, offset+3]; PutF[on, "%g to %g\N", rope[GetSymbolText[s]], card[GetNodeIndex[target]]]; RETURN[TRUE]; END; Offset[on, offset]; PutF[on, "node %g", card[GetNodeIndex[node]]]; IF node = startNode THEN PutRope[on, " (start node)"]; SELECT graphClass FROM LR0 => BEGIN ring _ GetRingNumber[node]; baseNodeIndex _ LAST[CARDINAL]; consistent _ TRUE; END; LALR1 => BEGIN ring _ GetRingNumber[node]; baseNodeIndex _ GetNodeIndex[GetBaseNode[node]]; consistent _ (ring # 0); END; SplitNode => BEGIN baseNode: Node _ GetBaseNode[node]; ring _ GetRingNumber[baseNode]; baseNodeIndex _ GetNodeIndex[baseNode]; consistent _ ring # 0 OR TestConsistencyOfNode[node]; END; ENDCASE => ERROR; IF ring # LAST[CARDINAL] THEN PutF[on, " (ring = %g)", card[ring]]; IF baseNodeIndex # LAST[CARDINAL] THEN PutF[on, " (base = %g)", card[baseNodeIndex]]; IF NOT consistent THEN PutRope[on, " (This node is NOT consistent)"]; PutRope[on, "\N"]; Offset[on, offset]; PutRope[on, " associated set\N"]; SELECT graphClass FROM LR0 => showAssociatedSet _ ShowLR0ItemSet; LALR1, SplitNode => showAssociatedSet _ ShowLR1ItemSet; ENDCASE => ERROR; showAssociatedSet[on, offset+3, GetAssociatedSet[node]]; Offset[on, offset]; PutRope[on, " arcs\N"]; GenerateArcs[node, ShowOneArc]; PutRope[on, "\N"]; END; ShowGraph: PUBLIC PROC[on: STREAM, ringsOnly: BOOLEAN, offset: CARDINAL, graph: Graph] = BEGIN index: CARDINAL _ 0; startNode: Node _ GetStartNode[graph]; ShowOneNode: PROC[node: Node] RETURNS[BOOLEAN] = BEGIN IF (NOT ringsOnly) OR (GetRingNumber[node] # LAST[CARDINAL]) THEN ShowNode[on, offset, node]; RETURN[TRUE]; END; Offset[on, offset]; PutF[on, "(start node = %g)\N", card[GetNodeIndex[startNode]]]; GenerateAllNodes[graph, ShowOneNode]; PutRope[on, "\N"]; PutRope[on, "\N"]; END; ShowGeneratedParser: PUBLIC PROC[on: STREAM, graph: Graph] = BEGIN ShowSymbol: PROC[text: ROPE] = {PutF[on, "symbol: %g\N", rope[text]]}; ShowUniqueToken: PROC[name: ROPE, spelling: ROPE] = {PutF[on, "uniqueToken: %g (spelled as: %g)\N", rope[name], rope[spelling]]}; ShowGenericToken: PROC[name: ROPE, class: ROPE] = {PutF[on, "genericToken: %g (class: %g)\N", rope[name], rope[class]]}; ShowShift: PROC[state: CARDINAL, terminalSeq: ROPE, newState: CARDINAL] = {PutF[on, "shift: %g <%g> %g\N", card[state], rope[terminalSeq], card[newState]]}; ShowReduction: PROC[state: CARDINAL, terminalSeq: ROPE, leftSide: ROPE, ruleNumber: CARDINAL, ruleSize: CARDINAL] = {PutF[on, "reduction: %g <%g> <%g %g %g>\N", card[state], rope[terminalSeq], rope[leftSide], card[ruleNumber], card[ruleSize]]}; ShowAcceptance: PROC[state: CARDINAL, terminalSeq: ROPE] = {PutF[on, "accept: %g <%g>\N", card[state], rope[terminalSeq]]}; ShowStart: PROC[state: CARDINAL] = {PutF[on, "start: %g\N", card[state]]}; GenerateParseActions[graph, ShowSymbol, ShowUniqueToken, ShowGenericToken, ShowShift, ShowReduction, ShowAcceptance, ShowStart]; END; ShowArcCounts: PUBLIC PROC[on: STREAM, g: Graph] = BEGIN h: Histogram _ MakeHistogram["node", "arc", 100]; SeeOneNode: PROC[n: Node] RETURNS[BOOLEAN] = BEGIN nArcs: CARDINAL _ 0; SeeOneArc: PROC[s: Symbol, t: Node] RETURNS[BOOLEAN] = {nArcs _ nArcs+1; RETURN[TRUE]}; GenerateArcs[n, SeeOneArc]; NoteNItemsInOneContainer[h, nArcs]; RETURN[TRUE]; END; GenerateAllNodes[g, SeeOneNode]; PrintHistogram[on, h]; END; ShowRingCounts: PUBLIC PROC[on: STREAM, g: Graph] = BEGIN h: Histogram _ MakeHistogram["node", "ring", 15]; SeeOneNode: PROC[n: Node] RETURNS[BOOLEAN] = BEGIN ring: CARDINAL _ SELECT GetClass[g] FROM LR0, LALR1 => GetRingNumber[n], SplitNode => GetRingNumber[GetBaseNode[n]], ENDCASE => ERROR; IF ring < LAST[CARDINAL] THEN NoteNItemsInOneContainer[h, ring]; RETURN[TRUE]; END; GenerateAllNodes[g, SeeOneNode]; PrintRingHistogram[on, h]; END; StartShowingSignals: PUBLIC SIGNAL[ROPE] = CODE; SignalRope: PUBLIC SIGNAL[ROPE] = CODE; SignalSymbol: PUBLIC SIGNAL[ROPE, Symbol] = CODE; SignalTerminalSeq: PUBLIC SIGNAL[text: ROPE, seq: TerminalSeq] = CODE; SignalTerminalSeqSet: PUBLIC SIGNAL[text: ROPE, set: TerminalSeqSet] = CODE; SignalLR0Item: PUBLIC SIGNAL[ROPE, LR0Item] = CODE; SignalLR1Item: PUBLIC SIGNAL[ROPE, LR1Item] = CODE; SignalLR0ItemSet: PUBLIC SIGNAL[text: ROPE, set: LR0ItemSet] = CODE; SignalLR1ItemSet: PUBLIC SIGNAL[text: ROPE, set: LR1ItemSet] = CODE; SignalNode: PUBLIC SIGNAL[text: ROPE, node: Node] = CODE; StopShowingSignals: PUBLIC SIGNAL[ROPE] = CODE; -- histograms Histogram: TYPE = REF HistogramBody; HistogramBody: PUBLIC TYPE = RECORD[ nameForContainer: ROPE, nameForItem: ROPE, nContainers: INT, nItems: INT, overflow: INT, counts: SEQUENCE limit: CARDINAL OF INT]; MakeHistogram: PUBLIC PROCEDURE[nameForContainer: ROPE, nameForItem: ROPE, maxSize: CARDINAL] RETURNS[Histogram] = BEGIN hist: Histogram _ NEW[HistogramBody[maxSize+1] _ [nameForContainer, nameForItem, 0, 0, 0, ]]; FOR I: CARDINAL IN [0..maxSize] DO hist.counts[I] _ 0 ENDLOOP; RETURN[hist] END; NoteNItemsInOneContainer: PUBLIC PROCEDURE[hist: Histogram, size: CARDINAL] = BEGIN IF size >= hist.limit THEN hist.overflow _ hist.overflow + 1 ELSE hist.counts[size] _ hist.counts[size]+ 1; hist.nContainers _ hist.nContainers + 1; hist.nItems _ hist.nItems + size; END; PrintHistogram: PUBLIC PROCEDURE[s: STREAM, hist: Histogram] = BEGIN s.PutF["total number of %gs: %g\N", rope[hist.nameForContainer], int[hist.nContainers]]; s.PutF["total number of %gs: %g\N", rope[hist.nameForItem], int[hist.nItems]]; s.PutF["following is number of %gs with given number of %gs\N", rope[hist.nameForContainer], rope[hist.nameForItem]]; s.PutF["in form n %gs: n %gs\N", rope[hist.nameForItem], rope[hist.nameForContainer]]; s.PutF["entries with 0 %gs will be skipped\N", rope[hist.nameForContainer]]; FOR I: CARDINAL IN [0..hist.limit) DO IF hist.counts[I] # 0 THEN s.PutF[" %g: %g\N", card[I], int[hist.counts[I]]]; ENDLOOP; IF hist.overflow # 0 THEN s.PutF[" >= %g: %g\N", int[hist.limit], int[hist.overflow]] END; -- following is a special case PrintRingHistogram: PROCEDURE[s: STREAM, hist: Histogram] = BEGIN s.PutF["total number of nodes: %g\N", int[hist.nContainers]]; s.PutF["following is number of nodes in each ring\N"]; s.PutF["in form ring: n nodes\N"]; FOR I: CARDINAL IN [0..hist.limit) DO IF hist.counts[I] # 0 THEN s.PutF[" %g: %g\N", card[I], int[hist.counts[I]]]; ENDLOOP; IF hist.overflow # 0 THEN s.PutF[" >= %g: %g\N", int[hist.limit], int[hist.overflow]] END; -- support code Offset: PROC[on: STREAM, count: CARDINAL] = {FOR I: CARDINAL IN [0..count) DO PutChar[on, ' ] ENDLOOP}; ShowLR1ItemSet: PUBLIC PROC[on: STREAM, offset: CARDINAL, set: REF ANY] = BEGIN lr1ItemSet: LR1ItemSet _ NarrowLR1ItemSet[set]; ShowOneSubset: PROC[subSet: LR1ItemSubset] = BEGIN Offset[on, offset]; PutRope[on, "[ "]; ShowLR0ItemInner[on, subSet.lr0Item]; PutRope[on, " : "]; ShowTerminalSeqSet[on, 0, subSet.terminals]; PutRope[on, "]\N"]; END; GenerateSubsetsFromLR1ItemSet[lr1ItemSet, ShowOneSubset, TRUE]; END; ShowTerminalSeq: PUBLIC PROC[on: STREAM, offset: CARDINAL, seq: TerminalSeq] = BEGIN symbol: Symbol _ GetSymbolFromTerminalSeq[seq]; Offset[on, offset]; PutChar[on, '<]; IF symbol # NIL THEN PutRope[on, GetSymbolText[symbol]]; PutChar[on, '>]; END; END.. jThis is only good for viewer io streams (as it uses looks information) this is the old code, using dot notation FOR I: CARDINAL IN [0..GetLength[production]) DO IF I = position THEN PutRope[on, " . "] ELSE PutRope[on, " "]; PutRope[on, GetSymbolText[GetRightSideSymbol[production, I]]]; ENDLOOP IF position = GetLength[production] THEN PutRope[on, " . "]; ÊȘJšœ˜J˜0J˜(J˜˜ Jšœ˜J˜?J˜)J˜TJšœl˜lJšœ˜JšœI˜IJ˜«Jšœ˜Jšœg˜g—J˜J˜Jšœ·˜·˜Jšœˆ˜ˆJ˜˜8J˜˜1J˜J˜8J˜:J˜˜0J˜>J˜5J˜—J˜J˜—J˜˜"J˜.—J˜˜%J˜˜#J˜7—˜J˜J˜sJ˜J˜—J˜J˜—J˜J˜+J˜FJ˜-J˜ J˜+˜J˜——˜TJ˜J˜˜$J˜J˜3J˜J˜—J˜J˜(J˜—J˜˜GJ˜J˜&J˜J˜J˜˜J™F——˜3J˜J˜J˜J˜8J˜:˜J™(™0J™>J™>J™——˜0J˜J˜nJ˜TJ˜—J™J˜ J˜—J˜˜MJ˜J˜kJ˜(J˜!J˜—J˜˜>J˜J˜XJ˜NJ˜uJ˜YJ˜L˜%˜J˜=—J˜—˜J˜C—J˜—J˜J˜˜;J˜J˜=J˜6J˜%˜%˜J˜=—J˜—˜J˜C—J˜—˜J˜—J˜J˜˜+J˜;J˜J˜—˜IJ˜J˜/˜,J˜J˜&J˜%J˜J˜,J˜J˜—Jšœ?˜?J˜J˜—˜NJ˜J˜/J˜J˜J˜8J˜J˜—J˜J˜—J˜—…—- 3Ò