Beispiel #1
0
func convert2postfix(tokens []string) []string {
	var stack util.Stack
	var result []string
	for _, token := range tokens {
		if isOperator(token) {
		OPERATOR:
			for {
				top, err := stack.Top()
				if err != nil || top == "(" {
					break OPERATOR
				}
				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 == ")" {
		CLOSE_PAREN:
			for {
				top, err := stack.Top()
				if err != nil || top == "(" {
					stack.Pop() // pop off "("
					break CLOSE_PAREN
				} else {
					pop, _ := stack.Pop()
					result = append(result, pop.(string))
				}
			}
		} 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 evaluatePostfix(postfix []string) (Serie, error) {
	// log.Println("postifx", postfix)
	var stack util.Stack
	for _, token := range postfix {
		if isOperand(token) {
			gd, err := scanGd(token)
			if err != nil {
				return Serie{}, err
			}
			stack.Push(Serie{Q: Poly{gd}})
		} else if isOperator(token) {
			pop2 := func() (s1, s2 Serie, err error) {
				op2, err := stack.Pop()
				if err != nil {
					return Serie{}, Serie{}, err
				}
				op1, err := stack.Pop()
				if err != nil {
					return Serie{}, Serie{}, err
				}
				return op1.(Serie), op2.(Serie), nil
			}
			pop1 := func() (s Serie, err error) {
				op, err := stack.Pop()
				if err != nil {
					return Serie{}, err
				}
				return op.(Serie), nil
			}

			switch token {
			case "*":
				s, err := pop1()
				if err != nil {
					return Serie{}, err
				}
				// log.Printf("Starring %#v", s)
				stack.Push(SerieStar(s))
			case "x":
				s1, s2, err := pop2()
				if err != nil {
					return Serie{}, err
				}
				// log.Printf("OTIMES series %#v AND %#v", s2, s1)
				// not commutative! reverse order (postfix -> infix)
				stack.Push(SerieOtimes(s2, s1))
			case "+":
				s1, s2, err := pop2()
				if err != nil {
					return Serie{}, err
				}
				// log.Printf("OPLUS series %#v AND %#v", s1, s2)
				stack.Push(SerieOplus(s1, s2))
			default:
				return Serie{}, fmt.Errorf("unknown operator %v", token)
			}
		} else {
			return Serie{}, fmt.Errorf("unknown token %v", token)
		}
	}

	// log.Println("Dumping stack\n", stack.Dump())
	tmp, err := stack.Pop()
	if err != nil {
		return Serie{}, err
	}
	if result, ok := tmp.(Serie); !ok {
		return Serie{}, fmt.Errorf("result is not a valid serie")
	} else {
		return result, nil
	}
}