public OperatorInfo(string lexeme, OperatorArity arity, int priority, OperatorAssociativity associativity = OperatorAssociativity.LeftToRight) { this.Lexeme = lexeme; this.Arity = arity; this.Priority = priority; this.Associativity = associativity; }
public TokenDefinition(TokenType tokenType, int precedence, OperatorAssociativity associativity, string pattern) : this(tokenType) { _precedence = precedence; _pattern = pattern; _associativity = associativity; }
public Operator(string text, int precedence, int qArguments, OperatorAssociativity assoc, Func <double, double, double> opFunc) { _text = text; _precedence = precedence; _qArguments = qArguments; _assoc = assoc; _opFunc = opFunc; }
public Operator() { SymbolText = string.Empty; OperandCount = 0; PrecedenceLevel = -1; Associativity = OperatorAssociativity.None; Execute = null; }
public ExpressionTokenMatcher(ITokenMatcher matcher, TokenType tokenType, int precedence, OperatorAssociativity associativity, TokenEvaluator tokenEvaluator) { _matcher = matcher; _tokenType = tokenType; _tokenEvaluator = tokenEvaluator; _precedence = precedence; _associativity = associativity; }
private BinaryOperator(string regularExpression, ushort precedence, OperatorAssociativity associativity, Func <double, double, double> evaluator) { RegularExpression = regularExpression; Associativity = associativity; Evaluator = evaluator; Precedence = precedence; }
public ExpressionToken(ExpressionTokenMatcher tokenMatcher, string text) : base(tokenMatcher, text) { switch (tokenMatcher.TokenType) { case TokenType.TernaryOperator: _numTerms = 3; break; case TokenType.UnaryOperator: _numTerms = 1; break; case TokenType.Operator: _numTerms = 2; break; } _precedence = tokenMatcher.Precedence; _associativity = tokenMatcher.Associativity; _tokenType = tokenMatcher.TokenType; _evaluator = tokenMatcher.Evaluator; }
/// <summary> /// Update token's priorty, symbol, associativity and parameter count /// </summary> /// <param name="_symbol">New operator symbol</param> /// <param name="_assoc">New associativity</param> /// <param name="_priority">New priority</param> /// <param name="_paramCount">New parameter count</param> public void SetValues(string _symbol, OperatorAssociativity _assoc, int _priority, int _paramCount, bool setAsOpToken = true) { symbol = _symbol; assoc = _assoc; priority = _priority; paramCount = _paramCount; if (setAsOpToken) { tknType = TokenType.OPERATOR; } }
private OperatorAssociativity GetOperatorAssociativity(string operatorText) { OperatorAssociativity assoc = OperatorAssociativity.Left; for (int i = 0; i < _operators.Length; i++) { if (_operators[i].Text == operatorText) { assoc = _operators[i].Associativity; break; } } return(assoc); }
// INITIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a new operator instance. /// </summary> /// <param name="token"> The token that corresponds to this operator. If the operator consists /// of multiple tokens (e.g. ?:) then this is the first token in the sequence. </param> /// <param name="precedence"> An integer that indicates the order of evaluation. Higher /// precedence operators are evaluated first. </param> /// <param name="placement"> A value that indicates where operands are allowed. </param> /// <param name="associativity"> Gets a value that indicates whether multiple operators of this /// type are grouped left-to-right or right-to-left. </param> /// <param name="type"> The type of operator: this decides what algorithm to use to calculate the result. </param> /// <param name="secondaryToken"> The second token in the sequence. </param> /// <param name="rhsPrecedence"> The precedence for the secondary or tertiary operand. </param> private Operator(Token token, int precedence, OperatorPlacement placement, OperatorAssociativity associativity, OperatorType type, Token secondaryToken = null, int rhsPrecedence = -1) { if (token == null) { throw new ArgumentNullException(nameof(token)); } if (token == secondaryToken) { throw new ArgumentException("Token and secondaryToken must be different."); } if ((placement & (OperatorPlacement.HasLHSOperand | OperatorPlacement.HasRHSOperand)) == 0) { throw new ArgumentException("An operator must take at least one operand."); } if (secondaryToken == null && (placement & OperatorPlacement.HasSecondaryRHSOperand) != 0) { throw new ArgumentException("HasSecondaryRHSOperand can only be specified along with a secondary token."); } if (secondaryToken == null && (placement & OperatorPlacement.InnerOperandIsOptional) != 0) { throw new ArgumentException("InnerOperandIsOptional can only be specified along with a secondary token."); } if ((placement & OperatorPlacement.InnerOperandIsOptional) != 0 && (placement & OperatorPlacement.HasRHSOperand) == 0) { throw new ArgumentException("InnerOperandIsOptional can only be specified along with HasRHSOperand."); } this.Token = token; this.HasLHSOperand = (placement & OperatorPlacement.HasLHSOperand) != 0; this.HasRHSOperand = (placement & OperatorPlacement.HasRHSOperand) != 0; this.Associativity = associativity; this.Type = type; this.SecondaryToken = secondaryToken; this.HasSecondaryRHSOperand = (placement & OperatorPlacement.HasSecondaryRHSOperand) != 0; this.InnerOperandIsOptional = (placement & OperatorPlacement.InnerOperandIsOptional) != 0; this.Precedence = this.SecondaryPrecedence = this.TertiaryPrecedence = precedence; if (rhsPrecedence >= 0 && this.HasRHSOperand) { this.SecondaryPrecedence = rhsPrecedence; } if (rhsPrecedence >= 0 && this.HasSecondaryRHSOperand) { this.TertiaryPrecedence = rhsPrecedence; } // Every operator instance is stored in a list for retrieval by the parser. allOperators.Add(this); }
public OperatorDescriptor(IBinaryOperatorType binaryOperatorType, OperatorAssociativity associativity, IEnumerable<string> operatorSymbols) { if (binaryOperatorType == null) { throw new ArgumentNullException("binaryOperatorType"); } this.binaryOperatorType = binaryOperatorType; this.associativity = associativity; if (operatorSymbols == null) { throw new ArgumentNullException("operatorSymbols"); } this.operatorSymbols = operatorSymbols.ToList().AsReadOnly(); }
/// <summary> /// Create a token with given arguments /// </summary> /// <param name="tknType">Token type</param> /// <param name="val">Stored value</param> /// <param name="symbol">Operator symbol</param> /// <param name="assoc">Associativity</param> /// <param name="priority">Priority</param> /// <param name="paramCount">Parameter count</param> /// <param name="name">Matrix or function name</param> /// <param name="paramTypes">Parameter type names</param> /// <param name="service">Function service name</param> /// <param name="returns">Return type name</param> public Token(TokenType tknType, dynamic val, string symbol, OperatorAssociativity assoc, int priority, int paramCount, string name, List <string> paramTypes, string service, string returns) { this.tknType = tknType; this.val = val; this.symbol = symbol; this.assoc = assoc; this.priority = priority; this.paramCount = paramCount; this.name = name; this.paramTypes = paramTypes; this.service = service; this.returns = returns; }
public void AddTernaryTokenMatcher(ITokenMatcher matcher1, ITokenMatcher matcher2, int precedence, OperatorAssociativity associativity, TokenEvaluator tokenEvaluator) { ExpressionTokenMatcher root = new ExpressionTokenMatcher(null, TokenType.TernaryOperator, tokenEvaluator); ExpressionTokenMatcher partial1 = new ExpressionTokenMatcher(matcher1, TokenType.TernaryOperator1, precedence, associativity, null); ExpressionTokenMatcher partial2 = new ExpressionTokenMatcher(matcher2, TokenType.TernaryOperator1, precedence, associativity, null); partial1.Root = root; partial2.Root = root; AddTokenMatcher(partial1); AddTokenMatcher(partial2); }
// INITIALIZATION //_________________________________________________________________________________________ private Operator(Token token, int precedence, OperatorPlacement placement, OperatorAssociativity associativity, OperatorType type) : this(token, precedence, placement, associativity, type, null, -1) { }
/// <summary> /// Creates a new operator instance. /// </summary> /// <param name="token"> The token that corresponds to this operator. If the operator consists /// of multiple tokens (e.g. ?:) then this is the first token in the sequence. </param> /// <param name="precedence"> An integer that indicates the order of evaluation. Higher /// precedence operators are evaluated first. </param> /// <param name="placement"> A value that indicates where operands are allowed. </param> /// <param name="associativity"> Gets a value that indicates whether multiple operators of this /// type are grouped left-to-right or right-to-left. </param> /// <param name="type"> The type of operator: this decides what algorithm to use to calculate the result. </param> /// <param name="secondaryToken"> The second token in the sequence. </param> /// <param name="rhsPrecedence"> The precedence for the secondary or tertiary operand. </param> private Operator(Token token, int precedence, OperatorPlacement placement, OperatorAssociativity associativity, OperatorType type, Token secondaryToken, int rhsPrecedence) { if (token == null) { throw new ArgumentNullException("token"); } if (token == secondaryToken) { throw new ArgumentException("Token and secondaryToken must be different."); } if ((placement & (OperatorPlacement.HasLHSOperand | OperatorPlacement.HasRHSOperand)) == 0) { throw new ArgumentException("An operator must take at least one operand."); } if (secondaryToken == null && (placement & OperatorPlacement.HasSecondaryRHSOperand) != 0) { throw new ArgumentException("HasSecondaryRHSOperand can only be specified along with a secondary token."); } if (secondaryToken == null && (placement & OperatorPlacement.InnerOperandIsOptional) != 0) { throw new ArgumentException("InnerOperandIsOptional can only be specified along with a secondary token."); } if ((placement & OperatorPlacement.InnerOperandIsOptional) != 0 && (placement & OperatorPlacement.HasRHSOperand) == 0) { throw new ArgumentException("InnerOperandIsOptional can only be specified along with HasRHSOperand."); } this.Token = token; this.HasLHSOperand = (placement & OperatorPlacement.HasLHSOperand) != 0; this.HasRHSOperand = (placement & OperatorPlacement.HasRHSOperand) != 0; this.Associativity = associativity; this.Type = type; this.SecondaryToken = secondaryToken; this.HasSecondaryRHSOperand = (placement & OperatorPlacement.HasSecondaryRHSOperand) != 0; this.InnerOperandIsOptional = (placement & OperatorPlacement.InnerOperandIsOptional) != 0; this.Precedence = this.SecondaryPrecedence = this.TertiaryPrecedence = precedence; if (rhsPrecedence >= 0 && this.HasRHSOperand) { this.SecondaryPrecedence = rhsPrecedence; } if (rhsPrecedence >= 0 && this.HasSecondaryRHSOperand) { this.TertiaryPrecedence = rhsPrecedence; } // If prefix: if (HasLHSOperand) { token.PostfixOperator = this; } else { token.PrefixOperator = this; } if (SecondaryToken != null) { // Update the secondary token, this time with post/pre inverted: if (HasRHSOperand) { SecondaryToken.PostfixOperator = this; } else { SecondaryToken.PrefixOperator = this; } if (InnerOperandIsOptional) { SecondaryToken.PrefixOperator = this; } } Arity = (this.HasLHSOperand ? 1 : 0) + (this.HasRHSOperand ? 1 : 0) + (this.HasSecondaryRHSOperand ? 1 : 0); }
public void AddTokenMatcher(ITokenMatcher tokenMatcher, TokenType tokenType, int precedence, OperatorAssociativity associativity, TokenEvaluator tokenEvaluator) { AddTokenMatcher(new ExpressionTokenMatcher(tokenMatcher, tokenType, precedence, associativity, tokenEvaluator)); }
public void AddTokenMatcher(ITokenMatcher tokenMatcher, TokenType tokenType, int precedence, OperatorAssociativity associativity, TokenEvaluator tokenEvaluator, int?numTerms = null) { var matcher = new ExpressionTokenMatcher(tokenMatcher, tokenType, precedence, associativity, tokenEvaluator); if (numTerms != null) { matcher.NumTerms = numTerms; } AddTokenMatcher(matcher); }
public void AddBinaryOperator(string pattern, int precedence, OperatorAssociativity associativity, TokenEvaluator evaluator) { AddTokenDefinition(new TokenDefinition(TokenType.Operator, precedence, associativity, pattern), evaluator); }
public Operator(string symbol, int precedence, OperatorAssociativity associativity) { Symbol = symbol; Precedence = precedence; Associativity = associativity; }
/// <summary> /// Creates new instace of OperatorBase with given parameters. /// </summary> /// <param name="symbol">Symbol of this function or operator.</param> /// <param name="precedence">Precedence of this function or operator.</param> /// <param name="associativity">Associativity of this function or operator.</param> public OperatorBase(string symbol, int precedence, OperatorAssociativity associativity) : base(symbol) { Precedence = precedence; Associativity = associativity; }
public OperatorToken(char value, int precedence, OperatorAssociativity operatorAssociativity) : base(value) { this.Precedence = precedence; this.OperatorAssociativity = operatorAssociativity; }
private static Nodes.ParseTreeNode CombineBinaryOperators(List<Nodes.ParseTreeNode> operands, List<Token> operators, IBinaryOperatorType operatorType, OperatorAssociativity associativity) { if (operators.Count + 1 != operands.Count) { throw new InvalidOperationException("You cannot combine binary operators if the number of operands is not equal to the number of operators plus one."); } // If there is just one operand, just return it. if (operands.Count == 1) { return operands[0]; } // If there are just two operands, all associativity rules are equivalent. if (operands.Count == 2) { return new Nodes.BinaryOperatorNode { Left = operands[0], Operator = operators[0], OperatorType = operatorType, Right = operands[1], }; } // If there are more than two operands and the operator is non-associative, throw a parse error. if (associativity == OperatorAssociativity.NonAssociative) { throw new ParseException("The operator '" + operatorType.Name + "' is non-associative and therefore may not be used in groups of 3 or more without using parentheses for clarification.", operators[2].Span.Start); } // Otherwise, build up the tree with the proper associativity. if (associativity == OperatorAssociativity.LeftAssociative) { Nodes.ParseTreeNode accumulator = null; for (int i = 0; i < operands.Count; i++) { if (accumulator == null) { accumulator = operands[i]; } else { var thenNode = new Nodes.BinaryOperatorNode { Left = accumulator, Operator = operators[i - 1], OperatorType = operatorType, Right = operands[i], }; accumulator = thenNode; } } return accumulator; } else { Nodes.ParseTreeNode accumulator = null; for (int i = operands.Count - 1; i >= 0; i--) { if (accumulator == null) { accumulator = operands[i]; } else { var thenNode = new Nodes.BinaryOperatorNode { Left = operands[i], Operator = operators[i], OperatorType = operatorType, Right = accumulator }; accumulator = thenNode; } } return accumulator; } }
// INITIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a new operator instance. /// </summary> /// <param name="token"> The token that corresponds to this operator. If the operator consists /// of multiple tokens (e.g. ?:) then this is the first token in the sequence. </param> /// <param name="precedence"> An integer that indicates the order of evaluation. Higher /// precedence operators are evaluated first. </param> /// <param name="placement"> A value that indicates where operands are allowed. </param> /// <param name="associativity"> Gets a value that indicates whether multiple operators of this /// type are grouped left-to-right or right-to-left. </param> /// <param name="type"> The type of operator: this decides what algorithm to use to calculate the result. </param> /// <param name="secondaryToken"> The second token in the sequence. </param> /// <param name="rhsPrecedence"> The precedence for the secondary or tertiary operand. </param> private Operator(Token token, int precedence, OperatorPlacement placement, OperatorAssociativity associativity, OperatorType type, Token secondaryToken = null, int rhsPrecedence = -1) { if (token == null) throw new ArgumentNullException("token"); if (token == secondaryToken) throw new ArgumentException("Token and secondaryToken must be different."); if ((placement & (OperatorPlacement.HasLHSOperand | OperatorPlacement.HasRHSOperand)) == 0) throw new ArgumentException("An operator must take at least one operand."); if (secondaryToken == null && (placement & OperatorPlacement.HasSecondaryRHSOperand) != 0) throw new ArgumentException("HasSecondaryRHSOperand can only be specified along with a secondary token."); if (secondaryToken == null && (placement & OperatorPlacement.InnerOperandIsOptional) != 0) throw new ArgumentException("InnerOperandIsOptional can only be specified along with a secondary token."); if ((placement & OperatorPlacement.InnerOperandIsOptional) != 0 && (placement & OperatorPlacement.HasRHSOperand) == 0) throw new ArgumentException("InnerOperandIsOptional can only be specified along with HasRHSOperand."); this.Token = token; this.HasLHSOperand = (placement & OperatorPlacement.HasLHSOperand) != 0; this.HasRHSOperand = (placement & OperatorPlacement.HasRHSOperand) != 0; this.Associativity = associativity; this.Type = type; this.SecondaryToken = secondaryToken; this.HasSecondaryRHSOperand = (placement & OperatorPlacement.HasSecondaryRHSOperand) != 0; this.InnerOperandIsOptional = (placement & OperatorPlacement.InnerOperandIsOptional) != 0; this.Precedence = this.SecondaryPrecedence = this.TertiaryPrecedence = precedence; if (rhsPrecedence >= 0 && this.HasRHSOperand) this.SecondaryPrecedence = rhsPrecedence; if (rhsPrecedence >= 0 && this.HasSecondaryRHSOperand) this.TertiaryPrecedence = rhsPrecedence; // Every operator instance is stored in a list for retrieval by the parser. allOperators.Add(this); }
/// <summary> /// Creates EquationOperator with a given attributes. /// </summary> /// <param name="symbol">The symbol of this variable.</param> /// <param name="precedence">The precedence(importance) of this variable.</param> /// <param name="associativity">Determines if the operator is left or right associative.</param> /// <param name="func">The function being assigned to this operator.</param> public EquationOperator(string symbol, int precedence, OperatorAssociativity associativity, Func <double, double, double> func) : base(symbol, precedence, associativity) { this.func = func; }
private Operator(Token token, int precedence, OperatorPlacement placement, OperatorAssociativity associativity, OperatorType type, Token secondaryToken) : this(token, precedence, placement, associativity, type, token, -1) { }
public Queue <IToken> InfixToPostfix(string infixExpression) { Stack <string> operatorsStack = new Stack <string>(); Queue <IToken> outputQueue = new Queue <IToken>(); if (infixExpression == null) { throw new NullExpressionException("Null expression to parse!"); } else if (infixExpression == "") { throw new EmptyExpressionException("Empty expression to parse!"); } else { string exprWithoutSpaces = infixExpression.Replace(" ", ""); for (int i = 0; i < exprWithoutSpaces.Length; i++) { IToken currToken = ReadCurrentToken(exprWithoutSpaces, i); if (currToken is NumberToken) { //string currNumberString = ReadValueString(exprWithoutSpaces, i); outputQueue.Enqueue(currToken); i += currToken.Text.Length - 1; } else if (currToken is Operator) { OperatorAssociativity assoc = (currToken as Operator).Associativity; //else //{ // string topOperator = operatorsStack.Peek(); // int stackTopPrecedence = GetOperatorPrecedence(topOperator); // int currPrecedence = GetOperatorPrecedence(currToken.Text); // if (currPrecedence <= stackTopPrecedence && assoc == OperatorAssociativity.Left || // currPrecedence < stackTopPrecedence && assoc == OperatorAssociativity.Right) // { // string poppedOperatorString = operatorsStack.Pop(); // IToken poppedOperator = GetOperatorByText(poppedOperatorString); // outputQueue.Enqueue(poppedOperator); // operatorsStack.Push(currToken.Text); // } // else // { // operatorsStack.Push(currToken.Text); // } //} bool isFinish = false; if (operatorsStack.Count == 0) { operatorsStack.Push(currToken.Text); } else { while (!isFinish) { string topOperator = operatorsStack.Peek(); if (IsOperator(topOperator)) { int stackTopPrecedence = GetOperatorPrecedence(topOperator); int currPrecedence = GetOperatorPrecedence(currToken.Text); if (currPrecedence <= stackTopPrecedence && assoc == OperatorAssociativity.Left || currPrecedence < stackTopPrecedence && assoc == OperatorAssociativity.Right) { string poppedOperatorString = operatorsStack.Pop(); IToken poppedOperator = GetOperatorByText(poppedOperatorString); outputQueue.Enqueue(poppedOperator); } else { isFinish = true; } if (operatorsStack.Count > 0) { topOperator = operatorsStack.Peek(); } else { isFinish = true; } } else { isFinish = true; } } operatorsStack.Push(currToken.Text); i += currToken.Text.Length - 1; } } else if (currToken is Constant) { outputQueue.Enqueue(currToken); i += currToken.Text.Length - 1; } else { if (exprWithoutSpaces[i] == '(') { operatorsStack.Push(exprWithoutSpaces[i].ToString()); } else if (exprWithoutSpaces[i] == ')') { while (operatorsStack.Peek() != "(") { outputQueue.Enqueue(GetOperatorByText(operatorsStack.Pop())); if (operatorsStack.Count == 1 && operatorsStack.Peek() != "(") { throw new ParenthesesMismatchException("Parentheses mismatch!"); } } operatorsStack.Pop(); //if (IsOperator(operatorsStack.Peek())) //{ // outputQueue.Enqueue(operatorsStack.Pop()); //} } } } while (operatorsStack.Count > 0) { if (operatorsStack.Peek() == "(" || operatorsStack.Peek() == ")") { throw new ParenthesesMismatchException("Parentheses mismatch!"); } else { outputQueue.Enqueue(GetOperatorByText(operatorsStack.Pop())); } } } return(outputQueue); }
public void AddTernaryOperator(string pattern1, string pattern2, int precedence, OperatorAssociativity associativity, TokenEvaluator evaluator) { TokenDefinition root = new TokenDefinition(TokenType.TernaryOperator, evaluator); TokenDefinition partial1 = new TokenDefinition(TokenType.TernaryOperator1, precedence, associativity, pattern1); TokenDefinition partial2 = new TokenDefinition(TokenType.TernaryOperator2, precedence, associativity, pattern2); partial1.Root = root; partial2.Root = root; AddTokenDefinition(partial1); AddTokenDefinition(partial2); }