simplify parser func

This commit is contained in:
Jesse Bannon 2023-12-13 16:08:21 -08:00
parent fb4d9066c9
commit bf0eafb04a

View file

@ -148,6 +148,10 @@ class _Parser:
self._error_highlight_pos = 0 self._error_highlight_pos = 0
self._ast: List[Argument] = [] self._ast: List[Argument] = []
self._bracket_counter_pos_stack: List[int] = []
self._bracket_counter = 0
self._literal_str = ""
try: try:
self._syntax_tree = self._parse() self._syntax_tree = self._parse()
except UserException as exc: except UserException as exc:
@ -499,74 +503,79 @@ class _Parser:
else: else:
raise UNREACHABLE raise UNREACHABLE
def _parse(self) -> SyntaxTree: def _parse_main_loop(self, ch: str) -> bool:
bracket_counter_pos_stack: List[int] = [] if ch == "}":
bracket_counter = 0 if self._bracket_counter == 0:
literal_str = "" raise BRACKET_NOT_CLOSED
while ch := self._read():
if ch == "}":
if bracket_counter == 0:
raise BRACKET_NOT_CLOSED
del bracket_counter_pos_stack[-1] del self._bracket_counter_pos_stack[-1]
bracket_counter -= 1 self._bracket_counter -= 1
continue return True
if ch == "{": if ch == "{":
bracket_counter_pos_stack.append(self._pos - 1) # pos incremented when read self._bracket_counter_pos_stack.append(self._pos - 1) # pos incremented when read
bracket_counter += 1 self._bracket_counter += 1
if literal_str: if self._literal_str:
self._ast.append(String(value=literal_str)) self._ast.append(String(value=self._literal_str))
literal_str = "" self._literal_str = ""
# Allow whitespace after bracket opening # Allow whitespace after bracket opening
while ch1 := self._read(increment_pos=False): while ch1 := self._read(increment_pos=False):
if not ch1.isspace(): if not ch1.isspace():
break break
self._pos += 1 self._pos += 1
if ch1 is None: if ch1 is None:
break # will hit closing bracket error return False # will hit closing bracket error
if ch1 == "%": if ch1 == "%":
self._pos += 1 self._pos += 1
self._ast.append(self._parse_function()) self._ast.append(self._parse_function())
elif ch1 == "[": elif ch1 == "[":
self._pos += 1 self._pos += 1
self._ast.append(self._parse_array()) self._ast.append(self._parse_array())
elif ch1 == "{": elif ch1 == "{":
self._pos += 1 self._pos += 1
self._ast.append(self._parse_map()) self._ast.append(self._parse_map())
elif _is_variable_start(ch1): elif _is_variable_start(ch1):
self._ast.append(self._parse_variable()) self._ast.append(self._parse_variable())
elif _is_numeric_start(ch1): elif _is_numeric_start(ch1):
raise NUMERICS_ONLY_ARGS raise NUMERICS_ONLY_ARGS
elif ( elif (
_is_string_start_single_char(ch1) _is_string_start_single_char(ch1)
or _is_string_start_multi_char(self._read(increment_pos=False, length=3)) or _is_string_start_multi_char(self._read(increment_pos=False, length=3))
or _is_null(self._read(increment_pos=False, length=4)) or _is_null(self._read(increment_pos=False, length=4))
): ):
raise STRINGS_ONLY_ARGS raise STRINGS_ONLY_ARGS
elif _is_boolean_true( elif _is_boolean_true(self._read(increment_pos=False, length=4)) or _is_boolean_false(
self._read(increment_pos=False, length=4) self._read(increment_pos=False, length=5)
) or _is_boolean_false(self._read(increment_pos=False, length=5)): ):
raise BOOLEAN_ONLY_ARGS raise BOOLEAN_ONLY_ARGS
elif _is_custom_function_argument_start(self._read(increment_pos=False)): elif _is_custom_function_argument_start(self._read(increment_pos=False)):
raise CUSTOM_FUNCTION_ARGUMENTS_ONLY_ARGS raise CUSTOM_FUNCTION_ARGUMENTS_ONLY_ARGS
else:
raise _UNEXPECTED_CHAR_ARGUMENT(arg_type=ParsedArgType.SCRIPT)
elif bracket_counter == 0:
# Only accumulate literal str if not in brackets
literal_str += ch
else: else:
# Should only be possible to get here if it's a space raise _UNEXPECTED_CHAR_ARGUMENT(arg_type=ParsedArgType.SCRIPT)
assert ch.isspace() elif self._bracket_counter == 0:
# Only accumulate literal str if not in brackets
self._literal_str += ch
else:
# Should only be possible to get here if it's a space
assert ch.isspace()
if bracket_counter != 0: return True
self._error_highlight_pos = bracket_counter_pos_stack[-1]
def _parse(self) -> SyntaxTree:
while ch := self._read():
continue_parse = self._parse_main_loop(ch)
if not continue_parse:
break
if self._bracket_counter != 0:
self._error_highlight_pos = self._bracket_counter_pos_stack[-1]
raise BRACKET_NOT_CLOSED raise BRACKET_NOT_CLOSED
if literal_str: if self._literal_str:
self._ast.append(String(value=literal_str)) self._ast.append(String(value=self._literal_str))
return SyntaxTree(ast=self._ast) return SyntaxTree(ast=self._ast)