diff --git a/common/lib/calc/calc/calc.py b/common/lib/calc/calc/calc.py index fc45f107bc..b55055dcd1 100644 --- a/common/lib/calc/calc/calc.py +++ b/common/lib/calc/calc/calc.py @@ -381,10 +381,19 @@ class ParseAugmenter(object): # Predefine recursive variables. expr = Forward() - # Handle variables passed in. They must start with letters/underscores - # and may contain numbers afterward. - inner_varname = Word(alphas + "_", alphanums + "_") - varname = Group(inner_varname)("variable") + # Handle variables passed in. They must start with a letter + # and may contain numbers and underscores afterward. + inner_varname = Combine(Word(alphas, alphanums + "_") + ZeroOrMore("'")) + # Alternative variable name in tensor format + # Tensor name must start with a letter, continue with alphanums + # Indices may be alphanumeric + # e.g., U_{ijk}^{123} + upper_indices = Literal("^{") + Word(alphanums) + Literal("}") + lower_indices = Literal("_{") + Word(alphanums) + Literal("}") + tensor_lower = Combine(Word(alphas, alphanums) + lower_indices + ZeroOrMore("'")) + tensor_mixed = Combine(Word(alphas, alphanums) + Optional(lower_indices) + upper_indices + ZeroOrMore("'")) + # Test for mixed tensor first, then lower tensor alone, then generic variable name + varname = Group(tensor_mixed | tensor_lower | inner_varname)("variable") varname.setParseAction(self.variable_parse_action) # Same thing for functions. diff --git a/common/lib/calc/calc/tests/test_calc.py b/common/lib/calc/calc/tests/test_calc.py index d8da18c93f..77acca9f48 100644 --- a/common/lib/calc/calc/tests/test_calc.py +++ b/common/lib/calc/calc/tests/test_calc.py @@ -440,7 +440,7 @@ class EvaluatorTest(unittest.TestCase): """ Substitution of variables into simple equations """ - variables = {'x': 9.72, 'y': 7.91, 'loooooong': 6.4} + variables = {'x': 9.72, 'y': 7.91, 'loooooong': 6.4, "f_0'": 2.0, "T_{ijk}^{123}''": 5.2} # Should not change value of constant # even with different numbers of variables... @@ -452,6 +452,8 @@ class EvaluatorTest(unittest.TestCase): self.assertEqual(calc.evaluator(variables, {}, 'x'), 9.72) self.assertEqual(calc.evaluator(variables, {}, 'y'), 7.91) self.assertEqual(calc.evaluator(variables, {}, 'loooooong'), 6.4) + self.assertEqual(calc.evaluator(variables, {}, "f_0'"), 2.0) + self.assertEqual(calc.evaluator(variables, {}, "T_{ijk}^{123}''"), 5.2) # Test a simple equation self.assertAlmostEqual(