/// <summary> /// Returns a TDIL directive that represents the given action <paramref name="instruction"/> string based on the given /// associated <paramref name="translationInstruction"/>. /// </summary> /// <param name="instruction">Instruction string to convert</param> /// <param name="translationInstruction">Translation instruction to convert the instruction</param> /// <returns>TDIL directive</returns> /// <exception cref="ArgumentNullException">If any argument is NULL</exception> public string ToDirective(string instruction, IBuddyTranslationInstruction translationInstruction) { if (string.IsNullOrEmpty(instruction)) { throw new ArgumentNullException(nameof(instruction)); } if (translationInstruction == null) { throw new ArgumentNullException(nameof(translationInstruction)); } using (ParameterAdjustmentTable pat = ParameterAdjustmentTable.Create()) { string processedInstruction = pat.Process(instruction); Dictionary <string, IPatternParameter> paramCache = new Dictionary <string, IPatternParameter>(); IInstructionEvaluationResult evaRslt = _instructionEvaluator.Evaluate(processedInstruction, _instructionTable[translationInstruction], paramCache); if (evaRslt.IsError) { // TODO } string result = _instructionFormatter.ToString(translationInstruction, paramCache); return(result); } }
/// <summary> Adds the given <paramref name="instruction"/> to the translator. </summary> /// <param name="instruction">Instruction to add</param> /// <exception cref="ArgumentNullException">If <paramref name="instruction"/> is null</exception> /// <exception cref="InvalidInstructionTranslationPatternException">If the <paramref name="instruction"/> declares an invalid instruction pattern</exception> public void AddTranslationInstruction(IBuddyTranslationInstruction instruction) { Assert.NotNull(() => instruction); InstructionTranslationInfo instructionInfo = new InstructionTranslationInfo(instruction); _instructionTable.Add(instruction, instructionInfo); }
public void ToString_Throws( IBuddyTranslationInstruction translationInstruction, IDictionary <string, IPatternParameter> parameters, Type expectedType ) { Assert.Throws(expectedType, () => ToString(translationInstruction, parameters)); }
/// <summary> /// Creates an evaluation result that indicates an error. /// </summary> /// <param name="instruction">Evaluated instruction</param> /// <param name="translationInstruction">Translation instruction</param> /// <param name="message">Evaluation result message</param> /// <returns></returns> public static EvaluationResult Error(string instruction, IBuddyTranslationInstruction translationInstruction, string message) { return(new EvaluationResult { IsError = true, Instruction = instruction, TranslationInstruction = translationInstruction, Message = message }); }
/// <summary> /// Returns a TDIL directive that represents the given action <paramref name="instruction"/> string. If the declared action is not known, /// an <see cref="UnknownTranslationInstructionException"/> is thrown. /// </summary> /// <param name="instruction">Action line string to convert</param> /// <returns>TDIL directive</returns> /// <exception cref="UnknownTranslationInstructionException">If the declared action is not known.</exception> public string ToDirective(string instruction) { IBuddyTranslationInstruction translationInstruction = GetTranslationInstruction(instruction); if (translationInstruction == null) { throw new UnknownTranslationInstructionException($"Cannot map the given line '{instruction}' to an action step"); } return(ToDirective(instruction, translationInstruction)); }
/// <summary> /// Returns an instance of <see cref="IBuddyTranslationInstruction"/> that is derived by the action of the given action <paramref name="instruction"/>. /// If the line is null or empty, an <see cref="ArgumentNullException"/> is thrown. Additionally, there is an /// <see cref="BuddyLanguageFormatException"/> if the line doesn't start with an action word. /// If no associated action step is found, NULL is returned. /// </summary> /// <param name="instruction">Action line to process</param> /// <returns>Instance of <see cref="IBuddyTranslationInstruction"/> or NULL</returns> public IBuddyTranslationInstruction GetTranslationInstruction(string instruction) { if (string.IsNullOrEmpty(instruction)) { throw new ArgumentNullException(nameof(instruction), "Must not be NULL or empty!"); } string[] instructionWords = instruction.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string leadingWord = instructionWords.FirstOrDefault(); if (leadingWord == null) { throw new BuddyLanguageFormatException("Given instruction must start with a commanding word!"); } IBuddyTranslationInstruction actionStep = _instructionTable.FirstOrDefault(entry => entry.Key.InstructionId == leadingWord).Key; return(actionStep); }
/// <summary> /// Processes and evaluates the given <paramref name="instruction"/> to create the instruction meta data. /// </summary> /// <param name="instruction">Instruction to process</param> /// <exception cref="InvalidInstructionTranslationPatternException">If the instruction pattern is invalid</exception> private void CreateMetaInfo(IBuddyTranslationInstruction instruction) { string directivePattern = instruction.InstructionPattern; if (string.IsNullOrEmpty(directivePattern)) { throw new InvalidInstructionTranslationPatternException(string.Format("Directive pattern of instruction '{0}' is NULL or empty", instruction.GetType())); } string[] directiveTokens = directivePattern.SplitToBuddyTokens(); if (directiveTokens.Length == 0) { throw new InvalidInstructionTranslationPatternException(string.Format("Directive pattern of instruction '{0}' has no tokens. Pattern is '{1}'", instruction.GetType(), directivePattern)); } string leadingWord = directiveTokens[0]; if (string.IsNullOrEmpty(leadingWord)) { throw new InvalidInstructionTranslationPatternException(string.Format("Directive pattern of instruction '{0}' has an empty leading word. Pattern is '{1}'", instruction.GetType(), directivePattern)); } InstructionTranslationInfo instructionInfo = this; // Add leading word token instructionInfo.AddToken(new WordToken { Value = leadingWord }); // Process remaining tokens for (int i = 0; ++i != directiveTokens.Length;) { string token = directiveTokens[i]; ProcessToken(token, instructionInfo); } }
/// <summary> /// Creates a new instance for the given <paramref name="instruction"/>. /// </summary> /// <param name="instruction">Instruction to provide meta data</param> /// <exception cref="InvalidInstructionTranslationPatternException">If the instruction pattern is invalid</exception> public InstructionTranslationInfo(IBuddyTranslationInstruction instruction) { iInstruction = instruction; CreateMetaInfo(instruction); }
public string ToString(IBuddyTranslationInstruction translationInstruction, IDictionary <string, IPatternParameter> parameters) { InstructionFormatter instructionFormatter = new InstructionFormatter(); return(instructionFormatter.ToString(translationInstruction, parameters)); }
/// <summary> /// Creates a string representing a directive based on the given <paramref name="actionStep"/> and the /// given <paramref name="parameters"/>. /// </summary> /// <param name="actionStep">Action step to format</param> /// <param name="parameters">Parameters to use</param> /// <returns>String representing a directive based on the given action step</returns> /// <exception cref="ArgumentNullException">If any parameter is NULL</exception> /// <exception cref="InstructionFormattingException">If not all declared parameters could be replaced</exception> public virtual string ToString(IBuddyTranslationInstruction actionStep, IDictionary <string, IPatternParameter> parameters) { if (actionStep == null) { throw new ArgumentNullException(nameof(actionStep)); } if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } string tdilPattern = actionStep.TdilPattern; string result = tdilPattern; if (actionStep is IReferableInstruction referableInstruction) { string resultReference = referableInstruction.ResultReferencePattern; resultReference = resultReference.Replace("#", "1"); result = $"{resultReference} = {result}"; } // Process all parameter references MatchCollection matches = _tdilPatternParameterRegex.Matches(result); for (IEnumerator matchItr = matches.GetEnumerator(); matchItr.MoveNext();) { Match match = (Match)matchItr.Current; if (match == null) { continue; } Group paramRefGrp = match.Groups["paramRef"]; Group closureGrp = match.Groups["closure"]; Group nameGrp = match.Groups["name"]; EClosureType closureType = EClosureType.None; string parameterExpression = paramRefGrp.Value; string[] pureParamNames; // Do we have a closure with alternatives? if (closureGrp.Success) { string coreFunction = parameterExpression.Substring(2, parameterExpression.Length - 3); if (coreFunction.IndexOf('|') != -1) { closureType = EClosureType.Alternative; pureParamNames = coreFunction.Split('|'); } else { closureType = EClosureType.Conjunction; pureParamNames = coreFunction.Split('&'); } } else // Plain old reference { pureParamNames = new[] { nameGrp.Value }; } // Look up referenced pattern parameter string parameterValueFunction = null; IPatternParameter patternParameter = null; for (int i = -1; ++i != pureParamNames.Length;) { string pureParamName = pureParamNames[i]; string reducedParamName = pureParamName.Split('.')[0]; if (parameters.TryGetValue(reducedParamName, out var locPatternParameter)) { string assignedValueFunction = $"${pureParamName}"; // When this is a conjunction, we have to combine all pattern parameter if (closureType == EClosureType.Conjunction) { parameterValueFunction = string.Concat(parameterValueFunction ?? string.Empty, ",", assignedValueFunction); patternParameter = Combine(patternParameter, locPatternParameter); continue; } // In all other cases, just resolve the first matching pattern parameter patternParameter = locPatternParameter; parameterValueFunction = assignedValueFunction; break; } } // Do we have one? if (patternParameter == null) { throw new InstructionFormattingException($"The TDIL pattern '{tdilPattern}' contains a mandatory parameter '{parameterExpression}' that could not be resolved!"); } // Calculate value string valueStr = patternParameter.EvaluateExpression(parameterValueFunction); if (valueStr == null) { throw new InstructionFormattingException($"Expression '{parameterExpression}' could not be evaluated by pattern parameter of '{patternParameter}'"); } // Insert and replace result = result.Replace(parameterExpression, valueStr); } // Ensure all parameters have been replaced if (result.Contains('~')) { throw new InstructionFormattingException($"At least one parameter could not be set. Pattern is '{tdilPattern}'. Result is '{result}'."); } return(result); }