Skip to content
Snippets Groups Projects
Commit 6503a97a authored by Sander Mathijs van Veen's avatar Sander Mathijs van Veen
Browse files

Solved preprocessor inserting multiplication signs in keywords.

parent 3d713049
No related branches found
No related tags found
No related merge requests found
...@@ -141,6 +141,10 @@ class Parser(BisonParser): ...@@ -141,6 +141,10 @@ class Parser(BisonParser):
import re import re
# Replace known keywords with escape sequences.
for i, keyword in enumerate(Parser.words):
data = re.sub(keyword, chr(i), data, flags=re.I)
# TODO: remove this quick preprocessing hack. This hack enables # TODO: remove this quick preprocessing hack. This hack enables
# concatenated expressions, since the grammar currently does not # concatenated expressions, since the grammar currently does not
# support those. This workaround will replace: # support those. This workaround will replace:
...@@ -151,20 +155,24 @@ class Parser(BisonParser): ...@@ -151,20 +155,24 @@ 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*(\()' # )( -> ) * (
+ '|([a-z0-9])\s*(\()' # match: a( result: a * ( + '|([\x00-\x09\x0b-\x19a-z0-9])\s*(\()' # a( -> a * (
+ '|(\))\s*([a-z0-9])' # match: )a result: ) * a + '|(\))\s*([\x00-\x09\x0b-\x19a-z0-9])' # )a -> ) * a
+ '|([a-z])\s*([a-z]+)' # match: ab result: a * b + '|([\x00-\x09\x0b-\x19a-z])\s*'
+ '|([0-9])\s*([a-z])' # match: 4a result: 4 * a +'([\x00-\x09\x0b-\x19a-z]+)' # ab -> a * b
+ '|([a-z])\s*([0-9])' # match: a4 result: a ^ 4 + '|([0-9])\s*([\x00-\x09\x0b-\x19a-z])' # 4a -> 4 * a
+ '|([0-9])\s+([0-9]))') # match: 4 4 result: 4 * 4 + '|([\x00-\x09\x0b-\x19a-z])\s*([0-9])' # a4 -> a ^ 4
+ '|([0-9])\s+([0-9]))' # 4 4 -> 4 * 4
)
def preprocess_data(match): def preprocess_data(match):
left, right = filter(None, match.groups()) left, right = filter(None, match.groups())
# Filter words (otherwise they will be preprocessed as well) # Make sure there are no multiplication and exponentiation signs
if left + right in Parser.words: # inserted between a function and its argument(s): "sin x" should
return left + right # not be written as "sin*x", because that is bogus.
if ord(left) <= 0x9 or 0x0b <= ord(left) <= 0x19:
return left + ' ' + right
# If all characters on the right are numbers. e.g. "a4", the # If all characters on the right are numbers. e.g. "a4", the
# expression implies exponentiation. Make sure ")4" is not # expression implies exponentiation. Make sure ")4" is not
...@@ -180,18 +188,20 @@ class Parser(BisonParser): ...@@ -180,18 +188,20 @@ class Parser(BisonParser):
data_before = data data_before = data
# Iteratively replace all matches. # Iteratively replace all matches.
while True: i = 0
data_after = re.sub(pattern, preprocess_data, data)
if data == data_after: while i < len(data):
break data = data[:i] + re.sub(pattern, preprocess_data, data[i:])
i += 1
data = data_after # Replace escape sequences with original keywords.
for i, keyword in enumerate(Parser.words):
data = data.replace(chr(i), keyword)
if self.verbose and data_before != data_after: # pragma: nocover if self.verbose and data_before != data: # pragma: nocover
print 'hook_read_after() modified the input data:' print 'hook_read_after() modified the input data:'
print 'before:', repr(data_before) print 'before:', repr(data_before)
print 'after :', repr(data_after) print 'after :', repr(data)
return data return data
......
...@@ -50,7 +50,8 @@ class TestParser(unittest.TestCase): ...@@ -50,7 +50,8 @@ class TestParser(unittest.TestCase):
root, x = tree('sin x, x') root, x = tree('sin x, x')
self.assertEqual(root, sin(x)) self.assertEqual(root, sin(x))
self.assertEqual(tree('sin x ^ 2'), sin(x) ** 2) #FIXME: self.assertEqual(tree('sin x ^ 2'), sin(x ** 2))
self.assertEqual(tree('sin 2 x'), sin(2) * x)
self.assertEqual(tree('sin(x) ^ 2'), sin(x) ** 2) self.assertEqual(tree('sin(x) ^ 2'), sin(x) ** 2)
self.assertEqual(tree('sin (x) ^ 2'), sin(x) ** 2) self.assertEqual(tree('sin (x) ^ 2'), sin(x) ** 2)
self.assertEqual(tree('sin(x ^ 2)'), sin(x ** 2)) self.assertEqual(tree('sin(x ^ 2)'), sin(x ** 2))
......
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