Skip to content

Commit

Permalink
Merge pull request #2 from 7hens/v0.2
Browse files Browse the repository at this point in the history
V0.2
  • Loading branch information
7hens authored Sep 25, 2022
2 parents 1102181 + 032c42d commit 3c00cfd
Show file tree
Hide file tree
Showing 121 changed files with 2,693 additions and 2,092 deletions.
79 changes: 34 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,71 +10,60 @@ NOTE: grule is experimental yet.
## Sample - Json parser

```kotlin
class JsonRegLexerTest: Grule() {
val string by token(L / """(".*?")""")
val number by token(L / "\\d+(\\.\\d+)?")
val bool by token(L / "true|false")
val nil by token(L / "null")
class JsonRegMatcherTest : Grammar() {
val string by lexer { X / """(".*?")""" }
val number by lexer { X / "\\d+(\\.\\d+)?" }
val bool by lexer { X / "true|false" }
val nil by lexer { X / "null" }

init {
token(L - "{}[]:,")
skip(L + L_space or L_wrap)
lexer.token { X - "{}[]:," }
lexer.skip { SPACE or WRAP }
}

val jObject: Parser by p { jString or jNumber or jBool or jNil or jArray or jDict }
val jString by P + string
val jNumber by P + number
val jBool by P + bool
val jNil by P + nil
val jArray by P + "[" + jObject.join(P + ",") + "]"
val jPair by P + jString + ":" + jObject
val jDict by P + "{" + jPair.join(P + ",") + "}"
val jObject: Parser by parser { jString or jNumber or jBool or jNil or jArray or jDict }
val jString by parser { X + string }
val jNumber by parser { X + number }
val jBool by parser { X + bool }
val jNil by parser { X + nil }
val jArray by parser { X + "[" + jObject.join(X + ",") + "]" }
val jPair by parser { X + jString + ":" + jObject }
val jDict by parser { X + "{" + jPair.join(X + ",") + "}" }

@Test
fun json() {
val source = """{ "a": [1, 2.34], "b": "hello" }"""
println(source)
println("-----------------")

val astNode = parse(jObject, source)
val astNode = jObject.parse(tokenStream(source))
println(astNode.toStringTree())
}
}

```

Output

```plain
{ "a": [1, 2.34], "b": "hello" }
-----------------
jObject
└─ jDict
├─ ({)
├─ jPair
│ ├─ jString
│ │ └─ string ("a")
│ ├─ (:)
│ └─ jObject
│ └─ jArray
│ ├─ ([)
│ ├─ jObject
│ │ └─ jInteger
│ │ └─ integer (1)
│ ├─ (,)
│ ├─ jObject
│ │ └─ jFloat
│ │ └─ float (2.34)
│ └─ (])
├─ (,)
├─ jPair
│ ├─ jString
│ │ └─ string ("b")
│ ├─ (:)
│ └─ jObject
│ └─ jString
│ └─ string ("hello")
└─ (})
jObject/jDict
├─ {
├─ jPair
│ ├─ jString/string("a")
│ ├─ :
│ └─ jObject/jArray
│ ├─ [
│ ├─ jObject/jNumber/number(1)
│ ├─ ,
│ ├─ jObject/jNumber/number(2.34)
│ └─ ]
├─ ,
├─ jPair
│ ├─ jString/string("b")
│ ├─ :
│ └─ jObject/jString/string("hello")
└─ }
```

## Setting up the dependency
Expand All @@ -91,6 +80,6 @@ allprojects {

```kotlin
dependencies {
implementation("com.github.7hens.grule:grule:0.1")
implementation("com.github.7hens.grule:grule:0.2")
}
```
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ group = "com.github.7hens.grule"
version = "-SNAPSHOT"

repositories {
mavenLocal()
mavenCentral()
maven("https://maven.aliyun.com/repository/public")
maven("https://jitpack.io")
mavenCentral()
mavenLocal()
}

kotlin {
Expand Down
5 changes: 5 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Grule

## Matcher

![matcher.svg](matcher.svg)
3 changes: 3 additions & 0 deletions docs/matcher.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
10 changes: 5 additions & 5 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Empty file modified gradlew
100644 → 100755
Empty file.
37 changes: 0 additions & 37 deletions src/commonMain/kotlin/io/grule/CompositeException.kt

This file was deleted.

22 changes: 22 additions & 0 deletions src/commonMain/kotlin/io/grule/Grammar.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.grule

import io.grule.lexer.Lexer
import io.grule.lexer.LexerContext
import io.grule.parser.Parser

@Suppress("MemberVisibilityCanBePrivate")
open class Grammar : Lexer {
val lexer = Lexer.factory()
val parser = Parser.factory()

override fun lex(context: LexerContext) {
return lexer.lex(context)
}

companion object {
inline operator fun <T> invoke(crossinline fn: Grammar.() -> T): T {
return fn(Grammar())
}
}
}

51 changes: 0 additions & 51 deletions src/commonMain/kotlin/io/grule/Grule.kt

This file was deleted.

23 changes: 0 additions & 23 deletions src/commonMain/kotlin/io/grule/lexer/CharStream.kt

This file was deleted.

108 changes: 33 additions & 75 deletions src/commonMain/kotlin/io/grule/lexer/Lexer.kt
Original file line number Diff line number Diff line change
@@ -1,75 +1,33 @@
package io.grule.lexer

abstract class Lexer {
abstract fun match(charStream: CharStream, offset: Int = 0): Int

open fun not(): Lexer {
return LexerNot(this)
}

open operator fun plus(lexer: Lexer): Lexer {
return LexerPlus(mutableListOf(this, lexer))
}

operator fun plus(text: String): Lexer {
return plus(LexerString(text))
}

operator fun plus(char: Char): Lexer {
return minus(listOf(char))
}

operator fun minus(charSet: Iterable<Char>): Lexer {
return plus(LexerCharSet(charSet))
}

operator fun minus(charArray: CharArray): Lexer {
return minus(charArray.toList())
}

operator fun minus(text: String): Lexer {
return minus(text.toList())
}

operator fun div(text: String): Lexer {
return plus(LexerRegex(text))
}

open infix fun or(lexer: Lexer): Lexer {
return LexerOr(mutableListOf(this, lexer))
}

open fun repeat(minTimes: Int = 0, maxTimes: Int = Int.MAX_VALUE): Lexer {
return LexerRepeat(this, minTimes, maxTimes)
}

fun join(separator: Lexer, minTimes: Int = 0, maxTimes: Int = Int.MAX_VALUE): Lexer {
val min = maxOf(minTimes - 1, 0)
val max = maxOf(maxTimes - 1, 0)
return (LexerBuilder() + this + separator).untilGreedy(this, min, max)
}

fun optional(): Lexer {
return repeat(0, 1)
}

fun interlace(separator: Lexer): Lexer {
return LexerBuilder() + separator.optional() + join(separator) + separator.optional()
}

fun untilGreedy(terminal: Lexer, minTimes: Int = 0, maxTimes: Int = Int.MAX_VALUE): Lexer {
return LexerUntilGreedy(this, terminal, minTimes, maxTimes)
}

fun untilNonGreedy(terminal: Lexer, minTimes: Int = 0, maxTimes: Int = Int.MAX_VALUE): Lexer {
return LexerUntilNonGreedy(this, terminal, minTimes, maxTimes)
}

fun test(): Lexer {
return LexerTest(this)
}

companion object {
val EOF: Lexer = LexerEOF
}
}
package io.grule.lexer

import io.grule.node.KeyOwner
import io.grule.token.CharStream
import io.grule.token.TokenStream
import io.grule.token.TokenStreamImpl

@Suppress("MemberVisibilityCanBePrivate")
interface Lexer : LexerMatcherExt, KeyOwner {
override val key: Any get() = this

fun lex(context: LexerContext)

fun tokenStream(charStream: CharStream): TokenStream {
return TokenStreamImpl(charStream, this)
}

fun tokenStream(text: String): TokenStream {
return tokenStream(CharStream.fromString(text))
}

companion object {
val EOF: Lexer = LexerEOF

fun indent(newLine: Lexer, indent: Lexer, dedent: Lexer): Lexer {
return LexerIndent(newLine, indent, dedent)
}

fun factory(): LexerFactory {
return LexerFactory()
}
}
}
Loading

0 comments on commit 3c00cfd

Please sign in to comment.