Coverage for python/lsst/daf/butler/registry/queries/exprParser/parserLex.py : 56%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# This file is part of daf_butler. # # Developed for the LSST Data Management System. # This product includes software developed by the LSST Project # (https://www.lsst.org). # See the COPYRIGHT file at the top-level directory of this distribution # for details of code ownership. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
# ------------------------------- # Imports of standard modules -- # -------------------------------
# ----------------------------- # Imports for other modules -- # -----------------------------
# ---------------------------------- # Local non-exported definitions -- # ----------------------------------
"""Regular expression to match range literal in the form NUM..NUM[:NUM], this must match t_RANGE_LITERAL docstring. """
# ------------------------ # Exported definitions -- # ------------------------
"""Exception raised for lex-phase errors.
Attributes ---------- expression : str Full initial expression being parsed remain : str Remaining non-parsed part of the expression pos : int Current parsing position, offset from beginning of expression in characters lineno : int Current line number in the expression """
Exception.__init__(self, "Unexpected character at position {}".format(pos)) self.expression = expression self.remain = remain self.pos = pos self.lineno = lineno
"""Class which defines PLY lexer. """
"""Factory for lexers.
Returns ------- `ply.lex.Lexer` instance. """
# make sure that flags that we need are there kw = dict(reflags=reflags | re.IGNORECASE | re.VERBOSE) kw.update(kwargs)
return lex.lex(object=cls(), **kw)
# literals = ""
# reserved words in a grammar. # SQL has reserved words which we could potentially make reserved in our # grammar too, for now try to pretend we don't care about SQL # IS="IS", IN="IN", # NULL="NULL", OR="OR", AND="AND", NOT="NOT", # BETWEEN="BETWEEN", # LIKE="LIKE", # ESCAPE="ESCAPE", # REGEXP="REGEXP" )
# List of token names. 'NUMERIC_LITERAL', 'STRING_LITERAL', 'RANGE_LITERAL', # 'TIME_LITERAL', # 'DURATION_LITERAL', 'IDENTIFIER', 'LPAREN', 'RPAREN', 'EQ', 'NE', 'LT', 'LE', 'GT', 'GE', 'ADD', 'SUB', 'MUL', 'DIV', 'MOD', 'COMMA' ) + tuple(reserved.values())
# Regular expression rules for simple tokens
# A string containing ignored characters (spaces and tabs)
# Define a rule so we can track line numbers r'\n+' t.lexer.lineno += len(t.value)
# quoted string r"'.*?'" # strip quotes t.value = t.value[1:-1] return t
# range literal in format N..M[:S], spaces allowed, see _RE_RANGE def t_RANGE_LITERAL(self, t): match = re.match(_RE_RANGE, t.value) start = int(match.group("start")) stop = int(match.group("stop")) stride = match.group("stride") if stride is not None: stride = int(stride) t.value = (start, stop, stride) return t
# numbers are used as strings by parser, do not convert r"""\d+(\.\d*)?(e[-+]?\d+)? # 1, 1., 1.1, 1e10, 1.1e-10, etc. | \.\d+(e[-+]?\d+)? # .1, .1e10, .1e+10 """ return t
# identifiers can have dot, and we only support ASCII r"[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)?" # Check for reserved words t.type = self.reserved.get(t.value.upper(), 'IDENTIFIER') return t
"Error handling rule" lexer = t.lexer raise ParserLexError(lexer.lexdata, t.value, lexer.lexpos, lexer.lineno) |