Commit ba9ea5f7 authored by Stefan Behnel's avatar Stefan Behnel

Make the "Method" scanner action a direct feature of the embedded Plex,...

Make the "Method" scanner action a direct feature of the embedded Plex, instead of hacking it back into the Lexicon with a stray import.
See GH-2831.
parent 4fe5191b
...@@ -16,8 +16,7 @@ IDENT = 'IDENT' ...@@ -16,8 +16,7 @@ IDENT = 'IDENT'
def make_lexicon(): def make_lexicon():
from ..Plex import \ from ..Plex import \
Str, Any, AnyBut, AnyChar, Rep, Rep1, Opt, Bol, Eol, Eof, \ Str, Any, AnyBut, AnyChar, Rep, Rep1, Opt, Bol, Eol, Eof, \
TEXT, IGNORE, State, Lexicon TEXT, IGNORE, Method, State, Lexicon
from .Scanning import Method
letter = Any("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_") letter = Any("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_")
nonzero_digit = Any("123456789") nonzero_digit = Any("123456789")
......
...@@ -9,11 +9,6 @@ cdef unicode any_string_prefix, IDENT ...@@ -9,11 +9,6 @@ cdef unicode any_string_prefix, IDENT
cdef get_lexicon() cdef get_lexicon()
cdef initial_compile_time_env() cdef initial_compile_time_env()
cdef class Method:
cdef object name
cdef dict kwargs
cdef readonly object __name__ # for tracing the scanner
## methods commented with '##' out are used by Parsing.py when compiled. ## methods commented with '##' out are used by Parsing.py when compiled.
@cython.final @cython.final
......
...@@ -51,25 +51,6 @@ pyx_reserved_words = py_reserved_words + [ ...@@ -51,25 +51,6 @@ pyx_reserved_words = py_reserved_words + [
] ]
class Method(object):
def __init__(self, name, **kwargs):
self.name = name
self.kwargs = kwargs or None
self.__name__ = name # for Plex tracing
def __call__(self, stream, text):
method = getattr(stream, self.name)
# self.kwargs is almost always unused => avoid call overhead
return method(text, **self.kwargs) if self.kwargs is not None else method(text)
def __copy__(self):
return self # immutable, no need to copy
def __deepcopy__(self, memo):
return self # immutable, no need to copy
#------------------------------------------------------------------ #------------------------------------------------------------------
class CompileTimeScope(object): class CompileTimeScope(object):
......
cdef class Action: cdef class Action:
cdef perform(self, token_stream, text) cdef perform(self, token_stream, text)
cpdef same_as(self, other) cpdef same_as(self, other)
cdef class Return(Action): cdef class Return(Action):
cdef object value cdef object value
cdef perform(self, token_stream, text) cdef perform(self, token_stream, text)
cpdef same_as(self, other) cpdef same_as(self, other)
cdef class Call(Action): cdef class Call(Action):
cdef object function cdef object function
cdef perform(self, token_stream, text) cdef perform(self, token_stream, text)
cpdef same_as(self, other) cpdef same_as(self, other)
cdef class Method(Action):
cdef object name
cdef dict kwargs
cdef readonly object __name__ # for tracing the scanner
cdef class Begin(Action): cdef class Begin(Action):
cdef object state_name cdef object state_name
cdef perform(self, token_stream, text) cdef perform(self, token_stream, text)
cpdef same_as(self, other) cpdef same_as(self, other)
cdef class Ignore(Action): cdef class Ignore(Action):
cdef perform(self, token_stream, text) cdef perform(self, token_stream, text)
cdef class Text(Action): cdef class Text(Action):
cdef perform(self, token_stream, text) cdef perform(self, token_stream, text)
...@@ -14,6 +14,12 @@ class Action(object): ...@@ -14,6 +14,12 @@ class Action(object):
def same_as(self, other): def same_as(self, other):
return self is other return self is other
def __copy__(self):
return self # immutable, no need to copy
def __deepcopy__(self, memo):
return self # immutable, no need to copy
class Return(Action): class Return(Action):
""" """
...@@ -52,6 +58,26 @@ class Call(Action): ...@@ -52,6 +58,26 @@ class Call(Action):
return isinstance(other, Call) and self.function is other.function return isinstance(other, Call) and self.function is other.function
class Method(Action):
"""
Plex action that calls a specific method on the token stream,
passing the matched text and any provided constant keyword arguments.
"""
def __init__(self, name, **kwargs):
self.name = name
self.kwargs = kwargs or None
self.__name__ = name # for Plex tracing
def perform(self, token_stream, text):
method = getattr(token_stream, self.name)
# self.kwargs is almost always unused => avoid call overhead
return method(text, **self.kwargs) if self.kwargs is not None else method(text)
def same_as(self, other):
return isinstance(other, Method) and self.name == other.name and self.kwargs == other.kwargs
class Begin(Action): class Begin(Action):
""" """
Begin(state_name) is a Plex action which causes the Scanner to Begin(state_name) is a Plex action which causes the Scanner to
......
...@@ -28,7 +28,7 @@ see the attached docstrings for more information. ...@@ -28,7 +28,7 @@ see the attached docstrings for more information.
# flake8: noqa:F401 # flake8: noqa:F401
from __future__ import absolute_import from __future__ import absolute_import
from .Actions import TEXT, IGNORE, Begin from .Actions import TEXT, IGNORE, Begin, Method
from .Lexicons import Lexicon, State from .Lexicons import Lexicon, State
from .Regexps import RE, Seq, Alt, Rep1, Empty, Str, Any, AnyBut, AnyChar, Range from .Regexps import RE, Seq, Alt, Rep1, Empty, Str, Any, AnyBut, AnyChar, Range
from .Regexps import Opt, Rep, Bol, Eol, Eof, Case, NoCase from .Regexps import Opt, Rep, Bol, Eol, Eof, Case, NoCase
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment