Add lists to base items

This commit is contained in:
Bartłomiej Pluta
2019-07-10 21:56:38 +02:00
parent ab990f3071
commit 9dc8d5a650
3 changed files with 126 additions and 77 deletions

View File

@@ -1,4 +1,5 @@
from smnp.ast.node.atom import AtomParser from smnp.ast.node.atom import AtomParser
from smnp.ast.node.list import ListParser
from smnp.ast.node.operator import BinaryOperator from smnp.ast.node.operator import BinaryOperator
from smnp.ast.parser import Parser from smnp.ast.parser import Parser
from smnp.token.type import TokenType from smnp.token.type import TokenType
@@ -7,5 +8,10 @@ from smnp.token.type import TokenType
class Chain(BinaryOperator): class Chain(BinaryOperator):
pass pass
itemParser = Parser.oneOf(
ListParser,
AtomParser,
)
ChainParser = Parser.leftAssociativeOperatorParser(itemParser, [TokenType.DOT], itemParser, lambda left, op, right: Chain.withValues(left, op, right))
ChainParser = Parser.leftAssociativeOperatorParser(AtomParser, [TokenType.DOT], AtomParser, lambda left, op, right: Chain.withValues(left, op, right))

View File

@@ -1,4 +1,3 @@
from smnp.ast.node.expression import ExpressionNode
from smnp.ast.node.ignore import IgnoredNode from smnp.ast.node.ignore import IgnoredNode
from smnp.ast.node.model import Node, ParseResult from smnp.ast.node.model import Node, ParseResult
from smnp.ast.node.none import NoneNode from smnp.ast.node.none import NoneNode
@@ -7,11 +6,19 @@ from smnp.token.type import TokenType
def abstractIterableParser(iterableNodeType, openTokenType, closeTokenType, itemParser): def abstractIterableParser(iterableNodeType, openTokenType, closeTokenType, itemParser):
class AbstractIterableTailNode(ExpressionNode):
class AbstractIterable(Node):
def __init__(self, pos): def __init__(self, pos):
super().__init__(pos) super().__init__(pos)
self.children = [NoneNode(), NoneNode()]
self.children.append(NoneNode()) @property
def value(self):
return self[0]
@value.setter
def value(self, value):
self[0] = value
@property @property
def next(self): def next(self):
@@ -21,83 +28,120 @@ def abstractIterableParser(iterableNodeType, openTokenType, closeTokenType, item
def next(self, value): def next(self, value):
self[1] = value self[1] = value
@classmethod class AbstractIterableTail(AbstractIterable):
def _parse(cls, input): pass
def abstractIterableParser(input):
return Parser.oneOf( return Parser.oneOf(
AbstractIterableTailNode._parser1(), emptyIterable,
AbstractIterableTailNode._parser2(), openIterable
)(input) )(input)
@staticmethod def emptyIterable(input):
def _parser1(): def createNode(open, close):
return Parser.terminalParser(closeTokenType) node = AbstractIterable(open.pos)
node.value = open
@staticmethod node.next = close
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, doAssert=True),
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 node
return Parser.allOf( return Parser.allOf(
Parser.terminalParser(openTokenType), Parser.terminalParser(openTokenType),
Parser.terminalParser(closeTokenType), Parser.terminalParser(closeTokenType),
createNode=emptyIterable createNode=createNode
) )(input)
@staticmethod def openIterable(input):
def _parser2(): def createNode(open, item, tail):
def createNode(openParen, expr, iterableTail): node = AbstractIterable(open.pos)
node = AbstractIterableNode(openParen.pos) node.value = item
node.value = expr node.next = tail
node.next = iterableTail
return node return node
return Parser.allOf( return Parser.allOf(
Parser.terminalParser(openTokenType, lambda val, pos: Node(pos)), Parser.terminalParser(openTokenType),
itemParser, itemParser,
AbstractIterableTailNode.parse, abstractIterableTailParser,
createNode=createNode createNode=createNode
) )(input)
return toFlatDesiredNode(iterableNodeType, AbstractIterableNode.parse) def abstractIterableTailParser(input):
return Parser.oneOf(
closeIterable,
nextItem,
)(input)
def nextItem(input):
def createNode(comma, item, tail):
node = AbstractIterableTail(item.pos)
node.value = item
node.next = tail
return node
return Parser.allOf(
Parser.terminalParser(TokenType.COMMA, doAssert=True),
itemParser,
abstractIterableTailParser,
createNode=createNode
)(input)
def closeIterable(input):
return Parser.terminalParser(closeTokenType)(input)
return toFlatDesiredNode(iterableNodeType, abstractIterableParser)
#
# @classmethod
# def _parse(cls, input):
# return Parser.oneOf(
# AbstractIterableTail._parser1(input),
# AbstractIterableTail._parser2(input),
# )(input)
#
# @staticmethod
# def _parser1(input):
# return Parser.terminalParser(closeTokenType)
#
# class AbstractIterableNode(ExpressionNode):
# @classmethod
# def _parse(cls, input):
# return Parser.oneOf(
# AbstractIterableNode._parser1(input),
# AbstractIterableNode._parser2(input)
# )(input)
#
# @staticmethod
# def _parser1(input):
# 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(input):
# def createNode(openParen, expr, iterableTail):
# node = AbstractIterableNode(openParen.pos)
# node.value = expr
# node.next = iterableTail
# return node
#
# return Parser.allOf(
# Parser.terminalParser(openTokenType, lambda val, pos: Node(pos)),
# itemParser,
# AbstractIterableTail.parse,
# createNode=createNode
# )
#return toFlatDesiredNode(iterableNodeType, AbstractIterableNode.parse)
def toFlatDesiredNode(iterableNodeType, parser): def toFlatDesiredNode(iterableNodeType, parser):
@@ -114,7 +158,7 @@ def toFlatDesiredNode(iterableNodeType, parser):
return ParseResult.FAIL() return ParseResult.FAIL()
return parse return Parser(parse, "flat", [parser])
def flattenList(node, output=None): def flattenList(node, output=None):

View File

@@ -1,13 +1,12 @@
from smnp.ast.node.expression import ExpressionNode from smnp.ast.node.atom import AtomParser
from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.iterable import abstractIterableParser
from smnp.ast.node.operator import LeftAssociativeOperatorNode from smnp.ast.node.model import Node
from smnp.ast.parser import Parser
from smnp.token.type import TokenType from smnp.token.type import TokenType
class ListNode(LeftAssociativeOperatorNode): class ListNode(Node):
pass
@classmethod
def _lhsParser(cls): ListParser = abstractIterableParser(ListNode, TokenType.OPEN_SQUARE, TokenType.CLOSE_SQUARE,
return abstractIterableParser(ListNode, TokenType.OPEN_SQUARE, TokenType.CLOSE_SQUARE, AtomParser) #TODO -> zamienić na expr czy coś
Parser.doAssert(ExpressionNode.parse, "expression"))