Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
01/14/17 19:08:39 (7 years ago)
Author:
gkronber
Message:

#2657,#2677 merged r14258, r14316, r14319 and 14347.

Location:
stable
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14116 r14564  
    3737  /// </summary>
    3838  public sealed class InfixExpressionParser {
    39     private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, End, NA };
     39    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, End, NA };
    4040    private class Token {
    4141      internal double doubleVal;
     
    102102        { "MEAN", new Average()},
    103103        { "IF", new IfThenElse()},
    104         { ">", new GreaterThan()},
    105         { "<", new LessThan()},
     104        { "GT", new GreaterThan()},
     105        { "LT", new LessThan()},
    106106        { "AND", new And()},
    107107        { "OR", new Or()},
     
    138138        }
    139139        if (char.IsDigit(str[pos])) {
    140           // read number (=> read until white space or operator)
     140          // read number (=> read until white space or operator or comma)
    141141          var sb = new StringBuilder();
    142142          sb.Append(str[pos]);
    143143          pos++;
    144144          while (pos < str.Length && !char.IsWhiteSpace(str[pos])
    145             && (str[pos] != '+' || str[pos-1] == 'e' || str[pos-1] == 'E')     // continue reading exponents
     145            && (str[pos] != '+' || str[pos - 1] == 'e' || str[pos - 1] == 'E')     // continue reading exponents
    146146            && (str[pos] != '-' || str[pos - 1] == 'e' || str[pos - 1] == 'E')
    147             && str[pos] != '*'           
     147            && str[pos] != '*'
    148148            && str[pos] != '/'
    149             && str[pos] != ')') {
     149            && str[pos] != ')'
     150            && str[pos] != ',') {
    150151            sb.Append(str[pos]);
    151152            pos++;
     
    211212          pos++;
    212213          yield return new Token { TokenType = TokenType.RightPar, strVal = ")" };
    213         }
    214       }
    215     }
    216 
    217     // S = Expr EOF
    218     // Expr = ['-' | '+'] Term { '+' Term | '-' Term }
    219     // Term = Fact { '*' Fact | '/' Fact }
    220     // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
     214        } else if (str[pos] == ',') {
     215          pos++;
     216          yield return new Token { TokenType = TokenType.Comma, strVal = "," };
     217        } else {
     218          throw new ArgumentException("Invalid character: " + str[pos]);
     219        }
     220      }
     221    }
     222
     223    // S       = Expr EOF
     224    // Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
     225    // Term    = Fact { '*' Fact | '/' Fact }
     226    // Fact    = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
     227    // ArgList = Expr { ',' Expr }
    221228    private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
    222229      var expr = ParseExpr(tokens);
     
    326333    }
    327334
    328     // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
     335    // Fact = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
    329336    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    330337      var next = tokens.Peek();
     
    346353          if (lPar.TokenType != TokenType.LeftPar)
    347354            throw new ArgumentException("expected (");
    348           var expr = ParseExpr(tokens);
     355          var args = ParseArgList(tokens);
     356
     357          // check semantic constraints
     358          if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length)
     359            throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
     360              funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
     361          foreach (var arg in args) funcNode.AddSubtree(arg);
     362
    349363          var rPar = tokens.Dequeue();
    350364          if (rPar.TokenType != TokenType.RightPar)
    351365            throw new ArgumentException("expected )");
    352366
    353           funcNode.AddSubtree(expr);
    354367          return funcNode;
    355368        } else {
     
    369382      }
    370383    }
     384
     385    // ArgList = Expr { ',' Expr }
     386    private ISymbolicExpressionTreeNode[] ParseArgList(Queue<Token> tokens) {
     387      var exprList = new List<ISymbolicExpressionTreeNode>();
     388      exprList.Add(ParseExpr(tokens));
     389      while (tokens.Peek().TokenType != TokenType.RightPar) {
     390        var comma = tokens.Dequeue();
     391        if (comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
     392        exprList.Add(ParseExpr(tokens));
     393      }
     394      return exprList.ToArray();
     395    }
    371396  }
    372397}
Note: See TracChangeset for help on using the changeset viewer.