BEGIN OPEN GrammarBasic;
-- These graphs are used to represent LR(0) canonical parsers, LALR(1) parsers, LR(1) canonical parsers, and my split node parsers.
-- a graph is a collection of nodes and arcs
Graph: TYPE = REF GraphBody;
GraphBody: TYPE;
Node: TYPE = REF NodeBody;
NodeBody: TYPE;
GraphClass: TYPE = {LR0, LALR1, SplitNode};
-- operations on graphs as a whole
CreateEmptyGraph: PROC[Grammar, GraphClass] RETURNS[Graph];
GetGraphStats: PROC[Graph] RETURNS[nNodes, nArcs, nNodesMarkedToSplit: INT];
GetClass: PROC[Graph] RETURNS[GraphClass];
GetGrammar: PROC[Graph] RETURNS[Grammar];
GetStartNode: PROC[Graph] RETURNS[Node];
GetAnyStage1Node: PROC[Graph] RETURNS[Node];
GetAnyDirtyNode: PROC[Graph] RETURNS[Node];
GenerateAllNodes: PROC[Graph, PROC[Node] RETURNS[--continue--BOOLEAN]];
ClearAllUpperNodePointers: PROC[Graph];
IndexTheNodes: PROC[Graph]; -- can only be done once
CleanTheGraph: PROCEDURE[graph: Graph] RETURNS[Graph]; -- so that it can be garbage collected (returns NIL)
-- operations on nodes
CreateTentativeStage1Node: PROC[g: Graph, s: REF ANY, base: Node] RETURNS[Node];
InstallStage1Node: PROC[n: Node, startNode: BOOLEAN];
SetUpperNode: PROC[n: Node, upper: Node];
SetRingNumber: PROC[n: Node, ring: CARDINAL];
AppendAnArc: PROC[source: Node, s: Symbol, target: Node];
ResetArcTarget: PROC[source: Node, s: Symbol, newTarget: Node];
SetAssociatedSet: PROC[Node, --new value-- REF ANY, --old value-- REF ANY]; -- S
MarkAsStage2: PROC[Node];
MarkNodeDirty: PROC[Node];
MarkNodeToSplit: PROC[Node];
GetGraph: PROC[Node] RETURNS[Graph];
GenerateArcs: PROC[Node, PROC[Symbol, Node] RETURNS[--continue-- BOOLEAN]];
FollowSymbol: PROC[Node, Symbol] RETURNS[Node];
GetAssociatedSet: PROC[Node] RETURNS[REF ANY]; -- S
GetBaseNode: PROC[Node] RETURNS[Node]; -- upsilon
GetUpperNode: PROC[Node] RETURNS[Node]; -- psi
GetRingNumber: PROC[Node] RETURNS[CARDINAL];
GetSplittingMark: PROC[Node] RETURNS[BOOLEAN];
NarrowNode: PROC[REF ANY] RETURNS[Node];
GetNodeIndex: PROC[Node] RETURNS[CARDINAL];
END..