// Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number private ISymbolicExpressionTreeNode ParseFact(Queue <Token> tokens) { var next = tokens.Peek(); if (next.TokenType == TokenType.LeftPar) { tokens.Dequeue(); var expr = ParseExpr(tokens); var rPar = tokens.Dequeue(); if (rPar.TokenType != TokenType.RightPar) { throw new ArgumentException("expected )"); } return(expr); } else if (next.TokenType == TokenType.Identifier) { var idTok = tokens.Dequeue(); if (tokens.Peek().TokenType == TokenType.LeftPar) { // function identifier var funcId = idTok.strVal.ToUpperInvariant(); var funcNode = GetSymbol(funcId).CreateTreeNode(); var lPar = tokens.Dequeue(); if (lPar.TokenType != TokenType.LeftPar) { throw new ArgumentException("expected ("); } var expr = ParseExpr(tokens); var rPar = tokens.Dequeue(); if (rPar.TokenType != TokenType.RightPar) { throw new ArgumentException("expected )"); } funcNode.AddSubtree(expr); return(funcNode); } else { // variable var varNode = (VariableTreeNode)variable.CreateTreeNode(); varNode.Weight = 1.0; varNode.VariableName = idTok.strVal; return(varNode); } } else if (next.TokenType == TokenType.Number) { var numTok = tokens.Dequeue(); var constNode = (ConstantTreeNode)constant.CreateTreeNode(); constNode.Value = numTok.doubleVal; return(constNode); } else { throw new ArgumentException(string.Format("unexpected token in expression {0}", next.strVal)); } }
private ISymbolicExpressionTreeNode ParseVariable(Queue <Token> tokens) { Token varTok = tokens.Dequeue(); Debug.Assert(varTok.StringValue == "VARIABLE"); VariableTreeNode t = (VariableTreeNode)variable.CreateTreeNode(); t.Weight = tokens.Dequeue().DoubleValue; t.VariableName = tokens.Dequeue().StringValue; return(t); }
/// SimpleFact = '(' Expr ')' /// | '{' Expr '}' /// | 'LAG' '(' varId ',' ['+' | '-' ] number ')' /// | funcId '(' ArgList ') /// | VarExpr /// | number /// ArgList = Expr { ',' Expr } /// VarExpr = varId OptFactorPart /// OptFactorPart = [ ('=' varVal | '[' ['+' | '-' ] number {',' ['+' | '-' ] number } ']' ) ] /// varId = ident | ' ident ' | " ident " /// varVal = ident | ' ident ' | " ident " /// ident = '_' | letter { '_' | letter | digit } private ISymbolicExpressionTreeNode ParseSimpleFact(Queue <Token> tokens) { var next = tokens.Peek(); if (next.TokenType == TokenType.LeftPar) { var initPar = tokens.Dequeue(); // match par type var expr = ParseExpr(tokens); var rPar = tokens.Dequeue(); if (rPar.TokenType != TokenType.RightPar) { throw new ArgumentException("expected closing parenthesis"); } if (initPar.strVal == "(" && rPar.strVal == "}") { throw new ArgumentException("expected closing )"); } if (initPar.strVal == "{" && rPar.strVal == ")") { throw new ArgumentException("expected closing }"); } return(expr); } else if (next.TokenType == TokenType.Identifier) { var idTok = tokens.Dequeue(); if (tokens.Peek().TokenType == TokenType.LeftPar) { // function identifier or LAG var funcId = idTok.strVal.ToUpperInvariant(); var funcNode = GetSymbol(funcId).CreateTreeNode(); var lPar = tokens.Dequeue(); if (lPar.TokenType != TokenType.LeftPar) { throw new ArgumentException("expected ("); } // handle 'lag' specifically if (funcNode.Symbol is LaggedVariable) { var varId = tokens.Dequeue(); if (varId.TokenType != TokenType.Identifier) { throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\""); } var comma = tokens.Dequeue(); if (comma.TokenType != TokenType.Comma) { throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\""); } double sign = 1.0; if (tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") { // read sign var signTok = tokens.Dequeue(); if (signTok.strVal == "-") { sign = -1.0; } } var lagToken = tokens.Dequeue(); if (lagToken.TokenType != TokenType.Number) { throw new ArgumentException("Number expected, Format for lagged variables: \"lag(x, -1)\""); } if (!lagToken.doubleVal.IsAlmost(Math.Round(lagToken.doubleVal))) { throw new ArgumentException("Time lags must be integer values"); } var laggedVarNode = funcNode as LaggedVariableTreeNode; laggedVarNode.VariableName = varId.strVal; laggedVarNode.Lag = (int)Math.Round(sign * lagToken.doubleVal); laggedVarNode.Weight = 1.0; } else { // functions var args = ParseArgList(tokens); // check number of arguments if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) { throw new ArgumentException(string.Format("Symbol {0} requires between {1} and {2} arguments.", funcId, funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity)); } foreach (var arg in args) { funcNode.AddSubtree(arg); } } var rPar = tokens.Dequeue(); if (rPar.TokenType != TokenType.RightPar) { throw new ArgumentException("expected )"); } return(funcNode); } else { // variable if (tokens.Peek().TokenType == TokenType.Eq) { // binary factor tokens.Dequeue(); // skip Eq var valTok = tokens.Dequeue(); if (valTok.TokenType != TokenType.Identifier) { throw new ArgumentException("expected identifier"); } var binFactorNode = (BinaryFactorVariableTreeNode)binaryFactorVar.CreateTreeNode(); binFactorNode.Weight = 1.0; binFactorNode.VariableName = idTok.strVal; binFactorNode.VariableValue = valTok.strVal; return(binFactorNode); } else if (tokens.Peek().TokenType == TokenType.LeftBracket) { // factor variable var factorVariableNode = (FactorVariableTreeNode)factorVar.CreateTreeNode(); factorVariableNode.VariableName = idTok.strVal; tokens.Dequeue(); // skip [ var weights = new List <double>(); // at least one weight is necessary var sign = 1.0; if (tokens.Peek().TokenType == TokenType.Operator) { var opToken = tokens.Dequeue(); if (opToken.strVal == "+") { sign = 1.0; } else if (opToken.strVal == "-") { sign = -1.0; } else { throw new ArgumentException(); } } if (tokens.Peek().TokenType != TokenType.Number) { throw new ArgumentException("number expected"); } var weightTok = tokens.Dequeue(); weights.Add(sign * weightTok.doubleVal); while (tokens.Peek().TokenType == TokenType.Comma) { // skip comma tokens.Dequeue(); if (tokens.Peek().TokenType == TokenType.Operator) { var opToken = tokens.Dequeue(); if (opToken.strVal == "+") { sign = 1.0; } else if (opToken.strVal == "-") { sign = -1.0; } else { throw new ArgumentException(); } } weightTok = tokens.Dequeue(); if (weightTok.TokenType != TokenType.Number) { throw new ArgumentException("number expected"); } weights.Add(sign * weightTok.doubleVal); } var rightBracketToken = tokens.Dequeue(); if (rightBracketToken.TokenType != TokenType.RightBracket) { throw new ArgumentException("closing bracket ] expected"); } factorVariableNode.Weights = weights.ToArray(); return(factorVariableNode); } else { // variable var varNode = (VariableTreeNode)variable.CreateTreeNode(); varNode.Weight = 1.0; varNode.VariableName = idTok.strVal; return(varNode); } } } else if (next.TokenType == TokenType.Number) { var numTok = tokens.Dequeue(); var constNode = (ConstantTreeNode)constant.CreateTreeNode(); constNode.Value = numTok.doubleVal; return(constNode); } else { throw new ArgumentException(string.Format("unexpected token in expression {0}", next.strVal)); } }