Migrate loop parser to Kotlin
This commit is contained in:
@@ -2,5 +2,5 @@ import interpreter.Interpreter
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val interpreter = Interpreter()
|
||||
interpreter.run("if (true) { return 2; 2*2; { 3+3; 1*2**3.@c:14 == (2 > not false) } throw \"Hello, world\" } else { false }")
|
||||
interpreter.run("{ [2, 3, 4] as (i, j, k) ^ { x y z } % i == 2 [1, xyz, [true, { 1 -> false, 2 -> { @c -> @d, @e -> false } }, [@c], 4, \"h\"]] 2 @c @d * 3.14 }")
|
||||
}
|
||||
@@ -5,11 +5,7 @@ import dsl.ast.model.node.Node
|
||||
|
||||
data class ParserOutput private constructor(val result: ParsingResult, val node: Node) {
|
||||
fun map(mapper: (Node) -> Node): ParserOutput {
|
||||
if(result == ParsingResult.FAILED) {
|
||||
throw RuntimeException("Mapping operation is not allowed for failed parsing output")
|
||||
}
|
||||
|
||||
return ok(mapper(node))
|
||||
return if(result == ParsingResult.OK) ok(mapper(node)) else fail()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
22
src/main/kotlin/dsl/ast/model/node/LoopNode.kt
Normal file
22
src/main/kotlin/dsl/ast/model/node/LoopNode.kt
Normal file
@@ -0,0 +1,22 @@
|
||||
package dsl.ast.model.node
|
||||
|
||||
class LoopNode(iterator: Node, parameters: Node, operator: Node, statement: Node, filter: Node): Node(4, operator.position) {
|
||||
val iterator: Node
|
||||
get() = children[0]
|
||||
|
||||
val parameters: Node
|
||||
get() = children[1]
|
||||
|
||||
val statement: Node
|
||||
get() = children[2]
|
||||
|
||||
val filter: Node
|
||||
get() = children[3]
|
||||
|
||||
init {
|
||||
children[0] = iterator
|
||||
children[1] = parameters
|
||||
children[2] = statement
|
||||
children[3] = filter
|
||||
}
|
||||
}
|
||||
5
src/main/kotlin/dsl/ast/model/node/LoopParametersNode.kt
Normal file
5
src/main/kotlin/dsl/ast/model/node/LoopParametersNode.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package dsl.ast.model.node
|
||||
|
||||
import dsl.token.model.entity.TokenPosition
|
||||
|
||||
class LoopParametersNode(items: List<Node>, position: TokenPosition) : AbstractIterableNode(items, position)
|
||||
@@ -11,7 +11,7 @@ class ConditionParser : Parser() {
|
||||
val ifStatementParser = allOf(listOf(
|
||||
terminal(TokenType.IF),
|
||||
terminal(TokenType.OPEN_PAREN),
|
||||
ExpressionParser(),
|
||||
SubexpressionParser(),
|
||||
terminal(TokenType.CLOSE_PAREN),
|
||||
StatementParser()
|
||||
)) {
|
||||
@@ -21,7 +21,7 @@ class ConditionParser : Parser() {
|
||||
val ifElseStatementParser = allOf(listOf(
|
||||
terminal(TokenType.IF),
|
||||
terminal(TokenType.OPEN_PAREN),
|
||||
ExpressionParser(),
|
||||
SubexpressionParser(),
|
||||
terminal(TokenType.CLOSE_PAREN),
|
||||
StatementParser(),
|
||||
terminal(TokenType.ELSE),
|
||||
|
||||
@@ -1,46 +1,13 @@
|
||||
package dsl.ast.parser
|
||||
|
||||
import dsl.ast.model.entity.ParserOutput
|
||||
import dsl.ast.model.node.LogicOperatorNode
|
||||
import dsl.ast.model.node.RelationOperatorNode
|
||||
import dsl.ast.model.node.SumOperatorNode
|
||||
import dsl.token.model.entity.TokenList
|
||||
import dsl.token.model.enumeration.TokenType
|
||||
|
||||
class ExpressionParser : Parser() {
|
||||
override fun tryToParse(input: TokenList): ParserOutput {
|
||||
val expr1Parser = leftAssociativeOperator(
|
||||
TermParser(),
|
||||
listOf(TokenType.PLUS, TokenType.MINUS),
|
||||
TermParser()
|
||||
) {
|
||||
lhs, operator, rhs -> SumOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
val expr2Parser = leftAssociativeOperator(
|
||||
expr1Parser,
|
||||
listOf(TokenType.RELATION, TokenType.OPEN_ANGLE, TokenType.CLOSE_ANGLE),
|
||||
expr1Parser
|
||||
) {
|
||||
lhs, operator, rhs -> RelationOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
val expr3Parser = leftAssociativeOperator(
|
||||
expr2Parser,
|
||||
listOf(TokenType.AND),
|
||||
expr2Parser
|
||||
) {
|
||||
lhs, operator, rhs -> LogicOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
val expr4Parser = leftAssociativeOperator(
|
||||
expr3Parser,
|
||||
listOf(TokenType.OR),
|
||||
expr3Parser
|
||||
) {
|
||||
lhs, operator, rhs -> LogicOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
return expr4Parser.parse(input)
|
||||
return oneOf(listOf(
|
||||
LoopParser(),
|
||||
SubexpressionParser()
|
||||
)).parse(input)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@ package dsl.ast.parser
|
||||
import dsl.ast.model.node.ListNode
|
||||
import dsl.token.model.enumeration.TokenType
|
||||
|
||||
class ListParser : AbstractIterableParser(TokenType.OPEN_SQUARE, ExpressionParser(), TokenType.CLOSE_SQUARE, {
|
||||
class ListParser : AbstractIterableParser(TokenType.OPEN_SQUARE, SubexpressionParser(), TokenType.CLOSE_SQUARE, {
|
||||
list, tokenPosition -> ListNode(list, tokenPosition)
|
||||
})
|
||||
8
src/main/kotlin/dsl/ast/parser/LoopParametersParser.kt
Normal file
8
src/main/kotlin/dsl/ast/parser/LoopParametersParser.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
package dsl.ast.parser
|
||||
|
||||
import dsl.ast.model.node.LoopParametersNode
|
||||
import dsl.token.model.enumeration.TokenType
|
||||
|
||||
class LoopParametersParser : AbstractIterableParser(TokenType.OPEN_PAREN, IdentifierParser(), TokenType.CLOSE_PAREN, {
|
||||
list, tokenPosition -> LoopParametersNode(list, tokenPosition)
|
||||
})
|
||||
34
src/main/kotlin/dsl/ast/parser/LoopParser.kt
Normal file
34
src/main/kotlin/dsl/ast/parser/LoopParser.kt
Normal file
@@ -0,0 +1,34 @@
|
||||
package dsl.ast.parser
|
||||
|
||||
import dsl.ast.model.entity.ParserOutput
|
||||
import dsl.ast.model.node.LoopNode
|
||||
import dsl.ast.model.node.LoopParametersNode
|
||||
import dsl.token.model.entity.TokenList
|
||||
import dsl.token.model.enumeration.TokenType
|
||||
|
||||
class LoopParser : Parser() {
|
||||
override fun tryToParse(input: TokenList): ParserOutput {
|
||||
val loopParametersParser = allOf(listOf(
|
||||
terminal(TokenType.AS),
|
||||
oneOf(listOf(
|
||||
mapNode(IdentifierParser()) { LoopParametersNode(listOf(it), it.position) },
|
||||
LoopParametersParser()
|
||||
))
|
||||
)) { it[1] }
|
||||
|
||||
val loopFilterParser = allOf(listOf(
|
||||
terminal(TokenType.PERCENT),
|
||||
assert(SubexpressionParser(), "filter as bool expression")
|
||||
)) { it[1] }
|
||||
|
||||
return allOf(listOf(
|
||||
SubexpressionParser(),
|
||||
optional(loopParametersParser),
|
||||
terminal(TokenType.CARET),
|
||||
StatementParser(),
|
||||
optional(loopFilterParser)
|
||||
)) {
|
||||
LoopNode(it[0], it[1], it[2], it[3], it[4])
|
||||
}.parse(input)
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ class MapEntryParser : Parser() {
|
||||
return allOf(listOf(
|
||||
keyParser,
|
||||
terminal(TokenType.ARROW),
|
||||
assert(ExpressionParser(), "expression")
|
||||
assert(SubexpressionParser(), "expression")
|
||||
)) {
|
||||
MapEntryNode(it[0], it[1], it[2])
|
||||
}.parse(input)
|
||||
|
||||
@@ -184,5 +184,14 @@ abstract class Parser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun mapNode(parser: Parser, mapper: (Node) -> Node) : Parser {
|
||||
return object : Parser() {
|
||||
override fun tryToParse(input: TokenList): ParserOutput {
|
||||
return parser.parse(input).map(mapper)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ class ReturnParser : Parser() {
|
||||
override fun tryToParse(input: TokenList): ParserOutput {
|
||||
return allOf(listOf(
|
||||
terminal(TokenType.RETURN),
|
||||
optional(ExpressionParser())
|
||||
optional(SubexpressionParser())
|
||||
)) {
|
||||
ReturnNode(it[1])
|
||||
}.parse(input)
|
||||
|
||||
46
src/main/kotlin/dsl/ast/parser/SubexpressionParser.kt
Normal file
46
src/main/kotlin/dsl/ast/parser/SubexpressionParser.kt
Normal file
@@ -0,0 +1,46 @@
|
||||
package dsl.ast.parser
|
||||
|
||||
import dsl.ast.model.entity.ParserOutput
|
||||
import dsl.ast.model.node.LogicOperatorNode
|
||||
import dsl.ast.model.node.RelationOperatorNode
|
||||
import dsl.ast.model.node.SumOperatorNode
|
||||
import dsl.token.model.entity.TokenList
|
||||
import dsl.token.model.enumeration.TokenType
|
||||
|
||||
class SubexpressionParser : Parser() {
|
||||
override fun tryToParse(input: TokenList): ParserOutput {
|
||||
val expr1Parser = leftAssociativeOperator(
|
||||
TermParser(),
|
||||
listOf(TokenType.PLUS, TokenType.MINUS),
|
||||
TermParser()
|
||||
) {
|
||||
lhs, operator, rhs -> SumOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
val expr2Parser = leftAssociativeOperator(
|
||||
expr1Parser,
|
||||
listOf(TokenType.RELATION, TokenType.OPEN_ANGLE, TokenType.CLOSE_ANGLE),
|
||||
expr1Parser
|
||||
) {
|
||||
lhs, operator, rhs -> RelationOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
val expr3Parser = leftAssociativeOperator(
|
||||
expr2Parser,
|
||||
listOf(TokenType.AND),
|
||||
expr2Parser
|
||||
) {
|
||||
lhs, operator, rhs -> LogicOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
val expr4Parser = leftAssociativeOperator(
|
||||
expr3Parser,
|
||||
listOf(TokenType.OR),
|
||||
expr3Parser
|
||||
) {
|
||||
lhs, operator, rhs -> LogicOperatorNode(lhs, operator, rhs)
|
||||
}
|
||||
|
||||
return expr4Parser.parse(input)
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ class ThrowParser : Parser() {
|
||||
override fun tryToParse(input: TokenList): ParserOutput {
|
||||
return allOf(listOf(
|
||||
terminal(TokenType.THROW),
|
||||
optional(ExpressionParser())
|
||||
optional(SubexpressionParser())
|
||||
)) {
|
||||
ThrowNode(it[1])
|
||||
}.parse(input)
|
||||
|
||||
Reference in New Issue
Block a user