mirror of
https://github.com/rgleichman/glance.git
synced 2024-11-22 23:28:34 +03:00
108 lines
5.7 KiB
Plaintext
108 lines
5.7 KiB
Plaintext
-- Pseudocode for collapsing a syntax graph.
|
|
|
|
-- New stateful algorithm
|
|
|
|
-- Note: Node refers to the FGL node, which is just an integer. The node label has to be looked up separately in the graph.
|
|
-- The node label has all of the information about the node such as what SyntaxNode it represents.
|
|
|
|
collapseRoots treeRoots = foldl' (collapseTree treeRoots)
|
|
|
|
collapseNodes :: SyntaxGrrah -> SyntaxGraph
|
|
collapseNodes originalGraph = finalGraph where
|
|
-- findTreeRoots returns a list of nodes that will embed other nodes, but are not embedded themselves.
|
|
-- These nodes are thus each a root of a collapsed node tree.
|
|
treeRoots = findTreeRoots originalGraph
|
|
-- Now collapse each tree of nodes
|
|
finalGraph = collapseRoots treeRoots originalGraph treeRoots
|
|
|
|
-- |findTreeRoots returns a list of nodes that might embed other nodes, but are not embedded themselves.
|
|
-- These nodes are thus each a root of a collapsed node tree.
|
|
-- A node is a treeRoot if all of these conditions are true:
|
|
-- 1. The SyntaxNode can embed other nodes (i.e. nodeCanEmbed is true)
|
|
-- 2. The node has at least one parent that can not embed (i.e. the node has a parent where nodeCanEmbed is false.)
|
|
-- Note: A treeRoot may not actually have any embeddable children, since collapseTree will do nothing in that case.
|
|
findTreeRoots :: SyntaxGraph -> [Node]
|
|
-- filterNodes is a library function that returns a list of the nodes in the graph
|
|
-- where the filter function is true.
|
|
-- filterNodes :: (Node -> Bool) -> Graph -> [Node]
|
|
findTreeRoots graph = filterNodes (isTreeRoot graph) graph
|
|
|
|
isTreeRoot :: SyntaxGraph -> Node -> Bool
|
|
isTreeRoot graph node = graphNodeCanEmbed graph node && hasAParentThatCannotEmbed where
|
|
hasAParentThatCannotEmbed = not $ null parentsThatCannotEmbed
|
|
parentsThatCannotEmbed = filter (graphNodeCanEmbed graph) (findParents graph node)
|
|
|
|
findParents :: Graph -> Node -> [Node]
|
|
findParents = _ -- TODO
|
|
|
|
graphNodeCanEmbed :: Graph -> Node -> Bool
|
|
graphNodeCanEmbed graph node = syntaxNodeCanEmbed $ lookupSyntaxNode graph node
|
|
|
|
lookupSyntaxNode :: SyntaxGraph -> Node -> SyntaxNode
|
|
|
|
collapseTree :: [Node] -> SyntaxGraph -> Node -> SyntaxGraph
|
|
collapseTree treeRoots oldGraph rootNode = case childrenToEmbed of
|
|
[] -> oldGraph
|
|
_ -> finalGraph
|
|
where
|
|
-- TODO Write pseudocode for subfunctions
|
|
childrenToEmbed = findChildrenToEmbed treeRoots rootNode oldGraph
|
|
-- Recursively collapse the children nodes
|
|
graphWithCollapsedChildren = collapseRoots treeRoots oldGraph childrenToEmbed
|
|
-- Transfer the edges of the children to rootNode
|
|
childEdgesToTransfer = findChildEdgesToTransfer childrenToEmbed graphWithCollapsedChildren
|
|
graphWithChildEdgesDeleted = deleteChildEdges childEdgesToTransfer graphWithCollapsedChildren
|
|
graphWithEdgesTransferred = addChildEdges rootNode childEdgesToTransfer graphWithChildEdgesDeleted
|
|
-- Modify the rootNode label (i.e. SyntaxNode) to incorporate the children it is embedding
|
|
graphWithChildrenCollapsed = embedChildSyntaxNodes rootNode childrenToEmbed graphWithEdgesTransferred
|
|
-- Delete the children that have been embedded
|
|
finalGraph = deleteChildren childrenToEmbed graphWithChildrenCollapsed
|
|
|
|
|
|
-- | findChildrenToEmbed returns a list of the node's children that can be embedded
|
|
-- A child can be embedded iff all of these conditions are true:
|
|
-- 1. The node is not a treeRoot (otherwise a cycle of embedding could occur)
|
|
-- 2. The SyntaxNode is embeddable (i.e. nodeIsEmbeddable is True)
|
|
-- 3. The node has exactly one parent that can embed (i.e. nodeCanEmbed is True for one parent)
|
|
findChildrenToEmbed :: Node -> SyntaxGraph -> [Node]
|
|
findChildrenToEmbed treeRoots node graph = if graphNodeCanEmbed node graph
|
|
then childrenToEmbed
|
|
else []
|
|
where
|
|
childrenToEmbed = _ -- TODO
|
|
|
|
-- | graphNodeCanEmbed returns true if the label (SyntaxNode) associated with the
|
|
-- node can be embedded in other SyntaxNodes (i.e. nodeCanEmbed is True)
|
|
graphNodeCanEmbed :: Node -> SyntaxGraph -> Bool
|
|
graphNodeCanEmbed node graph = _
|
|
|
|
|
|
-- OLD ALGORITHM
|
|
-- To make the problem simpler, collapseNodes just cares about the
|
|
collapseNodes :: SyntaxGraph -> SyntaxGraph
|
|
collapseNodes inGraph = graphFold foldFunc initialOutputGraph inGraph where
|
|
initialOutputGraph = emptyGraph
|
|
|
|
foldFunc :: SyntaxGraph -> Context -> SyntaxGraph
|
|
foldFunc oldGraph context = let node = nodeInContext context in
|
|
-- The node can not be embedded, and can not embed other nodes, so it is by itself.
|
|
-- We thus just add it to the accumulator graph.
|
|
-- willEmbed is true iff the current node will embed other nodes in the graph
|
|
| not (willBeEmbedded context inGraph) && not (willEmbed context inGraph) = context & oldGraph
|
|
-- willBeEmbedded checks to see if the parent of the current node will embed the current node
|
|
-- In this case the current node will be embedded, and does not embed other node.
|
|
-- We do not add the current node since it will be embedded in its parent.
|
|
-- This case is not necessary. If the current node were to be added, it would simply be
|
|
-- removed again from the accumulation graph.
|
|
| willBeEmbedded context inGraph && not (willEmbed context) = oldGraph
|
|
-- This node will embed other nodes.
|
|
-- First we find our children that will be embedded. If the child is in the
|
|
-- oldGraph, then we also need to remove the child from the oldGraph.
|
|
-- If the child is not yet in the oldGraph, then we just embed it.
|
|
| willEmbed context inGraph =
|
|
newGraph where
|
|
(oldGraphChildren, oldGraphWithChildrenRemoved) = findAndRemoveChildren oldGraph context
|
|
remainingChildrem = getRemainingChildren oldGraphChildren inGraph context
|
|
embeddedNode = makeEmbeddedNode context oldGraphChildren remainingChildren
|
|
newGarph = embeddedNode & oldGraphWithChildrenRemoved
|