Add static typing for resources

This commit is contained in:
Romain Failliot 2022-01-09 18:04:54 -05:00
parent e975f66fde
commit 914ea66cc3
1 changed files with 155 additions and 153 deletions

View File

@ -31,7 +31,7 @@ import shlex
from distutils import util from distutils import util
from gettext import gettext as _ from gettext import gettext as _
from typing import Final from typing import Dict, Final, List, Optional, Pattern, Set, Tuple
from diffuse import utils from diffuse import utils
@ -45,134 +45,133 @@ class Resources:
# default keybindings # default keybindings
self.keybindings = {} self.keybindings = {}
self.keybindings_lookup = {} self.keybindings_lookup = {}
set_binding = self.setKeyBinding self.setKeyBinding('menu', 'open_file', 'Ctrl+o')
set_binding('menu', 'open_file', 'Ctrl+o') self.setKeyBinding('menu', 'open_file_in_new_tab', 'Ctrl+t')
set_binding('menu', 'open_file_in_new_tab', 'Ctrl+t') self.setKeyBinding('menu', 'open_modified_files', 'Shift+Ctrl+O')
set_binding('menu', 'open_modified_files', 'Shift+Ctrl+O') self.setKeyBinding('menu', 'open_commit', 'Shift+Ctrl+T')
set_binding('menu', 'open_commit', 'Shift+Ctrl+T') self.setKeyBinding('menu', 'reload_file', 'Shift+Ctrl+R')
set_binding('menu', 'reload_file', 'Shift+Ctrl+R') self.setKeyBinding('menu', 'save_file', 'Ctrl+s')
set_binding('menu', 'save_file', 'Ctrl+s') self.setKeyBinding('menu', 'save_file_as', 'Shift+Ctrl+A')
set_binding('menu', 'save_file_as', 'Shift+Ctrl+A') self.setKeyBinding('menu', 'save_all', 'Shift+Ctrl+S')
set_binding('menu', 'save_all', 'Shift+Ctrl+S') self.setKeyBinding('menu', 'new_2_way_file_merge', 'Ctrl+2')
set_binding('menu', 'new_2_way_file_merge', 'Ctrl+2') self.setKeyBinding('menu', 'new_3_way_file_merge', 'Ctrl+3')
set_binding('menu', 'new_3_way_file_merge', 'Ctrl+3') self.setKeyBinding('menu', 'new_n_way_file_merge', 'Ctrl+4')
set_binding('menu', 'new_n_way_file_merge', 'Ctrl+4') self.setKeyBinding('menu', 'close_tab', 'Ctrl+w')
set_binding('menu', 'close_tab', 'Ctrl+w') self.setKeyBinding('menu', 'undo_close_tab', 'Shift+Ctrl+W')
set_binding('menu', 'undo_close_tab', 'Shift+Ctrl+W') self.setKeyBinding('menu', 'quit', 'Ctrl+q')
set_binding('menu', 'quit', 'Ctrl+q') self.setKeyBinding('menu', 'undo', 'Ctrl+z')
set_binding('menu', 'undo', 'Ctrl+z') self.setKeyBinding('menu', 'redo', 'Shift+Ctrl+Z')
set_binding('menu', 'redo', 'Shift+Ctrl+Z') self.setKeyBinding('menu', 'cut', 'Ctrl+x')
set_binding('menu', 'cut', 'Ctrl+x') self.setKeyBinding('menu', 'copy', 'Ctrl+c')
set_binding('menu', 'copy', 'Ctrl+c') self.setKeyBinding('menu', 'paste', 'Ctrl+v')
set_binding('menu', 'paste', 'Ctrl+v') self.setKeyBinding('menu', 'select_all', 'Ctrl+a')
set_binding('menu', 'select_all', 'Ctrl+a') self.setKeyBinding('menu', 'clear_edits', 'Ctrl+r')
set_binding('menu', 'clear_edits', 'Ctrl+r') self.setKeyBinding('menu', 'dismiss_all_edits', 'Ctrl+d')
set_binding('menu', 'dismiss_all_edits', 'Ctrl+d') self.setKeyBinding('menu', 'find', 'Ctrl+f')
set_binding('menu', 'find', 'Ctrl+f') self.setKeyBinding('menu', 'find_next', 'Ctrl+g')
set_binding('menu', 'find_next', 'Ctrl+g') self.setKeyBinding('menu', 'find_previous', 'Shift+Ctrl+G')
set_binding('menu', 'find_previous', 'Shift+Ctrl+G') self.setKeyBinding('menu', 'go_to_line', 'Shift+Ctrl+L')
set_binding('menu', 'go_to_line', 'Shift+Ctrl+L') self.setKeyBinding('menu', 'realign_all', 'Ctrl+l')
set_binding('menu', 'realign_all', 'Ctrl+l') self.setKeyBinding('menu', 'isolate', 'Ctrl+i')
set_binding('menu', 'isolate', 'Ctrl+i') self.setKeyBinding('menu', 'first_difference', 'Shift+Ctrl+Up')
set_binding('menu', 'first_difference', 'Shift+Ctrl+Up') self.setKeyBinding('menu', 'previous_difference', 'Ctrl+Up')
set_binding('menu', 'previous_difference', 'Ctrl+Up') self.setKeyBinding('menu', 'next_difference', 'Ctrl+Down')
set_binding('menu', 'next_difference', 'Ctrl+Down') self.setKeyBinding('menu', 'last_difference', 'Shift+Ctrl+Down')
set_binding('menu', 'last_difference', 'Shift+Ctrl+Down') self.setKeyBinding('menu', 'first_tab', 'Shift+Ctrl+Page_Up')
set_binding('menu', 'first_tab', 'Shift+Ctrl+Page_Up') self.setKeyBinding('menu', 'previous_tab', 'Ctrl+Page_Up')
set_binding('menu', 'previous_tab', 'Ctrl+Page_Up') self.setKeyBinding('menu', 'next_tab', 'Ctrl+Page_Down')
set_binding('menu', 'next_tab', 'Ctrl+Page_Down') self.setKeyBinding('menu', 'last_tab', 'Shift+Ctrl+Page_Down')
set_binding('menu', 'last_tab', 'Shift+Ctrl+Page_Down') self.setKeyBinding('menu', 'shift_pane_right', 'Shift+Ctrl+parenright')
set_binding('menu', 'shift_pane_right', 'Shift+Ctrl+parenright') self.setKeyBinding('menu', 'shift_pane_left', 'Shift+Ctrl+parenleft')
set_binding('menu', 'shift_pane_left', 'Shift+Ctrl+parenleft') self.setKeyBinding('menu', 'convert_to_upper_case', 'Ctrl+u')
set_binding('menu', 'convert_to_upper_case', 'Ctrl+u') self.setKeyBinding('menu', 'convert_to_lower_case', 'Shift+Ctrl+U')
set_binding('menu', 'convert_to_lower_case', 'Shift+Ctrl+U') self.setKeyBinding('menu', 'sort_lines_in_ascending_order', 'Ctrl+y')
set_binding('menu', 'sort_lines_in_ascending_order', 'Ctrl+y') self.setKeyBinding('menu', 'sort_lines_in_descending_order', 'Shift+Ctrl+Y')
set_binding('menu', 'sort_lines_in_descending_order', 'Shift+Ctrl+Y') self.setKeyBinding('menu', 'remove_trailing_white_space', 'Ctrl+k')
set_binding('menu', 'remove_trailing_white_space', 'Ctrl+k') self.setKeyBinding('menu', 'convert_tabs_to_spaces', 'Ctrl+b')
set_binding('menu', 'convert_tabs_to_spaces', 'Ctrl+b') self.setKeyBinding('menu', 'convert_leading_spaces_to_tabs', 'Shift+Ctrl+B')
set_binding('menu', 'convert_leading_spaces_to_tabs', 'Shift+Ctrl+B') self.setKeyBinding('menu', 'increase_indenting', 'Shift+Ctrl+greater')
set_binding('menu', 'increase_indenting', 'Shift+Ctrl+greater') self.setKeyBinding('menu', 'decrease_indenting', 'Shift+Ctrl+less')
set_binding('menu', 'decrease_indenting', 'Shift+Ctrl+less') self.setKeyBinding('menu', 'convert_to_dos', 'Shift+Ctrl+E')
set_binding('menu', 'convert_to_dos', 'Shift+Ctrl+E') self.setKeyBinding('menu', 'convert_to_mac', 'Shift+Ctrl+C')
set_binding('menu', 'convert_to_mac', 'Shift+Ctrl+C') self.setKeyBinding('menu', 'convert_to_unix', 'Ctrl+e')
set_binding('menu', 'convert_to_unix', 'Ctrl+e') self.setKeyBinding('menu', 'copy_selection_right', 'Shift+Ctrl+Right')
set_binding('menu', 'copy_selection_right', 'Shift+Ctrl+Right') self.setKeyBinding('menu', 'copy_selection_left', 'Shift+Ctrl+Left')
set_binding('menu', 'copy_selection_left', 'Shift+Ctrl+Left') self.setKeyBinding('menu', 'copy_left_into_selection', 'Ctrl+Right')
set_binding('menu', 'copy_left_into_selection', 'Ctrl+Right') self.setKeyBinding('menu', 'copy_right_into_selection', 'Ctrl+Left')
set_binding('menu', 'copy_right_into_selection', 'Ctrl+Left') self.setKeyBinding('menu', 'merge_from_left_then_right', 'Ctrl+m')
set_binding('menu', 'merge_from_left_then_right', 'Ctrl+m') self.setKeyBinding('menu', 'merge_from_right_then_left', 'Shift+Ctrl+M')
set_binding('menu', 'merge_from_right_then_left', 'Shift+Ctrl+M') self.setKeyBinding('menu', 'help_contents', 'F1')
set_binding('menu', 'help_contents', 'F1') self.setKeyBinding('line_mode', 'enter_align_mode', 'space')
set_binding('line_mode', 'enter_align_mode', 'space') self.setKeyBinding('line_mode', 'enter_character_mode', 'Return')
set_binding('line_mode', 'enter_character_mode', 'Return') self.setKeyBinding('line_mode', 'enter_character_mode', 'KP_Enter')
set_binding('line_mode', 'enter_character_mode', 'KP_Enter') self.setKeyBinding('line_mode', 'first_line', 'Home')
set_binding('line_mode', 'first_line', 'Home') self.setKeyBinding('line_mode', 'first_line', 'g')
set_binding('line_mode', 'first_line', 'g') self.setKeyBinding('line_mode', 'extend_first_line', 'Shift+Home')
set_binding('line_mode', 'extend_first_line', 'Shift+Home') self.setKeyBinding('line_mode', 'last_line', 'End')
set_binding('line_mode', 'last_line', 'End') self.setKeyBinding('line_mode', 'last_line', 'Shift+G')
set_binding('line_mode', 'last_line', 'Shift+G') self.setKeyBinding('line_mode', 'extend_last_line', 'Shift+End')
set_binding('line_mode', 'extend_last_line', 'Shift+End') self.setKeyBinding('line_mode', 'up', 'Up')
set_binding('line_mode', 'up', 'Up') self.setKeyBinding('line_mode', 'up', 'k')
set_binding('line_mode', 'up', 'k') self.setKeyBinding('line_mode', 'extend_up', 'Shift+Up')
set_binding('line_mode', 'extend_up', 'Shift+Up') self.setKeyBinding('line_mode', 'extend_up', 'Shift+K')
set_binding('line_mode', 'extend_up', 'Shift+K') self.setKeyBinding('line_mode', 'down', 'Down')
set_binding('line_mode', 'down', 'Down') self.setKeyBinding('line_mode', 'down', 'j')
set_binding('line_mode', 'down', 'j') self.setKeyBinding('line_mode', 'extend_down', 'Shift+Down')
set_binding('line_mode', 'extend_down', 'Shift+Down') self.setKeyBinding('line_mode', 'extend_down', 'Shift+J')
set_binding('line_mode', 'extend_down', 'Shift+J') self.setKeyBinding('line_mode', 'left', 'Left')
set_binding('line_mode', 'left', 'Left') self.setKeyBinding('line_mode', 'left', 'h')
set_binding('line_mode', 'left', 'h') self.setKeyBinding('line_mode', 'extend_left', 'Shift+Left')
set_binding('line_mode', 'extend_left', 'Shift+Left') self.setKeyBinding('line_mode', 'right', 'Right')
set_binding('line_mode', 'right', 'Right') self.setKeyBinding('line_mode', 'right', 'l')
set_binding('line_mode', 'right', 'l') self.setKeyBinding('line_mode', 'extend_right', 'Shift+Right')
set_binding('line_mode', 'extend_right', 'Shift+Right') self.setKeyBinding('line_mode', 'page_up', 'Page_Up')
set_binding('line_mode', 'page_up', 'Page_Up') self.setKeyBinding('line_mode', 'page_up', 'Ctrl+u')
set_binding('line_mode', 'page_up', 'Ctrl+u') self.setKeyBinding('line_mode', 'extend_page_up', 'Shift+Page_Up')
set_binding('line_mode', 'extend_page_up', 'Shift+Page_Up') self.setKeyBinding('line_mode', 'extend_page_up', 'Shift+Ctrl+U')
set_binding('line_mode', 'extend_page_up', 'Shift+Ctrl+U') self.setKeyBinding('line_mode', 'page_down', 'Page_Down')
set_binding('line_mode', 'page_down', 'Page_Down') self.setKeyBinding('line_mode', 'page_down', 'Ctrl+d')
set_binding('line_mode', 'page_down', 'Ctrl+d') self.setKeyBinding('line_mode', 'extend_page_down', 'Shift+Page_Down')
set_binding('line_mode', 'extend_page_down', 'Shift+Page_Down') self.setKeyBinding('line_mode', 'extend_page_down', 'Shift+Ctrl+D')
set_binding('line_mode', 'extend_page_down', 'Shift+Ctrl+D') self.setKeyBinding('line_mode', 'delete_text', 'BackSpace')
set_binding('line_mode', 'delete_text', 'BackSpace') self.setKeyBinding('line_mode', 'delete_text', 'Delete')
set_binding('line_mode', 'delete_text', 'Delete') self.setKeyBinding('line_mode', 'delete_text', 'x')
set_binding('line_mode', 'delete_text', 'x') self.setKeyBinding('line_mode', 'clear_edits', 'r')
set_binding('line_mode', 'clear_edits', 'r') self.setKeyBinding('line_mode', 'isolate', 'i')
set_binding('line_mode', 'isolate', 'i') self.setKeyBinding('line_mode', 'first_difference', 'Ctrl+Home')
set_binding('line_mode', 'first_difference', 'Ctrl+Home') self.setKeyBinding('line_mode', 'first_difference', 'Shift+P')
set_binding('line_mode', 'first_difference', 'Shift+P') self.setKeyBinding('line_mode', 'previous_difference', 'p')
set_binding('line_mode', 'previous_difference', 'p') self.setKeyBinding('line_mode', 'next_difference', 'n')
set_binding('line_mode', 'next_difference', 'n') self.setKeyBinding('line_mode', 'last_difference', 'Ctrl+End')
set_binding('line_mode', 'last_difference', 'Ctrl+End') self.setKeyBinding('line_mode', 'last_difference', 'Shift+N')
set_binding('line_mode', 'last_difference', 'Shift+N') # self.setKeyBinding('line_mode', 'copy_selection_right', 'Shift+L')
# set_binding('line_mode', 'copy_selection_right', 'Shift+L') # self.setKeyBinding('line_mode', 'copy_selection_left', 'Shift+H')
# set_binding('line_mode', 'copy_selection_left', 'Shift+H') self.setKeyBinding('line_mode', 'copy_left_into_selection', 'Shift+L')
set_binding('line_mode', 'copy_left_into_selection', 'Shift+L') self.setKeyBinding('line_mode', 'copy_right_into_selection', 'Shift+H')
set_binding('line_mode', 'copy_right_into_selection', 'Shift+H') self.setKeyBinding('line_mode', 'merge_from_left_then_right', 'm')
set_binding('line_mode', 'merge_from_left_then_right', 'm') self.setKeyBinding('line_mode', 'merge_from_right_then_left', 'Shift+M')
set_binding('line_mode', 'merge_from_right_then_left', 'Shift+M') self.setKeyBinding('align_mode', 'enter_line_mode', 'Escape')
set_binding('align_mode', 'enter_line_mode', 'Escape') self.setKeyBinding('align_mode', 'align', 'space')
set_binding('align_mode', 'align', 'space') self.setKeyBinding('align_mode', 'enter_character_mode', 'Return')
set_binding('align_mode', 'enter_character_mode', 'Return') self.setKeyBinding('align_mode', 'enter_character_mode', 'KP_Enter')
set_binding('align_mode', 'enter_character_mode', 'KP_Enter') self.setKeyBinding('align_mode', 'first_line', 'g')
set_binding('align_mode', 'first_line', 'g') self.setKeyBinding('align_mode', 'last_line', 'Shift+G')
set_binding('align_mode', 'last_line', 'Shift+G') self.setKeyBinding('align_mode', 'up', 'Up')
set_binding('align_mode', 'up', 'Up') self.setKeyBinding('align_mode', 'up', 'k')
set_binding('align_mode', 'up', 'k') self.setKeyBinding('align_mode', 'down', 'Down')
set_binding('align_mode', 'down', 'Down') self.setKeyBinding('align_mode', 'down', 'j')
set_binding('align_mode', 'down', 'j') self.setKeyBinding('align_mode', 'left', 'Left')
set_binding('align_mode', 'left', 'Left') self.setKeyBinding('align_mode', 'left', 'h')
set_binding('align_mode', 'left', 'h') self.setKeyBinding('align_mode', 'right', 'Right')
set_binding('align_mode', 'right', 'Right') self.setKeyBinding('align_mode', 'right', 'l')
set_binding('align_mode', 'right', 'l') self.setKeyBinding('align_mode', 'page_up', 'Page_Up')
set_binding('align_mode', 'page_up', 'Page_Up') self.setKeyBinding('align_mode', 'page_up', 'Ctrl+u')
set_binding('align_mode', 'page_up', 'Ctrl+u') self.setKeyBinding('align_mode', 'page_down', 'Page_Down')
set_binding('align_mode', 'page_down', 'Page_Down') self.setKeyBinding('align_mode', 'page_down', 'Ctrl+d')
set_binding('align_mode', 'page_down', 'Ctrl+d') self.setKeyBinding('character_mode', 'enter_line_mode', 'Escape')
set_binding('character_mode', 'enter_line_mode', 'Escape')
# default colours # default colours
self.colours = { self.colours: Dict[str, _Colour] = {
'alignment': _Colour(1.0, 1.0, 0.0), 'alignment': _Colour(1.0, 1.0, 0.0),
'character_selection': _Colour(0.7, 0.7, 1.0), 'character_selection': _Colour(0.7, 0.7, 1.0),
'cursor': _Colour(0.0, 0.0, 0.0), 'cursor': _Colour(0.0, 0.0, 0.0),
@ -192,7 +191,7 @@ class Resources:
} }
# default floats # default floats
self.floats = { self.floats: Dict[str, float] = {
'alignment_opacity': 1.0, 'alignment_opacity': 1.0,
'character_difference_opacity': 0.4, 'character_difference_opacity': 0.4,
'character_selection_opacity': 0.4, 'character_selection_opacity': 0.4,
@ -202,29 +201,29 @@ class Resources:
} }
# default options # default options
self.options = { self.options: Dict[str, str] = {
'log_print_output': 'False', 'log_print_output': 'False',
'log_print_stack': 'False', 'log_print_stack': 'False',
'use_flatpak': 'False' 'use_flatpak': 'False'
} }
# default strings # default strings
self.strings = {} self.strings: Dict[str, str] = {}
# syntax highlighting support # syntax highlighting support
self.syntaxes = {} self.syntaxes: Dict[str, _SyntaxParser] = {}
self.syntax_file_patterns = {} self.syntax_file_patterns: Dict[str, Pattern] = {}
self.syntax_magic_patterns = {} self.syntax_magic_patterns: Dict[str, Pattern] = {}
self.current_syntax = None self.current_syntax: Optional[_SyntaxParser] = None
# list of imported resources files (we only import each file once) # list of imported resources files (we only import each file once)
self.resource_files = set() self.resource_files: Set[str] = set()
# special string resources # special string resources
self.setDifferenceColours('difference_1 difference_2 difference_3') self.setDifferenceColours('difference_1 difference_2 difference_3')
# keyboard action processing # keyboard action processing
def setKeyBinding(self, ctx, s, v): def setKeyBinding(self, ctx: str, s: str, v: str) -> None:
action_tuple = (ctx, s) action_tuple = (ctx, s)
modifiers = Gdk.ModifierType(0) modifiers = Gdk.ModifierType(0)
key = None key = None
@ -282,7 +281,7 @@ class Resources:
return [] return []
# colours used for indicating differences # colours used for indicating differences
def setDifferenceColours(self, s): def setDifferenceColours(self, s: str) -> None:
colours = s.split() colours = s.split()
if len(colours) > 0: if len(colours) > 0:
self.difference_colours = colours self.difference_colours = colours
@ -322,7 +321,7 @@ class Resources:
return util.strtobool(self.getOption(option)) return util.strtobool(self.getOption(option))
# string resources # string resources
def getString(self, symbol): def getString(self, symbol: str) -> str:
try: try:
return self.strings[symbol] return self.strings[symbol]
except KeyError: except KeyError:
@ -336,7 +335,7 @@ class Resources:
def getSyntax(self, name): def getSyntax(self, name):
return self.syntaxes.get(name, None) return self.syntaxes.get(name, None)
def guessSyntaxForFile(self, name, ss): def guessSyntaxForFile(self, name: str, ss: List[str]) -> Optional[str]:
name = os.path.basename(name) name = os.path.basename(name)
for key, pattern in self.syntax_file_patterns.items(): for key, pattern in self.syntax_file_patterns.items():
if pattern.search(name): if pattern.search(name):
@ -350,7 +349,7 @@ class Resources:
return None return None
# parse resource files # parse resource files
def parse(self, file_name): def parse(self, file_name: str) -> None:
# only process files once # only process files once
if file_name in self.resource_files: if file_name in self.resource_files:
return return
@ -514,12 +513,12 @@ class Resources:
file=file_name file=file_name
) )
utils.logError(f'{error_msg}: {e.msg}') utils.logError(f'{error_msg}: {e.msg}')
except ValueError as e: except ValueError:
error_msg = _('Value error at line {line} of {file}').format( error_msg = _('Value error at line {line} of {file}').format(
line=i + 1, line=i + 1,
file=file_name file=file_name
) )
utils.logError(f'{error_msg}: {e.msg}') utils.logError(error_msg)
except re.error: except re.error:
error_msg = _('Regex error at line {line} of {file}.') error_msg = _('Regex error at line {line} of {file}.')
utils.logError(error_msg.format(line=i + 1, file=file_name)) utils.logError(error_msg.format(line=i + 1, file=file_name))
@ -558,7 +557,7 @@ class _Colour:
class _SyntaxParser: class _SyntaxParser:
# create a new state machine that begins in initial_state and classifies # create a new state machine that begins in initial_state and classifies
# all characters not matched by the patterns as default_token_type # all characters not matched by the patterns as default_token_type
def __init__(self, initial_state, default_token_type): def __init__(self, initial_state: str, default_token_type: str) -> None:
# initial state for the state machine when parsing a new file # initial state for the state machine when parsing a new file
self.initial_state = initial_state self.initial_state = initial_state
# default classification of characters that are not explicitly matched # default classification of characters that are not explicitly matched
@ -567,30 +566,33 @@ class _SyntaxParser:
# mappings from a state to a list of (pattern, token_type, next_state) # mappings from a state to a list of (pattern, token_type, next_state)
# tuples indicating the new state for the state machine when 'pattern' # tuples indicating the new state for the state machine when 'pattern'
# is matched and how to classify the matched characters # is matched and how to classify the matched characters
self.transitions_lookup = {initial_state: []} self.transitions_lookup: Dict[str, List[Tuple[Pattern, str, str]]] = {initial_state: []}
# Adds a new edge to the finite state machine from prev_state to # Adds a new edge to the finite state machine from prev_state to
# next_state. Characters will be identified as token_type when pattern is # next_state. Characters will be identified as token_type when pattern is
# matched. Any newly referenced state will be added. Patterns for edges # matched. Any newly referenced state will be added. Patterns for edges
# leaving a state will be tested in the order they were added to the finite # leaving a state will be tested in the order they were added to the finite
# state machine. # state machine.
def addPattern(self, prev_state, next_state, token_type, pattern): def addPattern(
lookup = self.transitions_lookup self,
prev_state: str,
next_state: str,
token_type: str,
pattern: Pattern) -> None:
for state in prev_state, next_state: for state in prev_state, next_state:
if state not in lookup: if state not in self.transitions_lookup:
lookup[state] = [] self.transitions_lookup[state] = []
lookup[prev_state].append([pattern, token_type, next_state]) self.transitions_lookup[prev_state].append((pattern, token_type, next_state))
# given a string and an initial state, identify the final state and tokens # given a string and an initial state, identify the final state and tokens
def parse(self, state_name, s): def parse(self, state_name, s):
lookup = self.transitions_lookup transitions, blocks, start = self.transitions_lookup[state_name], [], 0
transitions, blocks, start = lookup[state_name], [], 0
while start < len(s): while start < len(s):
for pattern, token_type, next_state in transitions: for pattern, token_type, next_state in transitions:
m = pattern.match(s, start) m = pattern.match(s, start)
if m is not None: if m is not None:
end, state_name = m.span()[1], next_state end, state_name = m.span()[1], next_state
transitions = lookup[state_name] transitions = self.transitions_lookup[state_name]
break break
else: else:
end, token_type = start + 1, self.default_token_type end, token_type = start + 1, self.default_token_type
@ -602,4 +604,4 @@ class _SyntaxParser:
return state_name, blocks return state_name, blocks
theResources: Final[Resources] = Resources() theResources: Final = Resources()