Improve parsers to handle empty input code
This commit is contained in:
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user