From 5daabd2548139efd3f5b76fb49c306063c685b23 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 24 Jul 2011 21:53:03 -0400 Subject: [PATCH] Expression reboot - Implemented A3::extract_pattern. - Implemented A3::infix, which inserts 'and' operators where necessary in expressions. - Began implementation of A3::expand which converts old-style filters (pri:H) to the new algebraic style (priority = H). --- src/A3.cpp | 113 +++++++++++++++++++++++++++++++++++++++++------------ src/A3.h | 4 +- 2 files changed, 92 insertions(+), 25 deletions(-) diff --git a/src/A3.cpp b/src/A3.cpp index 5327e824a..1548c3bbe 100644 --- a/src/A3.cpp +++ b/src/A3.cpp @@ -555,8 +555,7 @@ const A3 A3::extract_filter () const filter.push_back (*arg); } - filter = tokenize (filter); - return filter; + return expand (infix (tokenize (filter))); } //////////////////////////////////////////////////////////////////////////////// @@ -745,6 +744,75 @@ const A3 A3::tokenize (const A3& input) const return output; } +//////////////////////////////////////////////////////////////////////////////// +// Insert 'and' operators between adjacent non-operators. +// +// ) --> ) and +// ( --> ( +// ) ( --> ) and ( +// --> and +// +const A3 A3::infix (const A3& input) const +{ + Arg previous ("?", "op"); + + A3 modified; + std::vector ::const_iterator arg; + for (arg = input.begin (); arg != input.end (); ++arg) + { + // Old-style filters need 'and' conjunctions. + if ((previous._category != "op" || previous._raw == ")") && + (arg->_category != "op" || arg->_raw == "(")) + { + modified.push_back (Arg ("and", "op")); + } + + // Now insert the adjacent non-operator. + modified.push_back (*arg); + previous = *arg; + } + + return modified; +} + +//////////////////////////////////////////////////////////////////////////////// +const A3 A3::expand (const A3& input) const +{ + A3 expanded; + std::vector ::const_iterator arg; + for (arg = input.begin (); arg != input.end (); ++arg) + { +/* + if (arg->_category == "attr") + { + } + else if (arg->_category == "attmod") + { + } + else if (arg->_category == "tag") + { + } + else if (arg->_category == "word") + { + } + else +*/ + if (arg->_category == "pattern") + { + std::string value; + A3::extract_pattern (arg->_raw, value); + + expanded.push_back (Arg ("description", "dom")); + expanded.push_back (Arg ("~", "op")); + expanded.push_back (Arg (value, "rx")); + } + else + expanded.push_back (*arg); + } + + return expanded; +} + //////////////////////////////////////////////////////////////////////////////// // :['"][]['"] bool A3::is_attr (Nibbler& n, std::string& result) @@ -1130,6 +1198,25 @@ bool A3::is_tag (Nibbler& n, std::string& result) return false; } +//////////////////////////////////////////////////////////////////////////////// +bool A3::extract_pattern (const std::string& input, std::string& pattern) +{ + Nibbler n (input); + if (n.skip ('/') && + n.getUntil ('/', pattern) && + n.skip ('/')) + { + if (!n.depleted ()) + throw std::string ("Unrecognized character(s) at end of pattern."); + + return true; + } + else + throw std::string ("Malformed pattern."); + + return false; +} + @@ -1300,28 +1387,6 @@ bool A3::extract_subst ( return false; } -//////////////////////////////////////////////////////////////////////////////// -bool A3::extract_pattern (const std::string& input, std::string& pattern) -{ - Nibbler n (input); - if (n.skip ('/') && - n.getUntil ('/', pattern) && - n.skip ('/')) - { - if (pattern == "") - throw std::string ("Cannot search for an empty pattern."); - - if (!n.depleted ()) - throw std::string ("Unrecognized character(s) at end of pattern."); - - return true; - } - else - throw std::string ("Malformed pattern."); - - return false; -} - //////////////////////////////////////////////////////////////////////////////// // A sequence can be: // diff --git a/src/A3.h b/src/A3.h index 646c3dd7a..976b5fe51 100644 --- a/src/A3.h +++ b/src/A3.h @@ -104,6 +104,8 @@ public: const std::vector extract_words () const; const A3 tokenize (const A3&) const; + const A3 infix (const A3&) const; + const A3 expand (const A3&) const; static bool is_attr (Nibbler&, std::string&); static bool is_attmod (Nibbler&, std::string&); @@ -117,6 +119,7 @@ public: static bool is_uuid (Nibbler&, std::string&); static bool is_tag (Nibbler&, std::string&); + static bool extract_pattern (const std::string&, std::string&); /* static bool is_operator (const std::string&, char&, int&, char&); static bool is_symbol_operator (const std::string&); @@ -124,7 +127,6 @@ public: static bool extract_attr (const std::string&, std::string&, std::string&); static bool extract_attmod (const std::string&, std::string&, std::string&, std::string&, std::string&); static bool extract_subst (const std::string&, std::string&, std::string&, bool&); - static bool extract_pattern (const std::string&, std::string&); static bool extract_id (const std::string&, std::vector &); static bool extract_uuid (const std::string&, std::vector &); static bool extract_tag (const std::string&, char&, std::string&);