From a9d73992c0e6f78ea2dbc3a54559464734f520e9 Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Wed, 24 Jun 2015 16:52:09 -0300 Subject: [PATCH 1/9] adds grako as dependency --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 4257353..3fba843 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,8 @@ 'Topic :: Utilities' ], + install_requires='grako==3.6.1', + test_suite = "tests", # metadata for upload to PyPI From aba705dc6118dded436da88e8dca2f01e69235ca Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Mon, 29 Jun 2015 11:46:32 -0300 Subject: [PATCH 2/9] creates IdentifierTestCase --- tests/test_expressions.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/test_expressions.py b/tests/test_expressions.py index 6db6715..7721bff 100644 --- a/tests/test_expressions.py +++ b/tests/test_expressions.py @@ -1,6 +1,6 @@ # -*- encoding: utf8 -*- import unittest -from expressions import Compiler, IdentifierPreprocessor +from expressions import Compiler from expressions import Variable, Function, UnaryOperator, BinaryOperator class ValidatingCompiler(Compiler): @@ -108,7 +108,26 @@ def test_function_call_compile(self): result = compiler.compile("f(x, y)") self.assertEqual("CALL f(x, y)", result) +class IdentifierPreprocessor(Compiler): + """ + CustomCompiler, just for testing + """ + def __init__(self): + super(IdentifierPreprocessor, self).__init__() + + self.variables = set() + self.functions = set() + + def compile_variable(self, context, variable): + self.variables.add(variable) + return variable + + def compile_function(self, context, function, args): + self.functions.add(function) + return function + class CustomCompilersTestCase(unittest.TestCase): + def test_preprocessor(self): pp = IdentifierPreprocessor() pp.compile("foo(a + b) * bar(b + c)") From d77d7296ce0bd0603f2540008386366e78f89531 Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Mon, 29 Jun 2015 11:46:40 -0300 Subject: [PATCH 3/9] tests running --- tests/test_expressions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_expressions.py b/tests/test_expressions.py index 7721bff..f7ab875 100644 --- a/tests/test_expressions.py +++ b/tests/test_expressions.py @@ -147,3 +147,6 @@ def test_preprocessor_unique(self): self.assertEqual(functions, ["foo"]) self.assertEqual(variables, ["a", "b", "c"]) + +if __name__ == '__main__': + unittest.main() From b6c61268c12eec19aff6b4a009714b09c530268c Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Mon, 29 Jun 2015 16:50:01 -0300 Subject: [PATCH 4/9] use assertion instead of pdb --- expressions/compiler.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/expressions/compiler.py b/expressions/compiler.py index 7d7e511..070fb9c 100644 --- a/expressions/compiler.py +++ b/expressions/compiler.py @@ -149,8 +149,7 @@ def _default(self, ast, node_type=None, *args): def variable(self, ast): # Note: ast is expected to be a _Result() from the `reference` rule value = ast.value - if not isinstance(ast, _Result): - import pdb; pdb.set_trace() + assert isinstance(ast, _Result) result = self.compiler.compile_variable(self.context, value) return _Result(result) From de717c54aba4f6fdff20aeefdbe4d2847068cb17 Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Mon, 29 Jun 2015 17:13:54 -0300 Subject: [PATCH 5/9] fixes grammar --- expressions/grammar.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/expressions/grammar.py b/expressions/grammar.py index 5cef0bb..f1f164e 100644 --- a/expressions/grammar.py +++ b/expressions/grammar.py @@ -15,7 +15,7 @@ from grako.parsing import graken, Parser -__version__ = (2014, 9, 19, 16, 34, 11, 4) +__version__ = (2015, 6, 29, 20, 11, 40, 0) __all__ = [ 'ExpressionParser', @@ -25,10 +25,13 @@ class ExpressionParser(Parser): - def __init__(self, whitespace=None, nameguard=True, **kwargs): + def __init__(self, whitespace=None, nameguard=None, **kwargs): super(ExpressionParser, self).__init__( whitespace=whitespace, nameguard=nameguard, + comments_re=None, + eol_comments_re=None, + ignorecase=None, **kwargs ) @@ -139,9 +142,7 @@ def block0(): self._token('/') with self._option(): self._token('%') - with self._option(): - self._token('//') - self._error('expecting one of: % * / //') + self._error('expecting one of: % * /') self._factor_() self._closure(block0) @@ -247,7 +248,7 @@ def _comparison_operator_(self): with self._group(): with self._choice(): with self._option(): - self._token('==') + self._token('=') with self._option(): self._token('!=') with self._option(): @@ -262,7 +263,7 @@ def _comparison_operator_(self): self._token('in') with self._option(): self._token('is') - self._error('expecting one of: != < <= == > >= in is') + self._error('expecting one of: != < <= = > >= in is') @graken() def _NAME_(self): @@ -340,7 +341,7 @@ def NAME(self, ast): return ast -def main(filename, startrule, trace=False, whitespace=None): +def main(filename, startrule, trace=False, whitespace=None, nameguard=None): import json with open(filename) as f: text = f.read() @@ -350,7 +351,8 @@ def main(filename, startrule, trace=False, whitespace=None): startrule, filename=filename, trace=trace, - whitespace=whitespace) + whitespace=whitespace, + nameguard=nameguard) print('AST:') print(ast) print() @@ -374,6 +376,9 @@ def __call__(self, parser, namespace, values, option_string): parser = argparse.ArgumentParser(description="Simple parser for Expression.") parser.add_argument('-l', '--list', action=ListRules, nargs=0, help="list all rules and exit") + parser.add_argument('-n', '--no-nameguard', action='store_true', + dest='no_nameguard', + help="disable the 'nameguard' feature") parser.add_argument('-t', '--trace', action='store_true', help="output trace information") parser.add_argument('-w', '--whitespace', type=str, default=string.whitespace, @@ -387,5 +392,6 @@ def __call__(self, parser, namespace, values, option_string): args.file, args.startrule, trace=args.trace, - whitespace=args.whitespace + whitespace=args.whitespace, + nameguard=not args.no_nameguard ) From 69c30aca6b3f8724312fbcc037a061b9cca52ed3 Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Mon, 29 Jun 2015 17:19:32 -0300 Subject: [PATCH 6/9] fixes comparison operators grammar --- expressions/grammar.ebnf | 6 +++--- expressions/grammar.py | 8 ++++---- tests/test_expressions.py | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/expressions/grammar.ebnf b/expressions/grammar.ebnf index 7600635..cd6e990 100644 --- a/expressions/grammar.ebnf +++ b/expressions/grammar.ebnf @@ -14,8 +14,8 @@ term(binary) = factor {('*' | '/' | '%') factor} ; factor(unary) = ('+' | '-' | '~') factor | power ; power = atom ['^' factor] ; -atom = NUMBER - | STRING +atom = NUMBER + | STRING | function | variable | ( '(' @:test ')' ); @@ -30,7 +30,7 @@ reference = { @+:NAME '.'} @+:NAME; NUMBER = ?/[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/? ; STRING = ?/'[^'\\\r\n]*(?:\\.[^'\\\r\n]*)*'/? ; -comparison_operator = ('=' | '!=' | '<' | '<=' | '>' | '>=' +comparison_operator = ('=' | '!=' | '<=' | '<' | '>=' | '>' | 'in' | 'is' ); (* Allow any unicode character to be an identifier *) diff --git a/expressions/grammar.py b/expressions/grammar.py index f1f164e..65e99b9 100644 --- a/expressions/grammar.py +++ b/expressions/grammar.py @@ -15,7 +15,7 @@ from grako.parsing import graken, Parser -__version__ = (2015, 6, 29, 20, 11, 40, 0) +__version__ = (2015, 6, 29, 20, 16, 29, 0) __all__ = [ 'ExpressionParser', @@ -251,14 +251,14 @@ def _comparison_operator_(self): self._token('=') with self._option(): self._token('!=') - with self._option(): - self._token('<') with self._option(): self._token('<=') with self._option(): - self._token('>') + self._token('<') with self._option(): self._token('>=') + with self._option(): + self._token('>') with self._option(): self._token('in') with self._option(): diff --git a/tests/test_expressions.py b/tests/test_expressions.py index f7ab875..c9ba771 100644 --- a/tests/test_expressions.py +++ b/tests/test_expressions.py @@ -90,6 +90,30 @@ def test_operator(self): self.assertEqual(result.left, 1) self.assertEqual(result.right, 2) + result = compiler.compile("1 = 2") + self.assertIsInstance(result, BinaryOperator) + self.assertEqual(result.operator, "=") + self.assertEqual(result.left, 1) + self.assertEqual(result.right, 2) + + result = compiler.compile("1 != 2") + self.assertIsInstance(result, BinaryOperator) + self.assertEqual(result.operator, "!=") + self.assertEqual(result.left, 1) + self.assertEqual(result.right, 2) + + result = compiler.compile("1 >= 2") + self.assertIsInstance(result, BinaryOperator) + self.assertEqual(result.operator, ">=") + self.assertEqual(result.left, 1) + self.assertEqual(result.right, 2) + + result = compiler.compile("1 <= 2") + self.assertIsInstance(result, BinaryOperator) + self.assertEqual(result.operator, "<=") + self.assertEqual(result.left, 1) + self.assertEqual(result.right, 2) + @unittest.skip("later") def test_validating_compiler(self): compiler = ValidatingCompiler() From 674d94a62697a5b7ffe5ca7a3d17e629574a15dd Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Fri, 22 Jul 2016 11:24:34 -0300 Subject: [PATCH 7/9] version bump --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3fba843..9d22cab 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name = "expressions", - version = "0.2.2", + version = "0.2.3RC", packages = find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), package_data = { From f9c5dc2b8e982c41aa93baf55c1d8596d0168e1e Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Fri, 22 Jul 2016 11:25:11 -0300 Subject: [PATCH 8/9] more version bump --- expressions/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expressions/__init__.py b/expressions/__init__.py index 0f27f12..79326fd 100644 --- a/expressions/__init__.py +++ b/expressions/__init__.py @@ -1,4 +1,4 @@ from .compiler import * -__version__ = '0.2.2' +__version__ = '0.2.3RC' From 079359ee8111769ca18ade25aad4de0133e1bfc0 Mon Sep 17 00:00:00 2001 From: Vanderson Mota Date: Fri, 22 Jul 2016 12:22:14 -0300 Subject: [PATCH 9/9] version 0.2.3 --- expressions/__init__.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/expressions/__init__.py b/expressions/__init__.py index 79326fd..813186a 100644 --- a/expressions/__init__.py +++ b/expressions/__init__.py @@ -1,4 +1,4 @@ from .compiler import * -__version__ = '0.2.3RC' +__version__ = '0.2.3' diff --git a/setup.py b/setup.py index 9d22cab..428aa20 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name = "expressions", - version = "0.2.3RC", + version = "0.2.3", packages = find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), package_data = {