Enable parsing of composition strings when species names contain colons

This commit is contained in:
Ray Speth 2016-11-19 17:14:24 -05:00
parent 1db103cd87
commit 8e6d53d18b
4 changed files with 43 additions and 6 deletions

View file

@ -145,13 +145,13 @@ class chemkinConverterTest(utilities.CanteraTest):
self.assertEqual(gas.n_species, 7)
self.assertEqual(gas.species_name(0), '(Parens)')
self.assertEqual(gas.species_name(1), '@#$%^-2')
self.assertEqual(gas.species_index('co:lons'), 2)
self.assertEqual(gas.species_index('co:lons:'), 2)
self.assertEqual(gas.species_name(3), '[xy2]*{.}')
self.assertEqual(gas.species_name(4), 'plus+')
self.assertEqual(gas.species_name(5), 'eq=uals')
self.assertEqual(gas.species_name(6), 'plus')
self.assertEqual(gas.n_reactions, 6)
self.assertEqual(gas.n_reactions, 7)
nu = gas.product_stoich_coeffs() - gas.reactant_stoich_coeffs()
self.assertEqual(list(nu[:,0]), [-1, -1, 0, 2, 0, 0, 0])
self.assertEqual(list(nu[:,1]), [-2, 3, 0, -1, 0, 0, 0])
@ -159,6 +159,7 @@ class chemkinConverterTest(utilities.CanteraTest):
self.assertEqual(list(nu[:,3]), [3, 0, 0, 0, -2, -1, 0])
self.assertEqual(list(nu[:,4]), [2, 0, 0, 0, -1, 0, -1])
self.assertEqual(list(nu[:,5]), [1, 0, 0, 0, 1, -1, -1])
self.assertEqual(list(nu[:,6]), [2, 0, -1, 0, 0, -1, 0])
def test_unterminatedSections(self):
with self.assertRaises(ck2cti.InputParseError):

View file

@ -121,8 +121,9 @@ compositionMap parseCompString(const std::string& ss,
size_t start = 0;
size_t stop = 0;
size_t left = 0;
while (stop < ss.size()) {
size_t colon = ss.find(':', start);
size_t colon = ss.find(':', left);
if (colon == npos) {
break;
}
@ -137,8 +138,33 @@ compositionMap parseCompString(const std::string& ss,
throw CanteraError("parseCompString",
"Duplicate key: '" + name + "'.");
}
x[name] = fpValueCheck(ss.substr(valstart, stop-colon-1));
double value;
try {
value = fpValueCheck(ss.substr(valstart, stop-colon-1));
} catch (CanteraError& err) {
// If we have a key containing a colon, we expect this to fail. In
// this case, take the current substring as part of the key and look
// to the right of the next colon for the corresponding value.
// Otherwise, this is an invalid composition string.
std::string testname = ss.substr(valstart, stop-colon-1);
if (testname.find_first_of(" \n\t") != npos) {
// Space, tab, and newline are never allowed in names
throw;
} else if (ss.substr(valstart, stop-colon-1).find(':') != npos) {
left = colon + 1;
continue;
} else {
throw;
}
}
x[name] = value;
start = ss.find_first_not_of(", ;\n\t", stop+1);
left = start;
}
if (left != start) {
throw CanteraError("parseCompString", "Unable to parse key-value pair:"
"\n'{}'", ss.substr(start, stop));
}
if (stop != npos && !ba::trim_copy(ss.substr(stop)).empty()) {
throw CanteraError("parseCompString", "Found non-key:value data "

View file

@ -2,7 +2,7 @@ Elements
H C
End
SPEC
(Parens) @#$%^-2 co:lons [xy2]*{.} plus+ eq=uals plus
(Parens) @#$%^-2 co:lons: [xy2]*{.} plus+ eq=uals plus
end
thermo
@ -15,7 +15,7 @@ thermo
7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2
-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3
-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4
co:lons C 1H 4 G 200.000 3500.000 1000.000 1
co:lons: C 1H 4 G 200.000 3500.000 1000.000 1
7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2
-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3
-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4
@ -44,5 +44,6 @@ plus+ + (Parens) = 2plus+ 9.999e9 9.9 999.9
2 plus+ + eq=uals = 3(Parens) 9.999e9 9.9 999.9
plus + plus+ = 2 (Parens) 9.999e9 9.9 999.9
plus+ eq=uals = plus++(Parens) 9.999e9 9.9 999.9
co:lons: + eq=uals = 2 (Parens) 9.999e9 9.9 999.9
end

View file

@ -24,6 +24,15 @@ TEST(parseCompString, extra_spaces)
ASSERT_DOUBLE_EQ(1e-4, c["baz"]);
}
TEST(parseCompString, name_with_colon)
{
compositionMap c = parseCompString("foo: 1.0 co:lon:2,baz: 1e-4");
ASSERT_EQ((size_t) 3, c.size());
ASSERT_DOUBLE_EQ(1.0, c["foo"]);
ASSERT_DOUBLE_EQ(2.0, c["co:lon"]);
ASSERT_DOUBLE_EQ(1e-4, c["baz"]);
}
TEST(parseCompString, default_values)
{
std::vector<std::string> x = { "foo", "bar", "baz" };