namespace HeuristicLab.Algorithms.PushGP.Parser { using System.Collections.Generic; using System.Globalization; using HeuristicLab.Algorithms.PushGP.Expressions; public static class PushGPParser { private const string openBrace = "("; private const string closeBrace = ")"; private const char delimiter = ' '; private static readonly CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture("en-US"); private static readonly char[] symbolTrim = { '\r', '\n' }; public static Expression Parse(string source, int startIndex = 0) { var symbols = source.Split(delimiter); int endIndex; return Parse(symbols, 0, out endIndex); } private static Expression Parse(string[] symbols, int startIndex, out int endIndex) { var expressions = new List(); for (var i = startIndex; i < symbols.Length; i++) { var symbol = symbols[i].TrimEnd(symbolTrim); if (string.IsNullOrWhiteSpace(symbol)) continue; switch (symbol) { case openBrace: var subExpression = Parse(symbols, i + 1, out endIndex); expressions.Insert(0, subExpression); i = endIndex; continue; case closeBrace: endIndex = i; return new ExecExpandExpression(expressions.ToArray()); } // literal Expression expression; if (TryParseLiteral(symbol, out expression)) { expressions.Insert(0, expression); continue; } // expression if (ExpressionTable.TryGetStatelessExpression(symbol, out expression) || ExpressionTable.TryGetStatefullExpression(symbol, out expression)) { expressions.Insert(0, expression); continue; } // identifier - custom expression or named literals expressions.Insert(0, new NameDefineXExecExpression(symbol)); } endIndex = symbols.Length - 1; return expressions.Count == 1 ? expressions[0] : new ExecExpandExpression(expressions.ToArray()); } private static bool TryParseLiteral(string word, out Expression expression) { long longValue; if (long.TryParse(word, out longValue)) { expression = new IntegerPushExpression(longValue); return true; } double floatValue; if (double.TryParse(word, NumberStyles.Float, cultureInfo, out floatValue)) { expression = new FloatPushExpression(floatValue); return true; } bool booleanValue; if (bool.TryParse(word, out booleanValue)) { expression = new BooleanPushExpression(booleanValue); return true; } expression = null; return false; } } }