В Compile() добавлен хук для преобразования синтаксических деревьев
This commit is contained in:
parent
681c2de3ba
commit
ec3421340f
|
|
@ -653,8 +653,15 @@ namespace PascalABCCompiler
|
|||
|
||||
public delegate void ChangeCompilerStateEventDelegate(ICompiler sender, CompilerState State, string FileName);
|
||||
|
||||
public interface ISyntaxTreeChanger
|
||||
{
|
||||
void Change(SyntaxTree.syntax_tree_node sn);
|
||||
}
|
||||
|
||||
public class Compiler : MarshalByRefObject, ICompiler
|
||||
{
|
||||
public ISyntaxTreeChanger SyntaxTreeChanger = null; // SSM 17/08/15 - для операций над синтаксическим деревом после его построения
|
||||
|
||||
public static string Version
|
||||
{
|
||||
get
|
||||
|
|
@ -2208,7 +2215,7 @@ namespace PascalABCCompiler
|
|||
}
|
||||
}
|
||||
|
||||
private List<SyntaxTree.unit_or_namespace> GetSyntaxInterfaceUsesList(SyntaxTree.compilation_unit CurrentSyntaxUnit)
|
||||
public List<SyntaxTree.unit_or_namespace> GetSyntaxInterfaceUsesList(SyntaxTree.compilation_unit CurrentSyntaxUnit)
|
||||
{
|
||||
List<SyntaxTree.unit_or_namespace> result = null;
|
||||
if(CurrentSyntaxUnit is SyntaxTree.unit_module)
|
||||
|
|
@ -2450,7 +2457,7 @@ namespace PascalABCCompiler
|
|||
return Path.GetDirectoryName(FileName).ToLower() == CompilerOptions.SearchDirectory.ToLower();
|
||||
}
|
||||
|
||||
private void AddStandartUnitsToUsesSection(SyntaxTree.compilation_unit cu)
|
||||
public void AddStandartUnitsToUsesSection(SyntaxTree.compilation_unit cu)
|
||||
{
|
||||
//if (FileInSearchDirectory(cu.file_name)) return;
|
||||
|
||||
|
|
@ -2533,7 +2540,7 @@ namespace PascalABCCompiler
|
|||
throw new AssemblyReadingError(CurrentCompilationUnit.SyntaxTree.file_name,UnitName,sc);
|
||||
}
|
||||
|
||||
private TreeRealization.unit_node_list GetReferences(CompilationUnit Unit)
|
||||
public TreeRealization.unit_node_list GetReferences(CompilationUnit Unit)
|
||||
{
|
||||
//TODO переделать, ConvertDirectives определена дважды и вызывается дважды!
|
||||
TreeRealization.unit_node_list res = new TreeRealization.unit_node_list();
|
||||
|
|
@ -2618,7 +2625,7 @@ namespace PascalABCCompiler
|
|||
return false;
|
||||
}
|
||||
|
||||
private TreeRealization.using_namespace GetNamespace(SyntaxTree.unit_or_namespace _name_space)
|
||||
public TreeRealization.using_namespace GetNamespace(SyntaxTree.unit_or_namespace _name_space)
|
||||
{
|
||||
return new TreeRealization.using_namespace(SyntaxTree.Utils.IdentListToString(_name_space.name.idents, "."));
|
||||
}
|
||||
|
|
@ -2635,19 +2642,19 @@ namespace PascalABCCompiler
|
|||
return new TreeRealization.using_namespace(full_namespace_name);
|
||||
}
|
||||
|
||||
private void AddNamespaces(TreeRealization.using_namespace_list using_list, List<SyntaxTree.unit_or_namespace> namespaces, bool possible_is_units)
|
||||
public void AddNamespaces(TreeRealization.using_namespace_list using_list, List<SyntaxTree.unit_or_namespace> namespaces, bool possible_is_units)
|
||||
{
|
||||
foreach (SyntaxTree.unit_or_namespace ns in namespaces)
|
||||
using_list.AddElement(GetNamespace(using_list, SyntaxTree.Utils.IdentListToString(ns.name.idents, "."), ns, possible_is_units));
|
||||
}
|
||||
|
||||
private void AddNamespaces(TreeRealization.using_namespace_list using_list, SyntaxTree.using_list ul)
|
||||
public void AddNamespaces(TreeRealization.using_namespace_list using_list, SyntaxTree.using_list ul)
|
||||
{
|
||||
if (ul != null)
|
||||
AddNamespaces(using_list, ul.namespaces, false);
|
||||
}
|
||||
|
||||
private SyntaxTree.using_list GetInterfaceSyntaxUsingList(SyntaxTree.compilation_unit cu)
|
||||
public SyntaxTree.using_list GetInterfaceSyntaxUsingList(SyntaxTree.compilation_unit cu)
|
||||
{
|
||||
if (cu is SyntaxTree.unit_module)
|
||||
return (cu as SyntaxTree.unit_module).interface_part.using_namespaces;
|
||||
|
|
@ -2829,8 +2836,15 @@ namespace PascalABCCompiler
|
|||
throw new SourceFileNotFound(UnitName);
|
||||
else
|
||||
throw new UnitNotFound(CurrentCompilationUnit.SyntaxTree.file_name, UnitName, SyntaxUsesUnit.source_context);
|
||||
|
||||
CurrentUnit.SyntaxTree = InternalParseText(UnitName, SourceText, errorsList);
|
||||
|
||||
if (errorsList.Count == 0) // SSM 17/08/15 - для преобразования синтаксических деревьев извне
|
||||
{
|
||||
if (SyntaxTreeChanger != null)
|
||||
SyntaxTreeChanger.Change(CurrentUnit.SyntaxTree);
|
||||
}
|
||||
|
||||
if (errorsList.Count == 0 && need_gen_doc(CurrentUnit.SyntaxTree))
|
||||
{
|
||||
if (SourceText != null)
|
||||
|
|
|
|||
|
|
@ -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 = "1012";
|
||||
public const string Revision = "1013";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=2
|
||||
%REVISION%=1012
|
||||
%REVISION%=1013
|
||||
%MAJOR%=2
|
||||
%COREVERSION%=0
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '2.2.0.1012'
|
||||
!define VERSION '2.2.0.1013'
|
||||
|
|
@ -186,6 +186,10 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public partial class un_expr
|
||||
{
|
||||
public static un_expr Not(expression ex)
|
||||
{
|
||||
return new un_expr(ex, Operators.LogicalNOT);
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0} {1}", OperatorServices.ToString(operation_type, LanguageId.PascalABCNET),this.subnode);
|
||||
|
|
@ -906,10 +910,23 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public partial class goto_statement
|
||||
{
|
||||
static int lbnum = 0;
|
||||
|
||||
static public string newLabelName()
|
||||
{
|
||||
lbnum++;
|
||||
return "lb#" + lbnum.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "goto " + label;
|
||||
}
|
||||
|
||||
public static goto_statement New
|
||||
{
|
||||
get { return new goto_statement(newLabelName()); }
|
||||
}
|
||||
}
|
||||
|
||||
public partial class method_call
|
||||
|
|
@ -1479,5 +1496,39 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
return "sequence of " + this.elements_type.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class if_node
|
||||
{
|
||||
public if_node(expression _condition, statement _then_body)
|
||||
{
|
||||
this._condition = _condition;
|
||||
this._then_body = _then_body;
|
||||
this._else_body = null;
|
||||
}
|
||||
}
|
||||
public partial class empty_statement
|
||||
{
|
||||
public static empty_statement New
|
||||
{
|
||||
get { return new empty_statement(); }
|
||||
}
|
||||
}
|
||||
|
||||
public partial class case_node
|
||||
{
|
||||
public case_node(expression _param, case_variants _conditions)
|
||||
{
|
||||
this._param = _param;
|
||||
this._conditions = _conditions;
|
||||
this._else_statement = null;
|
||||
}
|
||||
public case_node(expression _param)
|
||||
{
|
||||
this._param = _param;
|
||||
this._conditions = new case_variants();
|
||||
this._else_statement = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParsePABC1", "ParsePABC1\ParsePABC1.csproj", "{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxVisitors", "ParsePABC1\SyntaxVisitors.csproj", "{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTree", "..\SyntaxTree\SyntaxTree.csproj", "{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YieldDesugarTest", "YieldDesugarTest\YieldDesugarTest.csproj", "{9EBC62C6-3092-4E9D-940E-476D332E0951}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -21,6 +23,10 @@ Global
|
|||
{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
|
||||
{9EBC62C6-3092-4E9D-940E-476D332E0951}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9EBC62C6-3092-4E9D-940E-476D332E0951}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9EBC62C6-3092-4E9D-940E-476D332E0951}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9EBC62C6-3092-4E9D-940E-476D332E0951}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class AllVarsInProcYields : CollectUpperNamespacesVisitor
|
||||
public class AllVarsInProcYields : CollectUpperNamespacesVisitor
|
||||
{
|
||||
public FindMainIdentsVisitor mids = new FindMainIdentsVisitor();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class BaseChangeVisitor : CollectUpperNodesVisitor
|
||||
public class BaseChangeVisitor : CollectUpperNodesVisitor
|
||||
{
|
||||
public override void DefaultVisit(syntax_tree_node n)
|
||||
{
|
||||
|
|
@ -52,6 +52,16 @@ namespace ParsePABC1
|
|||
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>();
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class BaseEnterExitVisitor: WalkingVisitorNew
|
||||
public class BaseEnterExitVisitor : WalkingVisitorNew
|
||||
{
|
||||
public BaseEnterExitVisitor()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class CollectUpperNamespacesVisitor : CollectUpperNodesVisitor
|
||||
public class CollectUpperNamespacesVisitor : CollectUpperNodesVisitor
|
||||
{
|
||||
protected List<declaration> list = new List<declaration>();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class CollectUpperNodesVisitor : BaseEnterExitVisitor
|
||||
public class CollectUpperNodesVisitor : BaseEnterExitVisitor
|
||||
{
|
||||
protected List<syntax_tree_node> listNodes = new List<syntax_tree_node>();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
public class FindLocalDefsVisitor : WalkingVisitorNew // Запускать только для подпрограмм
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ using PascalABCCompiler.Errors;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class ChangeWhileVisitor : BaseChangeVisitor
|
||||
public class ChangeWhileVisitor : BaseChangeVisitor
|
||||
{
|
||||
int lbnum = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class CalcConstExprs : BaseChangeVisitor // вычисление целых и вещественных константных выражений на этапе парсинга
|
||||
public class CalcConstExprs : BaseChangeVisitor // вычисление целых и вещественных константных выражений на этапе парсинга
|
||||
{
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,106 +0,0 @@
|
|||
<?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>
|
||||
<TargetFrameworkProfile />
|
||||
</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="NETGenerator">
|
||||
<HintPath>..\..\bin\NETGenerator.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" />
|
||||
<Reference Include="TreeConverter">
|
||||
<HintPath>..\..\bin\TreeConverter.dll</HintPath>
|
||||
</Reference>
|
||||
</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="..\..\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>
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
using System;
|
||||
using static System.Console;
|
||||
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.ParseText(fname, txt, err);
|
||||
|
||||
if (cu == null)
|
||||
{
|
||||
if (err.Count > 0)
|
||||
WriteLine(err[0]);
|
||||
else WriteLine("Не распарсилось");
|
||||
}
|
||||
return cu;
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cu = ParseFile(@"..\..\..\yield2.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());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class CountNodesVisitor : BaseEnterExitVisitor
|
||||
public class CountNodesVisitor : BaseEnterExitVisitor
|
||||
{
|
||||
public Dictionary<System.Type, int> d = new Dictionary<System.Type, int>();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ using PascalABCCompiler.Errors;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class DeleteRedundantBeginEnds : BaseChangeVisitor
|
||||
public class DeleteRedundantBeginEnds : BaseChangeVisitor
|
||||
{
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,14 +12,19 @@ using PascalABCCompiler;
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class SimplePrettyPrinterVisitor: WalkingVisitorNew
|
||||
public class SimplePrettyPrinterVisitor : WalkingVisitorNew
|
||||
{
|
||||
int off = 0;
|
||||
|
||||
bool printNodeType = false;
|
||||
|
||||
public static SimplePrettyPrinterVisitor New
|
||||
{
|
||||
get { return new SimplePrettyPrinterVisitor(); }
|
||||
}
|
||||
|
||||
public SimplePrettyPrinterVisitor()
|
||||
{
|
||||
OnEnter = Enter;
|
||||
|
|
@ -64,6 +69,14 @@ namespace ParsePABC1
|
|||
Println("type ");
|
||||
off += 2;
|
||||
}
|
||||
else if (st is case_variant)
|
||||
{
|
||||
var td = st as case_variant;
|
||||
Println(td.conditions.ToString()+": ");
|
||||
off += 2;
|
||||
//ProcessNode(td.type_def);
|
||||
//visitNode = false;
|
||||
}
|
||||
else if (st is type_declaration)
|
||||
{
|
||||
var td = st as type_declaration;
|
||||
|
|
@ -102,7 +115,7 @@ namespace ParsePABC1
|
|||
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 empty_statement || st is declarations || st is block || st is class_body || st is class_members || st is case_variants)
|
||||
{
|
||||
}
|
||||
else if (st is if_node)
|
||||
|
|
@ -130,6 +143,13 @@ namespace ParsePABC1
|
|||
Println("while " + wn.expr.ToString() + " do");
|
||||
off += 2;
|
||||
}
|
||||
else if (st is case_node)
|
||||
{
|
||||
var cn = st as case_node;
|
||||
|
||||
Println("case " + cn.param.ToString() + " of");
|
||||
off += 2;
|
||||
}
|
||||
else if (st is labeled_statement)
|
||||
{
|
||||
var lst = st as labeled_statement;
|
||||
|
|
@ -174,11 +194,11 @@ namespace ParsePABC1
|
|||
off -= 2;
|
||||
Println("end");
|
||||
}
|
||||
else if (st is while_node || st is if_node || st is type_declarations || st is variable_definitions)
|
||||
else if (st is while_node || st is if_node || st is type_declarations || st is variable_definitions || st is case_variant)
|
||||
{
|
||||
off -= 2;
|
||||
}
|
||||
else if (st is class_definition)
|
||||
else if (st is class_definition || st is case_node)
|
||||
{
|
||||
off -= 2;
|
||||
Println("end;");
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class DeleteLocalDefs : BaseChangeVisitor
|
||||
public 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>();
|
||||
|
|
|
|||
|
|
@ -8,44 +8,50 @@ using PascalABCCompiler.Errors;
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class ChangeWhileVisitor : BaseChangeVisitor
|
||||
public class LoweringVisitor : BaseChangeVisitor
|
||||
{
|
||||
int lbnum = 0;
|
||||
|
||||
public static ChangeWhileVisitor New
|
||||
public static LoweringVisitor New
|
||||
{
|
||||
get { return new ChangeWhileVisitor(); }
|
||||
get { return new LoweringVisitor(); }
|
||||
}
|
||||
|
||||
public string newLabelName()
|
||||
public static void Accept(procedure_definition pd)
|
||||
{
|
||||
lbnum++;
|
||||
return "lb#" + lbnum.ToString();
|
||||
New.ProcessNode(pd);
|
||||
}
|
||||
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
base.Enter(st);
|
||||
if (!(st is procedure_definition || st is block || st is statement_list || st is case_node || st is for_node || st is foreach_stmt || st is if_node || st is repeat_node || st is while_node || st is with_statement || st is try_stmt || st is lock_stmt))
|
||||
{
|
||||
visitNode = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(while_node wn)
|
||||
{
|
||||
ProcessNode(wn.statements);
|
||||
var gt1 = new goto_statement(newLabelName());
|
||||
var gt2 = new goto_statement(newLabelName());
|
||||
var gt3 = new goto_statement(newLabelName());
|
||||
var b = HasStatementVisitor<yield_node>.Has(wn);
|
||||
if (!b)
|
||||
return;
|
||||
|
||||
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());
|
||||
var gt1 = goto_statement.New;
|
||||
var gt2 = goto_statement.New;
|
||||
|
||||
var stl = new statement_list(lb3, gt2, lb1, gt3, lb2);
|
||||
var if0 = new if_node(un_expr.Not(wn.expr), gt1);
|
||||
var lb2 = new labeled_statement(gt2.label, if0);
|
||||
var lb1 = new labeled_statement(gt1.label, empty_statement.New);
|
||||
|
||||
ReplaceStatement(wn, SeqStatements(lb2, wn.statements, gt2, lb1));
|
||||
|
||||
Replace(wn, stl);
|
||||
// в declarations ближайшего блока добавить описание labels
|
||||
block bl = listNodes.FindLast(x => x is block) as block;
|
||||
|
||||
var ld = new label_definitions(gt1.label, gt2.label, gt3.label);
|
||||
bl.defs.Add(ld);
|
||||
bl.defs.Add(new label_definitions(gt1.label, gt2.label));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ using PascalABCCompiler.ParserTools;
|
|||
using PascalABCCompiler.Errors;
|
||||
|
||||
|
||||
namespace ParsePABC1
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor
|
||||
public class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor
|
||||
{
|
||||
int clnum = 0;
|
||||
|
||||
|
|
@ -29,6 +29,11 @@ namespace ParsePABC1
|
|||
|
||||
public bool hasYields = false;
|
||||
|
||||
public static ProcessYieldCapturedVarsVisitor New
|
||||
{
|
||||
get { return new ProcessYieldCapturedVarsVisitor(); }
|
||||
}
|
||||
|
||||
public ProcessYieldCapturedVarsVisitor()
|
||||
{
|
||||
//PrintInfo = false;
|
||||
|
|
@ -86,7 +91,7 @@ namespace ParsePABC1
|
|||
|
||||
var className = newClassName() + "Helper";
|
||||
var assG = new assign("Result", new new_expr(new named_type_reference(className),expression_list.Empty));
|
||||
var GetEnumerator = new procedure_definition("GetEnumerator", "System.Collections.IEnumerator", assG);
|
||||
var GetEnumerator = new procedure_definition("GetEnumerator", "System.Collections.IEnumerator", new assign("Result", "Self"));
|
||||
|
||||
var stl = new statement_list(assG);
|
||||
foreach (var id in lid)
|
||||
|
|
@ -104,6 +109,67 @@ namespace ParsePABC1
|
|||
return td;
|
||||
}
|
||||
|
||||
class ConstructFiniteAutomata
|
||||
{
|
||||
public statement_list res = new statement_list();
|
||||
statement_list stl;
|
||||
int curState = 0;
|
||||
|
||||
statement_list curStatList;
|
||||
statement_list StatListAfterCase = new statement_list();
|
||||
|
||||
case_node cas; // формируемый case
|
||||
|
||||
public ConstructFiniteAutomata(statement_list stl)
|
||||
{
|
||||
this.stl = stl;
|
||||
}
|
||||
|
||||
public void Process(statement st)
|
||||
{
|
||||
if (!(st is yield_node || st is labeled_statement))
|
||||
{
|
||||
curStatList.Add(st);
|
||||
}
|
||||
if (st is yield_node)
|
||||
{
|
||||
var yn = st as yield_node;
|
||||
curState += 1;
|
||||
curStatList.Add(new assign("current", yn.ex));
|
||||
curStatList.Add(new assign("state", curState));
|
||||
curStatList.Add(new assign("Result", new bool_const(true)));
|
||||
curStatList.Add(new procedure_call(new ident("exit")));
|
||||
|
||||
curStatList = new statement_list();
|
||||
case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList);
|
||||
cas.conditions.variants.Add(cv);
|
||||
}
|
||||
if (st is labeled_statement)
|
||||
{
|
||||
var ls = st as labeled_statement;
|
||||
curStatList = StatListAfterCase;
|
||||
curStatList.Add(new labeled_statement(ls.label_name,empty_statement.New));
|
||||
Process(ls.to_statement);
|
||||
}
|
||||
}
|
||||
|
||||
public void Transform()
|
||||
{
|
||||
cas = new case_node(new ident("state"));
|
||||
|
||||
curStatList = new statement_list();
|
||||
case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList);
|
||||
cas.conditions.variants.Add(cv);
|
||||
|
||||
foreach (var st in stl.subnodes)
|
||||
Process(st);
|
||||
|
||||
stl.subnodes = SeqStatements(cas,StatListAfterCase).ToList();
|
||||
//statement_list res = new statement_list(cas);
|
||||
res = stl;
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(procedure_definition pd)
|
||||
{
|
||||
hasYields = false;
|
||||
|
|
@ -120,7 +186,11 @@ namespace ParsePABC1
|
|||
// В результате работы в mids.vars что-то осталось. Это не локальные переменные и с ними непонятно что делать
|
||||
dld.AfterProcTraverse();
|
||||
|
||||
ChangeWhileVisitor.New.ProcessNode(pd);
|
||||
LoweringVisitor.Accept(pd);
|
||||
|
||||
var cfa = new ConstructFiniteAutomata((pd.proc_body as block).program_code);
|
||||
cfa.Transform();
|
||||
(pd.proc_body as block).program_code = cfa.res;
|
||||
|
||||
// Конструируем определение класса
|
||||
var cc = GenClassForYield(pd, dld.BlockDeletedIds.Union(dld.LocalDeletedIds));
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ function Gen(a,b: real): sequence of integer;
|
|||
var j,k: real;
|
||||
begin
|
||||
var i := 1;
|
||||
j := 2;
|
||||
while i<5 do
|
||||
begin
|
||||
yield i*i;
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue