private static List <Rule> ParseRulesConfigString(string rulesConfigString) { BracketedConfigProcessor bracketedConfigProcessor = new BracketedConfigProcessor(); return(bracketedConfigProcessor.ProcessConfig(rulesConfigString)); }
private static Expression ParseAtomicExpression(string expressionsSequence) { string prettyExpressionsSequence = expressionsSequence.Trim(); string COMPARISON_MARK_REGEX = $@"([<>]|!=|==)"; string FLOAT_REGEX = @"-?[0-9]*(?:\.[0-9]*)?"; string STRING_COMPARISON_REGEX = $"^\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*(?<cmp>{COMPARISON_MARK_REGEX})\\s*\".*\"$"; string FLOAT_COMPARISON_REGEX = $"^\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*(?<cmp>{COMPARISON_MARK_REGEX})\\s*(?<arg>{FLOAT_REGEX})\\s*$"; string INTERVAL_REGEX = $"^\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*in\\s*\\[(?<min>{FLOAT_REGEX})\\s*,(?<max>{FLOAT_REGEX})\\s*\\]$"; Expression expression = null; if (Regex.IsMatch(prettyExpressionsSequence, STRING_COMPARISON_REGEX)) { int firstQuotePosition = prettyExpressionsSequence.IndexOf("\""); int lastQuotePosition = prettyExpressionsSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyExpressionsSequence.Substring(start, len); if (BracketedConfigProcessor.AssertValidString(possibleString)) { Match m = Regex.Match(prettyExpressionsSequence, STRING_COMPARISON_REGEX); if (m.Length != 0) { string cmp = m.Groups["cmp"].Value; string comparisonType = null; switch (cmp) { case "<": comparisonType = "lt"; break; case ">": comparisonType = "gt"; break; case "!=": comparisonType = "ne"; break; case "==": comparisonType = "eq"; break; } if (comparisonType != null) { expression = new Comparison(m.Groups["var"].Value, possibleString, comparisonType); } } } } else if (Regex.IsMatch(prettyExpressionsSequence, FLOAT_COMPARISON_REGEX)) { Match m = Regex.Match(prettyExpressionsSequence, FLOAT_COMPARISON_REGEX); if (m.Length != 0) { string cmp = m.Groups["cmp"].Value; string comparison_type = null; switch (cmp) { case "<": comparison_type = "lt"; break; case ">": comparison_type = "gt"; break; case "!=": comparison_type = "ne"; break; case "==": comparison_type = "eq"; break; } if (comparison_type != null) { expression = new Comparison(m.Groups["var"].Value, m.Groups["arg"].Value, comparison_type); } } } else if (Regex.IsMatch(prettyExpressionsSequence, INTERVAL_REGEX)) { Match m = Regex.Match(prettyExpressionsSequence, INTERVAL_REGEX); if (m.Length != 0) { expression = new Interval(m.Groups["var"].Value, m.Groups["min"].Value, m.Groups["max"].Value); } } return(expression); }
public static Expression ParseExpressionsSequence(string expressionsSequence) { Expression expression = null; expression = ParseAtomicExpression(expressionsSequence); if (expression == null) { int firstOpeningBracePosition = expressionsSequence.IndexOf("("); int[] closingBracesPositions = BracketedConfigProcessor.AllIndexesOf(expressionsSequence, ")"); if (firstOpeningBracePosition == -1 || closingBracesPositions.Length != 0) { if (closingBracesPositions.Length > 0) { for (int tryingClosingBraceIndex = 0; tryingClosingBraceIndex != closingBracesPositions.Length; tryingClosingBraceIndex++) { int possibleExpression1Start = firstOpeningBracePosition + 1; int possibleExpression1End = closingBracesPositions[tryingClosingBraceIndex]; int possibleExpression1Length = possibleExpression1End - possibleExpression1Start; Expression expression1 = null; if (possibleExpression1Length >= 0) { string possibleExpression1Substring = expressionsSequence.Substring(possibleExpression1Start, possibleExpression1Length); expression1 = ParseExpressionsSequence(possibleExpression1Substring); } if (expression1 != null) { string restOfString = expressionsSequence.Substring(possibleExpression1End); if (!Regex.IsMatch(restOfString, @"^\s*\)\s*$")) { if (Regex.IsMatch(restOfString, @"^\s*\)\s*(and|AND).+$")) { string possibleExpression2Substring = restOfString.Substring(restOfString.IndexOf("and") + "and".Length); Expression expression2 = ParseExpressionsSequence(possibleExpression2Substring); if (expression1 != null && expression2 != null) { expression = new ExpressionAnd(new List <Expression> { expression1, expression2 }); } } else if (Regex.IsMatch(restOfString, @"^\s*\)\s*(or|OR).+$")) { string possibleExpression2Substring = restOfString.Substring(restOfString.IndexOf("or") + "or".Length); Expression expression2 = ParseExpressionsSequence(possibleExpression2Substring); if (expression1 != null && expression2 != null) { expression = new ExpressionOr(new List <Expression> { expression1, expression2 }); } } } else { expression = expression1; } if (expression != null) { break; } } } } } } return(expression); }
public static Action ParseActionSequence(string actionsSequence) { // ReSharper disable once RedundantAssignment Action action = null; action = ParseAtomicAction(actionsSequence); if (action == null) { int firstOpeningBracePosition = actionsSequence.IndexOf("("); int[] closingBracesPositions = BracketedConfigProcessor.AllIndexesOf(actionsSequence, ")"); if (firstOpeningBracePosition == -1 || closingBracesPositions.Length != 0) { if (closingBracesPositions.Length > 0) { for (int tryingClosingBraceIndex = 0; tryingClosingBraceIndex != closingBracesPositions.Length; tryingClosingBraceIndex++) { int possibleExpression1Start = firstOpeningBracePosition + 1; int possibleAction1End = closingBracesPositions[tryingClosingBraceIndex]; int possibleExpression1Length = possibleAction1End - possibleExpression1Start; Action action1 = null; if (possibleExpression1Length > 0) { string possibleAction1Substring = actionsSequence.Substring(possibleExpression1Start, possibleExpression1Length); action1 = ParseActionSequence(possibleAction1Substring); } if (action1 != null) { string restOfString = actionsSequence.Substring(possibleAction1End); if (!Regex.IsMatch(restOfString, @"^\s*\)\s*$")) { if (Regex.IsMatch(restOfString, @"^\s*\)\s*(and|AND).+$")) { string possibleAction2Substring = restOfString.Substring(restOfString.IndexOf("and") + "and".Length); Action action2 = ParseActionSequence(possibleAction2Substring); if (action2 != null) { action = new CombinedAction(new List <Action> { action1 }); if (action2 is OneOf) { ((CombinedAction)action).Actions.Add(action2); } else if (action2 is CombinedAction) { ((CombinedAction)action).Actions.AddRange(((CombinedAction)action2).Actions); } else { ((CombinedAction)action).Actions.Add(action2); } } } else if (Regex.IsMatch(restOfString, @"^\s*\)\s*(or|OR).+$")) { string possibleAction2Substring = restOfString.Substring(restOfString.IndexOf("or") + "or".Length); Action action2 = ParseActionSequence(possibleAction2Substring); if (action2 != null) { action = new OneOf(new List <Action> { action1 }); if (action2 is OneOf action2AsOneOf) { ((OneOf)action).Actions.AddRange(action2AsOneOf.Actions); } else { ((OneOf)action).Actions.Add(action2); } } } } else { action = action1; } if (action != null) { break; } } } } } } return(action); }
private static Action ParseAtomicAction(string actionSequence) { string ASSIGNEMENT_STRING_REGEX = $"^(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*=\\s*\".*\"$"; string ASSIGNEMENT_REGEX = $"^(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*=\\s*(?<value>\\S+)$"; string CLEAR_REGEX = $"^clear\\s+\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})$"; string SAY_REGEX = $"^say\\s+((?<probability>\\d*)\\s+)?\".*\"$"; string SAY_FAST_REGEX = $"^sayFast\\s+((?<probability>\\d*)\\s+)?\".*\"$"; string SHUT_UP_REGEX = $"^shutUp$"; string GPIO_REGEX = $"^GPIO\\s+((?<probability>\\d*)\\s+)?(?<signal>([10],)*[10])\\s+(?<time>\\d+)$"; string EXTERNAL_ACTION_NAME_REGEX_PATTERN = BracketedConfigProcessor.VARNAME_REGEX_PATTERN; string EXTERNAL_REGEX = $"^ext:(?<method>{EXTERNAL_ACTION_NAME_REGEX_PATTERN})\\s+\".*\"$"; string PLAY_DELAY_REGEX = $"^play\\s+((?<probability>\\d*)\\s+)?\".*\"(\\s+(?<time>\\d+))?$"; string STAY_ACTIVE_REGEX = $"^stayActive$"; string COMPARE_ANSWERS_REGEX = $"^compareAnswers\\s+(?<goodAnswer>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s+(?<realAnswer>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})$"; string QUIZ_REGEX = $"^\\s*quiz\\s+(\\\"(?<filename>.*)\\\"\\s*)((?<randomOrder>randomOrder)\\s*)?((?<length>\\d+\\:\\d+))?\\s*$"; Action action = null; string prettyActionSequence = actionSequence.Trim(); int probability; try { if (Regex.IsMatch(prettyActionSequence, ASSIGNEMENT_STRING_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); Match m = Regex.Match(prettyActionSequence, ASSIGNEMENT_STRING_REGEX); if (BracketedConfigProcessor.AssertValidString(possibleString)) { if (m.Length != 0) { action = new Assign(m.Groups["var"].Value, possibleString); } } } else if (Regex.IsMatch(prettyActionSequence, ASSIGNEMENT_REGEX)) { Match m = Regex.Match(prettyActionSequence, ASSIGNEMENT_REGEX); if (m.Length != 0) { action = new Assign(m.Groups["var"].Value, m.Groups["value"].Value); } } else if (Regex.IsMatch(prettyActionSequence, CLEAR_REGEX)) { Match m = Regex.Match(prettyActionSequence, CLEAR_REGEX); if (m.Length != 0) { action = new Clear(m.Groups["var"].Value); } } else if (Regex.IsMatch(prettyActionSequence, SAY_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); Match m = Regex.Match(prettyActionSequence, SAY_REGEX); if (m.Length != 0 && m.Groups["probability"].Value.Length != 0) { probability = Int32.Parse(m.Groups["probability"].Value); } else { probability = 100; } if (BracketedConfigProcessor.AssertValidString(possibleString)) { action = new Say(possibleString, probability); } } else if (Regex.IsMatch(prettyActionSequence, SAY_FAST_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); Match m = Regex.Match(prettyActionSequence, SAY_REGEX); if (m.Length != 0 && m.Groups["probability"].Value.Length != 0) { probability = Int32.Parse(m.Groups["probability"].Value); } else { probability = 100; } if (BracketedConfigProcessor.AssertValidString(possibleString)) { action = new SayFast(possibleString, probability); } } else if (Regex.IsMatch(prettyActionSequence, SHUT_UP_REGEX)) { action = new ShutUp(); } else if (Regex.IsMatch(prettyActionSequence, STAY_ACTIVE_REGEX)) { action = new StayActive(); } else if (Regex.IsMatch(prettyActionSequence, COMPARE_ANSWERS_REGEX)) { Match m = Regex.Match(prettyActionSequence, COMPARE_ANSWERS_REGEX); if (m.Length != 0) { action = new CompareAnswers(m.Groups["goodAnswer"].Value, m.Groups["realAnswer"].Value); } } else if (Regex.IsMatch(prettyActionSequence, PLAY_DELAY_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); Match m = Regex.Match(prettyActionSequence, PLAY_DELAY_REGEX); if (m.Length != 0 && m.Groups["probability"].Value.Length != 0) { probability = Int32.Parse(m.Groups["probability"].Value); } else { probability = 100; } Match m2 = Regex.Match(prettyActionSequence, PLAY_DELAY_REGEX); if (m2.Length != 0 && m2.Groups["time"].Value.Length != 0) { var time = Int32.Parse(m.Groups["time"].Value); if (BracketedConfigProcessor.AssertValidString(possibleString)) { action = new Play(possibleString, probability, time); } } else { if (BracketedConfigProcessor.AssertValidString(possibleString)) { action = new Play(possibleString, probability); } } } else if (Regex.IsMatch(prettyActionSequence, QUIZ_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); if (BracketedConfigProcessor.AssertValidString(possibleString)) { action = new Quiz(possibleString); Match m = Regex.Match(prettyActionSequence, QUIZ_REGEX); ((Quiz)action).randomOrdered = m.Length != 0 && m.Groups["randomOrder"].Value.Length != 0; // Match m = Regex.Match(prettyActionSequence, QUIZ_REGEX); if (m.Length != 0 && m.Groups["length"].Value.Length != 0) { var lengths = m.Groups["length"].Value.Split(':'); ((Quiz)action).lengthLowerBound = int.Parse(lengths[0]); ((Quiz)action).lengthUpperBound = int.Parse(lengths[1]); } } } else if (Regex.IsMatch(prettyActionSequence, GPIO_REGEX)) { Match m = Regex.Match(prettyActionSequence, GPIO_REGEX); if (m.Length != 0 && m.Groups["probability"].Value.Length != 0) { probability = Int32.Parse(m.Groups["probability"].Value); } else { probability = 100; } if (m.Length != 0) { action = new GPIO(m.Groups["signal"].Value.Split(',', ' ') .Select(Int32.Parse).ToList(), Int32.Parse(m.Groups["time"].Value), probability); } } else if (Regex.IsMatch(prettyActionSequence, EXTERNAL_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); if (BracketedConfigProcessor.AssertValidString(possibleString)) { Match m = Regex.Match(prettyActionSequence, EXTERNAL_REGEX); if (m.Length != 0) { action = new Extension(m.Groups["method"].Value, possibleString); } } } } catch { action = null; } return(action); }
public static Rule ParseRule(string ruleContainingString) { Rule rule; string oldRuleContainingString = ruleContainingString; string FULL_METAINFO_REGEX = $"priority\\s*=\\s*(?<priority1>\\d+)\\s*rule_set\\s*=\\s*\\\"(?<rule_set1>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\\"" + "|" + $"rule_set\\s*=\\s*\\\"(?<rule_set2>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\\"\\s*priority\\s*=\\s*(?<priority2>\\d+)"; string NONFULL_METAINFO_REGEX = "priority\\s*=\\s*(?<priority>\\d+)" + "|" + $"rule_set\\s*=\\s*\\\"(?<rule_set>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\\""; string RULE_WITH_FULL_METAINFO_REGEX = $"^\\(\\s*\\(\\s*({FULL_METAINFO_REGEX})\\s*\\)\\s*\\((?<rule>.*)\\)\\s*\\)$"; string RULE_WITH_NONFULL_METAINFO_REGEX = $"^\\(\\s*\\(\\s*({NONFULL_METAINFO_REGEX})\\s*\\)\\s*\\((?<rule>.*)\\)\\s*\\)$"; string priority = null; string rule_set = null; Match metaInfo = Regex.Match(ruleContainingString, RULE_WITH_FULL_METAINFO_REGEX); if (metaInfo.Length > 0) { if (metaInfo.Groups["priority1"].Value != null) { priority = metaInfo.Groups["priority1"].Value; rule_set = metaInfo.Groups["rule_set1"].Value; } else { priority = metaInfo.Groups["priority2"].Value; rule_set = metaInfo.Groups["rule_set2"].Value; } ruleContainingString = metaInfo.Groups["rule"].Value; } else { metaInfo = Regex.Match(ruleContainingString, RULE_WITH_NONFULL_METAINFO_REGEX); if (metaInfo.Length > 0) { priority = metaInfo.Groups["priority"].Value; rule_set = metaInfo.Groups["rule_set"].Value; ruleContainingString = metaInfo.Groups["rule"].Value; } } if (rule_set == "") { rule_set = null; } if (priority == "") { priority = null; } int[] arrowsPositions = BracketedConfigProcessor.AllIndexesOf(ruleContainingString, "=>"); int tryingArrowPositionIndex = 0; // TODO check arrow-containing expr or act while (true) { int tryingArrowPosition = arrowsPositions[tryingArrowPositionIndex]; try { int firstSymbolAfterArrowPosition = tryingArrowPosition + 2; int possibleActionStringLength = ruleContainingString.Length - firstSymbolAfterArrowPosition; Expression expr = Expression.ParseExpressionsSequence( ruleContainingString.Substring(0, tryingArrowPosition)); Action act = Action.ParseActionSequence( ruleContainingString.Substring(firstSymbolAfterArrowPosition, possibleActionStringLength)); rule = new Rule(expr, act); if (rule_set != null) { rule.RuleSet = rule_set; } if (priority != null) { rule.Priority = Int32.Parse(priority); } // Console.WriteLine($"PARSED: {oldRuleContainingString}"); return(rule); } catch { tryingArrowPositionIndex++; continue; } } throw new RuleParseException(); }
private static Expression ParseAtomicExpression(string expressionsSequence) { string prettyExpressionsSequence = expressionsSequence.Trim(); string COMPARISON_MARK_REGEX = $@"([<>]|!=|==)"; string FLOAT_REGEX = @"-?[0-9]*(?:\.[0-9]*)?"; string STRING_COMPARISON_REGEX = $"^\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*(?<cmp>{COMPARISON_MARK_REGEX})\\s*\".*\"$"; string FLOAT_COMPARISON_REGEX = $"^\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*(?<cmp>{COMPARISON_MARK_REGEX})\\s*(?<arg>{FLOAT_REGEX})\\s*$"; string INTERVAL_REGEX = $"^\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*in\\s*\\[(?<min>{FLOAT_REGEX})\\s*,(?<max>{FLOAT_REGEX})\\s*\\]$"; Expression expression = null; try { if (Regex.IsMatch(prettyExpressionsSequence, STRING_COMPARISON_REGEX)) { int firstQuotePosition = prettyExpressionsSequence.IndexOf("\""); int lastQuotePosition = prettyExpressionsSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyExpressionsSequence.Substring(start, len); BracketedConfigProcessor.AssertValidString(possibleString); Match m = Regex.Match(prettyExpressionsSequence, STRING_COMPARISON_REGEX); if (m.Length == 0) { throw new ExpressionParseException(); } string cmp = m.Groups["cmp"].Value; string comparison_type; if (cmp == "<") { comparison_type = "lt"; } else if (cmp == ">") { comparison_type = "gt"; } else if (cmp == "!=") { comparison_type = "ne"; } else if (cmp == "==") { comparison_type = "eq"; } else { throw new ExpressionParseException(); } expression = new Comparison(m.Groups["var"].Value, possibleString, comparison_type); //Console.WriteLine($"parsed {expressionsSequence} as comparison {m.Groups["var"].Value} {comparison_type} {possibleString}"); } else if (Regex.IsMatch(prettyExpressionsSequence, FLOAT_COMPARISON_REGEX)) { Match m = Regex.Match(prettyExpressionsSequence, FLOAT_COMPARISON_REGEX); if (m.Length == 0) { throw new ExpressionParseException(); } string cmp = m.Groups["cmp"].Value; string comparison_type; switch (cmp) { case "<": comparison_type = "lt"; break; case ">": comparison_type = "gt"; break; case "!=": comparison_type = "ne"; break; case "==": comparison_type = "eq"; break; default: throw new ExpressionParseException(); } expression = new Comparison(m.Groups["var"].Value, m.Groups["arg"].Value, comparison_type); //Console.WriteLine($"parsed {expressionsSequence} as comparison comparison {m.Groups["var"].Value} {comparison_type} {m.Groups["arg"].Value}"); } else if (Regex.IsMatch(prettyExpressionsSequence, INTERVAL_REGEX)) { Match m = Regex.Match(prettyExpressionsSequence, INTERVAL_REGEX); if (m.Length == 0) { throw new ActionParseException(); //TODO fix } expression = new Interval(m.Groups["var"].Value, m.Groups["min"].Value, m.Groups["max"].Value); //Console.WriteLine($"parsed {expressionsSequence} as interval check if {m.Groups["var"].Value} in [{m.Groups["min"].Value},{m.Groups["max"].Value}]"); } else { throw new ExpressionParseException(); } return(expression); } catch { throw new ExpressionParseException(); } }
public static Action ParseActionSequence(string actionsSequence) { Action action = null; try { action = ParseAtomicAction(actionsSequence); return(action); } catch { int firstOpeningBracePosition = actionsSequence.IndexOf("("); int[] closingBracesPositions = BracketedConfigProcessor.AllIndexesOf(actionsSequence, ")"); if (firstOpeningBracePosition != -1 && closingBracesPositions.Length == 0) { throw new ActionParseException(); } if (closingBracesPositions.Length > 0) { for (int tryingClosingBraceIndex = 0; tryingClosingBraceIndex != closingBracesPositions.Length; tryingClosingBraceIndex++) { try { int possibleExpression1Start = firstOpeningBracePosition + 1; int possibleAction1End = closingBracesPositions[tryingClosingBraceIndex]; int possibleExpression1Length = possibleAction1End - possibleExpression1Start; string possibleAction1Substring = actionsSequence.Substring(possibleExpression1Start, possibleExpression1Length); Action action1 = ParseActionSequence(possibleAction1Substring); string restOfString = actionsSequence.Substring(possibleAction1End); if (!Regex.IsMatch(restOfString, @"^\s*\)\s*$")) { if (Regex.IsMatch(restOfString, @"^\s*\)\s*(and|AND).+$")) { string possibleAction2Substring = restOfString.Substring( restOfString.IndexOf("and") + "and".Length); Action action2 = ParseActionSequence(possibleAction2Substring); if (action1 == null || action2 == null) { throw new ActionParseException(); } action = new CombinedAction( new List <Action> { action1, action2 }); } else if (Regex.IsMatch(restOfString, @"^\s*\)\s*(or|OR).+$")) { string possibleAction2Substring = restOfString.Substring( restOfString.IndexOf("or") + "or".Length); Action action2 = ParseActionSequence(possibleAction2Substring); if (action1 == null || action2 == null) { throw new ActionParseException(); } action = new OneOf(new List <Action> { action1, action2 }); } else { throw new ActionParseException(); } break; } else { action = action1; } break; } catch { } } if (action == null) { throw new ActionParseException(); } } return(action); } }
private static Action ParseAtomicAction(string actionSequence) { string ASSIGNEMENT_STRING_REGEX = $"^(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*=\\s*\\\"(?<value>\\S+)\\\"$"; string ASSIGNEMENT_REGEX = $"^(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\s*=\\s*(?<value>\\S+)$"; string CLEAR_REGEX = $"^clear\\s+\\$(?<var>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})$"; string SAY_REGEX = $"^say\\s+\".*\"$"; string GPIO_REGEX = $"^GPIO\\s+(?<signal>([10],)*[10])\\s+(?<time>\\d+)$"; string EXTERNAL_ACTION_NAME_REGEX_PATTERN = BracketedConfigProcessor.VARNAME_REGEX_PATTERN; string EXTERNAL_REGEX = $"^ext:(?<method>{EXTERNAL_ACTION_NAME_REGEX_PATTERN})\\s+\".*\"$"; Action action = null; string prettyActionSequence = actionSequence.Trim(); try { if (Regex.IsMatch(prettyActionSequence, ASSIGNEMENT_STRING_REGEX)) { Match m = Regex.Match(prettyActionSequence, ASSIGNEMENT_STRING_REGEX); if (m.Length == 0) { throw new ActionParseException(); } action = new Assign(m.Groups["var"].Value, m.Groups["value"].Value); //Console.WriteLine($"parsed {actionSequence} as assignement {m.Groups["var"].Value}:={m.Groups["value"].Value}"); } else if (Regex.IsMatch(prettyActionSequence, ASSIGNEMENT_REGEX)) { Match m = Regex.Match(prettyActionSequence, ASSIGNEMENT_REGEX); if (m.Length == 0) { throw new ActionParseException(); } action = new Assign(m.Groups["var"].Value, m.Groups["value"].Value); //Console.WriteLine($"parsed {actionSequence} as assignement {m.Groups["var"].Value}:={m.Groups["value"].Value}"); } else if (Regex.IsMatch(prettyActionSequence, CLEAR_REGEX)) { Match m = Regex.Match(prettyActionSequence, CLEAR_REGEX); if (m.Length == 0) { throw new ActionParseException(); } action = new Clear(m.Groups["var"].Value); //Console.WriteLine($"parsed {actionSequence} as clear {m.Groups["var"].Value}"); } else if (Regex.IsMatch(prettyActionSequence, SAY_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); BracketedConfigProcessor.AssertValidString(possibleString); action = new Say(possibleString); //Console.WriteLine($"parsed {actionSequence} as say {possibleString}"); } else if (Regex.IsMatch(prettyActionSequence, GPIO_REGEX)) { Match m = Regex.Match(prettyActionSequence, GPIO_REGEX); if (m.Length == 0) { throw new ActionParseException(); } action = new GPIO(m.Groups["signal"].Value.Split(',', ' ').Select(Int32.Parse).ToList(), Int32.Parse(m.Groups["time"].Value)); } else if (Regex.IsMatch(prettyActionSequence, EXTERNAL_REGEX)) { int firstQuotePosition = prettyActionSequence.IndexOf("\""); int lastQuotePosition = prettyActionSequence.LastIndexOf("\""); int start = firstQuotePosition + 1; int len = lastQuotePosition - start; string possibleString = prettyActionSequence.Substring(start, len); BracketedConfigProcessor.AssertValidString(possibleString); Match m = Regex.Match(prettyActionSequence, EXTERNAL_REGEX); if (m.Length == 0) { throw new ActionParseException(); } action = new Extension(m.Groups["method"].Value, possibleString); //Console.WriteLine($"parsed {actionSequence} as external {m.Groups["method"].Value} {possibleString}"); } else { throw new ActionParseException(); } if (action == null) { throw new ActionParseException(); } return(action); } catch { throw new ActionParseException(); } }
public static Rule ParseRule(string ruleContainingString) { Rule rule = null; //string oldRuleContainingString = ruleContainingString; string FULL_METAINFO_REGEX = $"priority\\s*=\\s*(?<priority1>\\d+)\\s*rule_set\\s*=\\s*\\\"(?<rule_set1>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\\"" + "|" + $"rule_set\\s*=\\s*\\\"(?<rule_set2>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\\"\\s*priority\\s*=\\s*(?<priority2>\\d+)"; string NONFULL_METAINFO_REGEX = "priority\\s*=\\s*(?<priority>\\d+)" + "|" + $"rule_set\\s*=\\s*\\\"(?<rule_set>{BracketedConfigProcessor.VARNAME_REGEX_PATTERN})\\\""; string RULE_WITH_FULL_METAINFO_REGEX = $"^\\(\\s*\\(\\s*({FULL_METAINFO_REGEX})\\s*\\)\\s*\\((?<rule>.*)\\)\\s*\\)$"; string RULE_WITH_NONFULL_METAINFO_REGEX = $"^\\(\\s*\\(\\s*({NONFULL_METAINFO_REGEX})\\s*\\)\\s*\\((?<rule>.*)\\)\\s*\\)$"; //string priority = null; //string rule_set = null; Match metaInfo = Regex.Match(ruleContainingString, RULE_WITH_FULL_METAINFO_REGEX); if (metaInfo.Length > 0) { //if (metaInfo.Groups["priority1"].Value != null) { // priority = metaInfo.Groups["priority1"].Value; // rule_set = metaInfo.Groups["rule_set1"].Value; //} //else { // priority = metaInfo.Groups["priority2"].Value; // rule_set = metaInfo.Groups["rule_set2"].Value; //} ruleContainingString = metaInfo.Groups["rule"].Value; } else { metaInfo = Regex.Match(ruleContainingString, RULE_WITH_NONFULL_METAINFO_REGEX); if (metaInfo.Length > 0) { //priority = metaInfo.Groups["priority"].Value; //rule_set = metaInfo.Groups["rule_set"].Value; ruleContainingString = metaInfo.Groups["rule"].Value; } } //if (rule_set == "") rule_set = null; //if (priority == "") priority = null; int[] arrowsPositions = BracketedConfigProcessor.AllIndexesOf(ruleContainingString, "=>"); // TODO check arrow-containing expr or act for (int tryingArrowPositionIndex = 0; tryingArrowPositionIndex < arrowsPositions.Length; tryingArrowPositionIndex++) { int tryingArrowPosition = arrowsPositions[tryingArrowPositionIndex]; int firstSymbolAfterArrowPosition = tryingArrowPosition + 2; int possibleActionStringLength = ruleContainingString.Length - firstSymbolAfterArrowPosition; var expr = Expression.ParseExpressionsSequence(ruleContainingString.Substring(0, tryingArrowPosition)); var act = Action.ParseActionSequence(ruleContainingString.Substring(firstSymbolAfterArrowPosition, possibleActionStringLength)); if (expr != null && act != null) { rule = new Rule(expr, act); //if (rule_set != null) { // rule.RuleSet = rule_set; //} //if (priority != null) { // rule.Priority = int.Parse(priority); //} break; } } return(rule); }