Create abstract iterable parser

This commit is contained in:
Bartłomiej Pluta
2019-07-05 18:07:26 +02:00
parent ed73aa1ad1
commit acd9a42e1b
3 changed files with 147 additions and 94 deletions

View File

@@ -0,0 +1,114 @@
from smnp.newast.node.expression import ExpressionNode
from smnp.newast.node.model import Node, ParseResult
from smnp.newast.node.none import NoneNode
from smnp.newast.parser import Parser
from smnp.token.type import TokenType
def abstractIterableParser(iterableNodeType, openTokenType, closeTokenType, itemParser):
class AbstractIterableTailNode(ExpressionNode):
def __init__(self, pos):
super().__init__(pos)
self.children.append(NoneNode())
@property
def next(self):
return self[1]
@next.setter
def next(self, value):
self[1] = value
@classmethod
def _parse(cls, input):
return Parser.oneOf(
AbstractIterableTailNode._parser1(),
AbstractIterableTailNode._parser2(),
)(input)
@staticmethod
def _parser1():
return Parser.terminalParser(closeTokenType)
@staticmethod
def _parser2():
def createNode(comma, expr, iterableTail):
node = AbstractIterableTailNode(expr.pos)
node.value = expr
node.next = iterableTail
return node
return Parser.allOf(
Parser.terminalParser(TokenType.COMMA),
itemParser,
AbstractIterableTailNode.parse,
createNode=createNode
)
class AbstractIterableNode(ExpressionNode):
def __init__(self, pos):
super().__init__(pos)
self.children.append(NoneNode())
@property
def next(self):
return self[1]
@next.setter
def next(self, value):
self[1] = value
@classmethod
def _parse(cls, input):
return Parser.oneOf(
AbstractIterableNode._parser1(),
AbstractIterableNode._parser2()
)(input)
@staticmethod
def _parser1():
def emptyIterable(openToken, closeToken):
node = AbstractIterableNode(openToken.pos)
node.value = openToken
node.next = closeToken
return node
return Parser.allOf(
Parser.terminalParser(openTokenType),
Parser.terminalParser(closeTokenType),
createNode=emptyIterable
)
@staticmethod
def _parser2():
def createNode(openParen, expr, iterableTail):
node = AbstractIterableNode(openParen.pos)
node.value = expr
node.next = iterableTail
return node
return Parser.allOf(
Parser.terminalParser(openTokenType, lambda v, pos: Node(pos)),
itemParser,
AbstractIterableTailNode.parse,
createNode=createNode
)
def toDesiredType(parser):
def parse(input):
result = parser(input)
if result.result:
node = iterableNodeType(result.node.pos)
node.children.clear()
node.children.extend([ result.node.value, result.node.next ])
return ParseResult.OK(node)
return ParseResult.FAIL()
return parse
return toDesiredType(AbstractIterableNode.parse)

View File

@@ -1,102 +1,10 @@
from smnp.newast.node.expression import ExpressionNode
from smnp.newast.node.model import Node
from smnp.newast.node.none import NoneNode
from smnp.newast.parser import Parser
from smnp.newast.node.iterable import abstractIterableParser
from smnp.token.type import TokenType
class ListTailNode(ExpressionNode):
def __init__(self, pos):
super().__init__(pos)
self.children.append(NoneNode())
@property
def next(self):
return self[1]
@next.setter
def next(self, value):
self[1] = value
@classmethod
def _parse(cls, input):
return Parser.oneOf(
ListTailNode._parser1(),
ListTailNode._parser2(),
)(input)
# listTail := ']'
@staticmethod
def _parser1():
return Parser.terminalParser(TokenType.CLOSE_PAREN)
# listTail := ',' expr listTail
@staticmethod
def _parser2():
def createNode(comma, expr, listTail):
node = ListTailNode(expr.pos)
node.value = expr
node.next = listTail
return node
return Parser.allOf(
Parser.terminalParser(TokenType.COMMA),
ExpressionNode.parse,
ListTailNode.parse,
createNode=createNode
)
class ListNode(ExpressionNode):
def __init__(self, pos):
super().__init__(pos)
self.children.append(NoneNode())
@property
def next(self):
return self[1]
@next.setter
def next(self, value):
self[1] = value
@classmethod
def _parse(cls, input):
return Parser.oneOf(
ListNode._parser1(),
ListNode._parser2()
)(input)
# list := '[' ']'
@staticmethod
def _parser1():
def emptyList(openParen, closeParen):
node = ListNode(openParen.pos)
node.value = openParen
node.next = closeParen
return node
return Parser.allOf(
Parser.terminalParser(TokenType.OPEN_PAREN),
Parser.terminalParser(TokenType.CLOSE_PAREN),
createNode=emptyList
)
# '[' expr listTail
@staticmethod
def _parser2():
def createNode(openParen, expr, listTail):
node = ListNode(openParen.pos)
node.value = expr
node.next = listTail
return node
return Parser.allOf(
Parser.terminalParser(TokenType.OPEN_PAREN, lambda v, pos: Node(pos)),
ExpressionNode.parse,
ListTailNode.parse,
createNode=createNode
)
return abstractIterableParser(ListNode, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN, ExpressionNode.parse)(input)

View File

@@ -11,3 +11,34 @@ def _flatListNode(listItemNode, list = []):
list.append(value)
_flatListNode(next, list)
return list
# NEW AST
# def toFlatList(parser):
# def decoratedParser(input):
# result = parser(input)
#
# if result.result:
# value = flattenList(result.node)
# node = iterableNodeType()
# for v in value:
# node.append(v)
# return ParseResult.OK(node)
#
# return ParseResult.FAIL()
#
# return decoratedParser
#
#
# def flattenList(node, output=None):
# if output is None:
# output = []
#
# if type(node.value) != IgnoredNode:
# output.append(node.value)
#
# if type(node.next) != IgnoredNode:
# flattenList(node.next, output)
#
# return output