From 0688f4292f21775dc3878e658b224fe93f996824 Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Sun, 6 Aug 2017 15:25:41 -0400 Subject: [PATCH] Use composition rather than inheritance to differentiate between different operators of the same level in parsing --- parsing.py | 107 ++++++++-------------------------------------- transformation.py | 37 ++++++++-------- 2 files changed, 36 insertions(+), 108 deletions(-) diff --git a/parsing.py b/parsing.py index 462c2b4..b791d46 100644 --- a/parsing.py +++ b/parsing.py @@ -65,89 +65,28 @@ FurParenthesizedExpression = collections.namedtuple( ], ) -FurAdditionExpression = collections.namedtuple( - 'FurAdditionExpression', +FurAdditionLevelExpression = collections.namedtuple( + 'FurAdditionLevelExpression', [ + 'operator', 'left', 'right', ], ) -FurSubtractionExpression = collections.namedtuple( - 'FurSubtractionExpression', +FurMultiplicationLevelExpression = collections.namedtuple( + 'FurMultiplicationLevelExpression', [ + 'operator', 'left', 'right', ], ) -FurMultiplicationExpression = collections.namedtuple( - 'FurMultiplicationExpression', - [ - 'left', - 'right', - ], -) - -FurIntegerDivisionExpression = collections.namedtuple( - 'FurIntegerDivisionExpression', - [ - 'left', - 'right', - ], -) - -FurModularDivisionExpression = collections.namedtuple( - 'FurModularDivisionExpression', - [ - 'left', - 'right', - ], -) - -FurEqualityExpression = collections.namedtuple( - 'FurEqualityExpression', - [ - 'left', - 'right', - ], -) - -FurInequalityExpression = collections.namedtuple( - 'FurInequalityExpression', - [ - 'left', - 'right', - ], -) - -FurLessThanOrEqualExpression = collections.namedtuple( - 'FurLessThanOrEqualExpression', - [ - 'left', - 'right', - ], -) - -FurGreaterThanOrEqualExpression = collections.namedtuple( - 'FurGreaterThanOrEqualExpression', - [ - 'left', - 'right', - ], -) - -FurLessThanExpression = collections.namedtuple( - 'FurLessThanExpression', - [ - 'left', - 'right', - ], -) - -FurGreaterThanExpression = collections.namedtuple( - 'FurGreaterThanExpression', +FurEqualityLevelExpression = collections.namedtuple( + 'FurEqualityLevelExpression', [ + 'operator', 'left', 'right', ], @@ -220,7 +159,7 @@ def _literal_level_expression_parser(index, tokens): _symbol_expression_parser, )(index, tokens) -def _left_recursive_infix_operator_parser(token_type, operand_parser, operator_to_expression_type_mapping): +def _left_recursive_infix_operator_parser(token_type, operand_parser, result_expression_type): def result_parser(index, tokens): failure = (False, index, None) @@ -236,7 +175,11 @@ def _left_recursive_infix_operator_parser(token_type, operand_parser, operator_t success, try_index, value = operand_parser(index + 1, tokens) if success: - result = operator_to_expression_type_mapping[tokens[index].match](left=result, right=value) + result = result_expression_type( + operator=tokens[index].match, + left=result, + right=value, + ) index = try_index return True, index, result @@ -247,35 +190,21 @@ def _multiplication_level_expression_parser(index, tokens): return _left_recursive_infix_operator_parser( 'multiplication_level_operator', _literal_level_expression_parser, - { - '*': FurMultiplicationExpression, - '//': FurIntegerDivisionExpression, - '%': FurModularDivisionExpression, - }, + FurMultiplicationLevelExpression, )(index, tokens) def _addition_level_expression_parser(index, tokens): return _left_recursive_infix_operator_parser( 'addition_level_operator', _multiplication_level_expression_parser, - { - '+': FurAdditionExpression, - '-': FurSubtractionExpression, - }, + FurAdditionLevelExpression, )(index, tokens) def _equality_level_expression_parser(index, tokens): return _left_recursive_infix_operator_parser( 'equality_level_operator', _addition_level_expression_parser, - { - '==': FurEqualityExpression, - '!=': FurInequalityExpression, - '>=': FurGreaterThanOrEqualExpression, - '<=': FurLessThanOrEqualExpression, - '>': FurGreaterThanExpression, - '<': FurLessThanExpression, - }, + FurEqualityLevelExpression, )(index, tokens) def _comma_separated_list_parser(index, tokens): diff --git a/transformation.py b/transformation.py index cd9d18d..e84a4bc 100644 --- a/transformation.py +++ b/transformation.py @@ -126,7 +126,6 @@ CAndExpression = collections.namedtuple( ], ) - CModularDivisionExpression = collections.namedtuple( 'CModularDivisionExpression', [ @@ -162,18 +161,18 @@ CProgram = collections.namedtuple( ], ) -EQUALITY_LEVEL_TYPE_MAPPING = { - parsing.FurEqualityExpression: CEqualityExpression, - parsing.FurInequalityExpression: CInequalityExpression, - parsing.FurLessThanOrEqualExpression: CLessThanOrEqualExpression, - parsing.FurGreaterThanOrEqualExpression: CGreaterThanOrEqualExpression, - parsing.FurLessThanExpression: CLessThanExpression, - parsing.FurGreaterThanExpression: CGreaterThanExpression, +EQUALITY_LEVEL_OPERATOR_MAPPING = { + '==': CEqualityExpression, + '!=': CInequalityExpression, + '<=': CLessThanOrEqualExpression, + '>=': CGreaterThanOrEqualExpression, + '<': CLessThanExpression, + '>': CGreaterThanExpression, } def transform_equality_level_expression(builtin_dependencies, symbol_list, expression): # Transform expressions like 1 < 2 < 3 into expressions like 1 < 2 && 2 < 3 - if type(expression.left) in EQUALITY_LEVEL_TYPE_MAPPING: + if isinstance(expression.left, parsing.FurEqualityLevelExpression): left = transform_equality_level_expression( builtin_dependencies, symbol_list, @@ -191,13 +190,13 @@ def transform_equality_level_expression(builtin_dependencies, symbol_list, expre # TODO Don't evaluate the middle expression twice return CAndExpression( left=left, - right=EQUALITY_LEVEL_TYPE_MAPPING[type(expression)]( + right=EQUALITY_LEVEL_OPERATOR_MAPPING[expression.operator]( left=middle, right=right, ), ) - return EQUALITY_LEVEL_TYPE_MAPPING[type(expression)]( + return EQUALITY_LEVEL_OPERATOR_MAPPING[expression.operator]( left=transform_expression(builtin_dependencies, symbol_list, expression.left), right=transform_expression(builtin_dependencies, symbol_list, expression.right), ) @@ -240,18 +239,18 @@ def transform_expression(builtin_dependencies, symbol_list, expression): if type(expression) in LITERAL_TYPE_MAPPING: return LITERAL_TYPE_MAPPING[type(expression)](value=expression.value) - if type(expression) in EQUALITY_LEVEL_TYPE_MAPPING: + if isinstance(expression, parsing.FurEqualityLevelExpression): return transform_equality_level_expression(builtin_dependencies, symbol_list, expression) - INFIX_TYPE_MAPPING = { - parsing.FurAdditionExpression: CAdditionExpression, - parsing.FurSubtractionExpression: CSubtractionExpression, - parsing.FurMultiplicationExpression: CMultiplicationExpression, - parsing.FurIntegerDivisionExpression: CIntegerDivisionExpression, - parsing.FurModularDivisionExpression: CModularDivisionExpression, + INFIX_OPERATOR_TO_TYPE_MAPPING = { + '+': CAdditionExpression, + '-': CSubtractionExpression, + '*': CMultiplicationExpression, + '//': CIntegerDivisionExpression, + '%': CModularDivisionExpression, } - return INFIX_TYPE_MAPPING[type(expression)]( + return INFIX_OPERATOR_TO_TYPE_MAPPING[expression.operator]( left=transform_expression(builtin_dependencies, symbol_list, expression.left), right=transform_expression(builtin_dependencies, symbol_list, expression.right), ) -- 2.20.1