Skip to content
Snippets Groups Projects
Commit 17c6fae8 authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Added logical operators.

parent 685f3ea3
No related branches found
No related tags found
No related merge requests found
......@@ -28,34 +28,36 @@ OP_MUL = 5
OP_DIV = 6
OP_POW = 7
OP_SUBSCRIPT = 8
OP_AND = 9
OP_OR = 10
# N-ary (functions)
OP_INT = 9
OP_INT_INDEF = 10
OP_COMMA = 11
OP_SQRT = 12
OP_DER = 13
OP_LOG = 14
OP_INT = 11
OP_INT_INDEF = 12
OP_COMMA = 13
OP_SQRT = 14
OP_DER = 15
OP_LOG = 16
# Goniometry
OP_SIN = 15
OP_COS = 16
OP_TAN = 17
OP_SIN = 17
OP_COS = 18
OP_TAN = 19
OP_SOLVE = 18
OP_EQ = 19
OP_SOLVE = 20
OP_EQ = 21
OP_POSSIBILITIES = 20
OP_HINT = 21
OP_REWRITE_ALL = 22
OP_REWRITE = 23
OP_POSSIBILITIES = 22
OP_HINT = 23
OP_REWRITE_ALL = 24
OP_REWRITE = 25
# Special identifiers
PI = 'pi'
E = 'e'
INFINITY = 'oo'
SPECIAL_TOKENS = [PI, INFINITY]
SPECIAL_TOKENS = [PI, E, INFINITY]
# Default base to use in parsing 'log(...)'
DEFAULT_LOGARITHM_BASE = 10
......@@ -75,6 +77,8 @@ OP_MAP = {
'/': OP_DIV,
'^': OP_POW,
'_': OP_SUBSCRIPT,
'^^': OP_AND,
'vv': OP_OR,
'sin': OP_SIN,
'cos': OP_COS,
'tan': OP_TAN,
......@@ -103,6 +107,8 @@ TOKEN_MAP = {
OP_DIV: 'DIVIDE',
OP_POW: 'POW',
OP_SUBSCRIPT: 'SUB',
OP_AND: 'AND',
OP_OR: 'OR',
OP_SQRT: 'FUNCTION',
OP_SIN: 'FUNCTION',
OP_COS: 'FUNCTION',
......@@ -226,6 +232,12 @@ class ExpressionBase(object):
def __pos__(self):
return self.reduce_negation()
def __and__(self, other):
return ExpressionNode(OP_AND, self, to_expression(other))
def __or__(self, other):
return ExpressionNode(OP_OR, self, to_expression(other))
def reduce_negation(self, n=1):
"""Remove n negation flags from the node."""
assert self.negated
......
......@@ -87,10 +87,12 @@ class Parser(BisonParser):
precedences = (
('left', ('COMMA', )),
('right', ('INTEGRAL', 'DERIVATIVE')),
('left', ('OR', )),
('left', ('AND', )),
('left', ('EQ', )),
('left', ('MINUS', 'PLUS')),
('left', ('TIMES', 'DIVIDE')),
('right', ('FUNCTION', )),
('left', ('EQ', )),
('left', ('NEG', )),
('right', ('POW', )),
('left', ('SUB', )),
......@@ -225,6 +227,9 @@ class Parser(BisonParser):
for i, keyword in enumerate(words):
data = data.replace(chr(i), keyword)
# Fix TIMES operator next to OR
data = re.sub(r'\*?vv\*?', 'vv', data)
if self.verbose and data_before != data: # pragma: nocover
print 'hook_read_after() modified the input data:'
print 'before:', repr(data_before)
......@@ -527,14 +532,16 @@ class Parser(BisonParser):
| exp TIMES exp
| exp DIVIDE exp
| exp EQ exp
| exp AND exp
| exp OR exp
| exp MINUS exp
| power
"""
if 0 <= option < 4: # rule: exp {PLUS,TIMES,DIVIDE,EQ} exp
if 0 <= option <= 5: # rule: exp {PLUS,TIMES,DIVIDE,EQ,AND,OR} exp
return Node(values[1], values[0], values[2])
if option == 4: # rule: exp MINUS exp
if option == 6: # rule: exp MINUS exp
node = values[2]
# Add negation to the left-most child
......@@ -549,7 +556,7 @@ class Parser(BisonParser):
return Node(OP_ADD, values[0], values[2])
if option == 5: # rule: power
if option == 7: # rule: power
return Node(OP_POW, *values[0])
raise BisonSyntaxError('Unsupported option %d in target "%s".'
......@@ -573,8 +580,9 @@ class Parser(BisonParser):
functions = []
for token in SPECIAL_TOKENS:
operators += '"%s"%s{ returntoken(IDENTIFIER); }\n' \
% (token, ' ' * (8 - len(token)))
if len(token) > 1:
operators += '"%s"%s{ returntoken(IDENTIFIER); }\n' \
% (token, ' ' * (8 - len(token)))
for op_str, op in OP_MAP.iteritems():
if TOKEN_MAP[op] == 'FUNCTION':
......
......@@ -38,6 +38,14 @@ class TestParser(unittest.TestCase):
self.assertNotEqual(possibilities1, possibilities2)
def test_binary(self):
a, b, c = tree('a, b, c')
self.assertEqual(tree('a ^^ b'), a & b)
self.assertEqual(tree('a vv b'), a | b)
self.assertEqual(tree('a vv b vv c'), (a | b) | c)
self.assertEqual(tree('a vv b ^^ c'), a | (b & c))
def test_preprocessor(self):
self.assertEqual(tree('ab'), tree('a * b'))
self.assertEqual(tree('abc'), tree('a * b * c'))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment