mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 08:35:43 +00:00
ZoneCodeGenerator: Add Next and Peek queries for Tags and Matches
This commit is contained in:
parent
f13eac7436
commit
a1670305c7
@ -31,7 +31,7 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
{
|
{
|
||||||
if (state.CurrentBlock is INameAssignable nameAssignableBlock)
|
if (state.CurrentBlock is INameAssignable nameAssignableBlock)
|
||||||
{
|
{
|
||||||
nameAssignableBlock.AssignName(GetMatcherTokens(NameToken)[0]);
|
nameAssignableBlock.AssignName(NextMatch(NameToken));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -29,12 +29,12 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
var isTypedef = HasMatcherTokens(TypedefToken);
|
var isTypedef = HasMatcherTokens(TypedefToken);
|
||||||
var name = HasMatcherTokens(NameToken) ? GetMatcherTokens(NameToken)[0] : RandomName.GenerateName();
|
var name = NextMatch(NameToken) ?? RandomName.GenerateName();
|
||||||
var parentType = DataTypeBaseType.INT;
|
var parentType = DataTypeBaseType.INT;
|
||||||
|
|
||||||
if (HasMatcherTokens(TypenameToken))
|
if (HasMatcherTokens(TypenameToken))
|
||||||
{
|
{
|
||||||
var typeName = GetMatcherTokens(TypenameToken)[0];
|
var typeName = NextMatch(TypenameToken);
|
||||||
var type = state.FindType(typeName);
|
var type = state.FindType(typeName);
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
|
@ -34,7 +34,7 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
var name = GetMatcherTokens(NameToken)[0];
|
var name = NextMatch(NameToken);
|
||||||
long value;
|
long value;
|
||||||
|
|
||||||
if (!(state.CurrentBlock is BlockEnum _enum))
|
if (!(state.CurrentBlock is BlockEnum _enum))
|
||||||
@ -42,11 +42,11 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
|
|
||||||
if (HasMatcherTokens(NumberValueToken))
|
if (HasMatcherTokens(NumberValueToken))
|
||||||
{
|
{
|
||||||
value = long.Parse(GetMatcherTokens(NumberValueToken)[0]);
|
value = long.Parse(NextMatch(NumberValueToken));
|
||||||
}
|
}
|
||||||
else if(HasMatcherTokens(EnumMemberValueToken))
|
else if(HasMatcherTokens(EnumMemberValueToken))
|
||||||
{
|
{
|
||||||
var stringValue = GetMatcherTokens(EnumMemberValueToken)[0];
|
var stringValue = NextMatch(EnumMemberValueToken);
|
||||||
var memberWithFittingName = state.FindEnumMember(stringValue);
|
var memberWithFittingName = state.FindEnumMember(stringValue);
|
||||||
|
|
||||||
if(memberWithFittingName == null)
|
if(memberWithFittingName == null)
|
||||||
|
@ -30,7 +30,7 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
var name = GetMatcherTokens(NameToken)[0];
|
var name = NextMatch(NameToken);
|
||||||
var _namespace = state.CurrentNamespace.ToString();
|
var _namespace = state.CurrentNamespace.ToString();
|
||||||
|
|
||||||
if (HasMatcherTokens(EnumToken))
|
if (HasMatcherTokens(EnumToken))
|
||||||
|
@ -23,7 +23,7 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
state.PushBlock(new BlockNamespace(state, GetMatcherTokens(NamespaceNameToken)[0]));
|
state.PushBlock(new BlockNamespace(state, NextMatch(NamespaceNameToken)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,16 +43,16 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
var isTypedef = HasMatcherTokens(TypedefToken);
|
var isTypedef = HasMatcherTokens(TypedefToken);
|
||||||
var name = HasMatcherTokens(NameToken) ? GetMatcherTokens(NameToken)[0] : RandomName.GenerateName();
|
var name = NextMatch(NameToken) ?? RandomName.GenerateName();
|
||||||
|
|
||||||
var block = new BlockStruct(state, name, isTypedef);
|
var block = new BlockStruct(state, name, isTypedef);
|
||||||
|
|
||||||
if (HasMatcherTokens(AlignToken))
|
if (HasMatcherTokens(AlignToken))
|
||||||
block.CustomAlignment = int.Parse(GetMatcherTokens(AlignToken)[0]);
|
block.CustomAlignment = int.Parse(NextMatch(AlignToken));
|
||||||
|
|
||||||
if (HasMatcherTokens(ParentToken))
|
if (HasMatcherTokens(ParentToken))
|
||||||
{
|
{
|
||||||
var parentDataTypeName = GetMatcherTokens(ParentToken)[0];
|
var parentDataTypeName = NextMatch(ParentToken);
|
||||||
var parentDataType = state.FindType(parentDataTypeName);
|
var parentDataType = state.FindType(parentDataTypeName);
|
||||||
|
|
||||||
if(parentDataType == null)
|
if(parentDataType == null)
|
||||||
|
@ -50,22 +50,22 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
var name = GetMatcherTokens(NameToken)[0];
|
var name = NextMatch(NameToken);
|
||||||
var pointerDepth = GetMatcherTokens(PointerTokens).Count;
|
var pointerDepth = GetMatcherTokenCount(PointerTokens);
|
||||||
|
|
||||||
var typeName = string.Join(" ", GetMatcherTokens(TypeNameTokens));
|
var typeName = NextMatch(TypeNameTokens);
|
||||||
var type = state.FindType(typeName);
|
var type = state.FindType(typeName);
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new TestFailedException($"Could not find type '{typeName}' of typedef '{name}'.");
|
throw new TestFailedException($"Could not find type '{typeName}' of typedef '{name}'.");
|
||||||
|
|
||||||
var arrayTokens = GetMatcherTokens(ArrayTokens);
|
var arraySize = new int[GetMatcherTokenCount(ArrayTokens)];
|
||||||
var arraySize = new int[arrayTokens.Count];
|
string arrayToken;
|
||||||
|
var index = 0;
|
||||||
for(var i = 0; i < arrayTokens.Count; i++)
|
while((arrayToken = NextMatch(ArrayTokens)) != null)
|
||||||
{
|
{
|
||||||
if (!int.TryParse(arrayTokens[i], out arraySize[i]))
|
if (!int.TryParse(arrayToken, out arraySize[index++]))
|
||||||
throw new TestFailedException($"Array size '{arrayTokens[i]}' is not numeric.");
|
throw new TestFailedException($"Array size '{arrayToken}' is not numeric.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var references = new List<ReferenceType>();
|
var references = new List<ReferenceType>();
|
||||||
|
@ -43,16 +43,16 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
var isTypedef = HasMatcherTokens(TypedefToken);
|
var isTypedef = HasMatcherTokens(TypedefToken);
|
||||||
var name = HasMatcherTokens(NameToken) ? GetMatcherTokens(NameToken)[0] : RandomName.GenerateName();
|
var name = NextMatch(NameToken) ?? RandomName.GenerateName();
|
||||||
|
|
||||||
var block = new BlockUnion(state, name, isTypedef);
|
var block = new BlockUnion(state, name, isTypedef);
|
||||||
|
|
||||||
if (HasMatcherTokens(AlignToken))
|
if (HasMatcherTokens(AlignToken))
|
||||||
block.CustomAlignment = int.Parse(GetMatcherTokens(AlignToken)[0]);
|
block.CustomAlignment = int.Parse(NextMatch(AlignToken));
|
||||||
|
|
||||||
if (HasMatcherTokens(ParentToken))
|
if (HasMatcherTokens(ParentToken))
|
||||||
{
|
{
|
||||||
var parentDataTypeName = GetMatcherTokens(ParentToken)[0];
|
var parentDataTypeName = NextMatch(ParentToken);
|
||||||
var parentDataType = state.FindType(parentDataTypeName);
|
var parentDataType = state.FindType(parentDataTypeName);
|
||||||
|
|
||||||
if(parentDataType == null)
|
if(parentDataType == null)
|
||||||
|
@ -55,26 +55,26 @@ namespace ZoneCodeGenerator.Parsing.C_Header.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(IHeaderParserState state)
|
protected override void ProcessMatch(IHeaderParserState state)
|
||||||
{
|
{
|
||||||
var name = GetMatcherTokens(NameToken)[0];
|
var name = NextMatch(NameToken);
|
||||||
var typeName = GetMatcherTokens(TypeNameToken)[0];
|
var typeName = NextMatch(TypeNameToken);
|
||||||
var type = state.FindType(typeName);
|
var type = state.FindType(typeName);
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new TestFailedException($"Type '{typeName}' not found.");
|
throw new TestFailedException($"Type '{typeName}' not found.");
|
||||||
|
|
||||||
var pointerDepth = GetMatcherTokens(PointerTokens).Count;
|
var pointerDepth = GetMatcherTokenCount(PointerTokens);
|
||||||
|
|
||||||
var arrayTokens = GetMatcherTokens(ArrayTokens);
|
|
||||||
var arraySize = new int[arrayTokens.Count];
|
|
||||||
|
|
||||||
int? bitSize = null;
|
int? bitSize = null;
|
||||||
if (HasMatcherTokens(BitSizeToken))
|
if (HasMatcherTokens(BitSizeToken))
|
||||||
bitSize = int.Parse(GetMatcherTokens(BitSizeToken)[0]);
|
bitSize = int.Parse(NextMatch(BitSizeToken));
|
||||||
|
|
||||||
for(var i = 0; i < arrayTokens.Count; i++)
|
string arrayToken;
|
||||||
|
var index = 0;
|
||||||
|
var arraySize = new int[GetMatcherTokenCount(ArrayTokens)];
|
||||||
|
while ((arrayToken = NextMatch(ArrayTokens)) != null)
|
||||||
{
|
{
|
||||||
if (!int.TryParse(arrayTokens[i], out arraySize[i]))
|
if (!int.TryParse(arrayToken, out arraySize[index++]))
|
||||||
throw new TestFailedException($"Array size '{arrayTokens[i]}' is not numeric.");
|
throw new TestFailedException($"Array size '{arrayToken}' is not numeric.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.CurrentBlock is IVariableHolder variableHolder)
|
if (state.CurrentBlock is IVariableHolder variableHolder)
|
||||||
|
@ -28,7 +28,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(ICommandParserState state)
|
protected override void ProcessMatch(ICommandParserState state)
|
||||||
{
|
{
|
||||||
var assetTypeName = GetMatcherTokens(AssetTypeNameToken)[0];
|
var assetTypeName = NextMatch(AssetTypeNameToken);
|
||||||
|
|
||||||
var assetType = state.Repository.GetDataTypeByName(assetTypeName);
|
var assetType = state.Repository.GetDataTypeByName(assetTypeName);
|
||||||
if (assetType == null)
|
if (assetType == null)
|
||||||
@ -47,7 +47,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
throw new LoadingException($"Could not find information for type '{assetTypeName}' to mark it as an asset.");
|
throw new LoadingException($"Could not find information for type '{assetTypeName}' to mark it as an asset.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var enumEntryName = GetMatcherTokens(AssetEnumEntryToken)[0];
|
var enumEntryName = NextMatch(AssetEnumEntryToken);
|
||||||
var enumEntry = state.Repository.GetAllEnums()
|
var enumEntry = state.Repository.GetAllEnums()
|
||||||
.SelectMany(_enum => _enum.Members)
|
.SelectMany(_enum => _enum.Members)
|
||||||
.FirstOrDefault(member => member.Name.Equals(enumEntryName, StringComparison.CurrentCultureIgnoreCase));
|
.FirstOrDefault(member => member.Name.Equals(enumEntryName, StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
@ -32,10 +32,10 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(ICommandParserState state)
|
protected override void ProcessMatch(ICommandParserState state)
|
||||||
{
|
{
|
||||||
var blockName = GetMatcherTokens(BlockNameToken)[0];
|
var blockName = NextMatch(BlockNameToken);
|
||||||
var blockNumber = int.Parse(GetMatcherTokens(BlockNumberToken)[0]);
|
var blockNumber = int.Parse(NextMatch(BlockNumberToken));
|
||||||
|
|
||||||
var blockTypeInput = GetMatcherTokens(BlockTypeToken)[0];
|
var blockTypeInput = NextMatch(BlockTypeToken);
|
||||||
if (!Enum.TryParse(blockTypeInput, true, out FastFileBlock.Type blockType))
|
if (!Enum.TryParse(blockTypeInput, true, out FastFileBlock.Type blockType))
|
||||||
{
|
{
|
||||||
var blockTypeValues = Enum.GetValues(typeof(FastFileBlock.Type)).OfType<FastFileBlock.Type>()
|
var blockTypeValues = Enum.GetValues(typeof(FastFileBlock.Type)).OfType<FastFileBlock.Type>()
|
||||||
|
@ -31,7 +31,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
throw new TestFailedException($"Game has already been set with value '{state.Game}'");
|
throw new TestFailedException($"Game has already been set with value '{state.Game}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
state.Game = GetMatcherTokens(GameNameToken)[0];
|
state.Game = NextMatch(GameNameToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(ICommandParserState state)
|
protected override void ProcessMatch(ICommandParserState state)
|
||||||
{
|
{
|
||||||
var typeName = GetMatcherTokens(TypeNameToken)[0];
|
var typeName = NextMatch(TypeNameToken);
|
||||||
var dataTypeToUse = state.Repository.GetDataTypeByName(typeName);
|
var dataTypeToUse = state.Repository.GetDataTypeByName(typeName);
|
||||||
|
|
||||||
if (dataTypeToUse == null)
|
if (dataTypeToUse == null)
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
if (name != null && success)
|
if (name != null && success)
|
||||||
result.AddNamedMatch(name, output);
|
result.AddNamedMatch(name, output);
|
||||||
|
result.AppendTag(Tag);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace ZoneCodeGenerator.Parsing.Matching.Matchers
|
|||||||
protected override TokenMatchingResult PerformTest(MatchingContext context, int tokenOffset)
|
protected override TokenMatchingResult PerformTest(MatchingContext context, int tokenOffset)
|
||||||
{
|
{
|
||||||
var result = new TokenMatchingResult(true, 0);
|
var result = new TokenMatchingResult(true, 0);
|
||||||
|
result.AppendTag(Tag);
|
||||||
|
|
||||||
foreach(var matcher in Matchers)
|
foreach(var matcher in Matchers)
|
||||||
{
|
{
|
||||||
@ -20,8 +21,7 @@ namespace ZoneCodeGenerator.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
if (matcherResult.Successful)
|
if (matcherResult.Successful)
|
||||||
{
|
{
|
||||||
matcherResult.CopyNamedMatchesTo(result);
|
matcherResult.CopyTo(result);
|
||||||
result.ConsumedTokenCount += matcherResult.ConsumedTokenCount;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,8 @@ namespace ZoneCodeGenerator.Parsing.Matching.Matchers
|
|||||||
protected override TokenMatchingResult PerformTest(MatchingContext context, int tokenOffset)
|
protected override TokenMatchingResult PerformTest(MatchingContext context, int tokenOffset)
|
||||||
{
|
{
|
||||||
var result = new TokenMatchingResult(false, 0);
|
var result = new TokenMatchingResult(false, 0);
|
||||||
|
result.AppendTag(Tag);
|
||||||
|
|
||||||
var matchedTimes = 0;
|
var matchedTimes = 0;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@ -32,8 +34,7 @@ namespace ZoneCodeGenerator.Parsing.Matching.Matchers
|
|||||||
if (!matcherResult.Successful)
|
if (!matcherResult.Successful)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
matcherResult.CopyNamedMatchesTo(result);
|
matcherResult.CopyTo(result);
|
||||||
result.ConsumedTokenCount += matcherResult.ConsumedTokenCount;
|
|
||||||
matchedTimes++;
|
matchedTimes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,10 @@ namespace ZoneCodeGenerator.Parsing.Matching.Matchers
|
|||||||
{
|
{
|
||||||
var matcherResult = matcher.Test(context, tokenOffset);
|
var matcherResult = matcher.Test(context, tokenOffset);
|
||||||
|
|
||||||
if (matcherResult.Successful)
|
if (!matcherResult.Successful) continue;
|
||||||
return matcherResult;
|
|
||||||
|
matcherResult.PrependTag(Tag);
|
||||||
|
return matcherResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TokenMatchingResult(false, 0);
|
return new TokenMatchingResult(false, 0);
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using ZoneCodeGenerator.Utils;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Parsing.Matching
|
namespace ZoneCodeGenerator.Parsing.Matching
|
||||||
{
|
{
|
||||||
class TokenMatchingResult : IEnumerable<KeyValuePair<string, List<string>>>
|
class TokenMatchingResult
|
||||||
{
|
{
|
||||||
public bool Successful { get; set; }
|
public bool Successful { get; set; }
|
||||||
public int ConsumedTokenCount { get; set; }
|
public int ConsumedTokenCount { get; set; }
|
||||||
|
|
||||||
private readonly Dictionary<string, List<string>> namedMatches;
|
private readonly Dictionary<string, List<string>> namedMatches;
|
||||||
|
public IReadOnlyDictionary<string, List<string>> NamedMatches => namedMatches;
|
||||||
|
|
||||||
|
private readonly List<string> matchedTags;
|
||||||
|
public IReadOnlyList<string> MatchedTags => matchedTags;
|
||||||
|
|
||||||
public TokenMatchingResult(bool success, int consumedTokenCount)
|
public TokenMatchingResult(bool success, int consumedTokenCount)
|
||||||
{
|
{
|
||||||
@ -23,6 +29,7 @@ namespace ZoneCodeGenerator.Parsing.Matching
|
|||||||
ConsumedTokenCount = consumedTokenCount;
|
ConsumedTokenCount = consumedTokenCount;
|
||||||
|
|
||||||
namedMatches = new Dictionary<string, List<string>>();
|
namedMatches = new Dictionary<string, List<string>>();
|
||||||
|
matchedTags = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddNamedMatch(string name, string value)
|
public void AddNamedMatch(string name, string value)
|
||||||
@ -33,27 +40,31 @@ namespace ZoneCodeGenerator.Parsing.Matching
|
|||||||
namedMatches[name].Add(value);
|
namedMatches[name].Add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<KeyValuePair<string, List<string>>> GetEnumerator()
|
public void PrependTag(string tag)
|
||||||
{
|
{
|
||||||
return namedMatches.GetEnumerator();
|
if (!string.IsNullOrEmpty(tag))
|
||||||
|
matchedTags.Insert(0, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
public void AppendTag(string tag)
|
||||||
{
|
{
|
||||||
return namedMatches.GetEnumerator();
|
if(!string.IsNullOrEmpty(tag))
|
||||||
|
matchedTags.Add(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> this[string key] => namedMatches.ContainsKey(key) ? namedMatches[key] : new List<string>();
|
public void CopyTo(TokenMatchingResult target)
|
||||||
|
|
||||||
public void CopyNamedMatchesTo(TokenMatchingResult target)
|
|
||||||
{
|
{
|
||||||
foreach(var namedMatchKey in namedMatches)
|
foreach(var (matchKey, matchValue) in namedMatches)
|
||||||
{
|
{
|
||||||
foreach (var namedMatch in namedMatchKey.Value)
|
foreach (var namedMatch in matchValue)
|
||||||
{
|
{
|
||||||
target.AddNamedMatch(namedMatchKey.Key, namedMatch);
|
target.AddNamedMatch(matchKey, namedMatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target.matchedTags.AddRange(matchedTags);
|
||||||
|
|
||||||
|
target.ConsumedTokenCount += ConsumedTokenCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,32 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using ZoneCodeGenerator.Parsing.Matching;
|
using ZoneCodeGenerator.Parsing.Matching;
|
||||||
|
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
||||||
|
using ZoneCodeGenerator.Utils;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Parsing.Testing
|
namespace ZoneCodeGenerator.Parsing.Testing
|
||||||
{
|
{
|
||||||
abstract class AbstractTokenTest<TState> : ITokenTest<TState> where TState : IParserState<TState>
|
abstract class AbstractTokenTest<TState> : ITokenTest<TState> where TState : IParserState<TState>
|
||||||
{
|
{
|
||||||
public int ConsumedTokenCount { get; private set; }
|
private TokenMatchingResult lastResult;
|
||||||
|
private int tagOffset;
|
||||||
|
private readonly Dictionary<string, int> matchOffset;
|
||||||
|
|
||||||
private readonly TokenMatcher[] matcherEntryPoint;
|
public int ConsumedTokenCount => lastResult?.ConsumedTokenCount ?? 0;
|
||||||
private readonly Dictionary<string, List<string>> matchedEntries;
|
|
||||||
|
private readonly TokenMatcher matcherEntryPoint;
|
||||||
private readonly Dictionary<string, TokenMatcher> taggedMatchers;
|
private readonly Dictionary<string, TokenMatcher> taggedMatchers;
|
||||||
private bool tested;
|
|
||||||
|
|
||||||
protected AbstractTokenTest(TokenMatcher[] matcherEntryPoint)
|
protected AbstractTokenTest(TokenMatcher[] matcherEntryPoint)
|
||||||
{
|
{
|
||||||
this.matcherEntryPoint = matcherEntryPoint;
|
this.matcherEntryPoint = new MatcherGroupAnd(matcherEntryPoint);
|
||||||
matchedEntries = new Dictionary<string, List<string>>();
|
|
||||||
taggedMatchers = new Dictionary<string, TokenMatcher>();
|
taggedMatchers = new Dictionary<string, TokenMatcher>();
|
||||||
tested = false;
|
|
||||||
|
lastResult = null;
|
||||||
|
tagOffset = 0;
|
||||||
|
matchOffset = new Dictionary<string, int>();
|
||||||
|
|
||||||
BuildTaggedMatcherList(matcherEntryPoint);
|
BuildTaggedMatcherList(matcherEntryPoint);
|
||||||
}
|
}
|
||||||
@ -40,31 +47,81 @@ namespace ZoneCodeGenerator.Parsing.Testing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Reset()
|
||||||
|
{
|
||||||
|
lastResult = null;
|
||||||
|
tagOffset = 0;
|
||||||
|
matchOffset.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
protected void AddTaggedMatcher(params TokenMatcher[] taggedMatcher)
|
protected void AddTaggedMatcher(params TokenMatcher[] taggedMatcher)
|
||||||
{
|
{
|
||||||
BuildTaggedMatcherList(taggedMatcher);
|
BuildTaggedMatcherList(taggedMatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ReadOnlyCollection<string> GetMatcherTokens(string matcherName)
|
protected string PeekTag()
|
||||||
{
|
{
|
||||||
return tested && matchedEntries.ContainsKey(matcherName) ? matchedEntries[matcherName].AsReadOnly() : new List<string>().AsReadOnly();
|
return lastResult?.MatchedTags.ElementAtOrDefault(tagOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string NextTag()
|
||||||
|
{
|
||||||
|
return lastResult?.MatchedTags.ElementAtOrDefault(tagOffset++);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool HasMatcherTokens(string matcherName)
|
protected bool HasMatcherTokens(string matcherName)
|
||||||
{
|
{
|
||||||
return tested && matchedEntries.ContainsKey(matcherName);
|
return GetMatcherTokenCount(matcherName) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int GetMatcherTokenCount(string matcherName)
|
||||||
|
{
|
||||||
|
if (lastResult == null || !lastResult.NamedMatches.TryGetValue(matcherName, out var matches))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string PeekMatch(string matcherName)
|
||||||
|
{
|
||||||
|
if (!lastResult.NamedMatches.TryGetValue(matcherName, out var matches))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchOffset.TryGetValue(matcherName, out var offset))
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches.ElementAtOrDefault(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string NextMatch(string matcherName)
|
||||||
|
{
|
||||||
|
if (!lastResult.NamedMatches.TryGetValue(matcherName, out var matches))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchOffset.TryGetValue(matcherName, out var offset))
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = matches.ElementAtOrDefault(offset++);
|
||||||
|
|
||||||
|
matchOffset[matcherName] = offset;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void ProcessMatch(TState state);
|
protected abstract void ProcessMatch(TState state);
|
||||||
|
|
||||||
public TokenTestResult PerformTest(TState state, ILexer lexer, bool verbose = false)
|
public TokenTestResult PerformTest(TState state, ILexer lexer, bool verbose = false)
|
||||||
{
|
{
|
||||||
var tokenOffset = 0;
|
|
||||||
matchedEntries.Clear();
|
|
||||||
|
|
||||||
ConsumedTokenCount = 0;
|
|
||||||
tested = true;
|
|
||||||
|
|
||||||
var context = new MatchingContext(lexer, taggedMatchers)
|
var context = new MatchingContext(lexer, taggedMatchers)
|
||||||
{
|
{
|
||||||
Verbose = verbose
|
Verbose = verbose
|
||||||
@ -75,30 +132,19 @@ namespace ZoneCodeGenerator.Parsing.Testing
|
|||||||
Console.WriteLine($"Test {GetType().Name} start");
|
Console.WriteLine($"Test {GetType().Name} start");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(var matcher in matcherEntryPoint)
|
Reset();
|
||||||
|
lastResult = matcherEntryPoint.Test(context, 0);
|
||||||
|
|
||||||
|
if (!lastResult.Successful)
|
||||||
{
|
{
|
||||||
var result = matcher.Test(context, tokenOffset);
|
if (context.Verbose)
|
||||||
|
|
||||||
if (!result.Successful)
|
|
||||||
{
|
{
|
||||||
if (context.Verbose)
|
Console.WriteLine($"Test {GetType().Name} failed");
|
||||||
{
|
|
||||||
Console.WriteLine($"Test {GetType().Name} failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
return TokenTestResult.NoMatch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenOffset += result.ConsumedTokenCount;
|
return TokenTestResult.NoMatch;
|
||||||
|
|
||||||
foreach (var entry in result)
|
|
||||||
{
|
|
||||||
matchedEntries.Add(entry.Key, entry.Value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsumedTokenCount = tokenOffset;
|
|
||||||
|
|
||||||
ProcessMatch(state);
|
ProcessMatch(state);
|
||||||
|
|
||||||
if (context.Verbose)
|
if (context.Verbose)
|
||||||
|
@ -152,7 +152,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(3, result.ConsumedTokenCount);
|
Assert.AreEqual(3, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("13", result["array_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("13", result.NamedMatches["array_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -168,7 +168,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(3, result.ConsumedTokenCount);
|
Assert.AreEqual(3, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("307", result["array_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("307", result.NamedMatches["array_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -184,7 +184,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(3, result.ConsumedTokenCount);
|
Assert.AreEqual(3, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("HELLO_WORLD", result["array_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("HELLO_WORLD", result.NamedMatches["array_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
Assert.AreEqual(10, result.ConsumedTokenCount);
|
Assert.AreEqual(10, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual(11, timesTested);
|
Assert.AreEqual(11, timesTested);
|
||||||
|
|
||||||
var namedMatches = result[LoopToken];
|
var namedMatches = result.NamedMatches[LoopToken];
|
||||||
|
|
||||||
Assert.AreEqual(10, namedMatches.Count);
|
Assert.AreEqual(10, namedMatches.Count);
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("const", result["test_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("const", result.NamedMatches["test_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("variable_n4me", result["name_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("variable_n4me", result.NamedMatches["name_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("420", result["number_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("420", result.NamedMatches["number_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -154,7 +154,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("421", result["number_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("421", result.NamedMatches["number_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("int", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("int", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -64,7 +64,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("GfxWorld", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("GfxWorld", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -80,7 +80,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(2, result.ConsumedTokenCount);
|
Assert.AreEqual(2, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("unsigned int", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("unsigned int", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -96,7 +96,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(2, result.ConsumedTokenCount);
|
Assert.AreEqual(2, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("signed int", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("signed int", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -112,7 +112,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(2, result.ConsumedTokenCount);
|
Assert.AreEqual(2, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("const int", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("const int", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -128,7 +128,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(2, result.ConsumedTokenCount);
|
Assert.AreEqual(2, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("long long", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("long long", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -144,7 +144,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(4, result.ConsumedTokenCount);
|
Assert.AreEqual(4, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("const unsigned long long", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("const unsigned long long", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -160,7 +160,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("int", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("int", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -176,7 +176,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(4, result.ConsumedTokenCount);
|
Assert.AreEqual(4, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("std::string", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("std::string", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -192,7 +192,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(4, result.ConsumedTokenCount);
|
Assert.AreEqual(4, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("std::int32_t", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("std::int32_t", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -208,7 +208,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(4, result.ConsumedTokenCount);
|
Assert.AreEqual(4, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("a::b", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("a::b", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -224,7 +224,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsFalse(result.Successful);
|
Assert.IsFalse(result.Successful);
|
||||||
Assert.AreEqual(0, result.ConsumedTokenCount);
|
Assert.AreEqual(0, result.ConsumedTokenCount);
|
||||||
Assert.That.IsZero(result["type_token"].Count);
|
Assert.IsFalse(result.NamedMatches.ContainsKey("type_token"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -240,7 +240,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsTrue(result.Successful);
|
Assert.IsTrue(result.Successful);
|
||||||
Assert.AreEqual(1, result.ConsumedTokenCount);
|
Assert.AreEqual(1, result.ConsumedTokenCount);
|
||||||
Assert.AreEqual("std", result["type_token"].ElementAtOrDefault(0));
|
Assert.AreEqual("std", result.NamedMatches["type_token"].ElementAtOrDefault(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -256,7 +256,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsFalse(result.Successful);
|
Assert.IsFalse(result.Successful);
|
||||||
Assert.AreEqual(0, result.ConsumedTokenCount);
|
Assert.AreEqual(0, result.ConsumedTokenCount);
|
||||||
Assert.That.IsZero(result["type_token"].Count);
|
Assert.IsFalse(result.NamedMatches.ContainsKey("type_token"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -272,7 +272,7 @@ namespace ZoneCodeGeneratorTests.Parsing.Matching.Matchers
|
|||||||
|
|
||||||
Assert.IsFalse(result.Successful);
|
Assert.IsFalse(result.Successful);
|
||||||
Assert.AreEqual(0, result.ConsumedTokenCount);
|
Assert.AreEqual(0, result.ConsumedTokenCount);
|
||||||
Assert.That.IsZero(result["type_token"].Count);
|
Assert.IsFalse(result.NamedMatches.ContainsKey("type_token"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user