Skip to content

Commit

Permalink
Adds parse_expressions() for lists of conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
remram44 committed Oct 8, 2013
1 parent 0ffafd6 commit f71c890
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 15 deletions.
40 changes: 27 additions & 13 deletions file_archive/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ def led(self, left, context):
lexer.register_tokens(Key, Number, String, Operator)


def _update_conditions(conditions, expr):
key, cond = expr
prec = conditions.get(key)
if prec is not None:
if prec['type'] != cond['type']:
raise ParserError("Differing types for conditions on key %s: "
"%s, %s" % (key, prec['type'], cond['type']))
for k in cond.keys():
if k != 'type' and k in prec:
raise ParserError("Multiple conditions %s on key %s" % (
k, key))
prec.update(cond)
else:
conditions[key] = cond


def parse_expression(expression):
tokens = lexer.lex(expression)
parser = Parser(tokens)
Expand All @@ -69,17 +85,15 @@ def parse_expression(expression):
expr = parser.expression()
if isinstance(expr, Token):
raise ParserError("Found unexpected token %s in query" % expr)
key, cond = expr
prec = conditions.get(key)
if prec is not None:
if prec['type'] != cond['type']:
raise ParserError("Differing types for conditions on key %s: "
"%s, %s" % (key, prec['type'], cond['type']))
for k in cond.keys():
if k != 'type' and k in prec:
raise ParserError("Multiple conditions %s on key %s" % (
k, key))
prec.update(cond)
else:
conditions[key] = cond
_update_conditions(conditions, expr)
return conditions


def parse_expressions(expression_list):
conditions = {}
for expression in expression_list:
expr = lexer.parse(expression)
if isinstance(expr, Token):
raise ParserError("Found unexpected token %s in query" % expr)
_update_conditions(conditions, expr)
return conditions
20 changes: 18 additions & 2 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
except ImportError:
import unittest

from file_archive.parser import parse_expression
from file_archive.parser import parse_expression, parse_expressions


class TestParser(unittest.TestCase):
Expand Down Expand Up @@ -45,9 +45,25 @@ def test_multi(self):
{'key1': {'type': 'int', 'equal': -12},
'key2': {'type': 'str', 'equal': '4 2'},
'key3': {'type': 'int', 'gt': 41}})
self.assertEqual(parse_expression('key1>2 key1<4'),
self.assertEqual(parse_expression('key1>2 key1<4 '),
{'key1': {'type': 'int', 'gt': 2, 'lt': 4}})
with self.assertRaises(tdparser.ParserError):
parse_expression('key1="str" key1<2')
with self.assertRaises(tdparser.ParserError):
parse_expression('key1="str" key1="otherstr"')

def test_multi_splitted(self):
self.assertEqual(parse_expressions(['key1=-12', 'key2 = "4 2"', '41< key3']),
{'key1': {'type': 'int', 'equal': -12},
'key2': {'type': 'str', 'equal': '4 2'},
'key3': {'type': 'int', 'gt': 41}})
self.assertEqual(parse_expressions(['key1>2 ', ' key1<4 ']),
{'key1': {'type': 'int', 'gt': 2, 'lt': 4}})
with self.assertRaises(tdparser.ParserError):
parse_expressions(['key1="str"', 'key1<2'])
with self.assertRaises(tdparser.ParserError):
parse_expressions(['key1="str"', 'key1="otherstr"'])
with self.assertRaises(tdparser.ParserError):
parse_expressions(['key1="str" key1<2'])
with self.assertRaises(tdparser.ParserError):
parse_expressions(['"value"'])

0 comments on commit f71c890

Please sign in to comment.