File: C:/Users/fred/anaconda3/Lib/site-packages/datashader/datashape/lexer.py
"""
Lexer for the datashape grammar.
"""
from __future__ import absolute_import, division, print_function
import re
import ast
import collections
from . import error
# This is updated to include all the token names from _tokens,
# where e.g. _tokens[NAME_LOWER-1] is the entry for NAME_LOWER
__all__ = ['lex', 'Token']
def _str_val(s):
# Use the Python parser via the ast module to parse the string,
# since the string_escape and unicode_escape codecs do the wrong thing
return ast.parse('u' + s).body[0].value.value
# A list of the token names, corresponding regex, and value extraction function
_tokens = [
('BOOLEAN', r'True|False', ast.literal_eval),
('NAME_LOWER', r'[a-z][a-zA-Z0-9_]*', lambda x : x),
('NAME_UPPER', r'[A-Z][a-zA-Z0-9_]*', lambda x : x),
('NAME_OTHER', r'_[a-zA-Z0-9_]*', lambda x : x),
('ASTERISK', r'\*'),
('COMMA', r','),
('EQUAL', r'='),
('COLON', r':'),
('LBRACKET', r'\['),
('RBRACKET', r'\]'),
('LBRACE', r'\{'),
('RBRACE', r'\}'),
('LPAREN', r'\('),
('RPAREN', r'\)'),
('ELLIPSIS', r'\.\.\.'),
('RARROW', r'->'),
('QUESTIONMARK', r'\?'),
('INTEGER', r'0(?![0-9])|-?[1-9][0-9]*', int),
('STRING', (r"""(?:"(?:[^"\n\r\\]|(?:\\u[0-9a-fA-F]{4})|(?:\\["bfnrt]))*")|""" +
r"""(?:'(?:[^'\n\r\\]|(?:\\u[0-9a-fA-F]{4})|(?:\\['bfnrt]))*')"""),
_str_val),
]
# Dynamically add all the token indices to globals() and __all__
__all__.extend(tok[0] for tok in _tokens)
globals().update((tok[0], i) for i, tok in enumerate(_tokens, 1))
# Regex for skipping whitespace and comments
_whitespace = r'(?:\s|(?:#.*$))*'
# Compile the token-matching and whitespace-matching regular expressions
_tokens_re = re.compile('|'.join('(' + tok[1] + ')' for tok in _tokens),
re.MULTILINE)
_whitespace_re = re.compile(_whitespace, re.MULTILINE)
Token = collections.namedtuple('Token', 'id, name, span, val')
def lex(ds_str):
"""A generator which lexes a datashape string into a
sequence of tokens.
Example
-------
import datashape
s = ' -> ... A... "string" 1234 Blah _eil(# comment'
print('lexing %r' % s)
for tok in datashape.lexer.lex(s):
print(tok.id, tok.name, tok.span, repr(tok.val))
"""
pos = 0
# Skip whitespace
m = _whitespace_re.match(ds_str, pos)
if m:
pos = m.end()
while pos < len(ds_str):
# Try to match a token
m = _tokens_re.match(ds_str, pos)
if m:
# m.lastindex gives us which group was matched, which
# is one greater than the index into the _tokens list.
id = m.lastindex
tokinfo = _tokens[id - 1]
name = tokinfo[0]
span = m.span()
if len(tokinfo) > 2:
val = tokinfo[2](ds_str[span[0]:span[1]])
else:
val = None
pos = m.end()
yield Token(id, name, span, val)
else:
raise error.DataShapeSyntaxError(pos, '<nofile>',
ds_str,
'Invalid DataShape token')
# Skip whitespace
m = _whitespace_re.match(ds_str, pos)
if m:
pos = m.end()