Skip to content

Commit 94931a9

Browse files
feat: added operators and separators in lexer dsl
1 parent 94d4c64 commit 94931a9

File tree

16 files changed

+312
-13
lines changed

16 files changed

+312
-13
lines changed

core/src/main/kotlin/io/github/cybercodernaj/parkour/lexer/LexerBuilder.kt

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ class LexerBuilder internal constructor() {
2626
private val _hardKeywords: MutableList<String> = mutableListOf()
2727
internal val hardKeywords: List<String> get() = _hardKeywords
2828

29+
private val _separators: MutableList<String> = mutableListOf()
30+
internal val separators: List<String> get() = _separators
31+
32+
private val _operators: MutableList<String> = mutableListOf()
33+
internal val operators: List<String> get() = _operators
34+
2935
/**
3036
* The lexer will skip over any strings that match this regex.
3137
* This acts like a token separator.
@@ -138,6 +144,44 @@ class LexerBuilder internal constructor() {
138144
fun hardKeywords(vararg keywords: String) {
139145
this._hardKeywords.addAll(keywords)
140146
}
147+
148+
/**
149+
* Separators are characters and symbols that act like delimiters to separate other meaningful elements. (Default: [])
150+
*
151+
* ### Usage
152+
*
153+
* ```kt
154+
* val myLexer = lexer {
155+
* separators(":", ",", "(", ")")
156+
* }
157+
* ```
158+
*
159+
* @param separators a variable number of separators
160+
* @author Nishant Aanjaney Jalan
161+
* @since 0.2.0
162+
*/
163+
fun separators(vararg separators: String) {
164+
this._separators.addAll(separators)
165+
}
166+
167+
/**
168+
* Operators are characters and symbols that may perform arithmetic or logical operations. (Default: [])
169+
*
170+
* ### Usage
171+
*
172+
* ```kt
173+
* val myLexer = lexer {
174+
* operators("+", "-", "||", "<=")
175+
* }
176+
* ```
177+
*
178+
* @param operators a variable number of operators
179+
* @author Nishant Aanjaney Jalan
180+
* @since 0.2.0
181+
*/
182+
fun operators(vararg operators: String) {
183+
this._operators.addAll(operators)
184+
}
141185
}
142186

143187
/**
@@ -167,6 +211,8 @@ fun lexer(init: LexerBuilder.() -> Unit): Lexer {
167211
singleLineComments = builder.singleLineComments,
168212
multilineComments = builder.multilineComments,
169213
identifiers = builder.identifiers,
170-
hardKeywords = builder.hardKeywords.sortedByDescending(String::length)
214+
hardKeywords = builder.hardKeywords.sortedByDescending(String::length),
215+
operators = builder.operators.sortedByDescending(String::length),
216+
separators = builder.separators.sortedByDescending(String::length),
171217
)
172218
}

core/src/main/kotlin/io/github/cybercodernaj/parkour/lexer/internal/Lexer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class Lexer internal constructor(
4949
private val multilineComments: Pair<Regex, Regex>? = Defaults.multilineComments,
5050
private val identifiers: Regex = Defaults.identifiers,
5151
private val hardKeywords: List<String> = emptyList(),
52-
private val operators: Set<String> = emptySet(),
53-
private val separators: Set<String> = emptySet(),
52+
private val operators: List<String> = emptyList(),
53+
private val separators: List<String> = emptyList(),
5454
private val integerLiteral: Regex? = Defaults.integerLiterals,
5555
private val floatingLiteral: Regex? = Defaults.floatingLiterals,
5656
private val singleLineString: Set<String> = Defaults.singleLineString,

core/src/test/kotlin/io/github/cybercodernaj/parkour/lexer/LexerBuilderTest.kt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,76 @@ class LexerBuilderTest {
9191
)
9292
)
9393
}
94+
95+
@Test
96+
fun `set separators`() {
97+
val myLexer = lexer {
98+
separators("(", ")", "<", ">", ",", ".")
99+
}
100+
101+
102+
myLexer.source = StringSource("Array<List<Set<Int>>>")
103+
104+
assertTokens(
105+
myLexer, listOf(
106+
Token.Identifier("Array", start = Position(0, 0), end = Position(0, 4)),
107+
Token.Separator("<", start = Position(0, 5), end = Position(0, 5)),
108+
Token.Identifier("List", start = Position(0, 6), end = Position(0, 9)),
109+
Token.Separator("<", start = Position(0, 10), end = Position(0, 10)),
110+
Token.Identifier("Set", start = Position(0, 11), end = Position(0, 13)),
111+
Token.Separator("<", start = Position(0, 14), end = Position(0, 14)),
112+
Token.Identifier("Int", start = Position(0, 15), end = Position(0, 17)),
113+
Token.Separator(">", start = Position(0, 18), end = Position(0, 18)),
114+
Token.Separator(">", start = Position(0, 19), end = Position(0, 19)),
115+
Token.Separator(">", start = Position(0, 20), end = Position(0, 20)),
116+
)
117+
)
118+
}
119+
120+
@Test
121+
fun `set operators`() {
122+
val myLexer = lexer {
123+
hardKeywords("val")
124+
operators("*", "**", "/", "//", "+", "-", "=", "==")
125+
}
126+
127+
myLexer.source = StringSource("val diff = new - old")
128+
129+
assertTokens(
130+
myLexer, listOf(
131+
Token.Keyword(
132+
value = "val",
133+
start = Position(0, 0),
134+
end = Position(0, 2),
135+
soft = false
136+
),
137+
Token.Identifier(
138+
value = "diff",
139+
start = Position(0, 4),
140+
end = Position(0, 7)
141+
),
142+
Token.Operator(
143+
value = "=",
144+
start = Position(0, 9),
145+
end = Position(0, 9)
146+
),
147+
Token.Identifier(
148+
value = "new",
149+
start = Position(0, 11),
150+
end = Position(0, 13)
151+
),
152+
Token.Operator(
153+
value = "-",
154+
start = Position(0, 15),
155+
end = Position(0, 15)
156+
),
157+
Token.Identifier(
158+
value = "old",
159+
start = Position(0, 17),
160+
end = Position(0, 19)
161+
)
162+
)
163+
)
164+
}
94165
}
95166

core/src/test/kotlin/io/github/cybercodernaj/parkour/lexer/internal/LexerLiteralTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import kotlin.test.fail
1111
class LexerLiteralTest {
1212
private val lexer = Lexer(
1313
hardKeywords = listOf("char"),
14-
operators = setOf("="),
14+
operators = listOf("="),
1515
escapeSequences = listOf(
1616
Regex("""\\f""") to { _ -> 'f' },
1717
Regex("""\\n""") to { _ -> '\n' },

core/src/test/kotlin/io/github/cybercodernaj/parkour/lexer/internal/LexerOperatorTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test
88
class LexerOperatorTest {
99
private val lexer = Lexer(
1010
hardKeywords = listOf("val", "var"),
11-
operators = setOf("*", "**", "/", "//", "+", "-", "=", "==")
11+
operators = listOf("**", "*", "//", "==", "/", "+", "-", "=")
1212
)
1313

1414
@Test

core/src/test/kotlin/io/github/cybercodernaj/parkour/lexer/internal/LexerSeparatorTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import io.github.cybercodernaj.parkour.utils.Position
66
import org.junit.jupiter.api.Test
77

88
class LexerSeparatorTest {
9-
private val lexer = Lexer(separators = setOf("(", ")", "<", ">", ",", "."))
9+
private val lexer = Lexer(separators = listOf("(", ")", "<", ">", ",", "."))
1010

1111
@Test
1212
fun `returns a series of valid tokens`() {

docs/core/io.github.cybercodernaj.parkour.lexer/-lexer-builder/hard-keywords.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<div class="cover ">
6464
<h1 class="cover"><span>hard</span><wbr><span><span>Keywords</span></span></h1>
6565
</div>
66-
<div class="platform-hinted " data-platform-hinted="data-platform-hinted"><div class="content sourceset-dependent-content" data-active="" data-togglable=":core:dokkaHtmlPartial/main"><div class="symbol monospace"><span class="token keyword">fun </span><a href="hard-keywords.html"><span class="token function">hardKeywords</span></a><span class="token punctuation">(</span><span class="parameters "><span class="parameter "><span class="token keyword">vararg </span>keywords<span class="token operator">: </span><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html">String</a></span></span><span class="token punctuation">)</span><span class="clearfix"><span class="floating-right">(<a href="https://github.com/cybercoder-naj/parkour/tree/main/core/src/main/kotlin/io/github/cybercodernaj/parkour/lexer/LexerBuilder.kt#L138">source</a>)</span></span></div><p class="paragraph">Hard keywords are a characters and symbols that give a particular meaning to a program. They may not be used as identifiers. (Default: [])</p><h3 class="">Usage</h3><div class="sample-container"><pre><code class="block lang-kt" theme="idea">val myLexer = lexer {<br> hardKeywords("class", "this", "fun", "keywords")<br>}</code></pre><span class="top-right-position"><span class="copy-icon"></span><div class="copy-popup-wrapper popup-to-left"><span class="copy-popup-icon"></span><span>Content copied to clipboard</span></div></span></div><span class="kdoc-tag"><h4 class="">Author</h4><p class="paragraph">Nishant Aanjaney Jalan</p></span><span class="kdoc-tag"><h4 class="">Since</h4><p class="paragraph">0.2.0</p></span><h4 class="">Parameters</h4><div class="table"><div class="table-row" data-filterable-current=":core:dokkaHtmlPartial/main" data-filterable-set=":core:dokkaHtmlPartial/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><u><span><span>keywords</span></span></u></div></span></div><div><div class="title"><p class="paragraph">a variable number of hard keywords</p></div></div></div></div></div></div></div>
66+
<div class="platform-hinted " data-platform-hinted="data-platform-hinted"><div class="content sourceset-dependent-content" data-active="" data-togglable=":core:dokkaHtmlPartial/main"><div class="symbol monospace"><span class="token keyword">fun </span><a href="hard-keywords.html"><span class="token function">hardKeywords</span></a><span class="token punctuation">(</span><span class="parameters "><span class="parameter "><span class="token keyword">vararg </span>keywords<span class="token operator">: </span><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html">String</a></span></span><span class="token punctuation">)</span><span class="clearfix"><span class="floating-right">(<a href="https://github.com/cybercoder-naj/parkour/tree/main/core/src/main/kotlin/io/github/cybercodernaj/parkour/lexer/LexerBuilder.kt#L144">source</a>)</span></span></div><p class="paragraph">Hard keywords are a characters and symbols that give a particular meaning to a program. They may not be used as identifiers. (Default: [])</p><h3 class="">Usage</h3><div class="sample-container"><pre><code class="block lang-kt" theme="idea">val myLexer = lexer {<br> hardKeywords("class", "this", "fun", "keywords")<br>}</code></pre><span class="top-right-position"><span class="copy-icon"></span><div class="copy-popup-wrapper popup-to-left"><span class="copy-popup-icon"></span><span>Content copied to clipboard</span></div></span></div><span class="kdoc-tag"><h4 class="">Author</h4><p class="paragraph">Nishant Aanjaney Jalan</p></span><span class="kdoc-tag"><h4 class="">Since</h4><p class="paragraph">0.2.0</p></span><h4 class="">Parameters</h4><div class="table"><div class="table-row" data-filterable-current=":core:dokkaHtmlPartial/main" data-filterable-set=":core:dokkaHtmlPartial/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><u><span><span>keywords</span></span></u></div></span></div><div><div class="title"><p class="paragraph">a variable number of hard keywords</p></div></div></div></div></div></div></div>
6767
</div>
6868
<div class="footer">
6969
<span class="go-to-top-icon"><a href="#content" id="go-to-top-link"></a></span><span>© 2024 Nishant Aanjaney Jalan</span><span class="pull-right"><span>Generated by </span><a href="https://github.com/Kotlin/dokka"><span>dokka</span><span class="padded-icon"></span></a></span>

docs/core/io.github.cybercodernaj.parkour.lexer/-lexer-builder/identifiers.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<div class="cover ">
6464
<h1 class="cover"><span><span>identifiers</span></span></h1>
6565
</div>
66-
<div class="platform-hinted " data-platform-hinted="data-platform-hinted"><div class="content sourceset-dependent-content" data-active="" data-togglable=":core:dokkaHtmlPartial/main"><div class="symbol monospace"><span class="token keyword">fun </span><a href="identifiers.html"><span class="token function">identifiers</span></a><span class="token punctuation">(</span><span class="parameters "><span class="parameter ">identifiers<span class="token operator">: </span><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/index.html">Regex</a></span></span><span class="token punctuation">)</span><span class="clearfix"><span class="floating-right">(<a href="https://github.com/cybercoder-naj/parkour/tree/main/core/src/main/kotlin/io/github/cybercodernaj/parkour/lexer/LexerBuilder.kt#L117">source</a>)</span></span></div><p class="paragraph">Supply the regex pattern that defines the rules for identifiers. Identifiers are parts of the program that are named by the user; for instance, the field name or class name.</p><h3 class="">Usage</h3><div class="sample-container"><pre><code class="block lang-kt" theme="idea">val myLexer = lexer {<br> // If all identifiers must be at least 2 characters and start with a lowercase english alphabet.<br> identifiers(Regex("[a-z][a-zA-Z0-9]+"))<br>}</code></pre><span class="top-right-position"><span class="copy-icon"></span><div class="copy-popup-wrapper popup-to-left"><span class="copy-popup-icon"></span><span>Content copied to clipboard</span></div></span></div><span class="kdoc-tag"><h4 class="">Author</h4><p class="paragraph">Nishant Aanjaney Jalan</p></span><span class="kdoc-tag"><h4 class="">Since</h4><p class="paragraph">0.2.0</p></span><h4 class="">Parameters</h4><div class="table"><div class="table-row" data-filterable-current=":core:dokkaHtmlPartial/main" data-filterable-set=":core:dokkaHtmlPartial/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><u><span><span>identifiers</span></span></u></div></span></div><div><div class="title"><p class="paragraph">regex defining the rules of the naming identifiers</p></div></div></div></div></div><h4 class="">See also</h4><div class="table"><div class="table-row" data-filterable-current=":core:dokkaHtmlPartial/main" data-filterable-set=":core:dokkaHtmlPartial/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><a href="../../io.github.cybercodernaj.parkour.lexer.internal/-lexer/-defaults/identifiers.html"><span>Lexer.</span><wbr><span>Defaults.</span><wbr><span><span>identifiers</span></span></a></div></span></div><div></div></div></div></div></div></div>
66+
<div class="platform-hinted " data-platform-hinted="data-platform-hinted"><div class="content sourceset-dependent-content" data-active="" data-togglable=":core:dokkaHtmlPartial/main"><div class="symbol monospace"><span class="token keyword">fun </span><a href="identifiers.html"><span class="token function">identifiers</span></a><span class="token punctuation">(</span><span class="parameters "><span class="parameter ">identifiers<span class="token operator">: </span><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/index.html">Regex</a></span></span><span class="token punctuation">)</span><span class="clearfix"><span class="floating-right">(<a href="https://github.com/cybercoder-naj/parkour/tree/main/core/src/main/kotlin/io/github/cybercodernaj/parkour/lexer/LexerBuilder.kt#L123">source</a>)</span></span></div><p class="paragraph">Supply the regex pattern that defines the rules for identifiers. Identifiers are parts of the program that are named by the user; for instance, the field name or class name.</p><h3 class="">Usage</h3><div class="sample-container"><pre><code class="block lang-kt" theme="idea">val myLexer = lexer {<br> // If all identifiers must be at least 2 characters and start with a lowercase english alphabet.<br> identifiers(Regex("[a-z][a-zA-Z0-9]+"))<br>}</code></pre><span class="top-right-position"><span class="copy-icon"></span><div class="copy-popup-wrapper popup-to-left"><span class="copy-popup-icon"></span><span>Content copied to clipboard</span></div></span></div><span class="kdoc-tag"><h4 class="">Author</h4><p class="paragraph">Nishant Aanjaney Jalan</p></span><span class="kdoc-tag"><h4 class="">Since</h4><p class="paragraph">0.2.0</p></span><h4 class="">Parameters</h4><div class="table"><div class="table-row" data-filterable-current=":core:dokkaHtmlPartial/main" data-filterable-set=":core:dokkaHtmlPartial/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><u><span><span>identifiers</span></span></u></div></span></div><div><div class="title"><p class="paragraph">regex defining the rules of the naming identifiers</p></div></div></div></div></div><h4 class="">See also</h4><div class="table"><div class="table-row" data-filterable-current=":core:dokkaHtmlPartial/main" data-filterable-set=":core:dokkaHtmlPartial/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><a href="../../io.github.cybercodernaj.parkour.lexer.internal/-lexer/-defaults/identifiers.html"><span>Lexer.</span><wbr><span>Defaults.</span><wbr><span><span>identifiers</span></span></a></div></span></div><div></div></div></div></div></div></div>
6767
</div>
6868
<div class="footer">
6969
<span class="go-to-top-icon"><a href="#content" id="go-to-top-link"></a></span><span>© 2024 Nishant Aanjaney Jalan</span><span class="pull-right"><span>Generated by </span><a href="https://github.com/Kotlin/dokka"><span>dokka</span><span class="padded-icon"></span></a></span>

0 commit comments

Comments
 (0)