+ success, index, value = _literal_level_expression_parser(index + 1, tokens)
+
+ if not success:
+ return failure
+
+ return (True, index, FurNegationExpression(value=value))
+
+def _literal_level_expression_parser(index, tokens):
+ return _or_parser(
+ _negation_expression_parser,
+ _function_call_expression_parser,
+ _parenthesized_expression_parser,
+ _integer_literal_expression_parser,
+ _string_literal_expression_parser,
+ _symbol_expression_parser,
+ )(index, tokens)
+
+def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser, order):
+ def result_parser(index, tokens):
+ failure = (False, index, None)
+
+ success, index, result = operand_parser(index, tokens)
+
+ if not success:
+ return failure
+
+ while success and index < len(tokens) and operator_token_matcher(tokens[index]):
+ success = False
+
+ if index + 1 < len(tokens):
+ success, try_index, value = operand_parser(index + 1, tokens)
+
+ if success:
+ result = FurInfixExpression(
+ order=order,
+ operator=tokens[index].match,
+ left=result,
+ right=value,
+ )
+ index = try_index
+
+ return True, index, result
+
+ return result_parser
+
+def _multiplication_level_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'multiplication_level_operator',
+ _literal_level_expression_parser,
+ 'multiplication_level',
+ )(index, tokens)
+
+def _addition_level_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'addition_level_operator',
+ _multiplication_level_expression_parser,
+ 'addition_level',
+ )(index, tokens)
+
+def _comparison_level_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'comparison_level_operator',
+ _addition_level_expression_parser,
+ 'comparison_level',
+ )(index, tokens)
+
+def _and_level_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'symbol' and token.match == 'and',
+ _comparison_level_expression_parser,
+ 'and_level',
+ )(index, tokens)
+
+def _or_level_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'symbol' and token.match == 'or',
+ _and_level_expression_parser,
+ 'or_level',
+ )(index, tokens)
+
+def _comma_separated_list_parser(subparser):
+ def result_parser(index, tokens):
+ start_index = index
+
+ items = []
+
+ success, index, item = subparser(index, tokens)
+
+ if success:
+ items.append(item)
+ else:
+ return (True, start_index, ())
+
+ while success and index < len(tokens) and tokens[index].type == 'comma':
+ success = False
+
+ if index + 1 < len(tokens):
+ success, try_index, item = subparser(index + 1, tokens)
+
+ if success:
+ items.append(item)
+ index = try_index
+
+ return True, index, tuple(items)
+
+ return result_parser