-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
071a686
commit c180f2a
Showing
42 changed files
with
1,457 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks> | ||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> | ||
<OutputType>Library</OutputType> | ||
<AssemblyName>NMF.AnyText.Core</AssemblyName> | ||
<RootNamespace>NMF.AnyText</RootNamespace> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
<OutputPath>..\..\Build</OutputPath> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\Transformations\Transformations\Transformations.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using NMF.AnyText.Rules; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace NMF.AnyText.Grammar | ||
{ | ||
public class GrammarContext | ||
{ | ||
private readonly IDictionary<Type, Rule> _rules; | ||
private readonly Dictionary<string, LiteralRule> _keywords = new Dictionary<string, LiteralRule>(); | ||
|
||
public GrammarContext(IDictionary<Type, Rule> rules) | ||
{ | ||
_rules = rules; | ||
} | ||
|
||
public T ResolveRule<T>() where T : Rule | ||
{ | ||
if (_rules.TryGetValue(typeof(T), out var rule)) | ||
{ | ||
return rule as T; | ||
} | ||
return null; | ||
} | ||
|
||
public LiteralRule ResolveKeyword(string keyword) | ||
{ | ||
if (!_keywords.TryGetValue(keyword, out var rule)) | ||
{ | ||
rule = new LiteralRule(keyword); | ||
_keywords.Add(keyword, rule); | ||
} | ||
return rule; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using NMF.AnyText.Rules; | ||
using NMF.Transformations; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace NMF.AnyText.Grammar | ||
{ | ||
public abstract class ReflectiveGrammar | ||
{ | ||
private GrammarContext _context; | ||
|
||
public T GetRule<T>() where T : Rule | ||
{ | ||
Initialize(); | ||
return _context?.ResolveRule<T>(); | ||
} | ||
|
||
public void Initialize() | ||
{ | ||
if (_context == null) | ||
{ | ||
var rules = Reflector.ReflectDictionary(GetGrammarTypeStack(), CreateDefaultRules, CreateCustomRules); | ||
_context = new GrammarContext(rules); | ||
foreach (var rule in rules.Values) | ||
{ | ||
rule.Initialize(_context); | ||
} | ||
} | ||
} | ||
|
||
private Stack<Type> GetGrammarTypeStack() | ||
{ | ||
var typeStack = new Stack<Type>(); | ||
var currentType = this.GetType(); | ||
while (currentType != typeof(ReflectiveGrammar)) | ||
{ | ||
typeStack.Push(currentType); | ||
currentType = currentType.BaseType; | ||
} | ||
return typeStack; | ||
} | ||
|
||
protected virtual IEnumerable<Rule> CreateDefaultRules() | ||
{ | ||
return null; | ||
} | ||
|
||
protected virtual IEnumerable<Rule> CreateCustomRules() | ||
{ | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
UserInterfaces/AnyText.Core/Model/AddAssignReferenceRule.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
using NMF.AnyText.Rules; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace NMF.AnyText.Model | ||
{ | ||
/// <summary> | ||
/// Denotes a rule that adds the value of an inner rule to a collection of the semantic element | ||
/// </summary> | ||
/// <typeparam name="TSemanticElement">The type of the context element</typeparam> | ||
/// <typeparam name="TReference">The type of the property value</typeparam> | ||
public abstract class AddAssignReferenceRule<TSemanticElement, TReference> : QuoteRule | ||
{ | ||
/// <inheritdoc /> | ||
protected internal override void OnActivate(RuleApplication application, ParseContext context) | ||
{ | ||
if (application.ContextElement is TSemanticElement contextElement) | ||
{ | ||
var resolveString = RuleHelper.Stringify(application.GetValue(context)); | ||
if (context.TryResolveReference<TReference>(contextElement, resolveString, out var propertyValue)) | ||
{ | ||
GetCollection(contextElement, context).Add(propertyValue); | ||
} | ||
else | ||
{ | ||
context.EnqueueResolveAction(new ResolveAction(application, resolveString, default, true)); | ||
} | ||
} | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected internal override void OnDeactivate(RuleApplication application, ParseContext context) | ||
{ | ||
if (application.ContextElement is TSemanticElement contextElement) | ||
{ | ||
var resolveString = RuleHelper.Stringify(application.GetValue(context)); | ||
if (context.TryResolveReference<TReference>(contextElement, resolveString, out var propertyValue)) | ||
{ | ||
GetCollection(contextElement, context).Remove(propertyValue); | ||
} | ||
else | ||
{ | ||
context.EnqueueResolveAction(new ResolveAction(application, resolveString, default, false)); | ||
} | ||
} | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected internal override bool OnValueChange(RuleApplication application, ParseContext context) | ||
{ | ||
// value change already handled in rule application | ||
return application.ContextElement is TSemanticElement; | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override RuleApplication CreateRuleApplication(RuleApplication app, ParseContext context) | ||
{ | ||
return new Application(this, app, app.Length, app.ExaminedTo); | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Obtains the child collection | ||
/// </summary> | ||
/// <param name="semanticElement">the semantic element</param> | ||
/// <param name="context">the parse context in which the collection is obtained</param> | ||
/// <returns>a collection of values</returns> | ||
public abstract ICollection<TReference> GetCollection(TSemanticElement semanticElement, ParseContext context); | ||
|
||
private sealed class Application : SingleRuleApplication | ||
{ | ||
public Application(Rule rule, RuleApplication inner, ParsePositionDelta endsAt, ParsePositionDelta examinedTo) : base(rule, inner, endsAt, examinedTo) | ||
{ | ||
} | ||
|
||
protected override void OnMigrate(RuleApplication oldValue, RuleApplication newValue, ParseContext context) | ||
{ | ||
if (oldValue.IsActive) | ||
{ | ||
oldValue.Deactivate(context); | ||
newValue.Activate(context); | ||
if (Rule is AddAssignRule<TSemanticElement, TReference> addAssignRule && ContextElement is TSemanticElement contextElement) | ||
{ | ||
var collection = addAssignRule.GetCollection(contextElement, context); | ||
if (oldValue.GetValue(context) is TReference oldProperty) | ||
{ | ||
collection.Remove(oldProperty); | ||
} | ||
if (newValue.GetValue(context) is TReference newProperty) | ||
{ | ||
collection.Add(newProperty); | ||
} | ||
} | ||
else | ||
{ | ||
Rule.OnValueChange(this, context); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
private sealed class ResolveAction : ParseResolveAction | ||
{ | ||
private readonly bool _isAdd; | ||
|
||
public ResolveAction(RuleApplication ruleApplication, string resolveString, ParsePosition position, bool isAdd) : base(ruleApplication, resolveString, position) | ||
{ | ||
_isAdd = isAdd; | ||
} | ||
|
||
public override void OnParsingComplete(ParseContext parseContext) | ||
{ | ||
var contextElement = RuleApplication.ContextElement; | ||
if (parseContext.TryResolveReference<TReference>(contextElement, ResolveString, out var reference)) | ||
{ | ||
var parent = (AddAssignReferenceRule<TSemanticElement, TReference>)(RuleApplication.Rule); | ||
var collection = parent.GetCollection((TSemanticElement)contextElement, parseContext); | ||
if (_isAdd) | ||
{ | ||
collection.Add(reference); | ||
} | ||
else | ||
{ | ||
collection.Remove(reference); | ||
} | ||
} | ||
else | ||
{ | ||
parseContext.Errors.Add(new ParseError(Position, $"Could not resolve '{ResolveString}' as {typeof(TReference).Name}")); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.