diff -r 44161f2c3226 -r 3020f8c76baa templates4/postfix.scala --- a/templates4/postfix.scala Wed Nov 28 17:13:40 2018 +0000 +++ b/templates4/postfix.scala Wed Nov 28 23:26:47 2018 +0000 @@ -3,10 +3,10 @@ // ======================== - +// type of tokens type Toks = List[String] -// the operations in the simple version +// the operations in the basic version of the algorithm val ops = List("+", "-", "*", "/") // the precedences of the operators @@ -21,39 +21,25 @@ // (6) Implement below the shunting yard algorithm. The most // convenient way to this in Scala is to implement a recursive -// function using pattern matching. The function takes some input -// tokens as first argument. The second and third arguments represent -// the stack and the output or the shunting yard algorithm. +// function and to heavily use pattern matching. The function syard +// takes some input tokens as first argument. The second and third +// arguments represent the stack and the output of the shunting yard +// algorithm. // // In the marking, you can assume the function is called only with -// an empty stack and empty output list. You can also assume the -// input are only properly formated (infix) arithmetic expressions -// (for example all parentheses are well-nested, the input only contains +// an empty stack and an empty output list. You can also assume the +// input os only properly formatted (infix) arithmetic expressions +// (all parentheses will be well-nested, the input only contains // operators and numbers). -// You can implement any helper function you need. I found it helpful -// to implement auxiliary functions: - -def is_op(op: String) : Boolean = ops.contains(op) - -def prec(op1: String, op2: String) : Boolean = precs(op1) <= precs(op2) +// You can implement any additional helper function you need. I found +// it helpful to implement two auxiliary functions for the pattern matching: +// +// def is_op(op: String) : Boolean = ... +// def prec(op1: String, op2: String) : Boolean = ... -def syard(toks: Toks, st: Toks = Nil, out: Toks = Nil) : Toks = (toks, st, out) match { - case (Nil, _, _) => out.reverse ::: st - case (num::in, st, out) if (num.forall(_.isDigit)) => - syard(in, st, num :: out) - case (op1::in, op2::st, out) if (is_op(op1) && is_op(op2) && prec(op1, op2)) => - syard(op1::in, st, op2 :: out) - case (op1::in, st, out) if (is_op(op1)) => syard(in, op1::st, out) - case ("("::in, st, out) => syard(in, "("::st, out) - case (")"::in, op2::st, out) => - if (op2 == "(") syard(in, st, out) else syard(")"::in, st, op2 :: out) - case (in, st, out) => { - println(s"in: ${in} st: ${st} out: ${out.reverse}") - Nil - } -} +// def syard(toks: Toks, st: Toks = Nil, out: Toks = Nil) : Toks = ... // test cases @@ -71,23 +57,14 @@ // (7) Implement a compute function that evaluates an input list -// in postfix notation. This function takes an input list of tokens -// and a stack as argument. The function should produce the -// result in form of an integer using the stack. You can assume -// this function will be only called with proper postfix expressions. +// in postfix notation. This function takes a list of tokens +// and a stack as argumenta. The function should produce the +// result as an integer using the stack. You can assume +// this function will be only called with proper postfix +// expressions. -def op_comp(s: String, n1: Int, n2: Int) = s match { - case "+" => n2 + n1 - case "-" => n2 - n1 - case "*" => n2 * n1 - case "/" => n2 / n1 -} +// def compute(toks: Toks, st: List[Int] = Nil) : Int = ... -def compute(toks: Toks, st: List[Int] = Nil) : Int = (toks, st) match { - case (Nil, st) => st.head - case (op::in, n1::n2::st) if (is_op(op)) => compute(in, op_comp(op, n1, n2)::st) - case (num::in, st) => compute(in, num.toInt::st) -} // test cases // compute(syard(split("3 + 4 * ( 2 - 1 )"))) // 7