Changeset 15017 for branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser
- Timestamp:
- 06/01/17 09:28:34 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs
r14952 r15017 1 1 namespace HeuristicLab.Problems.ProgramSynthesis.Push.Parser { 2 using System; 2 3 using System.Collections.Generic; 3 4 using System.Globalization; 4 5 using System.Linq; 6 using System.Text.RegularExpressions; 7 8 using HeuristicLab.Problems.ProgramSynthesis.Push.Constants; 5 9 using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions; 6 10 7 11 public static class PushParser { 8 private const string openBrace = "(";9 10 private const string closeBrace = ")";11 12 12 private const char delimiter = ' '; 13 13 … … 17 17 18 18 public static Expression Parse(string source, int startIndex = 0) { 19 var symbols = source.Split(delimiter); 19 bool error; 20 var symbols = GetSymbols(source, out error); // source.Split(delimiter); 20 21 21 22 int endIndex; 22 return Parse(symbols, 0, out endIndex);23 return Parse(symbols, startIndex, out endIndex); 23 24 } 24 25 … … 29 30 } 30 31 31 private static Expression Parse(string[] symbols, int startIndex, out int endIndex) { 32 private static IReadOnlyList<string> GetSymbols(string source, out bool error) { 33 var chars = source.ToCharArray(); 34 var symbols = new List<string>(); 35 36 for (var i = 0; i < chars.Length; i++) { 37 var cur = chars[i]; 38 int endIndex; 39 int length; 40 string str; 41 42 switch (cur) { 43 case delimiter: break; 44 case PushEnvironment.StringSymbol: 45 endIndex = source.IndexOf(PushEnvironment.StringSymbol, i + 1); 46 if (endIndex < i) { 47 error = true; 48 return symbols; 49 } 50 51 length = endIndex - i + 1; 52 str = source.Substring(i, length); 53 symbols.Add(str); 54 i += length; // skip following space 55 56 break; 57 58 case PushEnvironment.CharSymbol: 59 endIndex = source.IndexOf(PushEnvironment.CharSymbol, i + 1); 60 if (endIndex < i) { 61 error = true; 62 return symbols; 63 } 64 65 length = endIndex - i + 1; 66 str = source.Substring(i, length); 67 str = EscapeLikeALiteral(str); 68 symbols.Add(str); 69 i += length; // skip following space 70 71 break; 72 73 case PushEnvironment.VectorStartSymbol: 74 endIndex = source.IndexOf(PushEnvironment.VectorEndSymbol, i + 1); 75 if (endIndex < i) { 76 error = true; 77 return symbols; 78 } 79 80 length = endIndex - i + 1; 81 str = source.Substring(i, length); 82 symbols.Add(str); 83 i += length; // skip following space 84 break; 85 86 default: 87 endIndex = source.IndexOf(' ', i + 1); 88 89 length = endIndex < i 90 ? chars.Length - i 91 : endIndex - i; 92 93 str = source.Substring(i, length); 94 symbols.Add(str); 95 i += length; // skip following space 96 97 break; 98 } 99 } 100 101 error = true; 102 return symbols; 103 } 104 105 private static Expression Parse(IReadOnlyList<string> symbols, int startIndex, out int endIndex) { 32 106 var expressions = new List<Expression>(); 33 107 34 for (var i = startIndex; i < symbols. Length; i++) {108 for (var i = startIndex; i < symbols.Count; i++) { 35 109 var symbol = symbols[i].TrimEnd(symbolTrim); 36 110 … … 38 112 39 113 switch (symbol) { 40 case openBrace:114 case PushEnvironment.ProgramStartSymbolStr: 41 115 var subExpression = Parse(symbols, i + 1, out endIndex); 42 116 expressions.Insert(0, subExpression); 43 117 i = endIndex; 44 118 continue; 45 case closeBrace:119 case PushEnvironment.ProgramEndSymbolStr: 46 120 endIndex = i; 47 121 return new PushProgram(expressions); … … 66 140 } 67 141 68 endIndex = symbols. Length- 1;142 endIndex = symbols.Count - 1; 69 143 70 144 switch (expressions.Count) { … … 79 153 80 154 private static bool TryParseLiteral(string word, out Expression expression) { 81 if (word.StartsWith("'") && word.EndsWith("'") && word.Length == 3) { 82 expression = new CharPushExpression(word[1]); 83 return true; 84 } 85 86 if (word.StartsWith("\"") && word.EndsWith("\"")) { 87 expression = new StringPushExpression(word); 88 return true; 89 } 90 91 // "[]" has no values and can therefer not parsed correctly as vector of a specific type 92 if (word.StartsWith("[") && word.EndsWith("]") && word.Length > 3) { 155 if (word.StartsWith(PushEnvironment.CharSymbolStr) && 156 word.EndsWith(PushEnvironment.CharSymbolStr) && 157 word.Length == 3) { 158 expression = new CharPushExpression(word[1]); 159 return true; 160 } 161 162 if (word.StartsWith(PushEnvironment.StringSymbolStr) && 163 word.EndsWith(PushEnvironment.StringSymbolStr)) { 164 var stringValue = word.Length == 0 ? string.Empty : word.Substring(1, word.Length - 2); 165 expression = new StringPushExpression(stringValue); 166 return true; 167 } 168 169 // "[]" has no values and can therefor not parsed correctly as vector of a specific type 170 if (word.StartsWith(PushEnvironment.VectorStartSymbolStr) && 171 word.EndsWith(PushEnvironment.VectorEndSymbolStr) && 172 word.Length > 2) { 173 93 174 var vectorEntries = word 94 175 .Substring(1, word.Length - 2) 95 .Split(',') 96 .Select(x => { 97 Expression e; 98 var success = TryParseLiteral(x.Trim(), out e); 99 100 return new { success, e, type = e.GetType() }; 101 }) 176 .Split(PushEnvironment.VectorSeparatorSymbol) 102 177 .ToArray(); 103 178 … … 107 182 } 108 183 109 var vectorEntryType = vectorEntries.First().type; 110 if (vectorEntries.Any(x => !x.success || x.type != vectorEntryType)) { 184 Expression e; 185 var first = vectorEntries.First(); 186 if (!TryParseLiteral(first, out e)) { 111 187 expression = null; 112 188 return false; 113 189 } 114 190 115 var result = vectorEntries 116 .Select(x => x.e) 117 .ToArray(); 118 119 // TODO 120 //switch(vectorEntryType.GetHashCode()) 121 //{ 122 // case typeof(IntegerPushExpression).GetHashCode(): return new IntegerVectorPushExpression(result) 123 //} 124 125 //expression = new StringPushExpression(word); 126 //return true; 191 if (e.GetType() == typeof(IntegerPushExpression)) { 192 var integerValues = vectorEntries.Select(long.Parse).ToArray(); 193 expression = new IntegerVectorPushExpression(integerValues); 194 } else if (e.GetType() == typeof(FloatPushExpression)) { 195 var doubleValues = vectorEntries.Select(x => double.Parse(x, NumberStyles.Float, cultureInfo)).ToArray(); 196 expression = new FloatVectorPushExpression(doubleValues); 197 } else if (e.GetType() == typeof(StringPushExpression)) { 198 var stringValues = vectorEntries.Select(str => str.Substring(1, str.Length - 2)).ToArray(); 199 expression = new StringVectorPushExpression(stringValues); 200 } else if (e.GetType() == typeof(BooleanPushExpression)) { 201 var booleanValues = vectorEntries.Select(bool.Parse).ToArray(); 202 expression = new BooleanVectorPushExpression(booleanValues); 203 } else { 204 expression = null; 205 return false; 206 } 207 208 return true; 127 209 } 128 210 … … 148 230 return false; 149 231 } 232 233 private static string EscapeLikeALiteral(string src) { 234 return Regex.Replace(src, @"\\(?<simple>['""\\0abfnrtv])", m => { 235 var s = m.Groups["simple"].Value; 236 switch (s) { 237 case "'": return "'"; 238 case "\"": return "\""; 239 case "0": return "\0"; 240 case "a": return "\a"; 241 case "b": return "\b"; 242 case "f": return "\f"; 243 case "n": return "\n"; 244 case "r": return "\r"; 245 case "t": return "\t"; 246 case "v": return "\v"; 247 default: 248 throw new InvalidOperationException(); 249 } 250 }); 251 } 150 252 } 151 253 }
Note: See TracChangeset
for help on using the changeset viewer.