Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/01/17 09:28:34 (7 years ago)
Author:
pkimmesw
Message:

#2665 Fixed Benchmark Problem Definition, Converted LoopExpressions to stateless expressions, Added several unit test to ensure funcionality, Fixed UI bugs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs

    r14952 r15017  
    11namespace HeuristicLab.Problems.ProgramSynthesis.Push.Parser {
     2  using System;
    23  using System.Collections.Generic;
    34  using System.Globalization;
    45  using System.Linq;
     6  using System.Text.RegularExpressions;
     7
     8  using HeuristicLab.Problems.ProgramSynthesis.Push.Constants;
    59  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
    610
    711  public static class PushParser {
    8     private const string openBrace = "(";
    9 
    10     private const string closeBrace = ")";
    11 
    1212    private const char delimiter = ' ';
    1313
     
    1717
    1818    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);
    2021
    2122      int endIndex;
    22       return Parse(symbols, 0, out endIndex);
     23      return Parse(symbols, startIndex, out endIndex);
    2324    }
    2425
     
    2930    }
    3031
    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) {
    32106      var expressions = new List<Expression>();
    33107
    34       for (var i = startIndex; i < symbols.Length; i++) {
     108      for (var i = startIndex; i < symbols.Count; i++) {
    35109        var symbol = symbols[i].TrimEnd(symbolTrim);
    36110
     
    38112
    39113        switch (symbol) {
    40           case openBrace:
     114          case PushEnvironment.ProgramStartSymbolStr:
    41115            var subExpression = Parse(symbols, i + 1, out endIndex);
    42116            expressions.Insert(0, subExpression);
    43117            i = endIndex;
    44118            continue;
    45           case closeBrace:
     119          case PushEnvironment.ProgramEndSymbolStr:
    46120            endIndex = i;
    47121            return new PushProgram(expressions);
     
    66140      }
    67141
    68       endIndex = symbols.Length - 1;
     142      endIndex = symbols.Count - 1;
    69143
    70144      switch (expressions.Count) {
     
    79153
    80154    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
    93174        var vectorEntries = word
    94175          .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)
    102177          .ToArray();
    103178
     
    107182        }
    108183
    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)) {
    111187          expression = null;
    112188          return false;
    113189        }
    114190
    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;
    127209      }
    128210
     
    148230      return false;
    149231    }
     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    }
    150252  }
    151253}
Note: See TracChangeset for help on using the changeset viewer.