Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/eratio08/kpars
Very simple parser combinator library in Kotlin
https://github.com/eratio08/kpars
applicative functional-parsing kotlin monad monadic-parser-combinators parser parser-combinators parsing
Last synced: about 1 month ago
JSON representation
Very simple parser combinator library in Kotlin
- Host: GitHub
- URL: https://github.com/eratio08/kpars
- Owner: eratio08
- Created: 2024-04-06T22:01:02.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2024-04-08T15:59:53.000Z (9 months ago)
- Last Synced: 2024-04-08T23:24:44.140Z (9 months ago)
- Topics: applicative, functional-parsing, kotlin, monad, monadic-parser-combinators, parser, parser-combinators, parsing
- Language: Kotlin
- Homepage:
- Size: 72.3 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Parser Combinator in Kotlin
A very simple [parser combinator](https://www.cs.nott.ac.uk/~pszgmh/pearl.pdf) library implementation in Kotlin.
## Example
The following grammar
```
expr ::= expr addop term | term
term ::= term mulop factor | factor
factor ::= digit | ( expr )
digit ::= 0 | 1 | . . . | 9
addop ::= + | -
mulop ::= * | /
```Can be parsed and evaluated like this
```kotlin
// Parsers
fun add(a: Int, b: Int): Int = a + b
fun sub(a: Int, b: Int): Int = a - b
val addOp: Parser<(Int, Int) -> Int> =
(symbol("+") keepRight return_(::add)) or (symbol("-") keepRight return_(::sub))
fun mul(a: Int, b: Int): Int = a * b
fun div(a: Int, b: Int): Int = a / b
val mulOp: Parser<(Int, Int) -> Int> =
(symbol("*") keepRight return_(::mul)) or (symbol("/") keepRight return_(::div))
fun isDigit(c: Char): Boolean = when (c) {
in '0'..'9' -> true
else -> false
}
val digit = token(satisfies(::isDigit)) flatMap { x -> return_(x.code - '0'.code) }
fun expr(): Parser {
val factor = digit or (symbol("(") flatMap { _ -> expr() keepLeft symbol(")") })
val term = chainL1(factor, mulOp)
return chainL1(term, addOp)
}
// Evaluation
val res = apply(expr())("1 + 3 * 3").firstOrNull()?.first
// -> 10
```