- Rewrote ::findIdSequence to be more exacting in the definition of an ID.
  The previous implementation considered '1.2' to be an ID.
This commit is contained in:
Paul Beckingham
2014-06-25 21:42:00 -04:00
parent d4a003f121
commit 8bad1591dc

View File

@@ -1098,13 +1098,6 @@ void Parser::findAttributeModifier ()
// a range: 5-10 // a range: 5-10
// or a combination: 1,3,5-10 12 // or a combination: 1,3,5-10 12
// //
// If a sequence is followed by a non-number, then subsequent numbers are not
// interpreted as IDs. For example:
//
// 1 2 three 4
//
// The sequence is "1 2".
//
void Parser::findIdSequence () void Parser::findIdSequence ()
{ {
std::vector <Tree*>::iterator i; std::vector <Tree*>::iterator i;
@@ -1118,49 +1111,67 @@ void Parser::findIdSequence ()
if (! (*i)->hasTag ("?")) if (! (*i)->hasTag ("?"))
continue; continue;
std::string raw = (*i)->attribute ("raw"); // Container for min/max ID ranges.
Nibbler n (raw);
std::vector <std::pair <int, int> > ranges; std::vector <std::pair <int, int> > ranges;
// Split the ID list into elements.
std::string raw = (*i)->attribute ("raw");
std::vector <std::string> elements;
split (elements, raw, ',');
bool not_an_id = false;
std::vector <std::string>::iterator e;
for (e = elements.begin (); e != elements.end (); ++e)
{
// Split the ID range into min/max.
std::vector <std::string> terms;
split (terms, *e, '-');
if (terms.size () == 1)
{
Nibbler n (terms[0]);
int id; int id;
if (n.getUnsignedInt (id)) if (n.getUnsignedInt (id) &&
n.depleted ())
{ {
if (n.skip ('-')) ranges.push_back (std::pair <int, int> (id, id));
{
int end;
if (!n.getUnsignedInt (end))
throw std::string (STRING_A3_ID_AFTER_HYPHEN);
if (id > end)
throw std::string (STRING_A3_RANGE_INVERTED);
ranges.push_back (std::pair <int, int> (id, end));
} }
else else
ranges.push_back (std::pair <int, int> (id, id));
while (n.skip (','))
{ {
if (n.getUnsignedInt (id)) not_an_id = true;
break;
}
}
else if (terms.size () == 2)
{ {
if (n.skip ('-')) Nibbler n_min (terms[0]);
Nibbler n_max (terms[1]);
int id_min;
int id_max;
if (n_min.getUnsignedInt (id_min) &&
n_min.depleted () &&
n_max.getUnsignedInt (id_max) &&
n_max.depleted ())
{ {
int end; if (id_min > id_max)
if (!n.getUnsignedInt (end))
throw std::string (STRING_A3_ID_AFTER_HYPHEN);
if (id > end)
throw std::string (STRING_A3_RANGE_INVERTED); throw std::string (STRING_A3_RANGE_INVERTED);
ranges.push_back (std::pair <int, int> (id, end)); ranges.push_back (std::pair <int, int> (id_min, id_max));
} }
else else
ranges.push_back (std::pair <int, int> (id, id)); {
not_an_id = true;
break;
}
} }
else else
throw std::string (STRING_A3_MALFORMED_ID); throw std::string (STRING_A3_MALFORMED_ID);
} }
if (not_an_id)
continue;
// Now convert the ranges into an infix expression.
(*i)->unTag ("?"); (*i)->unTag ("?");
(*i)->removeAllBranches (); (*i)->removeAllBranches ();
(*i)->tag ("ID"); (*i)->tag ("ID");
@@ -1231,7 +1242,6 @@ void Parser::findIdSequence ()
branch->attribute ("raw", ")"); branch->attribute ("raw", ")");
branch->tag ("OP"); branch->tag ("OP");
} }
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////