CS 152 - Lecture 10

Cover page image

Cay S. Horstmann

Reminder: Context-Free Grammar

Reminder: Scala Combinator Parser

Transforming Combinator Parser Results

Returning Expression Trees

A Grammar Problem

Remedy: Manually Group Terms

Use foldLeft

Lab

???

Step 1

Complete the program from slides 3 and 4.

import java.io._
import scala.util.parsing.combinator._

class SimpleLanguageParser1 extends JavaTokenParsers {    
  def expr: Parser[Int] = (term ~ opt(("+" | "-") ~ expr)) ^^ { 
    case a ~ None => a
    case a ~ Some("+" ~ b) => a + b
    case a ~ Some("-" ~ b) => a - b
    } 
  . . .
  def factor: Parser[Int] = wholeNumber ^^ (_.toInt) | "(" ~> expr <~ ")"
}

object Main extends App {
  val parser = new SimpleLanguageParser1
  val result = parser.parse(parser.expr, new InputStreamReader(System.in))
  println(result)       
}
  1. How did you complete the parser?
  2. What result do you get when you input 3 + 4 * 5?
  3. On your platform, how did you have to indicate the end of console input? (I had to type Ctrl+D in Linux.)
  4. Why isn't the output a tree?

Step 2

Complete the program from Slide 5.

import java.io._
import scala.util.parsing.combinator._

class Expr
case class Number(value : Int) extends Expr
case class Variable(name : String) extends Expr
case class Operator(left : Expr, right : Expr, 
  f: (Int, Int) => Int) extends Expr

class SimpleLanguageParser2 extends JavaTokenParsers {    
  def expr: Parser[Expr] = (term ~ opt(("+" | "-") ~ expr)) ^^ { 
    case a ~ None => a
    case a ~ Some("+" ~ b) => Operator(a, b, _ + _)
    case a ~ Some("-" ~ b) => Operator(a, b, _ - _)
    } 
  ...
}

object Main {
  def main(args : Array[String]) : Unit = {}
  val parser = new SimpleLanguageParser
  val result = parser.parse(parser.expr, new InputStreamReader(System.in))
  println(result)       
}

NOTE: Unfortunately, (Number(_.toInt)) doesn't work. Use (x => Number(x.toInt))

  1. How did you complete the code?
  2. What did you get when you parsed 3 + 4 * 5?
  3. What did you get when you parsed 3 - 4 - 5?
  4. What happens when you flip expr and term in the right hand side of the first production? Try parsing 3 - 4 - 5 again.

Step 3

Complete the program from slide 8:

import java.io._
import scala.util.parsing.combinator._

class Expr
...

class SimpleLanguageParser3 extends JavaTokenParsers {    
  def expr: Parser[Expr] = (term ~ rep(("+" | "-") ~ term)) ^^ { 
      case a ~ lst =>  (a /: lst) { 
        case (x, "+" ~ y) => Operator(x, y, _ + _)
        case (x, "-" ~ y) => Operator(x, y, _ - _)
      }
    } 
  ...
}

object Main extends App {
   ...
}
  1. How did you complete the program?
  2. What did you get when you parsed 3 - 4 - 5?
  3. We never did anything about Variable. How can you enhance your program to parse them as well, e.g. 3 - 4 * x?