def parse_expression(self, expression): """ Uses postfix evaluation of filter string. http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html """ try: f = StringIO(expression) self._scanner = Scanner(self._lexicon, f, "query") while True: token = self._scanner.read() if token[0] in self._mapper: self._mapper[token[0]](token[1]) elif token[0] is None: break if self._parenthesis_count != 0: raise InvalidQueryError("Invalid parenthesis count") while len(self._operator_stack) > 0: self._postfix_result.append(self._operator_stack.pop()) except UnrecognizedInput as e: raise InvalidQueryError(str(e)) finally: f.close()
def parse_expression(self, expression): """ Uses postfix evaluation of filter string. http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html """ try: f = StringIO.StringIO(expression) self._scanner = Scanner(self._lexicon, f, 'query') while 1: token = self._scanner.read() if token[0] in self._mapper: self._mapper[token[0]](token[1]) elif token[0] is None: break if self._parenthesis_count != 0: raise InvalidQueryError('Invalid parenthesis count') while len(self._operator_stack) > 0: self._postfix_result.append(self._operator_stack.pop()) except UnrecognizedInput as e: raise InvalidQueryError(str(e)) finally: f.close()
def __init__(self, idl_text, name): f = cStringIO.StringIO(idl_text) Scanner.__init__(self, self.lex, f, name) self.parsed = [ ] self.errors = [ ] self.types = { } self.imports = { } self.comment = None self.cur = None self.namespace = None self.searchPath = None self.idl_text = idl_text self.name = name if name: searchPath = os.path.dirname(os.path.abspath(name)) if os.environ.has_key('BARRISTER_PATH'): searchPath = searchPath + os.pathsep + os.environ['BARRISTER_PATH'] self.searchPath = searchPath
def begin(self, state_name): Scanner.begin(self, state_name)
def __init__(self, info, name='<default>'): Scanner.__init__(self, self.lexicon, info, name)
class BaseQueryParser(object): """ Base Query Parser class provides a basic implementation to parse the `query` argument i.e. Basic WHERE clause as used in SQL. Note: The base class only provides a partial implementation of the SQL where clause. """ def __init__(self, expression=None): self.expression = expression self._state = 0 self._parenthesis_count = 0 self._operator_stack = [] self._postfix_result = [] self._condition = [0, 0, 0] self._in_collection = None self._identifiers = set() self._scanner = None self._lexicon = None self._mapper = None self._init() self.parse_expression(expression) def _init(self): comma = Str(",") whitespace = Rep1(Any(" \t\n")) open_parenthesis = Str("(") close_parenthesis = Str(")") letter = Range("AZaz") digit = Range("09") prefix = letter + Rep(letter) + Str(".") identifier = prefix + letter + Rep(letter | digit | Str("_")) comparators = NoCase(Str("=", "!=", "<", "<=", ">", ">=", "like", "in")) string_literal = Str("'") + Rep(AnyBut("'") | Str(" ") | Str("\\'")) + Str("'") integer_literal = Opt(Str("+", "-")) + Rep1(digit) float_literal = Opt(Str("+", "-")) + Rep1(digit) + Str(".") + Rep1(digit) operands = NoCase(Str("AND", "OR")) null = Str("NULL") COMMA = 1 OPEN_PARENTHESIS = 2 CLOSE_PARENTHESIS = 3 NULL = 4 OPERAND = 5 COMPARATOR = 6 STRING_LITERAL = 7 INTEGER_LITERAL = 8 FLOAT_LITERAL = 9 IDENTIFIER = 10 self._lexicon = Lexicon( [ (whitespace, IGNORE), (comma, COMMA), (open_parenthesis, OPEN_PARENTHESIS), (close_parenthesis, CLOSE_PARENTHESIS), (null, NULL), (operands, OPERAND), (comparators, COMPARATOR), (string_literal, STRING_LITERAL), (integer_literal, INTEGER_LITERAL), (float_literal, FLOAT_LITERAL), (identifier, IDENTIFIER), ] ) self._mapper = { COMMA: self.comma_handler, OPEN_PARENTHESIS: self.open_parenthesis_handler, CLOSE_PARENTHESIS: self.close_parenthesis_handler, NULL: self.null_handler, OPERAND: self.operand_handler, COMPARATOR: self.comparator_handler, STRING_LITERAL: self.string_literal_handler, INTEGER_LITERAL: self.integer_literal_handler, FLOAT_LITERAL: self.float_literal_handler, IDENTIFIER: self.identifier_handler, } @property def identifiers(self): return self._identifiers def parse_expression(self, expression): """ Uses postfix evaluation of filter string. http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html """ try: f = StringIO(expression) self._scanner = Scanner(self._lexicon, f, "query") while True: token = self._scanner.read() if token[0] in self._mapper: self._mapper[token[0]](token[1]) elif token[0] is None: break if self._parenthesis_count != 0: raise InvalidQueryError("Invalid parenthesis count") while len(self._operator_stack) > 0: self._postfix_result.append(self._operator_stack.pop()) except UnrecognizedInput as e: raise InvalidQueryError(str(e)) finally: f.close() def comma_handler(self, text): if self._state == 3: return file, line, char_pos = self._scanner.position() msg = "Invalid token: Line: %d Char: %d" % (line, char_pos) raise InvalidQueryError(msg) def open_parenthesis_handler(self, text): if self._state == 3: self._in_collection = [] return self._parenthesis_count += 1 self._operator_stack.append("(") def close_parenthesis_handler(self, text): if self._state == 3: self._condition[2] = self._in_collection self._postfix_result.append(tuple(self._condition)) self._state = 0 return if self._parenthesis_count <= 0: file, line, char_pos = self._scanner.position() msg = "Invalid parenthesis order: Line: %d Char: %d" % (line, char_pos) raise InvalidQueryError(msg) else: self._parenthesis_count -= 1 while len(self._operator_stack) > 0: operator = self._operator_stack.pop() if operator == "(": break else: self._postfix_result.append(operator) def null_handler(self, text): if self._state == 2: self._condition[2] = None self._postfix_result.append(tuple(self._condition)) self._state = 0 else: file, line, char_pos = self._scanner.position() msg = "NULL found out of order: Line: %d Char: %d" % (line, char_pos) raise InvalidQueryError(msg) def operand_handler(self, text): self._operator_stack.append(text.upper()) def comparator_handler(self, text): if self._state == 1: self._condition[1] = text.upper() self._state = 3 if self._condition[1] == "IN" else 2 else: file, line, char_pos = self._scanner.position() msg = "Comparator %r found out of order: Line: %d Char: %d" % ( text, line, char_pos, ) raise InvalidQueryError(msg) def string_literal_handler(self, text): if self._state == 2: self._condition[2] = text.strip("'") self._postfix_result.append(tuple(self._condition)) self._state = 0 elif self._state == 3: self._in_collection.append(text.strip("'")) else: file, line, char_pos = self._scanner.position() msg = "String literal %r found out of order: Line: %d Char: %d" % ( text, line, char_pos, ) raise InvalidQueryError(msg) def integer_literal_handler(self, text): if self._state == 2: self._condition[2] = text.strip() self._postfix_result.append(tuple(self._condition)) self._state = 0 elif self._state == 3: self._in_collection.append(text.strip()) else: file, line, char_pos = self._scanner.position() msg = "Integer literal %s found out of order: Line: %d Char: %d" % ( text, line, char_pos, ) raise InvalidQueryError(msg) def float_literal_handler(self, text): if self._state == 2: self._condition[2] = text.strip() self._postfix_result.append(tuple(self._condition)) self._state = 0 elif self._state == 3: self._in_collection.append(text.strip()) else: file, line, char_pos = self._scanner.position() msg = "Integer literal %d found out of order: Line: %d Char: %d" % ( text, line, char_pos, ) raise InvalidQueryError(msg) def identifier_handler(self, text): if self._state == 0: self._condition[0] = text self._identifiers.add(text) self._state = 1 elif self._state == 2: self._condition[2] = ("I", text) self._postfix_result.append(tuple(self._condition)) self._identifiers.add(text) self._state = 0 else: file, line, char_pos = self._scanner.position() msg = "Field %r found out of order: Line: %d Char: %d" % ( text, line, char_pos, ) raise InvalidQueryError(msg) def evaluate(self): return self._postfix_result def clear(self): self._state = 0 self._parenthesis_count = 0 self._operator_stack = [] self._postfix_result = [] self._condition = [0, 0, 0] self._identifiers = set() self._scanner = None def __str__(self): comparator = { "=": "__eq__", "!=": "__ne__", "<": "__lt__", "<=": "__le__", ">": "__gt__", ">=": "__ge__", "LIKE": "like", "IN": "in_", } operators = {"AND": "and_", "OR": "or_"} operands = [] def condition_expansion(expr, field): operands.append("%s.%s ( %s )" % (field, comparator[expr[1]], expr[2])) for token in self._postfix_result: if isinstance(token, tuple): identifier = token[0] condition_expansion(token, identifier) elif isinstance(token, str) or isinstance(token, unicode): operand_2 = operands.pop() operand_1 = operands.pop() if token in operators: operands.append( "%s ( %s, %s )" % (operators[token], operand_1, operand_2) ) return operands.pop()
def __init__(self, f): Scanner.__init__(self, self.lexicon, f) self.stack = [] self.begin('start') self.result = 0
class BaseQueryParser(object): """ Base Query Parser class provides a basic implementation to parse the `query` argument i.e. Basic WHERE clause as used in SQL. Note: The base class only provides a partial implementation of the SQL where clause. """ def __init__(self, expression=None): self.expression = expression self._state = 0 self._parenthesis_count = 0 self._operator_stack = [] self._postfix_result = [] self._condition = [0, 0, 0] self._in_collection = None self._identifiers = set() self._scanner = None self._lexicon = None self._mapper = None self._init() self.parse_expression(expression) def _init(self): comma = Str(',') whitespace = Rep1(Any(' \t\n')) open_parenthesis = Str('(') close_parenthesis = Str(')') letter = Range('AZaz') digit = Range('09') prefix = letter + Rep(letter) + Str('.') identifier = prefix + letter + Rep(letter | digit | Str('_')) comparators = NoCase(Str('=', '!=', '<', '<=', '>', '>=', 'like', 'in')) string_literal = Str('\'') + Rep(AnyBut('\'') | Str(' ') | Str("\\'")) + Str('\'') integer_literal = Opt(Str('+', '-')) + Rep1(digit) float_literal = Opt(Str('+', '-')) + Rep1(digit) + Str('.') + Rep1(digit) operands = NoCase(Str('AND', 'OR')) null = Str('NULL') COMMA = 1 OPEN_PARENTHESIS = 2 CLOSE_PARENTHESIS = 3 NULL = 4 OPERAND = 5 COMPARATOR = 6 STRING_LITERAL = 7 INTEGER_LITERAL = 8 FLOAT_LITERAL = 9 IDENTIFIER = 10 self._lexicon = Lexicon([ (whitespace, IGNORE), (comma, COMMA), (open_parenthesis, OPEN_PARENTHESIS), (close_parenthesis, CLOSE_PARENTHESIS), (null, NULL), (operands, OPERAND), (comparators, COMPARATOR), (string_literal, STRING_LITERAL), (integer_literal, INTEGER_LITERAL), (float_literal, FLOAT_LITERAL), (identifier, IDENTIFIER) ]) self._mapper = { COMMA: self.comma_handler, OPEN_PARENTHESIS: self.open_parenthesis_handler, CLOSE_PARENTHESIS: self.close_parenthesis_handler, NULL: self.null_handler, OPERAND: self.operand_handler, COMPARATOR: self.comparator_handler, STRING_LITERAL: self.string_literal_handler, INTEGER_LITERAL: self.integer_literal_handler, FLOAT_LITERAL: self.float_literal_handler, IDENTIFIER: self.identifier_handler, } @property def identifiers(self): return self._identifiers def parse_expression(self, expression): """ Uses postfix evaluation of filter string. http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html """ try: f = StringIO.StringIO(expression) self._scanner = Scanner(self._lexicon, f, 'query') while 1: token = self._scanner.read() if token[0] in self._mapper: self._mapper[token[0]](token[1]) elif token[0] is None: break if self._parenthesis_count != 0: raise InvalidQueryError('Invalid parenthesis count') while len(self._operator_stack) > 0: self._postfix_result.append(self._operator_stack.pop()) except UnrecognizedInput as e: raise InvalidQueryError(str(e)) finally: f.close() def comma_handler(self, text): if self._state == 3: return file, line, char_pos = self._scanner.position() msg = 'Invalid token: Line: %d Char: %d' % (line, char_pos) raise InvalidQueryError(msg) def open_parenthesis_handler(self, text): if self._state == 3: self._in_collection = [] return self._parenthesis_count += 1 self._operator_stack.append('(') def close_parenthesis_handler(self, text): if self._state == 3: self._condition[2] = self._in_collection self._postfix_result.append(tuple(self._condition)) self._state = 0 return if self._parenthesis_count <= 0: file, line, char_pos = self._scanner.position() msg = 'Invalid parenthesis order: Line: %d Char: %d' % (line, char_pos) raise InvalidQueryError(msg) else: self._parenthesis_count -= 1 while len(self._operator_stack) > 0: operator = self._operator_stack.pop() if operator == '(': break else: self._postfix_result.append(operator) def null_handler(self, text): if self._state == 2: self._condition[2] = None self._postfix_result.append(tuple(self._condition)) self._state = 0 else: file, line, char_pos = self._scanner.position() msg = 'NULL found out of order: Line: %d Char: %d' % (line, char_pos) raise InvalidQueryError(msg) def operand_handler(self, text): self._operator_stack.append(text.upper()) def comparator_handler(self, text): if self._state == 1: self._condition[1] = text.upper() self._state = 3 if self._condition[1] == 'IN' else 2 else: file, line, char_pos = self._scanner.position() msg = 'Comparator %r found out of order: Line: %d Char: %d' % (text, line, char_pos) raise InvalidQueryError(msg) def string_literal_handler(self, text): if self._state == 2: self._condition[2] = text.strip("'") self._postfix_result.append(tuple(self._condition)) self._state = 0 elif self._state == 3: self._in_collection.append(text.strip("'")) else: file, line, char_pos = self._scanner.position() msg = 'String literal %r found out of order: Line: %d Char: %d' % (text, line, char_pos) raise InvalidQueryError(msg) def integer_literal_handler(self, text): if self._state == 2: self._condition[2] = text.strip() self._postfix_result.append(tuple(self._condition)) self._state = 0 elif self._state == 3: self._in_collection.append(text.strip()) else: file, line, char_pos = self._scanner.position() msg = 'Integer literal %s found out of order: Line: %d Char: %d' % (text, line, char_pos) raise InvalidQueryError(msg) def float_literal_handler(self, text): if self._state == 2: self._condition[2] = text.strip() self._postfix_result.append(tuple(self._condition)) self._state = 0 elif self._state == 3: self._in_collection.append(text.strip()) else: file, line, char_pos = self._scanner.position() msg = 'Integer literal %d found out of order: Line: %d Char: %d' % (text, line, char_pos) raise InvalidQueryError(msg) def identifier_handler(self, text): if self._state == 0: self._condition[0] = text self._identifiers.add(text) self._state = 1 elif self._state == 2: self._condition[2] = ('I', text) self._postfix_result.append(tuple(self._condition)) self._identifiers.add(text) self._state = 0 else: file, line, char_pos = self._scanner.position() msg = 'Field %r found out of order: Line: %d Char: %d' % (text, line, char_pos) raise InvalidQueryError(msg) def evaluate(self): return self._postfix_result def clear(self): self._state = 0 self._parenthesis_count = 0 self._operator_stack = [] self._postfix_result = [] self._condition = [0, 0, 0] self._identifiers = set() self._scanner = None def __str__(self): comparator = { '=': '__eq__', '!=': '__ne__', '<': '__lt__', '<=': '__le__', '>': '__gt__', '>=': '__ge__', 'LIKE': 'like', 'IN': 'in_' } operators = { 'AND': 'and_', 'OR': 'or_' } operands = [] def condition_expansion(expr, field): operands.append('%s.%s ( %s )' % (field, comparator[expr[1]], expr[2])) for token in self._postfix_result: if isinstance(token, tuple): identifier = token[0] condition_expansion(token, identifier) elif isinstance(token, str) or isinstance(token, unicode): operand_2 = operands.pop() operand_1 = operands.pop() if token in operators: operands.append('%s ( %s, %s )' % (operators[token], operand_1, operand_2)) return operands.pop()