Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/04/17 17:52:44 (7 years ago)
Author:
gkronber
Message:

#2650: merged the factors branch into trunk

Location:
trunk/sources
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources

  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic

  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14350 r14826  
    3333  /// Parses mathematical expressions in infix form. E.g. x1 * (3.0 * x2 + x3)
    3434  /// Identifier format (functions or variables): '_' | letter { '_' | letter | digit }
    35   /// Variables names can be set under quotes "" or '' because variable names might contain spaces.
     35  /// Variables names and variable values can be set under quotes "" or '' because variable names might contain spaces.
     36  ///   Variable = ident | " ident " | ' ident '
    3637  /// It is also possible to use functions e.g. log("x1") or real-valued constants e.g. 3.1415 .
    3738  /// Variable names are case sensitive. Function names are not case sensitive.
     39  ///
     40  ///
     41  /// S             = Expr EOF
     42  /// Expr          = ['-' | '+'] Term { '+' Term | '-' Term }
     43  /// Term          = Fact { '*' Fact | '/' Fact }
     44  /// Fact          = '(' Expr ')'
     45  ///                 | 'LAG' '(' varId ',' ['+' | '-' ] number ')'
     46  ///                 | funcId '(' ArgList ')'
     47  ///                 | VarExpr | number
     48  /// ArgList       = Expr { ',' Expr }
     49  /// VarExpr       = varId OptFactorPart
     50  /// OptFactorPart = [ ('=' varVal | '[' ['+' | '-' ] number {',' ['+' | '-' ] number } ']' ) ]
     51  /// varId         =  ident | ' ident ' | " ident "
     52  /// varVal        =  ident | ' ident ' | " ident "
     53  /// ident         =  '_' | letter { '_' | letter | digit }
    3854  /// </summary>
    3955  public sealed class InfixExpressionParser {
    40     private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, End, NA };
     56    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, LeftBracket, RightBracket, Comma, Eq, End, NA };
    4157    private class Token {
    4258      internal double doubleVal;
     
    6581    private Constant constant = new Constant();
    6682    private Variable variable = new Variable();
     83    private BinaryFactorVariable binaryFactorVar = new BinaryFactorVariable();
     84    private FactorVariable factorVar = new FactorVariable();
    6785
    6886    private ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
     
    150168            && str[pos] != '/'
    151169            && str[pos] != ')'
     170            && str[pos] != ']'
    152171            && str[pos] != ',') {
    153172            sb.Append(str[pos]);
     
    214233          pos++;
    215234          yield return new Token { TokenType = TokenType.RightPar, strVal = ")" };
     235        } else if (str[pos] == '[') {
     236          pos++;
     237          yield return new Token { TokenType = TokenType.LeftBracket, strVal = "[" };
     238        } else if (str[pos] == ']') {
     239          pos++;
     240          yield return new Token { TokenType = TokenType.RightBracket, strVal = "]" };
     241        } else if (str[pos] == '=') {
     242          pos++;
     243          yield return new Token { TokenType = TokenType.Eq, strVal = "=" };
    216244        } else if (str[pos] == ',') {
    217245          pos++;
     
    222250      }
    223251    }
    224 
    225     // S       = Expr EOF
    226     // Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
    227     // Term    = Fact { '*' Fact | '/' Fact }
    228     // Fact    = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
    229     // ArgList = Expr { ',' Expr }
     252    /// S             = Expr EOF
    230253    private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
    231254      var expr = ParseExpr(tokens);
     
    237260      return expr;
    238261    }
     262
     263    /// Expr          = ['-' | '+'] Term { '+' Term | '-' Term }
    239264    private ISymbolicExpressionTreeNode ParseExpr(Queue<Token> tokens) {
    240265      var next = tokens.Peek();
     
    300325    }
    301326
    302     // Term = Fact { '*' Fact | '/' Fact }
     327    /// Term          = Fact { '*' Fact | '/' Fact }
    303328    private ISymbolicExpressionTreeNode ParseTerm(Queue<Token> tokens) {
    304329      var factors = new List<ISymbolicExpressionTreeNode>();
     
    335360    }
    336361
    337     // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-'] number ')' | funcId '(' ArgList ')' | varId | number
     362    /// Fact          = '(' Expr ')'
     363    ///                 | 'LAG' '(' varId ',' ['+' | '-' ] number ')'
     364    ///                 | funcId '(' ArgList ')'
     365    ///                 | VarExpr | number
     366    /// ArgList       = Expr { ',' Expr }
     367    /// VarExpr       = varId OptFactorPart
     368    /// OptFactorPart = [ ('=' varVal | '[' ['+' | '-' ] number {',' ['+' | '-' ] number } ']' ) ]
     369    /// varId         =  ident | ' ident ' | " ident "
     370    /// varVal        =  ident | ' ident ' | " ident "
     371    /// ident         =  '_' | letter { '_' | letter | digit }
    338372    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    339373      var next = tokens.Peek();
     
    348382        var idTok = tokens.Dequeue();
    349383        if (tokens.Peek().TokenType == TokenType.LeftPar) {
    350           // function identifier
     384          // function identifier or LAG
    351385          var funcId = idTok.strVal.ToUpperInvariant();
    352386
     
    394428        } else {
    395429          // variable
    396           var varNode = (VariableTreeNode)variable.CreateTreeNode();
    397           varNode.Weight = 1.0;
    398           varNode.VariableName = idTok.strVal;
    399           return varNode;
     430          if (tokens.Peek().TokenType == TokenType.Eq) {
     431            // binary factor
     432            tokens.Dequeue(); // skip Eq
     433            var valTok = tokens.Dequeue();
     434            if (valTok.TokenType != TokenType.Identifier) throw new ArgumentException("expected identifier");
     435            var binFactorNode = (BinaryFactorVariableTreeNode)binaryFactorVar.CreateTreeNode();
     436            binFactorNode.Weight = 1.0;
     437            binFactorNode.VariableName = idTok.strVal;
     438            binFactorNode.VariableValue = valTok.strVal;
     439            return binFactorNode;
     440          } else if (tokens.Peek().TokenType == TokenType.LeftBracket) {
     441            // factor variable
     442            var factorVariableNode = (FactorVariableTreeNode)factorVar.CreateTreeNode();
     443            factorVariableNode.VariableName = idTok.strVal;
     444
     445            tokens.Dequeue(); // skip [
     446            var weights = new List<double>();
     447            // at least one weight is necessary
     448            var sign = 1.0;
     449            if (tokens.Peek().TokenType == TokenType.Operator) {
     450              var opToken = tokens.Dequeue();
     451              if (opToken.strVal == "+") sign = 1.0;
     452              else if (opToken.strVal == "-") sign = -1.0;
     453              else throw new ArgumentException();
     454            }
     455            if (tokens.Peek().TokenType != TokenType.Number) throw new ArgumentException("number expected");
     456            var weightTok = tokens.Dequeue();
     457            weights.Add(sign * weightTok.doubleVal);
     458            while (tokens.Peek().TokenType == TokenType.Comma) {
     459              // skip comma
     460              tokens.Dequeue();
     461              if (tokens.Peek().TokenType == TokenType.Operator) {
     462                var opToken = tokens.Dequeue();
     463                if (opToken.strVal == "+") sign = 1.0;
     464                else if (opToken.strVal == "-") sign = -1.0;
     465                else throw new ArgumentException();
     466              }
     467              weightTok = tokens.Dequeue();
     468              if (weightTok.TokenType != TokenType.Number) throw new ArgumentException("number expected");
     469              weights.Add(sign * weightTok.doubleVal);
     470            }
     471            var rightBracketToken = tokens.Dequeue();
     472            if (rightBracketToken.TokenType != TokenType.RightBracket) throw new ArgumentException("closing bracket ] expected");
     473            factorVariableNode.Weights = weights.ToArray();
     474            return factorVariableNode;
     475          } else {
     476            // variable
     477            var varNode = (VariableTreeNode)variable.CreateTreeNode();
     478            varNode.Weight = 1.0;
     479            varNode.VariableName = idTok.strVal;
     480            return varNode;
     481          }
    400482        }
    401483      } else if (next.TokenType == TokenType.Number) {
Note: See TracChangeset for help on using the changeset viewer.