diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IRGenerate.cs.old b/src/StgSharp.RegularAnalysis/.discard/RegexAnalyzer.IRGenerate.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IRGenerate.cs.old rename to src/StgSharp.RegularAnalysis/.discard/RegexAnalyzer.IRGenerate.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IROptimize.cs.old b/src/StgSharp.RegularAnalysis/.discard/RegexAnalyzer.IROptimize.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IROptimize.cs.old rename to src/StgSharp.RegularAnalysis/.discard/RegexAnalyzer.IROptimize.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.PrefixEmit.cs.old b/src/StgSharp.RegularAnalysis/.discard/RegexAnalyzer.PrefixEmit.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.PrefixEmit.cs.old rename to src/StgSharp.RegularAnalysis/.discard/RegexAnalyzer.PrefixEmit.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/RegexIR.Abstraction.cs.old b/src/StgSharp.RegularAnalysis/.discard/RegexIR.Abstraction.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/RegexIR.Abstraction.cs.old rename to src/StgSharp.RegularAnalysis/.discard/RegexIR.Abstraction.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/RegexIR.Prefix.cs.old b/src/StgSharp.RegularAnalysis/.discard/RegexIR.Prefix.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/RegexIR.Prefix.cs.old rename to src/StgSharp.RegularAnalysis/.discard/RegexIR.Prefix.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/RegexIR.cs.old b/src/StgSharp.RegularAnalysis/.discard/RegexIR.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/RegexIR.cs.old rename to src/StgSharp.RegularAnalysis/.discard/RegexIR.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/RegexIRGenerator.cs.old b/src/StgSharp.RegularAnalysis/.discard/RegexIRGenerator.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/RegexIRGenerator.cs.old rename to src/StgSharp.RegularAnalysis/.discard/RegexIRGenerator.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.MultiIR.cs.old b/src/StgSharp.RegularAnalysis/.discard/TextRegexSourceGen.GenClass.MultiIR.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.MultiIR.cs.old rename to src/StgSharp.RegularAnalysis/.discard/TextRegexSourceGen.GenClass.MultiIR.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.Prefix.cs.old b/src/StgSharp.RegularAnalysis/.discard/TextRegexSourceGen.GenClass.Prefix.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.Prefix.cs.old rename to src/StgSharp.RegularAnalysis/.discard/TextRegexSourceGen.GenClass.Prefix.cs.old diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.SingleIR.cs.old b/src/StgSharp.RegularAnalysis/.discard/TextRegexSourceGen.GenClass.SingleIR.cs.old similarity index 100% rename from src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.SingleIR.cs.old rename to src/StgSharp.RegularAnalysis/.discard/TextRegexSourceGen.GenClass.SingleIR.cs.old diff --git a/src/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs b/src/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs index 357d0013..36ea99fe 100644 --- a/src/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs +++ b/src/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs @@ -16,8 +16,9 @@ using System.Text; namespace StgSharp.RegularAnalysis.Abstraction { - public interface ITrinitySyntaxNode : ISyntaxNode - where TNode : ISyntaxNode + public interface ITrinitySyntaxNode : ISyntaxNode + where TNode : ISyntaxNode + where TPayload : ISyntaxPayload where TLabel : unmanaged { @@ -25,7 +26,9 @@ namespace StgSharp.RegularAnalysis.Abstraction } - public interface ISyntaxNode where TNode : ISyntaxNode + public interface ISyntaxNode + where TNode : ISyntaxNode + where TPayload : ISyntaxPayload where TLabel : unmanaged { @@ -45,7 +48,7 @@ namespace StgSharp.RegularAnalysis.Abstraction static abstract TNode Empty { get; } - Token Source { get; } + TPayload Source { get; } protected internal int EnumState { get; set; } diff --git a/src/StgSharp.RegularAnalysis/Abstraction/ISyntaxPayload.cs b/src/StgSharp.RegularAnalysis/Abstraction/ISyntaxPayload.cs new file mode 100644 index 00000000..f6f1f25c --- /dev/null +++ b/src/StgSharp.RegularAnalysis/Abstraction/ISyntaxPayload.cs @@ -0,0 +1,32 @@ +// ----------------------------------------------------------------------------- +// file="ISyntaxPayload" +// Project: StgSharp +// Copyright (c) Nitload. +// SPDX-License-Identifier: MIT +// ----------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis.Abstraction +{ + // TODO 不对劲,TCarrier是个昏招,还是去掉吧 + public interface ISyntaxPayload + where TSelf : ISyntaxPayload + where TCarrier : ISyntaxNode + where TLabel : unmanaged + { + + int Column { get; set; } + + int Row { get; set; } + + string Source { get; set; } + + TLabel Flag { get; set; } + + } +} diff --git a/src/StgSharp.RegularAnalysis/IR_RETIRED.md b/src/StgSharp.RegularAnalysis/IR_RETIRED.md index 9f0f943b..b88bbe83 100644 --- a/src/StgSharp.RegularAnalysis/IR_RETIRED.md +++ b/src/StgSharp.RegularAnalysis/IR_RETIRED.md @@ -27,13 +27,37 @@ IR 层代码因此归档而非删除:将来做 stepping 解释器时是字节 ## 需要在 AST 上补什么 +### 节点重设计(先于一切) + +`RegexAstNode` 不再挂载 `Token`:token 在 AST 构建时被**消费掉**, +转换为结构化载荷。节点只剩三样东西:`Label`(原 `Source.Flag`)、`IPayload`、拓扑。 +这把 IR 层真正有价值的部分(类型化语义)请了回来,线性形态留在 `.old` 里。 + +| Label | Payload | 转换时机 | +| --- | --- | --- | +| `UNIT` / `UNIT_SPAN` | `LiteralPayload(Text)`,**转义已消解** | AST 构建 | +| `UNIT_SET` | `CharSetPayload(Set)` | AST 构建 | +| `COUNT` | `CountPayload(Min, Max, IsGreedy)`,即 `{m,n}` 的唯一解析点 | AST 构建 | +| `GROUP_BEGIN` | `GroupPayload(Name, Index)` | AST 构建 | +| `CONCAT` / `ALT` | 无(null) | — | +| `FIND`(新) | `FindPayload(Anchor, IsNearest)` | phase 6 融合 pass | + +规则: + +1. 载荷全部是不可变 record,深拷贝共享引用不复制 +2. `ReplaceBy` / `RemoveAndAsChild` 搬运 `Label + Payload`,不再拷 Source +3. mask 决断载荷类型,取用走 `PayloadAs()`,类型不符当场抛 +4. pass 局部属性(`FirstAtom`/`LastAtom`)不住这个槽,放融合 pass 的 side table + +改造点:`ASTGenerate` 构造处(token→payload 转换)、`ASTOptimize` 里读 +`Value`/`Source` 的消费点、两个变形 API、`EmptyRegexAstNode`(Label=NONE)。 + ### 基础件(不存在,先补) -1. **子树深拷贝**——`(ab){2,3}` 展开需要克隆 body;配合破坏性移动可省一份 -2. **合成节点工厂**——展开要凭空造 CONCAT/COUNT 节点, - 需要 `Token` 的合成构造入口(如 `Token.Synthetic(flag, value)`) -3. **FIND 节点标签**——`RegexElementLabel` 新增 `FIND`,语义为"搜索连接" - (替代 IR 的 `FIND_COMPLEX`,见下) +1. **子树深拷贝**——`(ab){2,3}` 展开需要克隆 body;配合破坏性移动可省一份;载荷共享不拷 +2. **FIND 节点标签**——`RegexElementLabel` 新增 `FIND`,语义为"搜索连接" + (替代 IR 的 `FIND_COMPLEX`,见下);合成节点直接 `new(label, payload)`, + 无需伪造 token ### 树上规范化 pass(`OptimizeTree` 扩到六阶段) @@ -81,7 +105,9 @@ GROUP 的捕获终点落在锚起点**之前**。 | 文件 | 错误原因 | 处置 | | --- | --- | --- | | `RegexAnalyzer.cs` | `TextRegexSource` 记录携带 `List` 字段,`Analyze` 调 `GenerateIR`/`ScanAndOptimizeIR`/`EmitPrefix` | 砍掉 IR 字段与三个调用,管线止于 `OptimizeTree` | -| `TextRegexSourceGen.GenClass.cs` | `GenerateSource` 读 `source.IRs`,`GenerateBlock`/`GenerateRegion`/`MeasureRegionExtents`/`FindRegionEnd` 全是 IR 机器 | 重写为读 `source.Ast` 的节点递归;保留 `FormatStringLiteral`/`FormatCharLiteral`/charset 解析 | +| `TextRegexSourceGen.GenClass.cs` | `GenerateSource` 读 `source.IRs`,`GenerateBlock`/`GenerateRegion`/`MeasureRegionExtents`/`FindRegionEnd` 全是 IR 机器 | 重写为读 `source.Ast` 的节点递归;保留 `FormatStringLiteral`/`FormatCharLiteral`;charset 解析迁入 `CharSetPayload` 转换 | + +节点重设计落地时,`ASTGenerate`/`ASTOptimize` 会新增一批预期内错误(`Source`/`Value` 消费点),同批修复。 ## `.old` 文件清单与参考价值 diff --git a/src/StgSharp.RegularAnalysis/StgSharp.RegularAnalysis.csproj b/src/StgSharp.RegularAnalysis/StgSharp.RegularAnalysis.csproj index 0ab69b4c..87c61924 100644 --- a/src/StgSharp.RegularAnalysis/StgSharp.RegularAnalysis.csproj +++ b/src/StgSharp.RegularAnalysis/StgSharp.RegularAnalysis.csproj @@ -1,4 +1,4 @@ - + true @@ -34,6 +34,16 @@ + + + + + + + + + + diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.ASTNodeOptimize.cs b/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.ASTNodeOptimize.cs new file mode 100644 index 00000000..1105fa9f --- /dev/null +++ b/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.ASTNodeOptimize.cs @@ -0,0 +1,25 @@ +// ----------------------------------------------------------------------------- +// file="RegexAnalyzer.ASTNodeOptimize" +// Project: StgSharp +// Copyright (c) Nitload. +// SPDX-License-Identifier: MIT +// ----------------------------------------------------------------------------- + +using StgSharp.RegularAnalysis.Abstraction; +using System; + +namespace StgSharp.RegularAnalysis.Text +{ + internal partial class RegexAnalyzer + { + + private static bool TryFlattenCount( + RegexAstNode node + ) + { + // flatten count node if it matches raw string pattern + throw new NotImplementedException(); + } + + } +} diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.cs b/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.cs index 826e791e..a48ea10f 100644 --- a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.cs +++ b/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.cs @@ -44,10 +44,11 @@ namespace StgSharp.RegularAnalysis.Text public string Pattern { get; } internal AbstractSyntaxTree Ast { get; } - + /* internal List BaseIR { get; } internal List IRs { get; } + /**/ internal RegexInfo Info { get; } @@ -76,10 +77,11 @@ namespace StgSharp.RegularAnalysis.Text { return new TextRegexSource(regex, null, null, null, info, ex); } - List base_ir; + /* + // List base_ir; try { - base_ir = GenerateIR(tree, ref info); + // base_ir = GenerateIR(tree, ref info); } catch (Exception ex) { @@ -87,8 +89,8 @@ namespace StgSharp.RegularAnalysis.Text } try { - ScanAndOptimizeIR(base_ir, out List opt_ir); - List prefix_ir = EmitPrefix(opt_ir, ref info); + // ScanAndOptimizeIR(base_ir, out List opt_ir); + // List prefix_ir = EmitPrefix(opt_ir, ref info); return new TextRegexSource(regex, require_ast ? tree : null!, require_origin_ir ? base_ir : null!, prefix_ir, info); } @@ -97,6 +99,7 @@ namespace StgSharp.RegularAnalysis.Text return new TextRegexSource(regex, require_ast ? tree : null!, require_origin_ir ? base_ir : null!, null!, info, ex); } + /**/ #pragma warning restore CA1031 } diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAnanlyzer.ASTNodeOptimize.cs b/src/StgSharp.RegularAnalysis/Text/RegexAnanlyzer.ASTNodeOptimize.cs new file mode 100644 index 00000000..e69de29b diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAstNode.AdditionalPayload.cs b/src/StgSharp.RegularAnalysis/Text/RegexAstNode.AdditionalPayload.cs new file mode 100644 index 00000000..12301acd --- /dev/null +++ b/src/StgSharp.RegularAnalysis/Text/RegexAstNode.AdditionalPayload.cs @@ -0,0 +1,34 @@ +// ----------------------------------------------------------------------------- +// file="RegexAstNode.AdditionalPayload" +// Project: StgSharp +// Copyright (c) Nitload. +// SPDX-License-Identifier: MIT +// ----------------------------------------------------------------------------- + +using StgSharp.RegularAnalysis.Abstraction; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis.Text +{ + public class RegexCountPayload : ISyntaxPayload + { + + public int Min { get; set; } + + public int Max { get; set; } + + public string Source { get; set; } + + } + + public class RegexCommonPayload : IRegexAstNodeAdditionalPayload + { + + public string Source { get; set; } = string.Empty; + + } +} diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAstNode.cs b/src/StgSharp.RegularAnalysis/Text/RegexAstNode.cs index 1ca9d4ae..80af460f 100644 --- a/src/StgSharp.RegularAnalysis/Text/RegexAstNode.cs +++ b/src/StgSharp.RegularAnalysis/Text/RegexAstNode.cs @@ -10,6 +10,8 @@ using System.Runtime.CompilerServices; namespace StgSharp.RegularAnalysis.Text { + // TODO 现在存在的问题是,AstNode过于依赖NodeFlag表达其内部语义,这导致进行精细优化时识别节点语义复杂, + // TODO 当前Ast的类型差异过小,不利于保存特征数据,应当争取进一步细化,或者说这是AstNode一开始为了简化架构设计引入的妥协 internal class RegexAstNode : ISyntaxNode {