From 19908b97a6523bdf8fb21120dff5fa19870be848 Mon Sep 17 00:00:00 2001 From: Kodjo Sossouvi Date: Thu, 11 Mar 2021 18:00:50 +0100 Subject: [PATCH] Working on #48 : Refactored FunctionParser.py --- src/parsers/BaseExpressionParser.py | 12 +++----- src/parsers/FunctionParser.py | 39 +++++++++---------------- src/parsers/LogicalOperatorParser.py | 8 ++--- src/parsers/RelationalOperatorParser.py | 9 ++---- 4 files changed, 22 insertions(+), 46 deletions(-) diff --git a/src/parsers/BaseExpressionParser.py b/src/parsers/BaseExpressionParser.py index ab06b35..54027da 100644 --- a/src/parsers/BaseExpressionParser.py +++ b/src/parsers/BaseExpressionParser.py @@ -395,18 +395,14 @@ class BaseExpressionParser(BaseParser): def parse_input(self, context, parser_input, error_sink): raise NotImplementedError - def inner_parse_names(self, context, parser_input, error_sink, stop_condition): - - # def stop(): - # return token.type == TokenKind.EOF or \ - # paren_count == 0 and token.type == TokenKind.RPAR or \ - # token.type == TokenKind.IDENTIFIER and token.value in ("and", "or") or \ - # token.value == "not" and parser_input.the_token_after(True).value != "in" + def parse_tokens_stop_condition(self, token, parser_input): + raise NotImplementedError + def parse_tokens(self, context, parser_input, error_sink): def stop(): return token.type == TokenKind.EOF or \ paren_count == 0 and token.type == TokenKind.RPAR or \ - stop_condition(token, parser_input) + self.parse_tokens_stop_condition(token, parser_input) token = parser_input.token if token.type == TokenKind.EOF: diff --git a/src/parsers/FunctionParser.py b/src/parsers/FunctionParser.py index b5b3dbf..b1be237 100644 --- a/src/parsers/FunctionParser.py +++ b/src/parsers/FunctionParser.py @@ -39,6 +39,7 @@ class FunctionParser(BaseExpressionParser): super().__init__(self.NAME, 55) self.sep = sep self.longest_concepts_only = longest_concepts_only + self.expr_parser = kwargs.get("expr_parser", None) def function_parser_get_return_value_body(self, context, source, source_code_node): if source_code_node.error_when_parsing: @@ -51,12 +52,6 @@ class FunctionParser(BaseExpressionParser): body=source_code_node, try_parsed=source_code_node) - # def add_error(self, error, next_token=True): - # if not self.record_errors: - # return - # - # return super().add_error(error, next_token) - def parse(self, context, parser_input: ParserInput): ret = super().parse(context, parser_input) @@ -115,12 +110,15 @@ class FunctionParser(BaseExpressionParser): [TokenKind.RPAR])) return FunctionNode(start, parser_input.pos, [], start_node, None, params) - return FunctionNode(start, - parser_input.pos, - parser_input.tokens[start:parser_input.pos + 1], - start_node, - NameExprNode(parser_input.pos, parser_input.pos, [token]), - params) + ret = FunctionNode(start, + parser_input.pos, + parser_input.tokens[start:parser_input.pos + 1], + start_node, + NameExprNode(parser_input.pos, parser_input.pos, [token]), + params) + + parser_input.next_token() # do not forget to eat the trailing parenthesis + return ret def parse_parameters(self, context, parser_input, error_sink): nodes = [] @@ -157,25 +155,14 @@ class FunctionParser(BaseExpressionParser): new_error_sink = ErrorSink() func = self.parse_function(context, parser_input, new_error_sink) if func and not new_error_sink.has_error: - parser_input.next_token() return func # otherwise, eat until LPAR or separator parser_input.seek(start_pos) - tokens = [] - while True: - token = parser_input.token - if token is None: - break + return self.parse_tokens(context, parser_input, error_sink) - if token.value == self.sep or token.type == TokenKind.RPAR: - break - - tokens.append(token) - if not parser_input.next_token(skip_whitespace=False): - break - - return NameExprNode(start_pos, parser_input.pos - 1, tokens) if len(tokens) else None + def parse_tokens_stop_condition(self, token, parser_input): + return token.value == self.sep def to_source_code_node(self, context, function_node: FunctionNode): python_parser = PythonWithConceptsParser() diff --git a/src/parsers/LogicalOperatorParser.py b/src/parsers/LogicalOperatorParser.py index 69fbc30..2374db4 100644 --- a/src/parsers/LogicalOperatorParser.py +++ b/src/parsers/LogicalOperatorParser.py @@ -148,16 +148,12 @@ class LogicalOperatorParser(BaseExpressionParser): parser_input.tokens[start: parsed.end + 1], node) else: - return self.parse_names(context, parser_input, error_sink) + return self.parse_tokens(context, parser_input, error_sink) - @staticmethod - def stop_condition(token, parser_input): + def parse_tokens_stop_condition(self, token, parser_input): return token.type == TokenKind.IDENTIFIER and token.value in ("and", "or") or \ token.value == "not" and parser_input.the_token_after(True).value != "in" - def parse_names(self, context, parser_input, error_sink): - return self.inner_parse_names(context, parser_input, error_sink, self.stop_condition) - def compile_conjunctions(self, context, conjunctions, who): """ Transform a list of conjunctions (AND and OR) into one or multiple CompiledExpr diff --git a/src/parsers/RelationalOperatorParser.py b/src/parsers/RelationalOperatorParser.py index d02d891..b804eec 100644 --- a/src/parsers/RelationalOperatorParser.py +++ b/src/parsers/RelationalOperatorParser.py @@ -21,14 +21,14 @@ class RelationalOperatorParser(BaseExpressionParser): def parse_compare(self, context, parser_input, error_sink): start = parser_input.pos - left = self.parse_names(context, parser_input, error_sink) + left = self.parse_tokens(context, parser_input, error_sink) if left is None: return None if (comp := self.eat_comparison(parser_input)) is None: return left - right = self.parse_names(context, parser_input, error_sink) + right = self.parse_tokens(context, parser_input, error_sink) if comp == ComparisonType.IN and not isinstance(right, ParenthesisNode): t = right.tokens[0] @@ -40,12 +40,9 @@ class RelationalOperatorParser(BaseExpressionParser): end = right.end if right else parser_input.pos return ComparisonNode(start, end, parser_input.tokens[start: end + 1], comp, left, right) - def stop_condition(self, token, parser_input): + def parse_tokens_stop_condition(self, token, parser_input): return self.eat_comparison(parser_input, False) - def parse_names(self, context, parser_input, error_sink): - return self.inner_parse_names(context, parser_input, error_sink, self.stop_condition) - @staticmethod def eat_comparison(parser_input, eat=True): token = parser_input.token