diff --git a/src/CLI.cpp b/src/CLI.cpp index f0f53d34a..235930e66 100644 --- a/src/CLI.cpp +++ b/src/CLI.cpp @@ -305,13 +305,14 @@ void CLI::analyze () findOverrides (); categorize (); - // Remove all the syntactic sugar for FILTERs.. + // Remove all the syntactic sugar for FILTERs. desugarTags (); desugarAttributes (); desugarAttributeModifiers (); desugarPatterns (); desugarIDs (); desugarUUIDs (); + insertJunctions (); // Decompose the elements for MODIFICATIONs. decomposeModAttributes (); @@ -1190,6 +1191,71 @@ void CLI::desugarUUIDs () _args = reconstructed; } +//////////////////////////////////////////////////////////////////////////////// +// Two consecutive FILTER, ID or UUID arguments: +// +// ID ID --> ID or ID +// ID UUID --> ID or UUID +// UUID ID --> UUID or ID +// UUID UUID --> UUID or UUID +// +// Two consecutive FILTER, non-OP arguments that are not "(" or ")" need an +// "and" operator inserted between them. +// +// ) --> ) and +// ( --> ( +// ) ( --> ) and ( +// --> and +// +void CLI::insertJunctions () +{ + std::vector reconstructed; + std::vector ::iterator prev = _args.begin (); + std::vector ::iterator a; + for (a = _args.begin (); a != _args.end (); ++a) + { + if (a->hasTag ("FILTER")) + { + // The prev iterator should be the first FILTER arg. + if (prev == _args.begin ()) + prev = a; + + // Insert OR between consecutive FILTER ID/UUID args. + if (a != prev && + (prev->hasTag ("ID") || prev->hasTag ("UUID")) && + (a->hasTag ("ID") || a->hasTag ("UUID"))) + { + A opOr ("argOp", "or"); + opOr.tag ("FILTER"); + opOr.tag ("OP"); + reconstructed.push_back (opOr); + } + + // Insert AND between terms. + else if (a != prev) + { + if ((! prev->hasTag ("OP") && a->attribute ("raw") == "(") || + (! prev->hasTag ("OP") && ! a->hasTag ("OP")) || + (prev->attribute ("raw") == ")" && ! a->hasTag ("OP")) || + (prev->attribute ("raw") == ")" && a->attribute ("raw") == "(")) + { + A opOr ("argOp", "and"); + opOr.tag ("FILTER"); + opOr.tag ("OP"); + reconstructed.push_back (opOr); + } + } + + // Previous FILTER arg. + prev = a; + } + + reconstructed.push_back (*a); + } + + _args = reconstructed; +} + //////////////////////////////////////////////////////////////////////////////// void CLI::decomposeModAttributes () { diff --git a/src/CLI.h b/src/CLI.h index 57b55bbb8..ffcae07eb 100644 --- a/src/CLI.h +++ b/src/CLI.h @@ -86,6 +86,7 @@ private: void desugarPatterns (); void desugarIDs (); void desugarUUIDs (); + void insertJunctions (); void decomposeModAttributes (); void decomposeModAttributeModifiers (); void decomposeModTags ();