SyntaxTree/tree/FillParentNodeVisitor.cs
This commit is contained in:
parent
d9872e09d3
commit
c92984982e
101
SyntaxTree/tree/BaseChangeVisitor.cs
Normal file
101
SyntaxTree/tree/BaseChangeVisitor.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace PascalABCCompiler.SyntaxTree
|
||||
{
|
||||
public class BaseChangeVisitor : CollectUpperNodesVisitor
|
||||
{
|
||||
public override void DefaultVisit(syntax_tree_node n)
|
||||
{
|
||||
// frninja 07/12/15 - // SSM - это - идиотский код, приводивший к двойному обходу визитором всех узлов
|
||||
/*if (!_rootAdded)
|
||||
{
|
||||
_rootAdded = true;
|
||||
ProcessNode(n);
|
||||
}*/
|
||||
|
||||
// Элементы списков - с конца в начало чтобы можно было эти элементы изменять по ходу (удалять/вставлять/заменять один несколькими)
|
||||
var Сount = n.subnodes_count;
|
||||
var СountWithoutListElements = n.subnodes_without_list_elements_count;
|
||||
|
||||
for (var i = 0; i < СountWithoutListElements; i++)
|
||||
ProcessNode(n[i]);
|
||||
|
||||
for (var i = Сount - 1; i >= СountWithoutListElements; i--) // в обратном порядке
|
||||
ProcessNode(n[i]);
|
||||
}
|
||||
|
||||
public void Replace(syntax_tree_node from, syntax_tree_node to)
|
||||
{
|
||||
var upper = UpperNode();
|
||||
if (upper == null)
|
||||
throw new Exception("У корневого элемента нельзя получить UpperNode");
|
||||
upper.Replace(from, to);
|
||||
}
|
||||
|
||||
public T UpperNodeAs<T>(int up = 1) where T : syntax_tree_node
|
||||
{
|
||||
var stl = UpperNode(up) as T;
|
||||
if (stl == null)
|
||||
throw new Exception("Элемент вложен не в " + typeof(T));
|
||||
return stl;
|
||||
}
|
||||
|
||||
public T UpperTo<T>() where T : syntax_tree_node
|
||||
{
|
||||
syntax_tree_node upperNode = null;
|
||||
|
||||
int up = 1;
|
||||
|
||||
do
|
||||
{
|
||||
upperNode = UpperNode(up);
|
||||
++up;
|
||||
}
|
||||
while ((object)upperNode != null && !(upperNode is T));
|
||||
|
||||
return (object)upperNode != null ? upperNode as T : null;
|
||||
}
|
||||
|
||||
public bool DeleteInIdentList(ident id)
|
||||
{
|
||||
var idl = UpperNodeAs<ident_list>();
|
||||
return idl.Remove(id);
|
||||
}
|
||||
|
||||
public bool DeleteInStatementList(statement st)
|
||||
{
|
||||
var stl = UpperNodeAs<statement_list>();
|
||||
return stl.Remove(st);
|
||||
}
|
||||
|
||||
public static IEnumerable<statement> SeqStatements(params statement[] seq)
|
||||
{
|
||||
var l = new List<statement>();
|
||||
foreach (var st in seq)
|
||||
if (st is statement_list)
|
||||
l.AddRange((st as statement_list).list);
|
||||
else l.Add(st);
|
||||
return l;
|
||||
}
|
||||
|
||||
public void ReplaceStatement(statement from, statement to)
|
||||
{
|
||||
var stl = UpperNodeAs<statement_list>();
|
||||
stl.ReplaceInList(from, to);
|
||||
}
|
||||
|
||||
public void ReplaceStatement(statement from, IEnumerable<statement> to)
|
||||
{
|
||||
var stl = UpperNodeAs<statement_list>();
|
||||
stl.ReplaceInList(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
41
SyntaxTree/tree/CollectUpperNodesVisitor.cs
Normal file
41
SyntaxTree/tree/CollectUpperNodesVisitor.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace PascalABCCompiler.SyntaxTree
|
||||
{
|
||||
public class CollectUpperNodesVisitor : BaseEnterExitVisitor
|
||||
{
|
||||
protected List<syntax_tree_node> listNodes = new List<syntax_tree_node>();
|
||||
|
||||
public syntax_tree_node CurrentNode
|
||||
{
|
||||
get
|
||||
{
|
||||
return listNodes[listNodes.Count - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public syntax_tree_node UpperNode(int up = 1)
|
||||
{
|
||||
if (listNodes.Count - 1 - up < 0)
|
||||
return null;
|
||||
return listNodes[listNodes.Count - 1 - up];
|
||||
}
|
||||
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
listNodes.Add(st);
|
||||
}
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
listNodes.RemoveAt(listNodes.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
23
SyntaxTree/tree/FillParentNodeVisitor.cs
Normal file
23
SyntaxTree/tree/FillParentNodeVisitor.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PascalABCCompiler.SyntaxTree
|
||||
{
|
||||
public class FillParentNodeVisitor: CollectUpperNodesVisitor
|
||||
{
|
||||
public static FillParentNodeVisitor New
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FillParentNodeVisitor();
|
||||
}
|
||||
}
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
base.Enter(st);
|
||||
st.Parent = UpperNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue