Added Lexer state change
This commit is contained in:
parent
636197b9fd
commit
d8903d8301
18
sly/lex.py
18
sly/lex.py
@ -32,7 +32,7 @@
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
__version__ = '0.1'
|
__version__ = '0.1'
|
||||||
__all__ = ['Lexer']
|
__all__ = ['Lexer', 'LexerStateChange']
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
@ -62,6 +62,14 @@ class LexerBuildError(Exception):
|
|||||||
'''
|
'''
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class LexerStateChange(Exception):
|
||||||
|
'''
|
||||||
|
Exception raised to force a lexing state change
|
||||||
|
'''
|
||||||
|
def __init__(self, newstate, tok=None):
|
||||||
|
self.newstate = newstate
|
||||||
|
self.tok = tok
|
||||||
|
|
||||||
class Token(object):
|
class Token(object):
|
||||||
'''
|
'''
|
||||||
Representation of a single token.
|
Representation of a single token.
|
||||||
@ -192,6 +200,7 @@ class Lexer(metaclass=LexerMeta):
|
|||||||
raise LexerBuildError('literals must be specified as strings')
|
raise LexerBuildError('literals must be specified as strings')
|
||||||
|
|
||||||
def tokenize(self, text, lineno=1, index=0):
|
def tokenize(self, text, lineno=1, index=0):
|
||||||
|
while True:
|
||||||
# Local copies of frequently used values
|
# Local copies of frequently used values
|
||||||
_ignored_tokens = self._ignored_tokens
|
_ignored_tokens = self._ignored_tokens
|
||||||
_master_re = self._master_re
|
_master_re = self._master_re
|
||||||
@ -207,7 +216,7 @@ class Lexer(metaclass=LexerMeta):
|
|||||||
index += 1
|
index += 1
|
||||||
continue
|
continue
|
||||||
except IndexError:
|
except IndexError:
|
||||||
break
|
return
|
||||||
|
|
||||||
tok = Token()
|
tok = Token()
|
||||||
tok.lineno = lineno
|
tok.lineno = lineno
|
||||||
@ -246,6 +255,11 @@ class Lexer(metaclass=LexerMeta):
|
|||||||
index = self.index
|
index = self.index
|
||||||
lineno = self.lineno
|
lineno = self.lineno
|
||||||
|
|
||||||
|
except LexerStateChange as e:
|
||||||
|
self.__class__ = e.newstate
|
||||||
|
if e.tok:
|
||||||
|
yield e.tok
|
||||||
|
|
||||||
# Set the final state of the lexer before exiting (even if exception)
|
# Set the final state of the lexer before exiting (even if exception)
|
||||||
finally:
|
finally:
|
||||||
self.text = text
|
self.text = text
|
||||||
|
Loading…
Reference in New Issue
Block a user