An open API service indexing awesome lists of open source software.

https://github.com/notjustanna/tartar

Kotlin lexical analysis and pratt-parsing as a DSL
https://github.com/notjustanna/tartar

Last synced: 11 months ago
JSON representation

Kotlin lexical analysis and pratt-parsing as a DSL

Awesome Lists containing this project

README

          

# tartar

[![Maven metadata URL](https://img.shields.io/github/v/release/notjustanna/tartar?sort=semver)](https://maven.cafeteria.dev/releases/net/notjustanna/tartar)
[![GitHub issues](https://img.shields.io/github/issues/notjustanna/tartar)](https://github.com/notjustanna/tartar/issues)
[![License](https://img.shields.io/github/license/notjustanna/tartar)](https://github.com/notjustanna/tartar/tree/master/LICENSE)
[![Twitter](https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Fgithub.com%2Fnotjustanna%2Ftartar)](https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2Fnotjustanna%2Ftartar)

Kotlin trie-based lexical analysis and pratt-parsing as a DSL.

### Installation

Using in Gradle:

```gradle
repositories {
maven { url = 'https://maven.cafeteria.dev' }
}

dependencies {
implementation 'net.notjustanna:tartar:VERSION'
}
```

Using in Maven:

```xml


cafeteria
cafeteria
https://maven.cafeteria.dev

net.notjustanna
tartar
VERSION

```

### Usage

To create a lexer (also called a tokenizer) use `createLexer { ... }`, which exposes an interface to configure and add
matchers to the lexer.

To create a grammar use `createGrammar { ... }`, which exposes an interface to create and add prefix parsers and infix
parsers to the grammar.

To create a parser use `createParser(grammar) { ... }`, which will run the block of code on `parser.parse()`.

#### Example code

```kotlin
// Create a lexer as simple as a method call.
val lexer = Lexer.create> {
// Implement a token type per line.
'+' { processToken(PLUS) }
// Built-in extension functions.
'"' { processToken(STRING, readString(it), offset = 2) }
// NOOP tokens.
' '()
'\n'()
}

// Create a pratt-parser grammar. Dead simple.
val grammar = Grammar.create {
// Create a prefix parselet as a lambda function.
prefix(STRING) { token -> token.value }
// Create an infix parselet, with support to precedence as a lambda function.
infix(PLUS, 1) { left, _ -> left + parseExpression() }
}

// Use your grammar to create a pratt-parser.
val parser = SourceParser.create(lexer, grammar) { // Actual code run by the parser.
// Extension function: Throws if there's still tokens.
ensureEOF {
// Parses a expression using this parsers' grammar.
parseExpression()
}
}

// One line of code to rule them all.
val result = parser.parse(Source.classpath { "input.str" })
println(result)
```

See the full code [here](https://github.com/notjustanna/tartar/blob/master/src/test/java/examples/StringJoiner.kt),
as well as other examples [here](https://github.com/notjustanna/tartar/tree/master/src/test/java/examples).

### Special thanks

Special thanks to [Avarel](https://github.com/Avarel), this library wouldn't be possible
without his help, feedback and source code of [Lobos](https://github.com/Avarel/Lobos)
and [Kaiper](https://github.com/Avarel/Kaiper).