protected string DoShuntingYardAlgorithm(TokenizerInterface tokenizer) { // I have referred shunting-yard algorithm https://en.wikipedia.org/wiki/Shunting-yard_algorithm Token token = tokenizer.GetNextToken(); Token lastToken = null; bool first = true; bool afterOpenParenthesis = false; while (token.Type != TokenType.None) { // Token is a number, add it to the output queue. if (IsDigit(token)) { AddToOutput(token.GetValueAsString()); } else if (token.GetValueAsString() == ".") { AddToOutput(token.GetValueAsString()); } // Token is a left parenthesis "(", push it onto the stack. else if (token.GetValueAsString() == "(") { operatorStack.Push(token.GetValueAsString()); } // Token is a right parenthesis ")" else if (token.GetValueAsString() == ")") { string lastOperation = operatorStack.Peek(); while (lastOperation != "(") { AddToOutput(operatorStack.Pop()); lastOperation = operatorStack.Peek(); } // Pop the left parenthesis from the stack operatorStack.Pop(); // Mark parenthesis flag to avoid false unary operation detection afterOpenParenthesis = true; } // Token is an operator, o1 else if (IsOperator(token)) { string currentOperation = token.GetValueAsString(); // check for negation at the beginning of the input formal. if (first && currentOperation == "-") { currentOperation = "m"; } // check for plus sign at the beginning of the input formal. else if (first && currentOperation == "+") { currentOperation = "p"; } else if (operatorStack.Count > 0) { string lastOperation = operatorStack.Peek(); // If parenthesis flag is set avoid false unary operation detection if (!afterOpenParenthesis) { // check for negation direct after a '(' or after another operator. if ((IsOperator(lastOperation) || lastOperation == "(") && currentOperation == "-" && lastOperation != "p" && lastOperation != "m" && !IsDigit(lastToken)) { currentOperation = "m"; } // check for plus sign direct after a '(' or after another operator. if ((IsOperator(lastOperation) || lastOperation == "(") && currentOperation == "+" && lastOperation != "p" && lastOperation != "m" && !IsDigit(lastToken)) { currentOperation = "p"; } } //while there is an operator token, lastOperation while (IsOperator(lastOperation)) { // Check precedence of operators if (IsLeftAssociative(currentOperation) && LessOrEqualPrecedence(currentOperation, lastOperation) || IsRightAssociative(currentOperation) && LessPrecedence(currentOperation, lastOperation)) { AddToOutput(operatorStack.Pop()); if (operatorStack.Count == 0) { break; } else { lastOperation = operatorStack.Peek(); } } else { break; } } } operatorStack.Push(currentOperation); // Reset parenthesis flag. afterOpenParenthesis = false; } lastToken = token; token = tokenizer.GetNextToken(); first = false; } // If there are still operator tokens in the stack: while (operatorStack.Count > 0) { // Pop the operator onto the output queue. AddToOutput(operatorStack.Pop()); } return(CreateOutput(output)); }
public InfixToPostfixConverter(TokenizerInterface tokenizer) { myTokenizer = tokenizer; }