Create PoC of working left associativity

This commit is contained in:
Bartłomiej Pluta
2019-07-05 20:55:36 +02:00
parent bacaeb0005
commit 9e6ead49d2
5 changed files with 76 additions and 5 deletions

View File

@@ -0,0 +1,16 @@
from smnp.newast.node.expression import ExpressionNode
from smnp.newast.node.ignore import IgnoredNode
class AccessNode(ExpressionNode):
def __init__(self, pos):
super().__init__(pos)
self.children.append(IgnoredNode(pos))
@property
def next(self):
return self[1]
@next.setter
def next(self, value):
self[1] = value

View File

@@ -1,3 +1,4 @@
from smnp.newast.node.access import AccessNode
from smnp.newast.node.expression import ExpressionNode
from smnp.newast.parser import Parser
from smnp.token.type import TokenType
@@ -7,5 +8,26 @@ class IntegerLiteralNode(ExpressionNode):
@classmethod
def _parse(cls, input):
def createNode(left, right):
node = AccessNode(right.pos)
node.value = left
node.next = right
return node
return Parser.leftAssociativeOperatorParser(
IntegerLiteralNode._parseInteger(),
TokenType.DOT,
IntegerLiteralNode._parseAccessingProperty(),
createNode=createNode
)(input)
@staticmethod
def _parseInteger():
createNode = lambda v, pos: IntegerLiteralNode.withValue(v, pos)
return Parser.terminalParser(TokenType.INTEGER, createNode)(input)
return Parser.terminalParser(TokenType.INTEGER, createNode)
@staticmethod
def _parseAccessingProperty():
# TODO: Just for example. It is supposed to be functionCall (and identifier there)
return IntegerLiteralNode._parseInteger()

View File

@@ -56,6 +56,9 @@ class Node:
else:
print(prefix, '' if last else '', f"'{str(child)}'", sep="")
def __str__(self):
return self.__class__.__name__
class ParseResult():
def __init__(self, result, node):
@@ -72,4 +75,7 @@ class ParseResult():
def OK(node):
return ParseResult(True, node)
def __str__(self):
return f"{'OK' if self.result else 'FAILED'}[{self.node}]"

View File

@@ -1,5 +1,5 @@
from smnp.newast.node.ignore import IgnoredNode
from smnp.newast.node.model import ParseResult
from smnp.newast.node.model import ParseResult, Node
class Parser:
@@ -46,6 +46,7 @@ class Parser:
return ParseResult.FAIL()
return combinedParser
@staticmethod
def allOf(*parsers, createNode, exception=None):
if len(parsers) == 0:
@@ -68,8 +69,36 @@ class Parser:
results.append(result.node)
return ParseResult.OK(createNode(*results))
node = createNode(*results)
if not isinstance(node, Node):
raise RuntimeError("Function 'createNode' haven't returned a Node object. Probably forget to pass 'return'")
return ParseResult.OK(node)
return extendedParser
# leftAssociative -> left | left OP right
@staticmethod
def leftAssociativeOperatorParser(leftParser, operatorTokenType, rightParser, createNode):
def parse(input):
left = leftParser(input)
if left.result:
while Parser.terminalParser(operatorTokenType)(input).result:
right = rightParser(input)
left = ParseResult.OK(createNode(left.node, right.node))
return left
return ParseResult.FAIL()
return parse
@staticmethod
def epsilon():
def parser(input):
return ParseResult.OK(IgnoredNode((-1, -1)))
return parser