Improve parsers to handle empty input code

This commit is contained in:
2020-03-31 19:47:50 +02:00
parent 0dd0505cf0
commit b5e7e5b1af
3 changed files with 32 additions and 26 deletions

View File

@@ -129,12 +129,10 @@ abstract class Parser {
val items = mutableListOf<Node>()
while (true) {
val output = itemParser.parse(input)
if (output.result == ParsingResult.OK) {
items += output.node
} else if (items.isEmpty()) {
return ParserOutput.fail()
} else {
return ParserOutput.ok(createNode(items, items.first().position))
when {
output.result == ParsingResult.OK -> items += output.node
items.isEmpty() -> return ParserOutput.fail()
else -> return ParserOutput.ok(createNode(items, items.first().position))
}
}
}

View File

@@ -1,21 +1,33 @@
package io.smnp.dsl.ast.parser
import io.smnp.dsl.ast.model.entity.ParserOutput
import io.smnp.dsl.ast.model.enumeration.ParsingResult
import io.smnp.dsl.ast.model.node.Node
import io.smnp.dsl.ast.model.node.RootNode
import io.smnp.dsl.token.model.entity.TokenList
import io.smnp.dsl.token.model.entity.TokenPosition
import io.smnp.dsl.token.model.enumeration.TokenType
class RootParser : Parser() {
override fun tryToParse(input: TokenList): ParserOutput {
return assert(repeat(
oneOf(
allOf(ImportParser(), optional(terminal(TokenType.SEMICOLON))) { (import, _) -> import },
FunctionDefinitionParser(),
ExtendParser(),
StatementParser()
)
) { list, tokenPosition ->
RootNode(list, tokenPosition)
}, "import statement, function definition, extend statement or any other statement").parse(input)
}
override fun tryToParse(input: TokenList): ParserOutput {
val parser = assert(
oneOf(
allOf(ImportParser(), optional(terminal(TokenType.SEMICOLON))) { (import, _) -> import },
FunctionDefinitionParser(),
ExtendParser(),
StatementParser()
), "import statement, function definition, extend statement or any other statement"
)
val items = mutableListOf<Node>()
while (input.hasMore()) {
parser.parse(input).let {
if (it.result == ParsingResult.OK) {
items += it.node
}
}
}
return ParserOutput.ok(RootNode(items, items.firstOrNull()?.position ?: TokenPosition.NONE))
}
}

View File

@@ -5,7 +5,6 @@ import io.smnp.dsl.token.tokenizer.DefaultTokenizer
import io.smnp.environment.DefaultEnvironment
import io.smnp.environment.Environment
import io.smnp.evaluation.evaluator.RootEvaluator
import io.smnp.evaluation.model.enumeration.EvaluationResult
import java.io.File
class DefaultInterpreter {
@@ -35,19 +34,16 @@ class DefaultInterpreter {
environment.loadModule("smnp.lang")
val tokens = tokenizer.tokenize(lines, source)
if (printTokens) println(tokens)
val ast = parser.parse(tokens)
if (printAst) ast.node.pretty()
if (!dryRun) {
val result = evaluator.evaluate(ast.node, environment)
if (result.result == EvaluationResult.FAILED) {
throw RuntimeException("Evaluation failed")
}
evaluator.evaluate(ast.node, environment)
}
if (printTokens) println(tokens)
if (printAst) ast.node.pretty()
return environment
}