private void AddWhileBlock(FragmentMatchData matchData) { FragmentMatchData condition = (FragmentMatchData)matchData.Parts[0]; FragmentMatchData block = (FragmentMatchData)matchData.Parts[1]; int origActionStackLocation = _action.ActionStackLocation; _action.BlockDepth++; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.B, sourcePosition: matchData.StartIndex)); int lbIndex = _instructions.Count; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.L, sourcePosition: matchData.StartIndex, interruptable: true)); AddItem(condition); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.CPHR, sourcePosition: matchData.Parts[1].StartIndex)); int lbcIndex = _instructions.Count; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.NC, sourcePosition: matchData.Parts[1].StartIndex)); AddItem(block); int lbeIndex = _instructions.Count; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.LE, new object[] { lbIndex }, sourcePosition: matchData.StartIndex + matchData.Length)); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.BE, sourcePosition: matchData.StartIndex + matchData.Length)); _action.BlockDepth--; ProcessFlowControls(lbIndex, lbcIndex, lbeIndex); _action.ActionStackLocation = origActionStackLocation; }
private bool MatchFragmentNotCharacterClassBody(ref State state, FragmentMatchData matchData) { bool success = false; FragmentMatchData partMatcherData = null; int startIndex = state.CurrentIndex; int distinctIndex = state.DistinctIndex; partMatcherData = new FragmentMatchData { Name = "NotCharacterClassBody", StartIndex = state.CurrentIndex }; success = (MatchFragmentBoundsCaret(ref state, false, out StringMatchData startMatchData) && MatchFragmentPartsOneModeNotCharacterClassBody(ref state, partMatcherData)); if (success) { partMatcherData.Length = state.CurrentIndex - partMatcherData.StartIndex; partMatcherData.EndDistinctIndex = state.DistinctIndex; } else { state.CurrentIndex = startIndex; state.DistinctIndex = distinctIndex; } if (success) { matchData.Parts.Add(partMatcherData); } return(success); }
private IMatchData ConvertToLikeNameTree(FragmentMatchData matchData, IMatchData rootPart) { foreach (ExpressionPartInfo partInfo in ExtractExpressionParts(matchData).OrderBy(part => part.ExpressionOrder ?? int.MaxValue)) { if (partInfo.ExpressionOrder != null) { FragmentMatchData fragment = (FragmentMatchData)partInfo.Part; if (partInfo.Previous.Part is FragmentMatchData previousFragment && previousFragment.Name == fragment.Name) { fragment.Parts.InsertRange(0, previousFragment.Parts); } else { fragment.Parts.Insert(0, partInfo.Previous.Part); } fragment.Parts.Add(partInfo.Next.Part); if (partInfo.Previous.Previous is ExpressionPartInfo newPreviousPartInfo) { newPreviousPartInfo.Next = partInfo; partInfo.Previous = newPreviousPartInfo; } if (partInfo.Next.Next is ExpressionPartInfo newNextPartInfo) { newNextPartInfo.Previous = partInfo; partInfo.Next = newNextPartInfo; } rootPart = fragment; } }
private bool MatchFragmentCharacterRange(ref State state, FragmentMatchData matchData) { bool success = false; FragmentMatchData partMatcherData = null; int startIndex = state.CurrentIndex; int distinctIndex = state.DistinctIndex; partMatcherData = new FragmentMatchData { Name = "CharacterRange", StartIndex = state.CurrentIndex }; success = (MatchFragmentPartsOrderedModeCharacterRange(ref state, partMatcherData)); if (success) { partMatcherData.Length = state.CurrentIndex - partMatcherData.StartIndex; partMatcherData.EndDistinctIndex = state.DistinctIndex; } else { state.CurrentIndex = startIndex; state.DistinctIndex = distinctIndex; } if (success) { matchData.Parts.Add(partMatcherData); } return(success); }
private void AddIfElseBlock(FragmentMatchData matchData) { List <int> cbes = new List <int>(); foreach (FragmentMatchData partMatchData in matchData.Parts) { switch (partMatchData.Name) { case "IfStatement": cbes.Add(AddIfStatement(partMatchData)); break; case "ElseIfStatement": cbes.Add(AddElseIfStatement(partMatchData)); break; case "ElseStatement": AddElseStatement(partMatchData); break; } } int endBlockIndex = _instructions.Count; foreach (int cbe in cbes) { _instructions[cbe] = InstructionProvider <GroupState> .GetInstruction(InstructionCode.CSE, new IComparable[] { endBlockIndex }, sourcePosition : matchData.StartIndex + matchData.Length); } }
private void AddNot(FragmentMatchData matchData) { foreach (StringMatchData not in matchData.Parts) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RNot, sourcePosition: not.StartIndex)); } }
private void AddValuableChains(FragmentMatchData matchData) { foreach (FragmentMatchData partMatchData in matchData.Parts) { AddItem(partMatchData); } }
private void AddDecrement(FragmentMatchData matchData) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.PHR, sourcePosition: matchData.StartIndex)); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.VR, new object[] { 1 }, sourcePosition: matchData.StartIndex)); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RSubtract, sourcePosition: matchData.StartIndex)); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RR, sourcePosition: matchData.StartIndex)); }
private IMatchData ConvertToBinaryTree(FragmentMatchData matchData, IMatchData rootPart) { foreach (ExpressionPartInfo partInfo in ExtractExpressionParts(matchData).OrderBy(part => part.ExpressionOrder ?? int.MaxValue)) { if (partInfo.ExpressionOrder != null) { FragmentMatchData fragment = (FragmentMatchData)partInfo.Part; fragment.Parts.Insert(0, partInfo.Previous.Part); fragment.Parts.Add(partInfo.Next.Part); if (partInfo.Previous.Previous is ExpressionPartInfo newPreviousPartInfo) { newPreviousPartInfo.Next = partInfo; partInfo.Previous = newPreviousPartInfo; } if (partInfo.Next.Next is ExpressionPartInfo newNextPartInfo) { newNextPartInfo.Previous = partInfo; partInfo.Next = newNextPartInfo; } rootPart = fragment; } } return(rootPart); }
private void AddOperatedBooleanValuable(FragmentMatchData matchData) { AddItem(matchData.Parts.First(part => part.Name != "Nots")); foreach (IMatchData not in ((FragmentMatchData)matchData.Parts.FirstOrDefault(part => part.Name == "Nots")).Parts ?? Enumerable.Empty <IMatchData>()) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RNot, sourcePosition: not.StartIndex)); } }
private void AddValuedIndex(FragmentMatchData matchData) { FragmentMatchData evaluable = (FragmentMatchData)matchData.Parts[0]; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.PHR, sourcePosition: matchData.StartIndex)); AddItem(evaluable); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RVK, new object[] { _isAssignmentTarget }, sourcePosition: matchData.StartIndex)); }
private void AddFactorialMathValuable(FragmentMatchData matchData) { AddItem(matchData.Parts.First()); foreach (IMatchData factorial in ((FragmentMatchData)matchData.Parts.FirstOrDefault(part => part.Name == "Factorials")).Parts ?? Enumerable.Empty <IMatchData>()) { _instructions.Add(_instructionProvider.GetSpecialInstruction(new string[] { "RFAC" }, sourcePosition: factorial.StartIndex)); } }
private bool MatchFragmentPartsOrderedModeCharacterRange(ref State state, FragmentMatchData matchData) { bool success = true; bool partSuccess; int matchCount = 0; StringMatchData stringMatchData = null; int distinctIndex = state.DistinctIndex; ; success = MatchPartByTextMatcherAnyChar(ref state, matchData); if (!success) { if (stringMatchData != null) { state.CurrentIndex = stringMatchData.StartIndex; state.DistinctIndex = distinctIndex; } goto Break; } else { matchCount++; } distinctIndex = state.DistinctIndex; (partSuccess, stringMatchData) = MatchPatternDash(ref state, true, false); success = partSuccess; if (!success) { goto Break; } success = MatchPartByTextMatcherAnyChar(ref state, matchData); if (!success) { if (stringMatchData != null) { state.CurrentIndex = stringMatchData.StartIndex; state.DistinctIndex = distinctIndex; } goto Break; } else { matchCount++; } Break: success = success || 2 <= matchCount; if (!success) { state.FailureIndex = Math.Max(state.FailureIndex ?? 0, state.CurrentIndex); } return(success); }
private void AddItemReturn(FragmentMatchData matchData) { if (matchData.Parts.ElementAtOrDefault(0) is FragmentMatchData item) { AddItem(item, true); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RLR, new object[] { 1 }, sourcePosition: matchData.StartIndex)); } _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.AE, sourcePosition: matchData.StartIndex, interruptable: matchData.Parts.Count > 0)); }
private bool MatchPartByTextMatcherAnyChar(ref State state, FragmentMatchData matchData) { (bool success, StringMatchData partMatchData) = MatchPatternAnyChar(ref state, true, false); if (success) { matchData.Parts.Add(partMatchData); } return(success); }
private void AddDeclarationAssignment(FragmentMatchData matchData) { FragmentMatchData target = (FragmentMatchData)matchData.Parts[0]; FragmentMatchData evaluable = (FragmentMatchData)matchData.Parts[1]; AddNewStackVariable(target); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.PHR, sourcePosition: target.StartIndex)); AddItem(evaluable); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RR, sourcePosition: target.StartIndex)); }
private void AddDirectedValuableChain(FragmentMatchData matchData) { FragmentMatchData valuablePrefix = (FragmentMatchData)matchData.Parts[0]; FragmentMatchData valuableChain = (FragmentMatchData)matchData.Parts[1]; FragmentMatchData valuableSuffix = (FragmentMatchData)matchData.Parts[2]; AddValuableChains(valuableChain); AddValuableSuffix(valuableSuffix); AddValuablePrefix(valuablePrefix); }
private void AddAction(FragmentMatchData matchData, FragmentMatchData functionParameters, FragmentMatchData body) { // Start the declaration of the function _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.A, new object[] { false }, sourcePosition: functionParameters.StartIndex)); AddFunctionParameters(functionParameters); // Add instructions for the body of the function AddItem(body); // End the function declaration _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.AE, sourcePosition: matchData.StartIndex + matchData.Length)); }
private void AddNumber(FragmentMatchData matchData) { string numberStr = matchData.Parts.Last().ToString(); if (matchData.Parts.Count > 1) { numberStr = $"-{numberStr}"; } object numberObj = int.TryParse(numberStr, out int numberInt) ? numberInt : (object)double.Parse(numberStr); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.VR, new object[] { numberObj }, sourcePosition: matchData.StartIndex)); }
private void AddNewArray(FragmentMatchData matchData) { FragmentMatchData arrayInitializer = (FragmentMatchData)matchData.Parts[0]; if (arrayInitializer.Parts.ElementAtOrDefault(0) is FragmentMatchData evaluable) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.PHR, sourcePosition: matchData.StartIndex)); AddItem(evaluable); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.CVR, new object[] { true, null }, sourcePosition: matchData.StartIndex)); } else { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.CVR, new object[] { false, null }, sourcePosition: matchData.StartIndex)); } }
private void AddRules(FragmentMatchData matchData) { foreach (FragmentMatchData fragmentData in matchData.Parts.Cast <FragmentMatchData>()) { string name = ((FragmentMatchData)fragmentData.Parts[0]).Parts[0].ToString(); FragmentMatcher fragment = new FragmentMatcher(_fragmentMatcherMap.Count + 1, name); _fragmentMatcherMap[name] = (fragment, fragmentData); _languageMatcher.Fragments.Add(fragment); } foreach (KeyValuePair <string, (FragmentMatcher, FragmentMatchData)> fragmentPair in _fragmentMatcherMap.ToArray()) { AddRule(fragmentPair); } }
private void AddBlock(FragmentMatchData matchData) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.B, sourcePosition: matchData.StartIndex, interruptable: true)); int origActionStackLocation = _action.ActionStackLocation; _action.BlockDepth++; foreach (IMatchData partMatchData in matchData.Parts) { AddItem(partMatchData, true); } _action.Variables.Where(pair => pair.Value.Depth >= _action.BlockDepth).Select(pair => pair.Key).ToList().ForEach(key => _action.Variables.Remove(key)); _action.ActionStackLocation = origActionStackLocation; _action.BlockDepth--; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.BE, sourcePosition: matchData.StartIndex + matchData.Length, interruptable: true)); }
private void AddArgumentValues(FragmentMatchData matchData) { if (matchData.Parts.Count > 0) { bool first = true; foreach (FragmentMatchData partMatchData in matchData.Parts) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.PHR, sourcePosition: partMatchData.StartIndex)); AddItem(partMatchData, first); first = false; } _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RLR, new object[] { matchData.Parts.Count }, sourcePosition: matchData.StartIndex)); } _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RCE, sourcePosition: matchData.StartIndex)); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.LRR, new object[] { 1, false }, sourcePosition: matchData.StartIndex)); }
private int AddIfStatement(FragmentMatchData matchData) { FragmentMatchData condition = (FragmentMatchData)matchData.Parts[0]; FragmentMatchData body = (FragmentMatchData)matchData.Parts[1]; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.CS, sourcePosition: matchData.StartIndex, interruptable: true)); AddItem(condition); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.CPHR, sourcePosition: condition.StartIndex)); int cbcIndex = _instructions.Count; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.NC, sourcePosition: condition.StartIndex)); AddItem(body); int endBlockNeededIndex = _instructions.Count; _instructions[cbcIndex] = InstructionProvider <GroupState> .GetInstruction(InstructionCode.NC, new object[] { endBlockNeededIndex + 1 }, sourcePosition : matchData.Parts[1].StartIndex); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.CSE, new object[] { "endif" }, sourcePosition: matchData.StartIndex + matchData.Length)); return(endBlockNeededIndex); }
private void AddFunctionParameters(FragmentMatchData matchData) { string[] names = matchData.Parts.Select(part => GetIdentifierText((FragmentMatchData)part)).ToArray(); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.LRR, new object[] { names.Length, false }, sourcePosition: matchData.StartIndex)); List <object> payload = new List <object> { names.Length }; foreach (string name in names) { payload.Add(InstructionCode.CSP); payload.Add(name); AddParameterVariable(name); } if (matchData.Parts.Count > 0) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RCP, payload.ToArray(), sourcePosition: matchData.StartIndex)); } }
private bool MatchFragmentPartsOneModeNotCharacterClassBody(ref State state, FragmentMatchData matchData) { bool success = false; int matchCount = 0; success = MatchFragmentCharacterClassBody(ref state, matchData); if (success) { matchCount++; } success = false || matchCount > 0; if (!success) { state.FailureIndex = Math.Max(state.FailureIndex ?? 0, state.CurrentIndex); } return(success); }
private void AddAnonymousFunction(FragmentMatchData matchData) { FragmentMatchData functionParameters = (FragmentMatchData)matchData.Parts[0]; FragmentMatchData body = (FragmentMatchData)matchData.Parts[1]; ActionInfo outerAction = _action; ActionInfo innerAction = new ActionInfo { Parent = outerAction }; _action = innerAction; _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.J, payload: new object[] { "endaction" }, sourcePosition: matchData.StartIndex)); int actionStartIndex = _instructions.Count; AddAction(matchData, functionParameters, body); _action = outerAction; _instructions[actionStartIndex - 1] = InstructionProvider <GroupState> .GetInstruction(InstructionCode.J, payload : new object[] { _instructions.Count }, sourcePosition : matchData.StartIndex); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.AR, payload: new object[] { actionStartIndex }, sourcePosition: matchData.StartIndex)); if (innerAction.OrderedVariablesFromParent.Count > 0) { foreach (string name in innerAction.OrderedVariablesFromParent.Select(variable => variable.Name).Reverse()) { _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.PHR, sourcePosition: matchData.StartIndex)); AddGetStackVariable(name, matchData.StartIndex, false); } _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.RLR, new object[] { innerAction.OrderedVariablesFromParent.Count }, sourcePosition: matchData.StartIndex)); _instructions.Add(InstructionProvider <GroupState> .GetInstruction(InstructionCode.LRAS, new object[] { innerAction.OrderedVariablesFromParent.Count }, sourcePosition: matchData.StartIndex)); } if (_reprocessRequiredIndexes.Count > 0) { throw new LanguageConstraintException("Invalid operation", _reprocessRequiredIndexes.Values.FirstOrDefault()?.FirstOrDefault()); } }
public override MatcherResult Match(string code, string fragmentMatcher, bool matchFullText = true) { FragmentMatchData matchData = new FragmentMatchData { StartIndex = 0 }; Span <int> checkFlags = stackalloc int[7]; State state = new State() { Code = code, DistinctStringMatches = new List <StringMatchData>(2000), CheckFlags = checkFlags }; bool success = false; switch (fragmentMatcher) { case "NotCharacterClassBody": success = MatchFragmentNotCharacterClassBody(ref state, matchData); break; case "CharacterClassBody": success = MatchFragmentCharacterClassBody(ref state, matchData); break; case "CharacterRange": success = MatchFragmentCharacterRange(ref state, matchData); break; case "HexRange": success = MatchFragmentHexRange(ref state, matchData); break; } IMatchData resultMatchData = matchData.Parts.FirstOrDefault(); int? failureIndex = success ? null : state.FailureIndex; if (success && matchFullText && state.CurrentIndex != state.Code.Length) { success = false; failureIndex = state.CurrentIndex; } return(new MatcherResult(resultMatchData, success, state.CurrentIndex, failureIndex, state.MatchLogBuilder?.ToString())); }
protected void ConvertToExpressionTree(FragmentMatchData matchData, ExpressionMode expressionMode) { IMatchData rootPart = matchData.Parts.ElementAtOrDefault(0); switch (expressionMode) { case ExpressionMode.BinaryTree: rootPart = ConvertToBinaryTree(matchData, rootPart); break; case ExpressionMode.LikeNameTree: rootPart = ConvertToLikeNameTree(matchData, rootPart); break; } matchData.Parts.Clear(); if (rootPart != null) { matchData.Parts.Add(rootPart); } }
public override void Load(bool eager = false) { if (!_loaded) { List <IMatchData> parts = _matchData.Parts; int size = parts.Count; Dictionary <string, IJsonItem> items = new Dictionary <string, IJsonItem>(size); for (int i = 0; i < size; i++) { FragmentMatchData keyValue = (FragmentMatchData)parts[i]; JsonItem item = GetJsonItem(keyValue.Parts[1]); if (eager) { item.Load(eager); } items[GetStringText(GetStringMatchDataText((StringMatchData)keyValue.Parts[0]))] = item; } _items = items; _loaded = true; } }