Skip to content

Commit

Permalink
Attempt to resolve performance problems in issue #1418
Browse files Browse the repository at this point in the history
  • Loading branch information
erezsh committed May 27, 2024
1 parent 29bb78b commit 3a29aee
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 10 deletions.
13 changes: 7 additions & 6 deletions lark/parsers/lalr_interactive_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from lark.exceptions import UnexpectedToken
from lark.lexer import Token, LexerThread
from .lalr_parser_state import ParserState

###{standalone

Expand All @@ -14,7 +15,7 @@ class InteractiveParser:
For a simpler interface, see the ``on_error`` argument to ``Lark.parse()``.
"""
def __init__(self, parser, parser_state, lexer_thread: LexerThread):
def __init__(self, parser, parser_state: ParserState, lexer_thread: LexerThread):
self.parser = parser
self.parser_state = parser_state
self.lexer_thread = lexer_thread
Expand Down Expand Up @@ -63,15 +64,15 @@ def __copy__(self):
Calls to feed_token() won't affect the old instance, and vice-versa.
"""
return self.copy()

def copy(self, deepcopy_values=True):
return type(self)(
self.parser,
copy(self.parser_state),
self.parser_state.copy(deepcopy_values=deepcopy_values),
copy(self.lexer_thread),
)

def copy(self):
return copy(self)

def __eq__(self, other):
if not isinstance(other, InteractiveParser):
return False
Expand Down Expand Up @@ -109,7 +110,7 @@ def accepts(self):
conf_no_callbacks.callbacks = {}
for t in self.choices():
if t.isupper(): # is terminal?
new_cursor = copy(self)
new_cursor = self.copy(deepcopy_values=False)
new_cursor.parser_state.parse_conf = conf_no_callbacks
try:
new_cursor.feed_token(self.lexer_thread._Token(t, ''))
Expand Down
8 changes: 4 additions & 4 deletions lark/parsers/lalr_parser_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ def __eq__(self, other) -> bool:
return len(self.state_stack) == len(other.state_stack) and self.position == other.position

def __copy__(self):
return self.copy()

def copy(self, deepcopy_values=True) -> 'ParserState[StateT]':
return type(self)(
self.parse_conf,
self.lexer, # XXX copy
copy(self.state_stack),
deepcopy(self.value_stack),
deepcopy(self.value_stack) if deepcopy_values else copy(self.value_stack),
)

def copy(self) -> 'ParserState[StateT]':
return copy(self)

def feed_token(self, token: Token, is_end=False) -> Any:
state_stack = self.state_stack
value_stack = self.value_stack
Expand Down

0 comments on commit 3a29aee

Please sign in to comment.