示例#1
0
def ImportParser(input):
    return Parser.allOf(
        Parser.terminal(TokenType.IMPORT),
        Parser.doAssert(StringParser, "import source as string"),
        createNode=lambda imp, source: Import.withValue(source),
        name="import"
    )(input)
示例#2
0
def ReturnParser(input):
    return Parser.allOf(
        Parser.terminal(TokenType.RETURN),
        Parser.optional(ExpressionParser),
        createNode=lambda ret, val: Return.withValue(val, ret.pos),
        name="return"
    )(input)
示例#3
0
def BlockParser(input):
    return Parser.loop(
        Parser.terminal(TokenType.OPEN_CURLY),
        Parser.doAssert(StatementParser,
                        f"statement or '{TokenType.CLOSE_CURLY.key}'"),
        Parser.terminal(TokenType.CLOSE_CURLY),
        createNode=lambda open, statements, close: Block.withChildren(
            statements, open.pos))(input)
示例#4
0
def MethodsDeclarationParser(input):
    return Parser.loop(
        Parser.terminal(TokenType.OPEN_CURLY),
        Parser.doAssert(FunctionDefinitionParser,
                        f"method definition or '{TokenType.CLOSE_CURLY.key}'"),
        Parser.terminal(TokenType.CLOSE_CURLY),
        createNode=lambda open, methods, close: Block.withChildren(
            methods, open.pos),
        name="methods block")(input)
示例#5
0
    def emptyIterable(input):
        def createNode(open, close):
            node = AbstractIterable(open.pos)
            node.value = open
            node.next = close
            return node

        return Parser.allOf(Parser.terminal(openTokenType),
                            Parser.terminal(closeTokenType),
                            createNode=createNode)(input)
示例#6
0
def withSemicolon(parser, optional=False, doAssert=False):
    semicolonParser = Parser.optional(Parser.terminal(TokenType.SEMICOLON)) if optional else Parser.terminal(
        TokenType.SEMICOLON, doAssert=doAssert)

    return Parser.allOf(
        parser,
        semicolonParser,
        createNode=lambda stmt, semicolon: stmt,
        name="semicolon" + "?" if optional else ""
    )
示例#7
0
def FunctionDefinitionParser(input):
    return Parser.allOf(Parser.terminal(TokenType.FUNCTION),
                        Parser.doAssert(IdentifierLiteralParser,
                                        "function/method name"),
                        Parser.doAssert(ArgumentsDeclarationParser,
                                        "function/method arguments"),
                        Parser.doAssert(BlockParser, "function/method body"),
                        createNode=lambda _, name, args, body:
                        FunctionDefinition.withValues(name, args, body),
                        name="function definition")(input)
示例#8
0
    def openIterable(input):
        def createNode(open, item, tail):
            node = AbstractIterable(open.pos)
            node.value = item
            node.next = tail
            return node

        return Parser.allOf(Parser.terminal(openTokenType),
                            itemParser,
                            abstractIterableTailParser,
                            createNode=createNode)(input)
示例#9
0
def TypeParser(input):
    typeWithSpecifier = Parser.allOf(
        TypeLiteralParser,
        Parser.many(TypesListParser, createNode=TypeSpecifiers.withChildren),
        createNode=lambda type, specifiers: Type.withValues(
            type.pos, type, specifiers),
        name="type with specifiers?")

    return Parser.oneOf(typeWithSpecifier,
                        TypesListParser,
                        name="mult. types or type with specifier")(input)
示例#10
0
    def nextItem(input):
        def createNode(comma, item, tail):
            node = AbstractIterableTail(item.pos)
            node.value = item
            node.next = tail
            return node

        return Parser.allOf(Parser.doAssert(
            Parser.terminal(TokenType.COMMA),
            f"'{TokenType.COMMA.key}' or '{closeTokenType.key}'"),
                            itemParser,
                            abstractIterableTailParser,
                            createNode=createNode)(input)
示例#11
0
def MapParser(input):
    from smnp.ast.node.expression import ExpressionParser
    keyParser = Parser.oneOf(LiteralParser, IdentifierLiteralParser)
    valueParser = ExpressionParser

    mapEntryParser = Parser.allOf(keyParser,
                                  Parser.terminal(
                                      TokenType.ARROW,
                                      createNode=Operator.withValue),
                                  Parser.doAssert(valueParser, "expression"),
                                  createNode=MapEntry.withValues)

    return abstractIterableParser(Map, TokenType.OPEN_CURLY,
                                  TokenType.CLOSE_CURLY, mapEntryParser)(input)
示例#12
0
def OptionalArgumentParser(input):
    def createNode(type, variable, _, optional):
        pos = type.pos if isinstance(type, Type) else variable.pos
        node = Argument(pos)
        node.type = type
        node.variable = variable
        node.optionalValue = optional
        return node

    return Parser.allOf(Parser.optional(TypeParser),
                        Parser.doAssert(IdentifierLiteralParser,
                                        "argument name"),
                        Parser.terminal(TokenType.ASSIGN),
                        Parser.doAssert(ExpressionParser, "expression"),
                        createNode=createNode,
                        name="optional function argument")(input)
示例#13
0
def LiteralParser(input):
    return Parser.oneOf(IntegerParser,
                        FloatParser,
                        StringParser,
                        NoteParser,
                        BoolParser,
                        TypeLiteralParser,
                        name="literal")(input)
示例#14
0
def ExpressionWithoutLoopParser(input):
    expr1 = Parser.leftAssociativeOperatorParser(
        TermParser, [TokenType.PLUS, TokenType.MINUS], TermParser,
        lambda left, op, right: Sum.withValues(left, op, right))

    expr2 = Parser.leftAssociativeOperatorParser(
        expr1,
        [TokenType.RELATION, TokenType.OPEN_ANGLE, TokenType.CLOSE_ANGLE],
        expr1, lambda left, op, right: Relation.withValues(left, op, right))

    expr3 = Parser.leftAssociativeOperatorParser(
        expr2, [TokenType.AND], expr2,
        lambda left, op, right: And.withValues(left, op, right))

    return Parser.leftAssociativeOperatorParser(
        expr3, [TokenType.OR], expr3,
        lambda left, op, right: Or.withValues(left, op, right))(input)
示例#15
0
def RegularArgumentParser(input):
    def createNode(type, variable, vararg):
        pos = type.pos if isinstance(type, Type) else variable.pos
        node = Argument(pos)
        node.type = type
        node.variable = variable
        node.vararg = vararg is True
        return node

    return Parser.allOf(Parser.optional(TypeParser),
                        Parser.doAssert(IdentifierLiteralParser,
                                        "argument name"),
                        Parser.optional(
                            Parser.terminal(TokenType.DOTS,
                                            lambda val, pos: True)),
                        createNode=createNode,
                        name="regular function argument")(input)
示例#16
0
def AtomParser(input):
    from smnp.ast.node.identifier import IdentifierParser
    from smnp.ast.node.list import ListParser
    from smnp.ast.node.map import MapParser
    from smnp.ast.node.expression import ExpressionParser

    parentheses = Parser.allOf(Parser.terminal(TokenType.OPEN_PAREN),
                               Parser.doAssert(ExpressionParser, "expression"),
                               Parser.terminal(TokenType.CLOSE_PAREN),
                               createNode=lambda open, expr, close: expr,
                               name="grouping parentheses")

    return Parser.oneOf(parentheses,
                        LiteralParser,
                        IdentifierParser,
                        ListParser,
                        MapParser,
                        name="atom")(input)
示例#17
0
def ListParser(input):
    from smnp.ast.node.expression import ExpressionParser

    return abstractIterableParser(
        List,
        TokenType.OPEN_SQUARE,
        TokenType.CLOSE_SQUARE,
        Parser.doAssert(ExpressionParser, "expression")
    )(input)
示例#18
0
def IdentifierParser(input):
    functionCallParser = Parser.allOf(
        IdentifierLiteralParser,
        abstractIterableParser(ArgumentsList, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN, Parser.doAssert(ExpressionParser, "expression")),
        createNode=lambda name, arguments: FunctionCall.withChildren(name, arguments)
    )

    assignmentParser = Parser.allOf(
        IdentifierLiteralParser,
        Parser.terminal(TokenType.ASSIGN, createNode=Operator.withValue),
        Parser.doAssert(ExpressionParser, "expression"),
        createNode=lambda identifier, assign, expr: Assignment.withValues(identifier, assign, expr)
    )

    return Parser.oneOf(
        assignmentParser,
        functionCallParser,
        IdentifierLiteralParser
    )(input)
示例#19
0
def FactorParser(input):

    powerFactor = Parser.leftAssociativeOperatorParser(
        UnitParser,
        [TokenType.DOUBLE_ASTERISK],
        UnitParser,
        lambda left, op, right: Power.withValues(left, op, right),
        name="power operator"
    )

    notOperator = Parser.allOf(
        Parser.terminal(TokenType.NOT, Operator.withValue),
        powerFactor,
        createNode=NotOperator.withValues,
        name="not"
    )

    return Parser.oneOf(
        notOperator,
        powerFactor,
        name="factor"
    )(input)
示例#20
0
def toFlatDesiredNode(iterableNodeType, parser):
    def parse(input):
        result = parser(input)

        if result.result:
            value = flattenList(result.node)
            node = iterableNodeType(result.node.pos)
            node.children.clear()
            for v in value:
                node.append(v)
            return ParseResult.OK(node)

        return ParseResult.FAIL()

    return Parser(parse, "flat", [parser])
示例#21
0
def StatementParser(input):
    from smnp.ast.node.block import BlockParser
    from smnp.ast.node.condition import IfElseStatementParser
    from smnp.ast.node.expression import ExpressionParser
    from smnp.ast.node.ret import ReturnParser
    from smnp.ast.node.throw import ThrowParser

    return withSemicolon(
        Parser.oneOf(
            IfElseStatementParser,
            ExpressionParser,  # Must be above BlockParser because of Map's syntax with curly braces
            BlockParser,
            ReturnParser,
            ThrowParser,
            name="statement"
        ), optional=True)(input)
示例#22
0
def UnitParser(input):
    minusOperator = Parser.allOf(Parser.terminal(
        TokenType.MINUS, createNode=Operator.withValue),
                                 Parser.doAssert(AtomParser, "atom"),
                                 createNode=MinusOperator.withValues,
                                 name="minus")

    atom2 = Parser.oneOf(minusOperator, AtomParser, name="atom2")

    return Parser.leftAssociativeOperatorParser(
        atom2, [TokenType.DOT],
        Parser.doAssert(atom2, "atom"),
        createNode=lambda left, op, right: Access.withValues(left, op, right),
        name="unit")(input)
示例#23
0
    def parse(input):
        root = Program()

        # Start Symbol
        startSymbolParser = Parser.oneOf(
            ImportParser,
            FunctionDefinitionParser,
            ExtendParser,
            StatementParser,
            exception=lambda inp: SyntaxException(
                f"Invalid statement: {inp.currentToEndOfLine()}",
                inp.current().pos),
            name="start symbol")

        while input.hasCurrent():
            result = startSymbolParser(input)

            if result.result:
                root.append(result.node)

        return ParseResult.OK(root)
示例#24
0
def TypeLiteralParser(input):
    return Parser.terminal(TokenType.TYPE,
                           createNode=TypeLiteral.withValue)(input)
示例#25
0
def ArgumentsDeclarationParser(input):
    return abstractIterableParser(
        ArgumentsDeclaration, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN,
        Parser.doAssert(ArgumentParser, "function/method argument"))(input)
示例#26
0
def ArgumentParser(input):
    return Parser.oneOf(OptionalArgumentParser,
                        RegularArgumentParser,
                        name="function argument")(input)
示例#27
0
def NoteParser(input):
    return Parser.terminal(TokenType.NOTE,
                           createNode=NoteLiteral.withValue)(input)
示例#28
0
def ExtendParser(input):

    simpleExtend = Parser.allOf(
        Parser.terminal(TokenType.EXTEND),
        TypeParser,
        Parser.terminal(TokenType.AS),
        IdentifierLiteralParser,
        Parser.terminal(TokenType.WITH),
        Parser.doAssert(
            Parser.wrap(
                FunctionDefinitionParser,
                lambda method: Block.withChildren([method], method.pos)),
            "method definition"),
        createNode=lambda extend, type, _, variable, __, methods: Extend.
        withValues(extend.pos, type, variable, methods),
        name="simple extend")

    multiExtend = Parser.allOf(
        Parser.terminal(TokenType.EXTEND),
        Parser.doAssert(TypeParser, "type being extended"),
        Parser.terminal(TokenType.AS, doAssert=True),
        Parser.doAssert(IdentifierLiteralParser, "variable name"),
        Parser.doAssert(
            MethodsDeclarationParser,
            f"block with methods definitions or '{TokenType.WITH.key}' keyword"
        ),
        createNode=lambda extend, type, _, variable, methods: Extend.
        withValues(extend.pos, type, variable, methods),
        name="multiple extend")

    return Parser.oneOf(simpleExtend, multiExtend, name="extend")(input)
示例#29
0
def BoolParser(input):
    return Parser.terminal(TokenType.BOOL,
                           createNode=BoolLiteral.withValue)(input)
示例#30
0
def IdentifierLiteralParser(input):
    return Parser.terminal(TokenType.IDENTIFIER, createNode=Identifier.withValue)(input)