Created
May 8, 2022 09:17
-
-
Save avgprog/4f403c92f0e69141e360d358e84c69c8 to your computer and use it in GitHub Desktop.
Sample scala code for parsing user-defined expressions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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