Do some refactor with multiple left associative operators

This commit is contained in:
Bartłomiej Pluta
2019-07-10 15:25:00 +02:00
parent 0a7d29d4a1
commit e008be7952
6 changed files with 52 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
from smnp.ast.node.expression import ExpressionNode
from smnp.ast.node.ignore import IgnoredNode
from smnp.ast.node.none import NoneNode
from smnp.ast.parser import Parser
from smnp.error.syntax import SyntaxException
from smnp.token.type import TokenType
@@ -8,7 +8,7 @@ from smnp.token.type import TokenType
class AccessNode(ExpressionNode):
def __init__(self, pos):
super().__init__(pos)
self.children.append(IgnoredNode(pos))
self.children = [ NoneNode(), NoneNode() ]
@property
def left(self):
@@ -28,29 +28,29 @@ class AccessNode(ExpressionNode):
@classmethod
def accessParser(cls):
def createNode(left, right):
def createNode(left, operator, right):
node = AccessNode(right.pos)
node.left = left
node.right = right
return node
return Parser.leftAssociativeOperatorParser(
cls._accessLiteralParser(),
cls._accessLhs(),
TokenType.DOT,
cls._parseAccessingProperty(),
cls._accessRhs(),
createNode=createNode
)
@classmethod
def _accessLiteralParser(cls):
raise RuntimeError(f"_accessLiteralParser() is not implemented in {cls.__name__} class")
def _accessLhs(cls):
raise RuntimeError(f"_accessLhs() is not implemented in {cls.__name__} class")
@staticmethod
def _parseAccessingProperty():
def _accessRhs():
from smnp.ast.node.identifier import IdentifierNode
return Parser.oneOf(
IdentifierNode.functionCallParser(),
IdentifierNode.identifierParser(),
IdentifierNode._functionCallParser(),
exception=lambda input: SyntaxException(f"Expected property name or method call, found '{input.current().rawValue}'", input.currentPos())
)

View File

@@ -17,7 +17,6 @@ class BoolLiteralNode(LiteralNode, AccessNode, RelationOperatorNode):
@classmethod
def _parse(cls, input):
x = Parser.oneOf(
cls.relationParser(),
cls.accessParser(),
cls.literalParser()
@@ -25,9 +24,9 @@ class BoolLiteralNode(LiteralNode, AccessNode, RelationOperatorNode):
return x
@classmethod
def _accessLiteralParser(cls):
def _accessLhs(cls):
return cls.literalParser()
@classmethod
def _relationLiteralParser(cls):
def _relationLhs(cls):
return cls.literalParser()

View File

@@ -14,7 +14,7 @@ class IdentifierNode(AccessNode):
@classmethod
def _literalParser(cls):
return Parser.oneOf(
IdentifierNode._functionCallParser(),
IdentifierNode.functionCallParser(),
IdentifierNode._assignmentParser(),
IdentifierNode.identifierParser()
)
@@ -35,7 +35,7 @@ class IdentifierNode(AccessNode):
)
@staticmethod
def _functionCallParser():
def functionCallParser():
def createNode(name, arguments):
node = FunctionCallNode(name.pos)
node.name = name

15
smnp/ast/node/operator.py Normal file
View File

@@ -0,0 +1,15 @@
from smnp.ast.node.model import Node
class OperatorNode(Node):
def __init__(self, pos):
super().__init__(pos)
self.children = [None]
@property
def value(self):
return self[0]
@value.setter
def value(self, value):
self[0] = value

View File

@@ -1,5 +1,5 @@
from smnp.ast.node.expression import ExpressionNode
from smnp.ast.node.ignore import IgnoredNode
from smnp.ast.node.none import NoneNode
from smnp.ast.parser import Parser
from smnp.token.type import TokenType
@@ -7,7 +7,7 @@ from smnp.token.type import TokenType
class RelationOperatorNode(ExpressionNode):
def __init__(self, pos):
super().__init__(pos)
self.children.append(IgnoredNode(pos))
self.children = [ NoneNode(), NoneNode(), NoneNode()]
@property
def left(self):
@@ -18,33 +18,42 @@ class RelationOperatorNode(ExpressionNode):
self[0] = value
@property
def right(self):
def operator(self):
return self[1]
@operator.setter
def operator(self, value):
self[1] = value
@property
def right(self):
return self[2]
@right.setter
def right(self, value):
self[1] = value
self[2] = value
@classmethod
def relationParser(cls):
def createNode(left, right):
def createNode(left, operator, right):
node = RelationOperatorNode(right.pos)
node.left = left
node.operator = operator
node.right = right
return node
return Parser.leftAssociativeOperatorParser(
cls._relationLiteralParser(),
cls._relationLhs(),
TokenType.EQUAL,
cls._parseRelationProperty(),
cls._relationRhs(),
createNode=createNode
)
@classmethod
def _relationLiteralParser(cls):
raise RuntimeError(f"_relationLiteralParser() is not implemented in {cls.__name__} class")
def _relationLhs(cls):
raise RuntimeError(f"_relationLhs() is not implemented in {cls.__name__} class")
@staticmethod
def _parseRelationProperty():
def _relationRhs():
# TODO doAssert
return ExpressionNode.parse

View File

@@ -1,6 +1,7 @@
from smnp.ast.node.ignore import IgnoredNode
from smnp.ast.node.model import ParseResult, Node
from smnp.ast.node.none import NoneNode
from smnp.ast.node.operator import OperatorNode
from smnp.error.syntax import SyntaxException
@@ -99,11 +100,12 @@ class Parser:
left = leftParser(input)
oneAtLeast = False
if left.result:
while Parser.terminalParser(operatorTokenType)(input).result:
operator = Parser.terminalParser(operatorTokenType, lambda val, pos: OperatorNode.withChildren([val], pos))(input)
while operator.result:
oneAtLeast = True
right = rightParser(input)
left = ParseResult.OK(createNode(left.node, right.node))
left = ParseResult.OK(createNode(left.node, operator.node, right.node))
operator = Parser.terminalParser(operatorTokenType)(input)
if oneAtLeast:
return left