Skip to content

Instantly share code, notes, and snippets.

@avgprog
Created May 8, 2022 09:17
Show Gist options
  • Save avgprog/4f403c92f0e69141e360d358e84c69c8 to your computer and use it in GitHub Desktop.
Save avgprog/4f403c92f0e69141e360d358e84c69c8 to your computer and use it in GitHub Desktop.
Sample scala code for parsing user-defined expressions
/*
Description: Parses expressions with two user-defined functions ("Max","Sum") and one operator ("+") acting upon three lists:
"l1", "l2", "l3"
Sample expression which can be parsed by this program:
Sum(Max(l1,l2),l3)+Max(l1,Sum(l1,l2)+l3)
To know more or to create your own parsers, visit:
http://www.artima.com/pins1ed/combinator-parsing.html
*/
import scala.util.parsing.combinator._
class ExpressionParser extends JavaTokenParsers {
//Helper functions
val m = Map("l1" -> List(1, 2, 3), "l2" -> List(2, 1, 4), "l3" -> List(5, 4, 1))
def addColumns(x: List[Int], y: List[Int]): List[Int] = (x, y).zipped.map(_ + _)
def maxColumns(x: List[Int], y: List[Int]): List[Int] = (x, y).zipped.map((a, b) => if (a > b) a else b)
//Parsers
def expr: Parser[List[Int]] =
sum ^^ { case x => (List.fill(3)(0) /: x) ((a, b) => addColumns(a, b)) }
def term: Parser[List[Int]] =
"Sum(" ~> comma <~ ")" ^^ { case x => (List.fill(3)(0) /: x) ((a, b) => addColumns(a, b)) } |
"Max(" ~> comma <~ ")" ^^ { case x => (List.fill(3)(0) /: x) ((a, b) => maxColumns(a, b)) } |
identifier
def comma: Parser[List[List[Int]]] = repsep(expr, ",")
def sum: Parser[List[List[Int]]] = repsep(term, "+")
def identifier: Parser[List[Int]] = ident ^^ {
m(_)
}
}
object MyParser extends ExpressionParser {
def calculator(expr: Parser[Any], input: String) = {
parseAll(expr, input) match {
case Success(result, _) => Some(result)
case NoSuccess(_, _) => None
}
}
def main(args: Array[String]) {
while (true) {
val input = scala.io.StdIn.readLine()
println(calculator(expr, input).get)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment