From af3cb7027aa1b46ed4441cf1c5bbef0fba0cfb14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Thu, 11 Jul 2019 23:36:52 +0200 Subject: [PATCH] Add TypeParser (handling types list - specifiers etc.) --- smnp/ast/node/atom.py | 4 +- smnp/ast/node/expression.py | 2 +- smnp/ast/node/type.py | 74 ++++++++++++++++++++++++++++++- smnp/main.py | 9 ++-- smnp/token/tokenizers/keyword.py | 2 +- smnp/token/tokenizers/relation.py | 2 +- smnp/token/tools.py | 8 ++-- 7 files changed, 87 insertions(+), 14 deletions(-) diff --git a/smnp/ast/node/atom.py b/smnp/ast/node/atom.py index b1cfb6d..6f827aa 100644 --- a/smnp/ast/node/atom.py +++ b/smnp/ast/node/atom.py @@ -67,7 +67,7 @@ def BoolParser(input): return Parser.terminalParser(TokenType.BOOL, createNode=BoolLiteral.withValue)(input) -def TypeParser(input): +def TypeLiteralParser(input): return Parser.terminalParser(TokenType.TYPE, createNode=TypeLiteral.withValue)(input) @@ -77,7 +77,7 @@ def LiteralParser(input): StringParser, NoteParser, BoolParser, - TypeParser, + TypeLiteralParser, name="literal" )(input) diff --git a/smnp/ast/node/expression.py b/smnp/ast/node/expression.py index de9cac0..7c6e511 100644 --- a/smnp/ast/node/expression.py +++ b/smnp/ast/node/expression.py @@ -21,7 +21,7 @@ def ExpressionParser(input): expr2 = Parser.leftAssociativeOperatorParser( expr1, - [TokenType.RELATION], + [TokenType.RELATION, TokenType.OPEN_ANGLE, TokenType.CLOSE_ANGLE], expr1, lambda left, op, right: Expression.withValue(BinaryOperator.withValues(left, op, right)) ) diff --git a/smnp/ast/node/type.py b/smnp/ast/node/type.py index 5dc5189..be60221 100644 --- a/smnp/ast/node/type.py +++ b/smnp/ast/node/type.py @@ -5,7 +5,79 @@ # from smnp.token.type import TokenType # from smnp.type.model import Type # -# +from smnp.ast.node.atom import TypeLiteralParser +from smnp.ast.node.iterable import abstractIterableParser +from smnp.ast.node.model import Node +from smnp.ast.node.none import NoneNode +from smnp.ast.parser import Parser +from smnp.token.type import TokenType + + +class Type(Node): + def __init__(self, pos): + super().__init__(pos) + self.children = [NoneNode(), NoneNode()] + + @property + def type(self): + return self[0] + + @type.setter + def type(self, value): + self[0] = value + + @property + def specifiers(self): + return self[1] + + @specifiers.setter + def specifiers(self, value): + self[1] = value + + @classmethod + def withValues(cls, pos, type, specifiers=NoneNode()): + node = cls(pos) + node.type = type + node.specifiers = specifiers + return node + + +class TypesList(Node): + pass + + +def TypesListParser(input): + typeListItem = Parser.oneOf( + TypeParser + ) + + return abstractIterableParser( + TypesList, + TokenType.OPEN_ANGLE, + TokenType.CLOSE_ANGLE, + TypeParser + )(input) + + +class TypeSpecifiers(Node): + pass + + +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) + + # class TypeSpecifier(Node): # # @classmethod diff --git a/smnp/main.py b/smnp/main.py index 51e5ddf..784d92f 100644 --- a/smnp/main.py +++ b/smnp/main.py @@ -1,14 +1,15 @@ -import sys - +from smnp.ast.node.type import TypeParser from smnp.error.base import SmnpException -from smnp.program.interpreter import Interpreter +from smnp.token.tokenizer import tokenize def main(): try: #stdLibraryEnv = loadStandardLibrary() - Interpreter.interpretFile(sys.argv[1], printTokens=True, printAst=True, execute=False, baseEnvironment=None) + #Interpreter.interpretFile(sys.argv[1], printTokens=True, printAst=True, execute=False, baseEnvironment=None) #draft() + tokens = tokenize(['']) + TypeParser(tokens).node.print() except SmnpException as e: print(e.message()) diff --git a/smnp/token/tokenizers/keyword.py b/smnp/token/tokenizers/keyword.py index e1d2186..6658aa2 100644 --- a/smnp/token/tokenizers/keyword.py +++ b/smnp/token/tokenizers/keyword.py @@ -3,7 +3,7 @@ from smnp.token.type import TokenType from smnp.type.model import Type -typeTokenizer = separated(keywordsTokenizer(TokenType.TYPE, *[type.name.lower() for type in Type])) +typeTokenizer = separated(keywordsTokenizer(TokenType.TYPE, *[type.name.lower() for type in Type], mapKeyword=lambda value: Type[value.upper()])) diff --git a/smnp/token/tokenizers/relation.py b/smnp/token/tokenizers/relation.py index 1b70f81..485125d 100644 --- a/smnp/token/tokenizers/relation.py +++ b/smnp/token/tokenizers/relation.py @@ -3,4 +3,4 @@ from smnp.token.type import TokenType def relationOperatorTokenizer(input, current, line): - return keywordsTokenizer(TokenType.RELATION, "==", "!=", ">=", "<=", ">", "<")(input, current, line) \ No newline at end of file + return keywordsTokenizer(TokenType.RELATION, "==", "!=", ">=", "<=")(input, current, line) \ No newline at end of file diff --git a/smnp/token/tools.py b/smnp/token/tools.py index 88d73fa..d6ac7ad 100644 --- a/smnp/token/tools.py +++ b/smnp/token/tools.py @@ -16,10 +16,10 @@ def regexPatternTokenizer(type, pattern): return tokenizer -def keywordsTokenizer(type, *keywords): +def keywordsTokenizer(type, *keywords, mapKeyword=lambda x: x): def tokenizer(input, current, line): for keyword in keywords: - result = keywordTokenizer(type, keyword)(input, current, line) + result = keywordTokenizer(type, keyword, mapKeyword)(input, current, line) if result[0] > 0: return result return (0, None) @@ -27,10 +27,10 @@ def keywordsTokenizer(type, *keywords): return tokenizer -def keywordTokenizer(type, keyword): +def keywordTokenizer(type, keyword, mapKeyword=lambda x: x): def tokenizer(input, current, line): if len(input) >= current+len(keyword) and input[current:current+len(keyword)] == keyword: - return (len(keyword), Token(type, keyword, (line, current))) + return (len(keyword), Token(type, mapKeyword(keyword), (line, current))) return (0, None) return tokenizer