Skip to content

Instantly share code, notes, and snippets.

@duangsuse
Created February 2, 2021 14:13
Show Gist options
  • Save duangsuse/0e13cf4d45158345c08c9d94144a4d5a to your computer and use it in GitHub Desktop.
Save duangsuse/0e13cf4d45158345c08c9d94144a4d5a to your computer and use it in GitHub Desktop.
//src/main/kotlin/main.kt
import parser4k.*
import parser4k.commonparsers.token
import java.io.BufferedReader
import java.io.InputStreamReader
import java.math.BigDecimal
import kotlin.reflect.KProperty
abstract class CacheContainer<T>(val cache: OutputCache<T> = OutputCache())
object MinimalCalculator: CacheContainer<BigDecimal>() {
fun binaryExpr(s: String) = inOrder(ref { expr }, token(s), ref { expr })
val number by cache { oneOrMore(oneOf('0'..'9')).map { it.joinToString("").toBigDecimal() } }
val paren by cache { inOrder(token("("), ref { expr }, token(")")).skipWrapper() }
val power by cache { binaryExpr("^").map { (l, _, r) -> l.pow(r.toInt()) } }
val divide by cache { binaryExpr("/").mapLeftAssoc { (l, _, r) -> l.divide(r) } }
val multiply by cache { binaryExpr("*").mapLeftAssoc { (l, _, r) -> l * r } }
val minus by cache { binaryExpr("-").mapLeftAssoc { (l, _, r) -> l - r } }
val plus by cache { binaryExpr("+").mapLeftAssoc { (l, _, r) -> l + r } }
val expr: Parser<BigDecimal> = oneOfWithPrecedence(
oneOf(plus, minus),
oneOf(multiply, divide),
power,
paren.nestedPrecedence(),
number
).reset(cache)
fun evaluate(s: String) = s.parseWith(expr)
}
operator fun <T> OutputCache<T>.invoke(get_p: () -> Parser<T>) = OutputCacheBy(get_p())
class OutputCacheBy<T>(private val p: Parser<T>) {
operator fun getValue(self: CacheContainer<T>, _p: KProperty<*>) = p.with(self.cache)
}
fun main(args: Array<String>) {
val lr = BufferedReader(InputStreamReader(System.`in`))
fun ps1() = print(">")
ps1()
while (true) {
val ln = lr.readLine()
if (ln.isNullOrBlank()) break
println(MinimalCalculator.evaluate(ln)); ps1()
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>consoleApp</artifactId>
<groupId>me.duangsuse</groupId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>consoleApp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.code.style>official</kotlin.code.style>
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
</properties>
<repositories>
<repository>
<id>mavenCentral</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>1.4.10</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<mainClass>MainKt</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit</artifactId>
<version>1.4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>dev.forkhandles</groupId>
<artifactId>forkhandles-bom</artifactId>
<version>1.8.1.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>dev.forkhandles</groupId>
<artifactId>parser4k</artifactId>
<version>1.8.1.0</version>
</dependency>
</dependencies>
</project>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"
xmlns="http://maven.apache.org/SETTINGS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>bintray-fork-handles-maven</id>
<name>bintray</name>
<url>https://dl.bintray.com/fork-handles/maven</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>bintray-fork-handles-maven</id>
<name>bintray-plugins</name>
<url>https://dl.bintray.com/fork-handles/maven</url>
</pluginRepository>
</pluginRepositories>
<id>bintray</id>
</profile>
</profiles>
<activeProfiles>
<activeProfile>bintray</activeProfile>
</activeProfiles>
</settings>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment