Beispiel #1
0
// convert2postfix converts an infix expression to postfix
func convert2postfix(tokens []string) []string {
	var stack stack.Stack
	var result []string
	for _, token := range tokens {

		if isOperator(token) {

		OPERATOR:
			for {
				top, err := stack.Top()
				if err == nil && top != "(" {
					if opGTE(top.(string), token) {
						pop, _ := stack.Pop()
						result = append(result, pop.(string))
					} else {
						break OPERATOR
					}
				}
				break OPERATOR
			}
			stack.Push(token)

		} else if token == "(" {
			stack.Push(token)

		} else if token == ")" {
		PAREN:
			for {
				top, err := stack.Top()
				if err == nil && top != "(" {
					pop, _ := stack.Pop()
					result = append(result, pop.(string))
				} else {
					stack.Pop() // pop off "("
					break PAREN
				}
			}

		} else if isOperand(token) {
			result = append(result, token)
		}

	}

	for !stack.IsEmpty() {
		pop, _ := stack.Pop()
		result = append(result, pop.(string))
	}

	return result
}
Beispiel #2
0
func TestStack(t *testing.T) {
	count := 1
	var aStack stack.Stack
	assertTrue(t, aStack.Len() == 0, "expected empty Stack", count) // 1
	count++
	assertTrue(t, aStack.Cap() == 0, "expected empty Stack", count) // 2
	count++
	assertTrue(t, aStack.IsEmpty(), "expected empty Stack", count) // 3
	count++
	value, err := aStack.Pop()
	assertTrue(t, value == nil, "expected nil value", count) // 4
	count++
	assertTrue(t, err != nil, "expected error", count) // 5
	count++
	value1, err := aStack.Top()
	assertTrue(t, value1 == nil, "expected nil value", count) // 6
	count++
	assertTrue(t, err != nil, "expected error", count) // 7
	count++
	aStack.Push(1)
	aStack.Push(2)
	aStack.Push("three")
	assertTrue(t, aStack.Len() == 3, "expected nonempty Stack", count) // 8
	count++
	assertTrue(t, aStack.IsEmpty() == false, "expected nonempty Stack",
		count) // 9
	count++
	value2, err := aStack.Pop()
	assertEqualString(t, value2.(string), "three", "unexpected text",
		count) // 10
	count++
	assertTrue(t, err == nil, "no error expected", count) // 11
	count++
	value3, err := aStack.Top()
	assertTrue(t, value3 == 2, "unexpected number", count) // 12
	count++
	assertTrue(t, err == nil, "no error expected", count) // 13
	count++
	aStack.Pop()
	assertTrue(t, aStack.Len() == 1, "expected nonempty Stack", count) //14
	count++
	assertTrue(t, aStack.IsEmpty() == false, "expected nonempty Stack",
		count) // 15
	count++
	value4, err := aStack.Pop()
	assertTrue(t, value4 == 1, "unexpected number", count) // 16
	count++
	assertTrue(t, err == nil, "no error expected", count) // 17
	count++
	assertTrue(t, aStack.Len() == 0, "expected empty Stack", count) // 18
	count++
	assertTrue(t, aStack.IsEmpty(), "expected empty Stack", count) // 19
	count++
}
Beispiel #3
0
// evaluatePostfix takes a postfix expression and evaluates it
func evaluatePostfix(postfix []string) (*big.Rat, error) {
	var stack stack.Stack
	result := new(big.Rat) // note: a new(big.Rat) has value "0/1" ie zero
	for _, token := range postfix {
		if isOperand(token) {
			bigrat := new(big.Rat)
			if _, err := fmt.Sscan(token, bigrat); err != nil {
				return nil, fmt.Errorf("unable to scan %s", token)
			}
			stack.Push(bigrat)
		} else if isOperator(token) {

			op2, err2 := stack.Pop()
			if err2 != nil {
				return nil, err2
			}

			var op1 interface{}
			if token != "@" {
				var err1 error
				if op1, err1 = stack.Pop(); err1 != nil {
					return nil, err1
				}
			}

			dummy := new(big.Rat)
			switch token {
			case "**":
				float1 := BigratToFloat(op1.(*big.Rat))
				float2 := BigratToFloat(op2.(*big.Rat))
				float_result := math.Pow(float1, float2)
				stack.Push(FloatToBigrat(float_result))
			case "*":
				result := dummy.Mul(op1.(*big.Rat), op2.(*big.Rat))
				stack.Push(result)
			case "/":
				result := dummy.Quo(op1.(*big.Rat), op2.(*big.Rat))
				stack.Push(result)
			case "+":
				result = dummy.Add(op1.(*big.Rat), op2.(*big.Rat))
				stack.Push(result)
			case "-":
				result = dummy.Sub(op1.(*big.Rat), op2.(*big.Rat))
				stack.Push(result)
			case "<":
				if op1.(*big.Rat).Cmp(op2.(*big.Rat)) <= -1 {
					stack.Push(big.NewRat(1, 1))
				} else {
					stack.Push(new(big.Rat))
				}
			case ">":
				if op1.(*big.Rat).Cmp(op2.(*big.Rat)) >= 1 {
					stack.Push(big.NewRat(1, 1))
				} else {
					stack.Push(new(big.Rat))
				}

			case "==":
				if op1.(*big.Rat).Cmp(op2.(*big.Rat)) == 0 {
					stack.Push(big.NewRat(1, 1))
				} else {
					stack.Push(new(big.Rat))
				}
			case ">=":
				if op1.(*big.Rat).Cmp(op2.(*big.Rat)) >= 0 {
					stack.Push(big.NewRat(1, 1))
				} else {
					stack.Push(new(big.Rat))
				}
			case "<=":
				if op1.(*big.Rat).Cmp(op2.(*big.Rat)) <= 0 {
					stack.Push(big.NewRat(1, 1))
				} else {
					stack.Push(new(big.Rat))
				}
			case "&&":
				tmp_false := big.NewRat(0, 1)
				if op1.(*big.Rat).Cmp(tmp_false) != 0 && op2.(*big.Rat).Cmp(tmp_false) != 0 {
					stack.Push(big.NewRat(1, 1))
				} else {
					stack.Push(tmp_false)
				}

			case "||":
				tmp_false := big.NewRat(0, 1)
				if op1.(*big.Rat).Cmp(tmp_false) != 0 || op2.(*big.Rat).Cmp(tmp_false) != 0 {
					stack.Push(big.NewRat(1, 1))
				} else {
					stack.Push(tmp_false)
				}

			case "@":
				result := dummy.Mul(big.NewRat(-1, 1), op2.(*big.Rat))
				stack.Push(result)
			}
		} else {
			return nil, fmt.Errorf("unknown token %v", token)
		}
	}

	retval, err := stack.Pop()
	if err != nil {
		return nil, err
	}
	return retval.(*big.Rat), nil
}