Refactor parsers

This commit is contained in:
2020-03-13 18:10:25 +01:00
parent 764c607a69
commit 7eb543f2bc
15 changed files with 89 additions and 107 deletions

View File

@@ -7,35 +7,35 @@ import io.smnp.dsl.token.model.entity.TokenPosition
import io.smnp.dsl.token.model.enumeration.TokenType import io.smnp.dsl.token.model.enumeration.TokenType
abstract class AbstractIterableParser( abstract class AbstractIterableParser(
private val beginTokenType: TokenType, private val beginTokenType: TokenType,
private val itemParser: Parser, private val itemParser: Parser,
private val endTokenType: TokenType, private val endTokenType: TokenType,
private val createNode: (List<Node>, TokenPosition) -> Node private val createNode: (List<Node>, TokenPosition) -> Node
) : Parser() { ) : Parser() {
override fun tryToParse(input: TokenList): ParserOutput { override fun tryToParse(input: TokenList): ParserOutput {
val emptyIterableParser = allOf( val emptyIterableParser = allOf(
terminal(beginTokenType), terminal(beginTokenType),
terminal(endTokenType) terminal(endTokenType)
) { createNode(listOf(), it[0].position) } ) { (beginToken) -> createNode(listOf(), beginToken.position) }
val nonEmptyIterableParser = allOf( val nonEmptyIterableParser = allOf(
terminal(beginTokenType), terminal(beginTokenType),
allOf( allOf(
itemParser, itemParser,
optional(repeat(allOf( optional(repeat(allOf(
terminal(TokenType.COMMA), terminal(TokenType.COMMA),
itemParser itemParser
) { it[1] }) { list, position -> object : Node(list, position) {} } ) { (_, item) -> item }) { list, position -> object : Node(list, position) {} }
)) { list -> )) { (firstItem, otherAggregatedItems) ->
object : Node(listOf(list[0]) + list[1].children, TokenPosition.NONE) {} object : Node(listOf(firstItem) + otherAggregatedItems.children, TokenPosition.NONE) {}
}, },
terminal(endTokenType) terminal(endTokenType)
) { createNode(it[1].children.toList(), it[0].position) } ) { (beginToken, aggregatedItems) -> createNode(aggregatedItems.children.toList(), beginToken.position) }
return oneOf( return oneOf(
emptyIterableParser, emptyIterableParser,
nonEmptyIterableParser nonEmptyIterableParser
).parse(input) ).parse(input)
} }
} }

View File

@@ -6,13 +6,11 @@ import io.smnp.dsl.token.model.entity.TokenList
import io.smnp.dsl.token.model.enumeration.TokenType import io.smnp.dsl.token.model.enumeration.TokenType
class AssignmentOperatorParser : Parser() { class AssignmentOperatorParser : Parser() {
override fun tryToParse(input: TokenList): ParserOutput { override fun tryToParse(input: TokenList): ParserOutput {
return allOf( return allOf(
SimpleIdentifierParser(), SimpleIdentifierParser(),
terminal(TokenType.ASSIGN), terminal(TokenType.ASSIGN),
assert(ExpressionParser(), "expression") assert(ExpressionParser(), "expression")
) { ) { (target, assignToken, value) -> AssignmentOperatorNode(target, assignToken, value) }.parse(input)
AssignmentOperatorNode(it[0], it[1], it[2]) }
}.parse(input)
}
} }

View File

@@ -10,9 +10,7 @@ class AtomParser : Parser() {
terminal(TokenType.OPEN_PAREN), terminal(TokenType.OPEN_PAREN),
ExpressionParser(), ExpressionParser(),
terminal(TokenType.CLOSE_PAREN) terminal(TokenType.CLOSE_PAREN)
) { ) { (_, expression) -> expression }
it[1]
}
val literalParser = oneOf( val literalParser = oneOf(
parenthesesParser, parenthesesParser,

View File

@@ -16,8 +16,8 @@ class ExtendParser : Parser() {
assert(SimpleIdentifierParser(), "identifier"), assert(SimpleIdentifierParser(), "identifier"),
terminal(TokenType.WITH), terminal(TokenType.WITH),
assert(mapNode(FunctionDefinitionParser()) { BlockNode(Node.NONE, listOf(it), Node.NONE) }, "method definition") assert(mapNode(FunctionDefinitionParser()) { BlockNode(Node.NONE, listOf(it), Node.NONE) }, "method definition")
) { ) { (extendToken, targetType, identifier, method) ->
ExtendNode(it[1], it[3], it[5], it[0].position) ExtendNode(targetType, identifier, method, extendToken.position)
} }
val complexExtendParser = allOf( val complexExtendParser = allOf(
@@ -28,8 +28,8 @@ class ExtendParser : Parser() {
assert(loop(terminal(TokenType.OPEN_CURLY), assert(FunctionDefinitionParser(), "method definition or }"), terminal(TokenType.CLOSE_CURLY)) { assert(loop(terminal(TokenType.OPEN_CURLY), assert(FunctionDefinitionParser(), "method definition or }"), terminal(TokenType.CLOSE_CURLY)) {
begin, methods, end -> BlockNode(begin, methods, end) begin, methods, end -> BlockNode(begin, methods, end)
}, "block with methods' definitions or 'with' keyword with single method definition") }, "block with methods' definitions or 'with' keyword with single method definition")
) { ) { (extendToken, targetType, identifier, methods) ->
ExtendNode(it[1], it[3], it[4], it[0].position) ExtendNode(targetType, identifier, methods, extendToken.position)
} }
return oneOf( return oneOf(

View File

@@ -7,25 +7,21 @@ import io.smnp.dsl.token.model.entity.TokenList
import io.smnp.dsl.token.model.enumeration.TokenType import io.smnp.dsl.token.model.enumeration.TokenType
class FactorParser : Parser() { class FactorParser : Parser() {
override fun tryToParse(input: TokenList): ParserOutput { override fun tryToParse(input: TokenList): ParserOutput {
val factorParser = leftAssociativeOperator( val factorParser = leftAssociativeOperator(
UnitParser(), UnitParser(),
listOf(TokenType.DOUBLE_ASTERISK), listOf(TokenType.DOUBLE_ASTERISK),
assert(UnitParser(), "expression") assert(UnitParser(), "expression")
) { lhs, operator, rhs -> ) { lhs, operator, rhs -> PowerOperatorNode(lhs, operator, rhs) }
PowerOperatorNode(lhs, operator, rhs)
}
val notOperatorParser = allOf( val notOperatorParser = allOf(
terminal(TokenType.NOT), terminal(TokenType.NOT),
assert(factorParser, "expression") assert(factorParser, "expression")
) { ) { (notToken, expression) -> NotOperatorNode(notToken, expression) }
NotOperatorNode(it[0], it[1])
}
return oneOf( return oneOf(
notOperatorParser, notOperatorParser,
factorParser factorParser
).parse(input) ).parse(input)
} }
} }

View File

@@ -5,12 +5,10 @@ import io.smnp.dsl.ast.model.node.FunctionCallNode
import io.smnp.dsl.token.model.entity.TokenList import io.smnp.dsl.token.model.entity.TokenList
class FunctionCallParser : Parser() { class FunctionCallParser : Parser() {
override fun tryToParse(input: TokenList): ParserOutput { override fun tryToParse(input: TokenList): ParserOutput {
return allOf( return allOf(
SimpleIdentifierParser(), SimpleIdentifierParser(),
FunctionCallArgumentsParser() FunctionCallArgumentsParser()
) { ) { (identifier, arguments) -> FunctionCallNode(identifier, arguments) }.parse(input)
FunctionCallNode(it[0], it[1]) }
}.parse(input)
}
} }

View File

@@ -12,8 +12,8 @@ class FunctionDefinitionParser : Parser() {
assert(SimpleIdentifierParser(), "function/method name"), assert(SimpleIdentifierParser(), "function/method name"),
assert(FunctionDefinitionArgumentsParser(), "function/method arguments list"), assert(FunctionDefinitionArgumentsParser(), "function/method arguments list"),
assert(BlockParser(), "function/method body") assert(BlockParser(), "function/method body")
) { ) { (functionToken, identifier, arguments, body) ->
FunctionDefinitionNode(it[1], it[2], it[3], it[0].position) FunctionDefinitionNode(identifier, arguments, body, functionToken.position)
}.parse(input) }.parse(input)
} }
} }

View File

@@ -14,12 +14,12 @@ class LoopParser : Parser() {
mapNode(SimpleIdentifierParser()) { LoopParametersNode(listOf(it), it.position) }, mapNode(SimpleIdentifierParser()) { LoopParametersNode(listOf(it), it.position) },
LoopParametersParser() LoopParametersParser()
), "loop parameters") ), "loop parameters")
) { it[1] } ) { (_, parameters) -> parameters }
val loopFilterParser = allOf( val loopFilterParser = allOf(
terminal(TokenType.PERCENT), terminal(TokenType.PERCENT),
assert(SubexpressionParser(), "filter as bool expression") assert(SubexpressionParser(), "filter as bool expression")
) { it[1] } ) { (_, filter) -> filter }
return allOf( return allOf(
SubexpressionParser(), SubexpressionParser(),
@@ -27,8 +27,8 @@ class LoopParser : Parser() {
terminal(TokenType.CARET), terminal(TokenType.CARET),
assert(StatementParser(), "statement"), assert(StatementParser(), "statement"),
optional(loopFilterParser) optional(loopFilterParser)
) { ) { (iterator, parameters, caretToken, statement, filter) ->
LoopNode(it[0], it[1], it[2], it[3], it[4]) LoopNode(iterator, parameters, caretToken, statement, filter)
}.parse(input) }.parse(input)
} }
} }

View File

@@ -16,8 +16,6 @@ class MapEntryParser : Parser() {
keyParser, keyParser,
terminal(TokenType.ARROW), terminal(TokenType.ARROW),
assert(SubexpressionParser(), "expression") assert(SubexpressionParser(), "expression")
) { ) { (key, arrowToken, value) -> MapEntryNode(key, arrowToken, value) }.parse(input)
MapEntryNode(it[0], it[1], it[2])
}.parse(input)
} }
} }

View File

@@ -14,11 +14,11 @@ class OptionalFunctionDefinitionArgumentParser : Parser() {
optional(allOf( optional(allOf(
terminal(TokenType.COLON), terminal(TokenType.COLON),
assert(TypeParser(), "type name") assert(TypeParser(), "type name")
) { it[1] }) { UnionTypeNode(emptyList(), TokenPosition.NONE) }, ) { (_, type) -> type }) { UnionTypeNode(emptyList(), TokenPosition.NONE) },
terminal(TokenType.ASSIGN), terminal(TokenType.ASSIGN),
assert(ExpressionParser(), "expression") assert(ExpressionParser(), "expression")
) { ) { (identifier, type, defaultValue) ->
OptionalFunctionDefinitionArgumentNode(it[0], it[1], it[3]) OptionalFunctionDefinitionArgumentNode(identifier, type, defaultValue)
}.parse(input) }.parse(input)
} }
} }

View File

@@ -15,7 +15,7 @@ class RegularFunctionDefinitionArgumentParser : Parser() {
optional(allOf( optional(allOf(
terminal(TokenType.COLON), terminal(TokenType.COLON),
assert(TypeParser(), "type name") assert(TypeParser(), "type name")
) { it[1] }) { UnionTypeNode(emptyList(), TokenPosition.NONE) } ) { (_, type) -> type }) { UnionTypeNode(emptyList(), TokenPosition.NONE) }
) { (vararg, identifier, type) -> ) { (vararg, identifier, type) ->
RegularFunctionDefinitionArgumentNode(identifier, type, vararg) RegularFunctionDefinitionArgumentNode(identifier, type, vararg)
}.parse(input) }.parse(input)

View File

@@ -10,8 +10,6 @@ class SingleTypeParser : Parser() {
return allOf( return allOf(
SimpleIdentifierParser(), SimpleIdentifierParser(),
optional(repeat(TypeSpecifierParser()) { list, tokenPosition -> TypeSpecifiersNode(list, tokenPosition) }) optional(repeat(TypeSpecifierParser()) { list, tokenPosition -> TypeSpecifiersNode(list, tokenPosition) })
) { ) { (identifier, specifiers) -> SingleTypeNode(identifier, specifiers) }.parse(input)
SingleTypeNode(it[0], it[1])
}.parse(input)
} }
} }

View File

@@ -15,8 +15,6 @@ class StatementParser : Parser() {
ThrowParser() ThrowParser()
), ),
optional(terminal(TokenType.SEMICOLON)) optional(terminal(TokenType.SEMICOLON))
) { ) { (statement) -> statement }.parse(input)
it[0]
}.parse(input)
} }
} }

View File

@@ -10,8 +10,6 @@ class ThrowParser : Parser() {
return allOf( return allOf(
terminal(TokenType.THROW), terminal(TokenType.THROW),
optional(SubexpressionParser()) optional(SubexpressionParser())
) { ) { (_, value) -> ThrowNode(value) }.parse(input)
ThrowNode(it[1])
}.parse(input)
} }
} }

View File

@@ -7,21 +7,21 @@ import io.smnp.dsl.token.model.entity.TokenList
import io.smnp.dsl.token.model.enumeration.TokenType import io.smnp.dsl.token.model.enumeration.TokenType
class UnitParser : Parser() { class UnitParser : Parser() {
override fun tryToParse(input: TokenList): ParserOutput { override fun tryToParse(input: TokenList): ParserOutput {
val minusOperatorParser = allOf( val minusOperatorParser = allOf(
terminal(TokenType.MINUS), terminal(TokenType.MINUS),
assert(AtomParser(), "expression") assert(AtomParser(), "expression")
) { ) { (minusToken, expression) -> MinusOperatorNode(minusToken, expression) }
MinusOperatorNode(it[0], it[1])
}
val atom2 = oneOf( val atom2 = oneOf(
minusOperatorParser, minusOperatorParser,
AtomParser() AtomParser()
) )
return leftAssociativeOperator(atom2, listOf(TokenType.DOT), assert(atom2, "property or method call")) { lhs, operator, rhs -> return leftAssociativeOperator(
AccessOperatorNode(lhs, operator, rhs) atom2,
}.parse(input) listOf(TokenType.DOT),
} assert(atom2, "property or method call")
) { lhs, operator, rhs -> AccessOperatorNode(lhs, operator, rhs) }.parse(input)
}
} }