Commit 330a223a authored by Taddeus Kroes's avatar Taddeus Kroes

Added fix(/hack) that enables use of 'd' as a variable next to being iuses in 'd/dx'.

parent 2b325ca8
...@@ -59,7 +59,7 @@ class Parser(BisonParser): ...@@ -59,7 +59,7 @@ class Parser(BisonParser):
# of tokens of the lex script. # of tokens of the lex script.
tokens = ['NUMBER', 'IDENTIFIER', 'NEWLINE', 'QUIT', 'RAISE', 'GRAPH', tokens = ['NUMBER', 'IDENTIFIER', 'NEWLINE', 'QUIT', 'RAISE', 'GRAPH',
'LPAREN', 'RPAREN', 'FUNCTION', 'LBRACKET', 'RBRACKET', \ 'LPAREN', 'RPAREN', 'FUNCTION', 'LBRACKET', 'RBRACKET', \
'APOSTROPH', 'DELTA'] \ 'APOSTROPH', 'DERIVATIVE'] \
+ filter(lambda t: t != 'FUNCTION', TOKEN_MAP.values()) + filter(lambda t: t != 'FUNCTION', TOKEN_MAP.values())
# ------------------------------ # ------------------------------
...@@ -153,13 +153,13 @@ class Parser(BisonParser): ...@@ -153,13 +153,13 @@ class Parser(BisonParser):
# - "4a" with "4*a". # - "4a" with "4*a".
# - "a4" with "a^4". # - "a4" with "a^4".
pattern = ('(?:(\))\s*(\()' # match: )( result: ) * ( pattern = ('(?:(\))\s*(\()' # match: )( result: ) * (
+ '|([a-ce-z0-9])\s*(\()' # match: a( result: a * ( + '|([a-z0-9])\s*(\()' # match: a( result: a * (
+ '|(\))\s*([a-ce-z0-9])' # match: )a result: ) * a + '|(\))\s*([a-z0-9])' # match: )a result: ) * a
+ '|([a-ce-z])\s*([a-ce-z]+)' # match: ab result: a * b + '|([a-z])\s*([a-z]+)' # match: ab result: a * b
+ '|([0-9])\s*([a-ce-z])' # match: 4a result: 4 * a + '|([0-9])\s*([a-z])' # match: 4a result: 4 * a
+ '|([a-ce-z])\s*([0-9])' # match: a4 result: a ^ 4 + '|([a-z])\s*([0-9])' # match: a4 result: a ^ 4
+ '|([0-9])\s+([0-9]))') # match: 4 4 result: 4 * 4 + '|([0-9])\s+([0-9]))') # match: 4 4 result: 4 * 4
def preprocess_data(match): def preprocess_data(match):
left, right = filter(None, match.groups()) left, right = filter(None, match.groups())
...@@ -183,7 +183,10 @@ class Parser(BisonParser): ...@@ -183,7 +183,10 @@ class Parser(BisonParser):
# Iteratively replace all matches. # Iteratively replace all matches.
while True: while True:
data_after = re.sub(pattern, preprocess_data, data) # match: d/dx result: der_x
data_after = re.sub(r'd\s*/\s*d([a-z])', r'der_\1', data)
data_after = re.sub(pattern, preprocess_data, data_after)
if data == data_after: if data == data_after:
break break
...@@ -333,8 +336,6 @@ class Parser(BisonParser): ...@@ -333,8 +336,6 @@ class Parser(BisonParser):
| unary | unary
| binary | binary
| nary | nary
| bracket_derivative
| delta_derivative
""" """
# | concat # | concat
...@@ -349,51 +350,35 @@ class Parser(BisonParser): ...@@ -349,51 +350,35 @@ class Parser(BisonParser):
if option == 2: # rule: LPAREN exp RPAREN if option == 2: # rule: LPAREN exp RPAREN
return values[1] return values[1]
if 3 <= option <= 7: # rule: unary | binary | nary if 3 <= option <= 5: # rule: unary | binary | nary
# | bracket_derivative | delta_derivative
return values[0] return values[0]
raise BisonSyntaxError('Unsupported option %d in target "%s".' raise BisonSyntaxError('Unsupported option %d in target "%s".'
% (option, target)) # pragma: nocover % (option, target)) # pragma: nocover
def on_bracket_derivative(self, target, option, names, values): #def on_delta_derivative(self, target, option, names, values):
""" # """
bracket_derivative : LBRACKET exp RBRACKET APOSTROPH # delta_derivative : DELTA DIVIDE DELTA IDENTIFIER TIMES exp
| bracket_derivative APOSTROPH # | DELTA LPAREN exp RPAREN DIVIDE DELTA IDENTIFIER
""" # """
op = [k for k, v in OP_MAP.iteritems() if v == OP_DERIV][0]
if option == 0: # rule: LBRACKET exp RBRACKET APOSTROPH
return Node(op, values[1])
if option == 1: # rule: bracket_derivative APOSTROPH
return Node(op, values[0])
raise BisonSyntaxError('Unsupported option %d in target "%s".'
% (option, target)) # pragma: nocover
def on_delta_derivative(self, target, option, names, values):
"""
delta_derivative : DELTA DIVIDE DELTA IDENTIFIER TIMES exp
| DELTA LPAREN exp RPAREN DIVIDE DELTA IDENTIFIER
"""
op = [k for k, v in OP_MAP.iteritems() if v == OP_DERIV][0] # op = [k for k, v in OP_MAP.iteritems() if v == OP_DERIV][0]
if option == 0: # rule: DELTA DIVIDE DELTA IDENTIFIER TIMES exp # if option == 0: # rule: DELTA DIVIDE DELTA IDENTIFIER TIMES exp
return Node(op, values[5], Leaf(values[3])) # return Node(op, values[5], Leaf(values[3]))
if option == 1: # rule: DELTA LPAREN exp RPAREN DIVIDE DELTA IDENTIFIER # if option == 1: # rule: DELTA LPAREN exp RPAREN DIVIDE DELTA IDENTIFIER
return Node(op, values[2], Leaf(values[6])) # return Node(op, values[2], Leaf(values[6]))
raise BisonSyntaxError('Unsupported option %d in target "%s".' # raise BisonSyntaxError('Unsupported option %d in target "%s".'
% (option, target)) # pragma: nocover # % (option, target)) # pragma: nocover
def on_unary(self, target, option, names, values): def on_unary(self, target, option, names, values):
""" """
unary : MINUS exp %prec NEG unary : MINUS exp %prec NEG
| FUNCTION exp | FUNCTION exp
| DERIVATIVE TIMES exp
| bracket_derivative
""" """
if option == 0: # rule: NEG exp if option == 0: # rule: NEG exp
...@@ -413,6 +398,31 @@ class Parser(BisonParser): ...@@ -413,6 +398,31 @@ class Parser(BisonParser):
return Node(*values) return Node(*values)
if option == 2: # rule: DERIVATIVE exp
op = [k for k, v in OP_MAP.iteritems() if v == OP_DERIV][0]
return Node(op, values[2], Leaf(values[0][-1]))
if option == 3: # rule: bracket_derivative
return values[0]
raise BisonSyntaxError('Unsupported option %d in target "%s".'
% (option, target)) # pragma: nocover
def on_bracket_derivative(self, target, option, names, values):
"""
bracket_derivative : LBRACKET exp RBRACKET APOSTROPH
| bracket_derivative APOSTROPH
"""
op = [k for k, v in OP_MAP.iteritems() if v == OP_DERIV][0]
if option == 0: # rule: LBRACKET exp RBRACKET APOSTROPH
return Node(op, values[1])
if option == 1: # rule: bracket_derivative APOSTROPH
return Node(op, values[0])
raise BisonSyntaxError('Unsupported option %d in target "%s".' raise BisonSyntaxError('Unsupported option %d in target "%s".'
% (option, target)) # pragma: nocover % (option, target)) # pragma: nocover
...@@ -511,9 +521,9 @@ class Parser(BisonParser): ...@@ -511,9 +521,9 @@ class Parser(BisonParser):
%% %%
"d" { returntoken(DELTA); } "der_"[a-z] { returntoken(DERIVATIVE); }
[0-9]+"."?[0-9]* { returntoken(NUMBER); } [0-9]+"."?[0-9]* { returntoken(NUMBER); }
[a-ce-zA-Z] { returntoken(IDENTIFIER); } [a-zA-Z] { returntoken(IDENTIFIER); }
"(" { returntoken(LPAREN); } "(" { returntoken(LPAREN); }
")" { returntoken(RPAREN); } ")" { returntoken(RPAREN); }
""" + operators + r""" """ + operators + r"""
......
...@@ -69,4 +69,4 @@ class TestParser(unittest.TestCase): ...@@ -69,4 +69,4 @@ class TestParser(unittest.TestCase):
exp, x = tree('x ^ 2, x') exp, x = tree('x ^ 2, x')
self.assertEqual(tree('d/dx x ^ 2'), der(exp, x)) self.assertEqual(tree('d/dx x ^ 2'), der(exp, x))
self.assertEqual(tree('d(x ^ 2)/dx'), der(exp, x)) #self.assertEqual(tree('d(x ^ 2)/dx'), der(exp, x))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment