Проект с визиторами
This commit is contained in:
parent
cafd26fe61
commit
ec8e54ddaf
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "2";
|
||||
public const string Minor = "2";
|
||||
public const string Build = "0";
|
||||
public const string Revision = "966";
|
||||
public const string Revision = "967";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=2
|
||||
%REVISION%=966
|
||||
%REVISION%=967
|
||||
%MAJOR%=2
|
||||
%COREVERSION%=0
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '2.2.0.966'
|
||||
!define VERSION '2.2.0.967'
|
||||
34
_ParsePABC1/ParsePABC1.sln
Normal file
34
_ParsePABC1/ParsePABC1.sln
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParsePABC1", "ParsePABC1\ParsePABC1.csproj", "{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTree", "..\..\PascalABC.NET\!PABC_Git\SyntaxTree\SyntaxTree.csproj", "{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCompletion", "..\..\PascalABC.NET\!PABC_Git\CodeCompletion\CodeCompletion.csproj", "{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
81
_ParsePABC1/ParsePABC1/AllVarsInProcYieldsProba.cs
Normal file
81
_ParsePABC1/ParsePABC1/AllVarsInProcYieldsProba.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class AllVarsInProcYields : CollectUpperNamespacesVisitor
|
||||
{
|
||||
public FindMainIdentsVisitor mids = new FindMainIdentsVisitor();
|
||||
|
||||
public Dictionary<procedure_definition, ISet<string>> d = new Dictionary<procedure_definition, ISet<string>>();
|
||||
|
||||
public int countNodesVisited;
|
||||
|
||||
public AllVarsInProcYields()
|
||||
{
|
||||
PrintInfo = false;
|
||||
}
|
||||
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
base.Enter(st);
|
||||
countNodesVisited++;
|
||||
if (st is procedure_definition)
|
||||
{
|
||||
// пока вложенные процедуры не анализируются, хотя надо
|
||||
mids.vars.Clear();
|
||||
}
|
||||
|
||||
// сокращение обходимых узлов. Как сделать фильтр по тем узлам, которые необходимо обходить? Например, все операторы (без выражений и описаний), все описания (без операторов)
|
||||
if (st is assign || st is var_def_statement || st is procedure_call || st is procedure_header || st is expression)
|
||||
{
|
||||
visitNode = false;
|
||||
}
|
||||
}
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
if (st is procedure_definition)
|
||||
{
|
||||
if (mids.vars.Count>0)
|
||||
{
|
||||
d[st as procedure_definition] = new HashSet<string>(mids.vars);
|
||||
}
|
||||
var fld = new FindLocalDefsVisitor();
|
||||
st.visit(fld);
|
||||
fld.Print();
|
||||
var t = fld.ids.Intersect(mids.vars); // идентификаторы, захваченные из локального контекста
|
||||
|
||||
}
|
||||
base.Exit(st);
|
||||
}
|
||||
public override void visit(yield_node yn)
|
||||
{
|
||||
yn.visit(mids);
|
||||
// mids.vars - надо установить, какие из них - локальные, какие - из этого класса, какие - являются параметрами функции, а какие - глобальные (все остальные)
|
||||
// те, которые являются параметрами, надо скопировать в локальные переменные и переименовать использование везде по ходу данной функции
|
||||
// самое сложное - переменные-поля этого класса - они требуют в создаваемом классе, реализующем итератор, хранить Self текущего класса и добавлять это Self везде по ходу алгоритма
|
||||
// вначале будем считать, что переменные-поля этого класса и переменные-параметры не захватываются yield
|
||||
//base.visit(yn);
|
||||
}
|
||||
|
||||
public void PrintDict()
|
||||
{
|
||||
foreach (var a in d)
|
||||
{
|
||||
Console.Write("{0}: {1} ", a.Key.proc_header.name.meth_name, a.Value.Count);
|
||||
foreach (var v in a.Value)
|
||||
Console.Write("{0}, ", v);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("countNodesVisited={0}", countNodesVisited);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
6
_ParsePABC1/ParsePABC1/App.config
Normal file
6
_ParsePABC1/ParsePABC1/App.config
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
</configuration>
|
||||
72
_ParsePABC1/ParsePABC1/BaseVisitors/BaseChangeVisitor.cs
Normal file
72
_ParsePABC1/ParsePABC1/BaseVisitors/BaseChangeVisitor.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class BaseChangeVisitor : CollectUpperNodesVisitor
|
||||
{
|
||||
public void Replace(syntax_tree_node from, syntax_tree_node to)
|
||||
{
|
||||
var upper = UpperNode();
|
||||
if (upper == null)
|
||||
throw new Exception("У корневого элемента нельзя получить UpperNode");
|
||||
|
||||
int ind = -1;
|
||||
for (var i = 0; i < upper.subnodes_count; i++)
|
||||
if (from == upper[i])
|
||||
{
|
||||
ind = i;
|
||||
break;
|
||||
}
|
||||
upper[ind] = to;
|
||||
}
|
||||
|
||||
public statement_list UpperStatementList()
|
||||
{
|
||||
var stl = UpperNode() as statement_list;
|
||||
if (stl == null)
|
||||
throw new Exception("оператор вложен не в statement_list");
|
||||
return stl;
|
||||
}
|
||||
|
||||
public bool DeleteInStatementList(statement st)
|
||||
{
|
||||
var stl = UpperStatementList();
|
||||
bool b = stl.subnodes.Remove(st);
|
||||
return b;
|
||||
}
|
||||
public bool DeleteInIdentList(ident id)
|
||||
{
|
||||
var idl = UpperNode() as ident_list;
|
||||
if (idl==null)
|
||||
throw new Exception("идентификатор не вложен в id_list");
|
||||
var b = idl.idents.Remove(id);
|
||||
return b;
|
||||
}
|
||||
|
||||
public void ReplaceStatement(statement from, statement to)
|
||||
{
|
||||
var stl = UpperStatementList();
|
||||
var ind = stl.subnodes.IndexOf(from);
|
||||
if (ind == -1)
|
||||
throw new Exception("оператор from не найден - некорректный вызов ReplaceStatement");
|
||||
stl.subnodes[ind] = to;
|
||||
}
|
||||
public void ReplaceStatement(statement from, List<statement> to)
|
||||
{
|
||||
var stl = UpperStatementList();
|
||||
var ind = stl.subnodes.IndexOf(from);
|
||||
if (ind == -1)
|
||||
throw new Exception("оператор from не найден - некорректный вызов ReplaceStatement");
|
||||
stl.subnodes.RemoveAt(ind);
|
||||
stl.subnodes.InsertRange(ind, to);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
27
_ParsePABC1/ParsePABC1/BaseVisitors/BaseEnterExitVisitor.cs
Normal file
27
_ParsePABC1/ParsePABC1/BaseVisitors/BaseEnterExitVisitor.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class BaseEnterExitVisitor: WalkingVisitor
|
||||
{
|
||||
public BaseEnterExitVisitor()
|
||||
{
|
||||
OnEnter = Enter;
|
||||
OnLeave = Exit;
|
||||
}
|
||||
|
||||
public virtual void Enter(syntax_tree_node st)
|
||||
{
|
||||
}
|
||||
public virtual void Exit(syntax_tree_node st)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
59
_ParsePABC1/ParsePABC1/BaseVisitors/CollectNamespaces.cs
Normal file
59
_ParsePABC1/ParsePABC1/BaseVisitors/CollectNamespaces.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class CollectUpperNamespacesVisitor : CollectUpperNodesVisitor
|
||||
{
|
||||
protected List<declaration> list = new List<declaration>();
|
||||
|
||||
public bool PrintInfo = true;
|
||||
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
base.Enter(st);
|
||||
if (st is procedure_definition || st is class_definition)
|
||||
{
|
||||
list.Add(st as declaration);
|
||||
if (PrintInfo)
|
||||
Console.Write("+: "+st.GetType().Name);
|
||||
}
|
||||
}
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
if (st is procedure_definition || st is class_definition)
|
||||
{
|
||||
if (PrintInfo)
|
||||
Console.WriteLine("-: " + st.GetType().Name);
|
||||
list.RemoveAt(list.Count - 1);
|
||||
}
|
||||
base.Exit(st);
|
||||
}
|
||||
|
||||
public override void visit(procedure_definition p)
|
||||
{
|
||||
if (PrintInfo)
|
||||
Console.WriteLine(" " + p.proc_header.name.meth_name);
|
||||
|
||||
var ld = new FindLocalDefsVisitor();
|
||||
p.visit(ld);
|
||||
|
||||
base.visit(p);
|
||||
}
|
||||
public override void visit(class_definition cl)
|
||||
{
|
||||
type_declarations tds = UpperNode(2) as type_declarations;
|
||||
var f = tds.types_decl.Find(td => td.type_def == cl);
|
||||
if (PrintInfo)
|
||||
Console.WriteLine(" " + f.type_name);
|
||||
base.visit(cl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
50
_ParsePABC1/ParsePABC1/BaseVisitors/SmallHelperVisitors.cs
Normal file
50
_ParsePABC1/ParsePABC1/BaseVisitors/SmallHelperVisitors.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
public class FindLocalDefsVisitor : WalkingVisitor // Запускать только для подпрограмм
|
||||
{
|
||||
public ISet<string> ids = new HashSet<string>();
|
||||
private bool indef = false;
|
||||
public override void visit(ident id)
|
||||
{
|
||||
if (indef)
|
||||
ids.Add(id.name);
|
||||
}
|
||||
public override void visit(var_def_statement defs)
|
||||
{
|
||||
indef = true;
|
||||
ProcessNode(defs.vars); // исключаем типы - просматриваем только имена переменных
|
||||
indef = false;
|
||||
}
|
||||
|
||||
public void Print()
|
||||
{
|
||||
foreach (var x in ids)
|
||||
Console.Write(x + ", ");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
public class FindMainIdentsVisitor : WalkingVisitor // в выражении yield это надо будет.
|
||||
{
|
||||
public HashSet<string> vars = new HashSet<string>();
|
||||
public override void visit(ident id)
|
||||
{
|
||||
vars.Add(id.name);
|
||||
}
|
||||
public override void visit(dot_node dn)
|
||||
{
|
||||
ProcessNode(dn.left);
|
||||
if (dn.right.GetType() != typeof(ident))
|
||||
ProcessNode(dn.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
_ParsePABC1/ParsePABC1/ChangeWhileVisitor.cs
Normal file
56
_ParsePABC1/ParsePABC1/ChangeWhileVisitor.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class ChangeWhileVisitor : BaseChangeVisitor
|
||||
{
|
||||
int lbnum = 0;
|
||||
|
||||
public string newLabelName()
|
||||
{
|
||||
lbnum++;
|
||||
return "lb#" + lbnum.ToString();
|
||||
}
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
if (st.GetType() == typeof(while_node))
|
||||
{
|
||||
var wn = st as while_node;
|
||||
|
||||
var stl = new statement_list();
|
||||
|
||||
var gt1 = new goto_statement(newLabelName());
|
||||
var gt2 = new goto_statement(newLabelName());
|
||||
var gt3 = new goto_statement(newLabelName());
|
||||
|
||||
var if0 = new if_node(wn.expr, gt1, null);
|
||||
var lb3 = new labeled_statement(gt3.label, if0);
|
||||
var lb1 = new labeled_statement(gt1.label, wn.statements);
|
||||
var lb2 = new labeled_statement(gt2.label, new empty_statement());
|
||||
|
||||
stl.Add(lb3).Add(gt2).Add(lb1).Add(gt3).Add(lb2);
|
||||
|
||||
//var op = new if_node(wn.expr, wn.statements, null);
|
||||
Replace(wn, stl);
|
||||
// в declarations ближайшего блока добавить описание labels
|
||||
block bl = listNodes.FindLast(x => x is block) as block;
|
||||
|
||||
var il = new ident_list();
|
||||
il.Add(gt1.label).Add(gt2.label).Add(gt3.label);
|
||||
var ld = new label_definitions(il);
|
||||
bl.defs.Add(ld);
|
||||
}
|
||||
base.Exit(st);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
44
_ParsePABC1/ParsePABC1/CountNodesVisitor.cs
Normal file
44
_ParsePABC1/ParsePABC1/CountNodesVisitor.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class CountNodesVisitor : BaseEnterExitVisitor
|
||||
{
|
||||
public Dictionary<System.Type, int> d = new Dictionary<System.Type, int>();
|
||||
|
||||
public int exprcount,statcount;
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
if (d.ContainsKey(st.GetType()))
|
||||
d[st.GetType()] += 1;
|
||||
else d[st.GetType()] = 1;
|
||||
if (st is expression)
|
||||
exprcount++;
|
||||
if (st is statement)
|
||||
statcount++;
|
||||
}
|
||||
|
||||
public void PrintSortedByValue()
|
||||
{
|
||||
var q = d.Select(x => new { x.Key, x.Value }).OrderByDescending(y => y.Value);
|
||||
foreach (var a in q)
|
||||
Console.WriteLine("{0}: {1} ", a.Key.Name, a.Value);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Expressions Count: {0}", exprcount);
|
||||
Console.WriteLine("Statements Count: {0}", statcount);
|
||||
}
|
||||
|
||||
public void Print()
|
||||
{
|
||||
foreach (var a in d)
|
||||
Console.WriteLine("{0}: {1} ", a.Key.Name, a.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
87
_ParsePABC1/ParsePABC1/DeleteLocalDefs.cs
Normal file
87
_ParsePABC1/ParsePABC1/DeleteLocalDefs.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class DeleteLocalDefs : BaseChangeVisitor
|
||||
{
|
||||
public List<var_def_statement> LocalDeletedIds = new List<var_def_statement>();
|
||||
public List<var_def_statement> BlockDeletedIds = new List<var_def_statement>();
|
||||
public HashSet<string> idsToDelete;
|
||||
public HashSet<string> deletedIdsToDeleteInLocalScope = new HashSet<string>(); // одно множество и на Local и на Block
|
||||
|
||||
public DeleteLocalDefs(HashSet<string> ids) // надо запускать этот визитор начиная с корня подпрограммы
|
||||
{
|
||||
idsToDelete = ids;
|
||||
}
|
||||
public override void visit(var_statement vs)
|
||||
{
|
||||
var idents = vs.var_def.vars.idents;
|
||||
|
||||
var IdentsToDeleteInVarDef = idents.FindAll(id => idsToDelete.Contains(id.name)); // найти в операторе все идентификаторы для удаления
|
||||
if (IdentsToDeleteInVarDef.Count != 0)
|
||||
{
|
||||
deletedIdsToDeleteInLocalScope.UnionWith(IdentsToDeleteInVarDef.Select(id => id.name)); // добавить те идентификаторы, которые мы удаляем из данного описания
|
||||
|
||||
LocalDeletedIds.Add(new var_def_statement(new ident_list(IdentsToDeleteInVarDef), vs.var_def.vars_type, vs.var_def.inital_value)); // добавить описание из удаленных в данном разделе описаний идентификаторов
|
||||
idents.RemoveAll(id => idsToDelete.Contains(id.name)); // удалить в операторе все идентификаторы для удаления
|
||||
|
||||
idsToDelete.ExceptWith(deletedIdsToDeleteInLocalScope);
|
||||
|
||||
if (idents.Count == 0) // то и весь var_statement надо убить
|
||||
this.DeleteInStatementList(vs);
|
||||
}
|
||||
// Здесь мы не обрабатываем вложенный var_def_statement, поэтому когда мы будем обрабатывать его в другом visit, то это будут переменные до beginа подпрограммы или основной программы
|
||||
}
|
||||
public override void visit(var_def_statement vd)
|
||||
{
|
||||
var idents = vd.vars.idents;
|
||||
|
||||
var IdentsToDeleteInVarDef = idents.FindAll(id => idsToDelete.Contains(id.name)); // найти в операторе все идентификаторы для удаления
|
||||
if (IdentsToDeleteInVarDef.Count != 0)
|
||||
{
|
||||
deletedIdsToDeleteInLocalScope.UnionWith(IdentsToDeleteInVarDef.Select(id => id.name)); // добавить те идентификаторы, которые мы удаляем из данного описания
|
||||
|
||||
BlockDeletedIds.Add(new var_def_statement(new ident_list(IdentsToDeleteInVarDef), vd.vars_type, vd.inital_value)); // добавить описание из удаленных в данном разделе описаний идентификаторов
|
||||
idents.RemoveAll(id => idsToDelete.Contains(id.name)); // удалить в операторе все идентификаторы для удаления
|
||||
|
||||
if (idents.Count == 0)
|
||||
{
|
||||
// Выше - variable_definitions, еще выше - declarations
|
||||
var uvdsl = UpperNode() as variable_definitions;
|
||||
uvdsl.var_definitions.Remove(vd); // Проблема - мы удаляем первую var_def_statement и вторая становится первой. А в цикле обхода - индексы что естественно
|
||||
if (uvdsl.var_definitions.Count == 0)
|
||||
{
|
||||
var d = UpperNode(2) as declarations;
|
||||
d.defs.Remove(uvdsl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public override void visit(variable_definitions vd)
|
||||
{
|
||||
if (vd.var_definitions != null)
|
||||
for (int i = vd.var_definitions.Count - 1; i >= 0; --i) // в обратном порядке - тогда удаление текущего элемента работает корректно
|
||||
ProcessNode(vd.var_definitions[i]);
|
||||
}
|
||||
|
||||
public override void visit(declarations d)
|
||||
{
|
||||
if (d.defs != null)
|
||||
for (int i = d.defs.Count - 1; i >= 0; --i) // в обратном порядке - тогда удаление текущего элемента работает корректно
|
||||
ProcessNode(d.defs[i]);
|
||||
}
|
||||
|
||||
public void AfterProcTraverse()
|
||||
{
|
||||
idsToDelete.ExceptWith(deletedIdsToDeleteInLocalScope); // исключаем из множества удаляемых идентификаторов те, которые мы нашли и удалили в секции var_statement. Это надо делать не для каждого описания, а в конце подпрограммы после удаления из всех секций var_statement
|
||||
}
|
||||
}
|
||||
}
|
||||
36
_ParsePABC1/ParsePABC1/DeleteRedundantBeginEnds.cs
Normal file
36
_ParsePABC1/ParsePABC1/DeleteRedundantBeginEnds.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class DeleteRedundantBeginEnds : BaseChangeVisitor
|
||||
{
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
var stl = st as statement_list;
|
||||
if (stl != null && UpperNode() is statement_list)
|
||||
ReplaceStatement(stl, stl.subnodes);
|
||||
|
||||
var lst = st as labeled_statement;
|
||||
if (lst != null)
|
||||
{
|
||||
var sttl = lst.to_statement as statement_list;
|
||||
if (sttl != null)
|
||||
{
|
||||
sttl.subnodes[0] = new labeled_statement(lst.label_name, sttl.subnodes[0]); // а если [0] элемента вообще нет?
|
||||
ReplaceStatement(lst,sttl.subnodes);
|
||||
}
|
||||
}
|
||||
|
||||
base.Exit(st);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
120
_ParsePABC1/ParsePABC1/Optimization/CalcConstExprs.cs
Normal file
120
_ParsePABC1/ParsePABC1/Optimization/CalcConstExprs.cs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class CalcConstExprs : BaseChangeVisitor // вычисление целых и вещественных константных выражений на этапе парсинга
|
||||
{
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
bracket_expr bre = st as bracket_expr;
|
||||
if (bre != null)
|
||||
{
|
||||
if (bre.expr is int32_const)
|
||||
Replace(st, bre.expr);
|
||||
}
|
||||
|
||||
bin_expr vs = st as bin_expr;
|
||||
if (vs != null)
|
||||
{
|
||||
if (vs.left is int32_const && vs.right is int32_const)
|
||||
{
|
||||
var a = vs.left as int32_const;
|
||||
var b = vs.right as int32_const;
|
||||
var op = vs.operation_type;
|
||||
|
||||
syntax_tree_node res;
|
||||
switch (op)
|
||||
{
|
||||
case Operators.Plus:
|
||||
res = new int32_const(a.val + b.val);
|
||||
break;
|
||||
case Operators.Minus:
|
||||
res = new int32_const(a.val - b.val);
|
||||
break;
|
||||
case Operators.Multiplication:
|
||||
res = new int32_const(a.val * b.val);
|
||||
break;
|
||||
case Operators.Division:
|
||||
res = new double_const((double)a.val / b.val);
|
||||
break;
|
||||
case Operators.Greater:
|
||||
res = new bool_const(a.val > b.val);
|
||||
break;
|
||||
case Operators.Less:
|
||||
res = new bool_const(a.val < b.val);
|
||||
break;
|
||||
case Operators.GreaterEqual:
|
||||
res = new bool_const(a.val >= b.val);
|
||||
break;
|
||||
case Operators.LessEqual:
|
||||
res = new bool_const(a.val <= b.val);
|
||||
break;
|
||||
default:
|
||||
res = vs;
|
||||
break;
|
||||
}
|
||||
|
||||
Replace(vs, res);
|
||||
}
|
||||
if (vs.left is int32_const && vs.right is double_const || vs.right is int32_const && vs.left is double_const || vs.left is double_const && vs.right is double_const)
|
||||
{
|
||||
double x,y;
|
||||
if (vs.left is int32_const)
|
||||
x = (vs.left as int32_const).val;
|
||||
else
|
||||
x = (vs.left as double_const).val;
|
||||
if (vs.right is int32_const)
|
||||
y = (vs.right as int32_const).val;
|
||||
else
|
||||
y = (vs.right as double_const).val;
|
||||
|
||||
var op = vs.operation_type;
|
||||
|
||||
syntax_tree_node res;
|
||||
switch (op)
|
||||
{
|
||||
case Operators.Plus:
|
||||
res = new double_const(x + y);
|
||||
break;
|
||||
case Operators.Minus:
|
||||
res = new double_const(x - y);
|
||||
break;
|
||||
case Operators.Multiplication:
|
||||
res = new double_const(x * y);
|
||||
break;
|
||||
case Operators.Division:
|
||||
res = new double_const(x / y);
|
||||
break;
|
||||
case Operators.Greater:
|
||||
res = new bool_const(x > y);
|
||||
break;
|
||||
case Operators.Less:
|
||||
res = new bool_const(x < y);
|
||||
break;
|
||||
case Operators.GreaterEqual:
|
||||
res = new bool_const(x >= y);
|
||||
break;
|
||||
case Operators.LessEqual:
|
||||
res = new bool_const(x <= y);
|
||||
break;
|
||||
default:
|
||||
res = vs;
|
||||
break;
|
||||
}
|
||||
|
||||
Replace(vs, res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
base.Exit(st); // это обязательно!
|
||||
}
|
||||
}
|
||||
}
|
||||
103
_ParsePABC1/ParsePABC1/ParsePABC1.csproj
Normal file
103
_ParsePABC1/ParsePABC1/ParsePABC1.csproj
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ParsePABC1</RootNamespace>
|
||||
<AssemblyName>ParsePABC1</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Compiler">
|
||||
<HintPath>..\..\..\PascalABC.NET\!PABC_SVN1\bin\Compiler.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CompilerTools">
|
||||
<HintPath>..\..\..\PascalABC.NET\!PABC_SVN1\bin\CompilerTools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Errors">
|
||||
<HintPath>..\..\..\PascalABC.NET\!PABC_SVN1\bin\Errors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Localization">
|
||||
<HintPath>..\..\..\PascalABC.NET\!PABC_SVN1\bin\Localization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ParserTools">
|
||||
<HintPath>..\..\..\PascalABC.NET\!PABC_SVN1\bin\ParserTools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PascalABCParser">
|
||||
<HintPath>..\..\..\PascalABC.NET\!PABC_Git\bin\PascalABCParser.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AllVarsInProcYieldsProba.cs" />
|
||||
<Compile Include="BaseVisitors\BaseEnterExitVisitor.cs" />
|
||||
<Compile Include="BaseVisitors\BaseChangeVisitor.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ChangeWhileVisitor.cs" />
|
||||
<Compile Include="BaseVisitors\CollectNamespaces.cs" />
|
||||
<Compile Include="BaseVisitors\CollectUpperNodesVisitor.cs" />
|
||||
<Compile Include="CountNodesVisitor.cs" />
|
||||
<Compile Include="DeleteLocalDefs.cs" />
|
||||
<Compile Include="DeleteRedundantBeginEnds.cs" />
|
||||
<Compile Include="Optimization\CalcConstExprs.cs" />
|
||||
<Compile Include="ProcessYieldsCapturedVars.cs" />
|
||||
<Compile Include="Program.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SimplePrettyPrinterVisitor.cs" />
|
||||
<Compile Include="BaseVisitors\SmallHelperVisitors.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\PascalABC.NET\!PABC_Git\CodeCompletion\CodeCompletion.csproj">
|
||||
<Project>{1ab15f6e-c22e-499a-a7ed-54ba7de5cfa6}</Project>
|
||||
<Name>CodeCompletion</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\PascalABC.NET\!PABC_Git\SyntaxTree\SyntaxTree.csproj">
|
||||
<Project>{c2cac65a-b2ae-4ccc-b067-e6b8e75df73a}</Project>
|
||||
<Name>SyntaxTree</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
104
_ParsePABC1/ParsePABC1/ProcessYieldsCapturedVars.cs
Normal file
104
_ParsePABC1/ParsePABC1/ProcessYieldsCapturedVars.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor
|
||||
{
|
||||
int clnum = 0;
|
||||
|
||||
public string newClassName()
|
||||
{
|
||||
clnum++;
|
||||
return "clyield#" + clnum.ToString();
|
||||
}
|
||||
|
||||
|
||||
public FindMainIdentsVisitor mids = new FindMainIdentsVisitor(); // захваченные переменные процедуры по всем её yield
|
||||
|
||||
public int countNodesVisited;
|
||||
|
||||
public bool hasYields = false;
|
||||
|
||||
public ProcessYieldCapturedVarsVisitor()
|
||||
{
|
||||
//PrintInfo = false;
|
||||
}
|
||||
|
||||
/*public override void visit(procedure_definition pd)
|
||||
{
|
||||
|
||||
} */
|
||||
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
base.Enter(st);
|
||||
countNodesVisited++;
|
||||
|
||||
// сокращение обходимых узлов. Как сделать фильтр по тем узлам, которые необходимо обходить? Например, все операторы (без выражений и описаний), все описания (без операторов)
|
||||
if (st is assign || st is var_def_statement || st is procedure_call || st is procedure_header || st is expression)
|
||||
{
|
||||
visitNode = false;
|
||||
}
|
||||
if (st is procedure_definition)
|
||||
{
|
||||
mids.vars.Clear(); // очищать при входе в процедуру
|
||||
}
|
||||
}
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
if (st is procedure_definition) // т.е. мы разобрали процедуру и уже выходим. Это значит, что пока yield будет обрабатываться только в процедурах. Так это и надо.
|
||||
{
|
||||
if (!hasYields)
|
||||
return;
|
||||
|
||||
var dld = new DeleteLocalDefs(mids.vars); // mids.vars - все захваченные переменные
|
||||
st.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все захваченные переменные
|
||||
// В результате работы в mids.vars что-то осталось. Это не локальные переменные и с ними непонятно что делать
|
||||
dld.AfterProcTraverse();
|
||||
|
||||
var cm = new class_members(access_modifer.public_modifer);
|
||||
foreach (var m in dld.BlockDeletedIds)
|
||||
cm.Add(m);
|
||||
cm.Add(st as procedure_definition);
|
||||
var cc = new type_declaration(newClassName(), SyntaxTreeBuilder.BuildClassDefinition(true, cm), SyntaxTreeBuilder.BuildGenSC);
|
||||
var cct = new type_declarations(cc, null);
|
||||
|
||||
Replace(st, cct);
|
||||
|
||||
/*Console.WriteLine("Удаленные переменные: " + (st as procedure_definition).proc_header.name.meth_name.name);
|
||||
foreach (var dd in dld.deletedIdsToDeleteInLocalScope)
|
||||
Console.Write(dd + " ");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Оставшиеся переменные: " + (st as procedure_definition).proc_header.name.meth_name.name);
|
||||
foreach (var dd in mids.vars)
|
||||
Console.Write(dd + " ");
|
||||
Console.WriteLine();*/
|
||||
}
|
||||
base.Exit(st);
|
||||
}
|
||||
public override void visit(yield_node yn)
|
||||
{
|
||||
hasYields = true;
|
||||
yn.visit(mids);
|
||||
// mids.vars - надо установить, какие из них - локальные, какие - из этого класса, какие - являются параметрами функции, а какие - глобальные (все остальные)
|
||||
// те, которые являются параметрами, надо скопировать в локальные переменные и переименовать использование везде по ходу данной функции
|
||||
// самое сложное - переменные-поля этого класса - они требуют в создаваемом классе, реализующем итератор, хранить Self текущего класса и добавлять это Self везде по ходу алгоритма
|
||||
// вначале будем считать, что переменные-поля этого класса и переменные-параметры не захватываются yield
|
||||
//base.visit(yn);
|
||||
}
|
||||
public override void visit(declarations d) // в обратном порядке
|
||||
{
|
||||
if (d.defs != null)
|
||||
for (int i = d.defs.Count - 1; i >= 0; --i) // в обратном порядке - тогда удаление текущего элемента работает корректно
|
||||
ProcessNode(d.defs[i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
67
_ParsePABC1/ParsePABC1/Program.cs
Normal file
67
_ParsePABC1/ParsePABC1/Program.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static syntax_tree_node ParseFile(string fname)
|
||||
{
|
||||
Compiler c = new Compiler();
|
||||
|
||||
var err = new List<Error>();
|
||||
|
||||
var txt = System.IO.File.ReadAllText(fname);
|
||||
|
||||
var cu = c.ParsersController.Compile(fname, txt, err, PascalABCCompiler.Parsers.ParseMode.ForFormatter);
|
||||
|
||||
if (cu == null)
|
||||
{
|
||||
Console.WriteLine("Не распарсилось");
|
||||
}
|
||||
return cu;
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var cu = ParseFile(@"d:\w5\ex1.pas");
|
||||
if (cu == null)
|
||||
return;
|
||||
|
||||
/*cu.visit(new ChangeWhileVisitor());
|
||||
cu.visit(new DeleteRedundantBeginEnds());*/
|
||||
|
||||
/*cu.visit(new CollectUpperNamespacesVisitor());
|
||||
|
||||
var allv = new AllVarsInProcYields();
|
||||
cu.visit(allv);
|
||||
allv.PrintDict();*/
|
||||
|
||||
/*var cnt = new CountNodesVisitor();
|
||||
cu.visit(cnt);
|
||||
cnt.PrintSortedByValue();*/
|
||||
|
||||
/*var ld = new HashSet<string>();
|
||||
ld.Add("a");
|
||||
ld.Add("p1");
|
||||
ld.Add("s");
|
||||
var dld = new DeleteLocalDefs(ld);
|
||||
cu.visit(dld);*/
|
||||
|
||||
/*var p = new ProcessYieldCapturedVarsVisitor();
|
||||
cu.visit(p);*/
|
||||
|
||||
var p = new CalcConstExprs();
|
||||
cu.visit(p);
|
||||
|
||||
cu.visit(new SimplePrettyPrinterVisitor());
|
||||
}
|
||||
}
|
||||
}
|
||||
62
_ParsePABC1/ParsePABC1/ProgramOld.cs
Normal file
62
_ParsePABC1/ParsePABC1/ProgramOld.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static syntax_tree_node ParseFile(string fname)
|
||||
{
|
||||
Compiler c = new Compiler();
|
||||
|
||||
var err = new List<Error>();
|
||||
|
||||
var txt = System.IO.File.ReadAllText(fname);
|
||||
|
||||
var cu = c.ParsersController.Compile(fname, txt, err, PascalABCCompiler.Parsers.ParseMode.ForFormatter);
|
||||
|
||||
if (cu == null)
|
||||
{
|
||||
Console.WriteLine("Не распарсилось");
|
||||
}
|
||||
return cu;
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var cu = ParseFile(@"d:\w5\e.pas");
|
||||
if (cu == null)
|
||||
return;
|
||||
|
||||
//CodeFormatters.CodeFormatter cf = new CodeFormatters.CodeFormatter(0);
|
||||
//txt = cf.FormatTree(txt, cu as compilation_unit, 0, 0);
|
||||
|
||||
cu.visit(new ChangeWhileVisitor());
|
||||
cu.visit(new DeleteRedundantBeginEnds());
|
||||
|
||||
/*cu.visit(new CollectUpperNamespacesVisitor());
|
||||
|
||||
var allv = new AllVarsInProcYields();
|
||||
cu.visit(allv);
|
||||
allv.PrintDict();*/
|
||||
|
||||
/*var cnt = new CountNodesVisitor();
|
||||
cu.visit(cnt);
|
||||
cnt.PrintSortedByValue();*/
|
||||
|
||||
var ld = new List<string>();
|
||||
ld.Add("p1");
|
||||
var dld = new DeleteLocalDefs(ld);
|
||||
cu.visit(dld);
|
||||
|
||||
cu.visit(new SimplePrettyPrinterVisitor());
|
||||
}
|
||||
}
|
||||
}
|
||||
36
_ParsePABC1/ParsePABC1/Properties/AssemblyInfo.cs
Normal file
36
_ParsePABC1/ParsePABC1/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Управление общими сведениями о сборке осуществляется с помощью
|
||||
// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
|
||||
// связанные со сборкой.
|
||||
[assembly: AssemblyTitle("ParsePABC1")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ParsePABC1")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
|
||||
// для COM-компонентов. Если требуется обратиться к типу в этой сборке через
|
||||
// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||
[assembly: Guid("fa30eefc-3fcc-45a3-8b6f-465b1a5c17ba")]
|
||||
|
||||
// Сведения о версии сборки состоят из следующих четырех значений:
|
||||
//
|
||||
// Основной номер версии
|
||||
// Дополнительный номер версии
|
||||
// Номер сборки
|
||||
// Редакция
|
||||
//
|
||||
// Можно задать все значения или принять номера сборки и редакции по умолчанию
|
||||
// используя "*", как показано ниже:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
183
_ParsePABC1/ParsePABC1/SimplePrettyPrinterVisitor.cs
Normal file
183
_ParsePABC1/ParsePABC1/SimplePrettyPrinterVisitor.cs
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.PCU;
|
||||
using PascalABCCompiler.SemanticTreeConverters;
|
||||
using System.CodeDom.Compiler;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class SimplePrettyPrinterVisitor: WalkingVisitor
|
||||
{
|
||||
int off = 0;
|
||||
|
||||
bool printNodeType = false;
|
||||
|
||||
public SimplePrettyPrinterVisitor()
|
||||
{
|
||||
OnEnter = Enter;
|
||||
OnLeave = Exit;
|
||||
}
|
||||
|
||||
public void Println(string s)
|
||||
{
|
||||
Console.Write(new string(' ', off));
|
||||
Console.WriteLine(s);
|
||||
}
|
||||
public void Print(string s)
|
||||
{
|
||||
Console.Write(new string(' ', off));
|
||||
Console.Write(s);
|
||||
}
|
||||
public void PrintNoOffset(string s)
|
||||
{
|
||||
Console.Write(s);
|
||||
}
|
||||
public void PrintlnNoOffset(string s)
|
||||
{
|
||||
Console.WriteLine(s);
|
||||
}
|
||||
|
||||
public void PrintlnNode(syntax_tree_node st)
|
||||
{
|
||||
if (printNodeType)
|
||||
Console.Write(st.GetType().Name + ": ");
|
||||
Console.WriteLine(new string(' ', off)+st);
|
||||
}
|
||||
public virtual void Enter(syntax_tree_node st)
|
||||
{
|
||||
if (st is statement_list)
|
||||
{
|
||||
Println("begin");
|
||||
off += 2;
|
||||
}
|
||||
else if (st is type_declarations) // надо в visit и самому всё обрабатывать
|
||||
{
|
||||
var tds = st is type_declarations;
|
||||
Println("type ");
|
||||
off += 2;
|
||||
}
|
||||
else if (st is type_declaration)
|
||||
{
|
||||
var td = st as type_declaration;
|
||||
Print(td.type_name + " = ");
|
||||
ProcessNode(td.type_def);
|
||||
visitNode = false;
|
||||
}
|
||||
else if (st is class_definition)
|
||||
{
|
||||
var cd = st as class_definition;
|
||||
PrintlnNoOffset("class");
|
||||
off += 2;
|
||||
ProcessNode(cd.body);
|
||||
visitNode = false;
|
||||
}
|
||||
else if (st is access_modifer_node)
|
||||
{
|
||||
var am = st as access_modifer_node;
|
||||
Println(am.access_level.ToString());
|
||||
|
||||
}
|
||||
else if (st is variable_definitions)
|
||||
{
|
||||
var vds = st as variable_definitions;
|
||||
Println("var");
|
||||
off += 2;
|
||||
}
|
||||
else if (st is var_def_statement)
|
||||
{
|
||||
var vds = st as var_def_statement;
|
||||
Println(vds.ToString());
|
||||
}
|
||||
else if (st is empty_statement || st is declarations || st is block || st is class_body || st is class_members)
|
||||
{
|
||||
}
|
||||
else if (st is if_node)
|
||||
{
|
||||
var ifn = st as if_node;
|
||||
|
||||
Println("if " + ifn.condition.ToString() + " then");
|
||||
off += 2;
|
||||
ProcessNode(ifn.then_body);
|
||||
if (ifn.else_body == null)
|
||||
{
|
||||
visitNode = false;
|
||||
return;
|
||||
}
|
||||
off -= 2;
|
||||
Println("else ");
|
||||
off += 2;
|
||||
ProcessNode(ifn.else_body);
|
||||
visitNode = false;
|
||||
}
|
||||
else if (st is while_node)
|
||||
{
|
||||
var wn = st as while_node;
|
||||
|
||||
Println("while " + wn.expr.ToString() + " do");
|
||||
off += 2;
|
||||
}
|
||||
else if (st is labeled_statement)
|
||||
{
|
||||
var lst = st as labeled_statement;
|
||||
|
||||
Println(lst.label_name.name + ": ");
|
||||
ProcessNode(lst.to_statement);
|
||||
visitNode = false;
|
||||
}
|
||||
else if (st is var_statement || st is procedure_header)
|
||||
{
|
||||
Println(st.ToString());
|
||||
visitNode = false;
|
||||
}
|
||||
else if (st is procedure_definition)
|
||||
{
|
||||
Println("");
|
||||
}
|
||||
else if (st is statement || st is variable_definitions || st is label_definitions)
|
||||
{
|
||||
PrintlnNode(st);
|
||||
if (st is labeled_statement)
|
||||
visitNode = false;
|
||||
}
|
||||
else if (st is token_info)
|
||||
{
|
||||
var s = st.ToString();
|
||||
if (s == "begin" || s == "end")
|
||||
return;
|
||||
PrintlnNode(st);
|
||||
}
|
||||
else
|
||||
{
|
||||
var q = st.GetType().GetMethod("ToString", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
|
||||
if (q == null)
|
||||
Println(st.GetType().Name);
|
||||
}
|
||||
}
|
||||
public virtual void Exit(syntax_tree_node st)
|
||||
{
|
||||
if (st is statement_list)
|
||||
{
|
||||
off -= 2;
|
||||
Println("end");
|
||||
}
|
||||
else if (st is while_node || st is if_node || st is type_declarations || st is variable_definitions)
|
||||
{
|
||||
off -= 2;
|
||||
}
|
||||
else if (st is class_definition)
|
||||
{
|
||||
off -= 2;
|
||||
Println("end;");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Loading…
Reference in a new issue