from smnp.ast.node.chain import ChainParser from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.model import Node from smnp.ast.node.none import NoneNode from smnp.ast.node.operator import BinaryOperator, Operator, UnaryOperator from smnp.ast.node.valuable import Valuable from smnp.ast.parser import Parser from smnp.token.type import TokenType class Factor(Valuable): pass class NotOperator(UnaryOperator): pass class Loop(BinaryOperator): def __init__(self, pos): super().__init__(pos) self.children.append(NoneNode()) @property def parameters(self): return self[3] @parameters.setter def parameters(self, value): self[3] = value @classmethod def loop(cls, left, parameters, operator, right): node = cls(left.pos) node.left = left node.parameters = parameters node.operator = operator node.right = right return node class LoopParameters(Node): pass def FactorParser(input): from smnp.ast.node.expression import ExpressionParser from smnp.ast.node.statement import StatementParser from smnp.ast.node.identifier import IdentifierLiteralParser powerFactor = Parser.leftAssociativeOperatorParser( ChainParser, [TokenType.DOUBLE_ASTERISK], ChainParser, lambda left, op, right: Factor.withValue(BinaryOperator.withValues(left, op, right)), name="power operator" ) exprFactor = Parser.allOf( Parser.terminal(TokenType.OPEN_PAREN), ExpressionParser, Parser.terminal(TokenType.CLOSE_PAREN), createNode=lambda open, expr, close: expr, name="grouping parentheses" ) factorParser = Parser.oneOf( powerFactor, exprFactor, name="basic factor" ) notOperator = Parser.allOf( Parser.terminal(TokenType.NOT, Operator.withValue), factorParser, createNode=NotOperator.withValues, name="not" ) loopParameters = Parser.allOf( Parser.terminal(TokenType.AS), Parser.oneOf( Parser.wrap(IdentifierLiteralParser, lambda id: LoopParameters.withChildren([id], id.pos)), abstractIterableParser(LoopParameters, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN, IdentifierLiteralParser) ), createNode=lambda asKeyword, parameters: parameters, name="loop parameters" ) loopFactor = Parser.allOf( factorParser, Parser.optional(loopParameters), Parser.terminal(TokenType.DASH, createNode=Operator.withValue), StatementParser, createNode=Loop.loop, name="dash-loop" ) return Parser.oneOf( loopFactor, notOperator, factorParser )(input)