aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2019-08-15 22:05:55 +0200
committerMarvin Borner2019-08-15 22:05:55 +0200
commitcc8c02d780f703e0ea547e79dacf6a571686e1df (patch)
tree9937b657405332abacc1eec580077041b9da5708
parent49db23f1c8c3bf6c858eb75b70f9ffd0a839fb3c (diff)
Improved syntax analyser
-rw-r--r--src/runMain/kotlin/DataType.kt (renamed from src/runMain/kotlin/DataTypes.kt)0
-rw-r--r--src/runMain/kotlin/Lexical.kt8
-rw-r--r--src/runMain/kotlin/Syntax.kt23
-rw-r--r--src/runMain/kotlin/TokenType.kt (renamed from src/runMain/kotlin/TokenTypes.kt)3
-rw-r--r--src/runMain/kotlin/exceptions/SyntaxError.kt4
5 files changed, 21 insertions, 17 deletions
diff --git a/src/runMain/kotlin/DataTypes.kt b/src/runMain/kotlin/DataType.kt
index 4c6abb0..4c6abb0 100644
--- a/src/runMain/kotlin/DataTypes.kt
+++ b/src/runMain/kotlin/DataType.kt
diff --git a/src/runMain/kotlin/Lexical.kt b/src/runMain/kotlin/Lexical.kt
index 73b15aa..0d37065 100644
--- a/src/runMain/kotlin/Lexical.kt
+++ b/src/runMain/kotlin/Lexical.kt
@@ -4,7 +4,6 @@ import exceptions.*
class Lexical {
/**
* Analyzes the given [source] and returns the tokens divided into an array of statements
- * TODO: Add line number to token (abstract to class?)
*/
fun analyze(source: String): MutableList<MutableList<Token>> {
var buffer = ""
@@ -21,7 +20,7 @@ class Lexical {
val newToken = Token()
newToken.content = buffer
newToken.type = tokenType
- newToken.lineNumber = 13
+ newToken.lineNumber = 1
currentStatement.add(newToken)
buffer = ""
} else if (statementEnd) {
@@ -54,7 +53,8 @@ class Lexical {
token in logical -> Logical
(token + next).matches(Regex("[a-zA-Z]*")) -> Skip
- token.matches(Regex("[a-zA-Z]*")) -> Identifier
+ token.matches(Regex("[a-zA-Z]*")) && next == '(' -> Function
+ token.matches(Regex("[a-zA-Z]*")) -> Variable
(token + next).matches(Regex("[0-9]*")) -> Skip
token.matches(Regex("[0-9]*")) -> Constant
@@ -72,7 +72,7 @@ class Lexical {
}
}
- private val keyword = listOf("print") // TODO: DataType matching
+ private val keyword = listOf("if", "elif", "else", "for", "while")
private val assignment = listOf("=", "+=", "-=", "*=", "/*")
private val arithmetic = listOf("+", "-", "*", "/", "%")
private val comparison = listOf("==", "!=", "<", "<=", ">", ">=")
diff --git a/src/runMain/kotlin/Syntax.kt b/src/runMain/kotlin/Syntax.kt
index 19d8505..938814d 100644
--- a/src/runMain/kotlin/Syntax.kt
+++ b/src/runMain/kotlin/Syntax.kt
@@ -10,18 +10,22 @@ class Syntax {
removePadding(statement)
mergeStrings(statement)
mergeTokens(statement)
- // print(statement)
+ statement.forEach { println("${it.content} ${it.type}") }
statement.forEachIndexed { j, token ->
+ if (statement.count { it.content == "(" } != statement.count { it.content == ")" })
+ throw SyntaxError("Bracket", "Brackets are not even")
+
when (token.type) {
- Keyword -> allowNext(statement, j, listOf(Assignment, Constant))
+ Keyword -> allowNext(statement, j, listOf(Bracket))
+ Function -> allowNext(statement, j, listOf(Bracket))
Constant -> allowNext(statement, j, listOf(Comparison, Arithmetic, Logical, Bracket))
- Assignment -> allowNext(statement, j, listOf(Constant))
- Arithmetic -> allowNext(statement, j, listOf(Constant))
- Comparison -> allowNext(statement, j, listOf(Constant))
- Logical -> allowNext(statement, j, listOf(Constant))
- Identifier -> allowNext(statement, j, listOf(Keyword, Assignment))
+ Assignment -> allowNext(statement, j, listOf(Constant, Function))
+ Arithmetic -> allowNext(statement, j, listOf(Constant, Function))
+ Comparison -> allowNext(statement, j, listOf(Constant, Function))
+ Logical -> allowNext(statement, j, listOf(Constant, Function))
+ Variable -> allowNext(statement, j, listOf(Assignment, Bracket, Arithmetic, Logical, Comparison))
Punctuation -> allowNext(statement, j, listOf(Constant))
- Bracket -> allowNext(statement, j, listOf(Constant, Keyword, Logical, Assignment))
+ Bracket -> allowNext(statement, j, listOf(Constant, Keyword, Logical, Assignment, Variable))
Classifier -> Unit
Empty -> Unit
Skip -> throw UnknownType(token.content)
@@ -77,7 +81,8 @@ class Syntax {
*/
private fun allowNext(statement: MutableList<Token>, index: kotlin.Int, allowed: List<TokenType>) {
if (statement.size > index + 1 && nextNonEmpty(statement, index).type !in allowed) {
- throw SyntaxError(nextNonEmpty(statement, index))
+ val token = nextNonEmpty(statement, index)
+ throw SyntaxError(token.type.toString(), token.content)
}
}
diff --git a/src/runMain/kotlin/TokenTypes.kt b/src/runMain/kotlin/TokenType.kt
index aa37439..53e0ab2 100644
--- a/src/runMain/kotlin/TokenTypes.kt
+++ b/src/runMain/kotlin/TokenType.kt
@@ -3,11 +3,12 @@
*/
enum class TokenType {
Keyword,
+ Function,
Assignment,
Arithmetic,
Comparison,
Logical,
- Identifier,
+ Variable,
Constant,
Punctuation,
Bracket,
diff --git a/src/runMain/kotlin/exceptions/SyntaxError.kt b/src/runMain/kotlin/exceptions/SyntaxError.kt
index 952187e..8609d38 100644
--- a/src/runMain/kotlin/exceptions/SyntaxError.kt
+++ b/src/runMain/kotlin/exceptions/SyntaxError.kt
@@ -1,8 +1,6 @@
package exceptions
-import Token
-
/**
* Gets thrown if the syntax is wrong
*/
-class SyntaxError(context: Token) : Exception("Unexpected ${context.type}: ${context.content}") \ No newline at end of file
+class SyntaxError(description: String, context: String) : Exception("Unexpected $description: $context") \ No newline at end of file