diff options
author | Marvin Borner | 2019-08-15 22:05:55 +0200 |
---|---|---|
committer | Marvin Borner | 2019-08-15 22:05:55 +0200 |
commit | cc8c02d780f703e0ea547e79dacf6a571686e1df (patch) | |
tree | 9937b657405332abacc1eec580077041b9da5708 | |
parent | 49db23f1c8c3bf6c858eb75b70f9ffd0a839fb3c (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.kt | 8 | ||||
-rw-r--r-- | src/runMain/kotlin/Syntax.kt | 23 | ||||
-rw-r--r-- | src/runMain/kotlin/TokenType.kt (renamed from src/runMain/kotlin/TokenTypes.kt) | 3 | ||||
-rw-r--r-- | src/runMain/kotlin/exceptions/SyntaxError.kt | 4 |
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 |