diff --git a/Code/GraphMol/QueryOps.cpp b/Code/GraphMol/QueryOps.cpp index 402a8715f..1f093329f 100644 --- a/Code/GraphMol/QueryOps.cpp +++ b/Code/GraphMol/QueryOps.cpp @@ -95,70 +95,27 @@ ATOM_EQUALS_QUERY *makeAtomRingBondCountQuery(int what) { }; ATOM_EQUALS_QUERY *makeAtomInRingOfSizeQuery(int tgt) { - RANGE_CHECK(3, tgt, 20); auto *res = new ATOM_EQUALS_QUERY; res->setVal(tgt); - switch (tgt) { - case 3: - res->setDataFunc(queryAtomIsInRingOfSize<3>); - break; - case 4: - res->setDataFunc(queryAtomIsInRingOfSize<4>); - break; - case 5: - res->setDataFunc(queryAtomIsInRingOfSize<5>); - break; - case 6: - res->setDataFunc(queryAtomIsInRingOfSize<6>); - break; - case 7: - res->setDataFunc(queryAtomIsInRingOfSize<7>); - break; - case 8: - res->setDataFunc(queryAtomIsInRingOfSize<8>); - break; - case 9: - res->setDataFunc(queryAtomIsInRingOfSize<9>); - break; - case 10: - res->setDataFunc(queryAtomIsInRingOfSize<10>); - break; - case 11: - res->setDataFunc(queryAtomIsInRingOfSize<11>); - break; - case 12: - res->setDataFunc(queryAtomIsInRingOfSize<12>); - break; - case 13: - res->setDataFunc(queryAtomIsInRingOfSize<13>); - break; - case 14: - res->setDataFunc(queryAtomIsInRingOfSize<14>); - break; - case 15: - res->setDataFunc(queryAtomIsInRingOfSize<15>); - break; - case 16: - res->setDataFunc(queryAtomIsInRingOfSize<16>); - break; - case 17: - res->setDataFunc(queryAtomIsInRingOfSize<17>); - break; - case 18: - res->setDataFunc(queryAtomIsInRingOfSize<18>); - break; - case 19: - res->setDataFunc(queryAtomIsInRingOfSize<19>); - break; - case 20: - res->setDataFunc(queryAtomIsInRingOfSize<20>); - break; - } - + res->setDataFunc( + [tgt](Atom const *at) { return queryAtomIsInRingOfSize(at, tgt); }); res->setDescription("AtomRingSize"); return res; } +ATOM_RANGE_QUERY *makeAtomInRingOfSizeQuery(int lower, int upper, + bool lowerOpen, bool upperOpen) { + auto *res = new ATOM_RANGE_QUERY; + res->setLower(lower); + res->setUpper(upper); + res->setEndsOpen(lowerOpen, upperOpen); + res->setDataFunc([lower, upper, lowerOpen, upperOpen](Atom const *at) { + return queryAtomIsInRingOfSize(at, lower, upper, lowerOpen, upperOpen); + }); + res->setDescription("range_AtomRingSize"); + return res; +} + BOND_EQUALS_QUERY *makeBondInRingOfSizeQuery(int tgt) { RANGE_CHECK(3, tgt, 20); auto *res = new BOND_EQUALS_QUERY; @@ -1046,28 +1003,70 @@ Atom *replaceAtomWithQueryAtom(RWMol *mol, Atom *atom) { return mol->getAtomWithIdx(idx); } +enum class RangeQueryType : char { + EQUAL, + LESS, + GREATER, + RANGE +}; +void finalizeAtomRingSizeQuery(Queries::Query *query, + RangeQueryType qtype) { + switch (qtype) { + case RangeQueryType::EQUAL: { + auto tgt = static_cast(query)->getVal(); + query->setDataFunc( + [tgt](Atom const *at) { return queryAtomIsInRingOfSize(at, tgt); }); + } break; + case RangeQueryType::RANGE: { + auto rq = static_cast(query); + auto uv = rq->getUpper(); + auto lv = rq->getLower(); + auto [lo, uo] = rq->getEndsOpen(); + query->setDataFunc([lv, uv, lo, uo](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv, lo, uo); + }); + } break; + case RangeQueryType::LESS: { + auto lv = static_cast(query)->getVal(); + auto uv = -1; + query->setDataFunc([lv, uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + }); + } break; + case RangeQueryType::GREATER: { + auto lv = -1; + auto uv = static_cast(query)->getVal(); + query->setDataFunc([lv, uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + }); + } break; + default: + throw ValueErrorException("bad range query type"); + } +} + void finalizeQueryFromDescription( Queries::Query *query, Atom const *) { std::string descr = query->getDescription(); + RangeQueryType qtype = RangeQueryType::EQUAL; if (boost::starts_with(descr, "range_")) { descr = descr.substr(6); + qtype = RangeQueryType::RANGE; } else if (boost::starts_with(descr, "less_")) { descr = descr.substr(5); + qtype = RangeQueryType::LESS; } else if (boost::starts_with(descr, "greater_")) { descr = descr.substr(8); + qtype = RangeQueryType::GREATER; } - Queries::Query *tmpQuery; if (descr == "AtomRingBondCount") { query->setDataFunc(queryAtomRingBondCount); } else if (descr == "AtomHasRingBond") { query->setDataFunc(queryAtomHasRingBond); } else if (descr == "AtomRingSize") { - tmpQuery = makeAtomInRingOfSizeQuery( - static_cast(query)->getVal()); - query->setDataFunc(tmpQuery->getDataFunc()); - delete tmpQuery; + finalizeAtomRingSizeQuery(query, qtype); } else if (descr == "AtomMinRingSize") { query->setDataFunc(queryAtomMinRingSize); } else if (descr == "AtomImplicitValence") { diff --git a/Code/GraphMol/QueryOps.h b/Code/GraphMol/QueryOps.h index 720a306b0..01a43ba8a 100644 --- a/Code/GraphMol/QueryOps.h +++ b/Code/GraphMol/QueryOps.h @@ -24,6 +24,9 @@ #include #include +#include +#include + #ifdef RDK_BUILD_THREADSAFE_SSS #include #include @@ -322,6 +325,38 @@ static inline int queryAtomRingBondCount(Atom const *at) { return res; } +static inline int queryAtomIsInRingOfSize(Atom const *at, int tgt) { + if (at->getOwningMol().getRingInfo()->isAtomInRingOfSize(at->getIdx(), tgt)) { + return tgt; + } else { + return 0; + } +}; +//! returns the size of an SSSR ring the atom is in that's within the specified +//! range, or a value outside the range if there are no rings with a size in the +//! range. passing -1 for a bound leaves the range without a limit in that +//! direction +//! always returns a value outside the range for atoms that are not in a ring +static inline int queryAtomIsInRingOfSize(Atom const *at, int lower, int upper, + bool lowerOpen = false, + bool upperOpen = false) { + const auto ri = at->getOwningMol().getRingInfo(); + for (const auto ringSize : ri->atomRingSizes(at->getIdx())) { + if ((ringSize > lower || (ringSize == lower && !lowerOpen)) && + (upper < 0 || + (ringSize < upper || (ringSize == upper && !upperOpen)))) { + return ringSize; + } + } + // we didn't find it, return a result that's not in the acceptable range: + if (lower > -1) { + return -1; + } else if (upper > -1) { + return std::numeric_limits::max(); + } else { + return 0; + } +}; template int queryAtomIsInRingOfSize(Atom const *at) { if (at->getOwningMol().getRingInfo()->isAtomInRingOfSize(at->getIdx(), tgt)) { @@ -562,7 +597,13 @@ T *makeAtomInNRingsQuery(int what, const std::string &descr) { RDKIT_GRAPHMOL_EXPORT ATOM_EQUALS_QUERY *makeAtomInNRingsQuery(int what); //! returns a Query for matching atoms in rings of a particular size +template +T *makeAtomInRingOfSizeQuery(int tgt, const std::string &descr); +//! \overload RDKIT_GRAPHMOL_EXPORT ATOM_EQUALS_QUERY *makeAtomInRingOfSizeQuery(int tgt); +//! \overload +RDKIT_GRAPHMOL_EXPORT ATOM_RANGE_QUERY *makeAtomInRingOfSizeQuery( + int lower, int upper, bool lowerOpen = false, bool upperOpen = false); //! returns a Query for matching an atom's minimum ring size template diff --git a/Code/GraphMol/SmilesParse/SmartsWrite.cpp b/Code/GraphMol/SmilesParse/SmartsWrite.cpp index 3d95f0d08..e5d3da675 100644 --- a/Code/GraphMol/SmilesParse/SmartsWrite.cpp +++ b/Code/GraphMol/SmilesParse/SmartsWrite.cpp @@ -180,6 +180,10 @@ std::string getAtomSmartsSimple(const QueryAtom *qatom, res << "r"; hasVal = true; needParen = true; + } else if (descrip == "AtomRingSize") { + res << "k"; + hasVal = true; + needParen = true; } else if (descrip == "AtomInNRings") { res << "R"; if (mods == Modifiers::NONE && equery && equery->getVal() >= 0) { diff --git a/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake b/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake index cc72c9c7f..ee5cc31cc 100644 --- a/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake +++ b/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake @@ -558,8 +558,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 183 -#define YY_END_OF_BUFFER 184 +#define YY_NUM_RULES 184 +#define YY_END_OF_BUFFER 185 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -567,32 +567,33 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[221] = +static const flex_int16_t yy_accept[222] = { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 184, 182, - 181, 171, 148, 151, 168, 173, 159, 143, 157, 174, - 156, 167, 153, 169, 170, 146, 172, 182, 149, 6, - 145, 123, 124, 127, 122, 132, 125, 126, 128, 129, - 164, 152, 166, 182, 147, 144, 133, 134, 135, 136, - 137, 138, 162, 163, 150, 151, 145, 123, 124, 112, - 182, 127, 182, 122, 132, 16, 182, 182, 125, 126, - 128, 120, 129, 182, 87, 20, 69, 114, 35, 118, - 165, 144, 113, 119, 121, 138, 182, 116, 115, 117, - 160, 161, 154, 155, 0, 0, 0, 0, 0, 131, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 183, + 182, 172, 149, 152, 169, 174, 160, 144, 158, 175, + 157, 168, 154, 170, 171, 147, 173, 183, 150, 6, + 146, 124, 125, 128, 123, 133, 126, 127, 129, 130, + 165, 153, 167, 183, 148, 145, 134, 135, 136, 137, + 138, 139, 163, 164, 151, 152, 146, 124, 125, 112, + 183, 128, 183, 123, 133, 16, 183, 183, 126, 127, + 129, 120, 130, 183, 87, 20, 69, 114, 35, 118, + 166, 145, 113, 119, 122, 121, 139, 183, 116, 115, + 117, 161, 162, 155, 156, 0, 0, 0, 0, 0, - 130, 152, 175, 176, 177, 178, 179, 180, 158, 84, - 43, 13, 90, 15, 30, 80, 74, 51, 9, 102, - 78, 92, 17, 44, 53, 93, 91, 107, 23, 21, - 50, 26, 100, 105, 61, 63, 94, 58, 24, 109, - 95, 82, 28, 59, 29, 7, 67, 75, 62, 103, - 45, 72, 32, 52, 8, 98, 66, 111, 96, 12, - 22, 38, 104, 11, 37, 55, 10, 25, 97, 88, - 71, 86, 77, 42, 56, 79, 54, 73, 89, 83, - 33, 70, 99, 106, 41, 81, 40, 47, 18, 31, - 101, 14, 57, 46, 34, 68, 60, 39, 48, 85, + 132, 131, 153, 176, 177, 178, 179, 180, 181, 159, + 84, 43, 13, 90, 15, 30, 80, 74, 51, 9, + 102, 78, 92, 17, 44, 53, 93, 91, 107, 23, + 21, 50, 26, 100, 105, 61, 63, 94, 58, 24, + 109, 95, 82, 28, 59, 29, 7, 67, 75, 62, + 103, 45, 72, 32, 52, 8, 98, 66, 111, 96, + 12, 22, 38, 104, 11, 37, 55, 10, 25, 97, + 88, 71, 86, 77, 42, 56, 79, 54, 73, 89, + 83, 33, 70, 99, 106, 41, 81, 40, 47, 18, + 31, 101, 14, 57, 46, 34, 68, 60, 39, 48, - 19, 76, 64, 0, 49, 65, 27, 36, 140, 141, - 139, 142, 2, 5, 3, 4, 1, 110, 108, 0 + 85, 19, 76, 64, 0, 49, 65, 27, 36, 141, + 142, 140, 143, 2, 5, 3, 4, 1, 110, 108, + 0 } ; static const YY_CHAR yy_ec[256] = @@ -640,18 +641,18 @@ static const YY_CHAR yy_meta[85] = 1, 1, 1, 1 } ; -static const flex_int16_t yy_base[221] = +static const flex_int16_t yy_base[222] = { 0, - 0, 0, 79, 0, 217, 215, 213, 211, 220, 278, + 0, 0, 79, 0, 222, 217, 215, 213, 221, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 189, 278, 278, 278, 278, 278, 278, 202, 278, 103, - 278, 141, 141, 278, 278, 278, 278, 278, 278, 278, - 278, 149, 278, 69, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 192, 98, 33, 107, 76, - 20, 74, 102, 122, 31, 126, 121, 131, 146, 116, - 152, 171, 180, 196, 113, 278, 278, 120, 102, 68, - 278, 77, 278, 278, 278, 41, 84, 278, 278, 278, - 278, 278, 278, 278, 230, 63, 61, 49, 103, 278, + 192, 278, 278, 278, 278, 278, 278, 203, 278, 103, + 278, 142, 146, 278, 278, 278, 278, 278, 278, 278, + 278, 155, 278, 69, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 195, 98, 33, 107, 76, + 20, 74, 102, 122, 31, 127, 121, 131, 146, 125, + 152, 171, 180, 196, 114, 278, 278, 127, 123, 68, + 278, 87, 278, 278, 278, 278, 41, 89, 278, 278, + 278, 278, 278, 278, 278, 230, 63, 61, 49, 103, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, @@ -664,36 +665,38 @@ static const flex_int16_t yy_base[221] = 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 116, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278 + 278, 278, 278, 278, 116, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278 } ; -static const flex_int16_t yy_def[221] = +static const flex_int16_t yy_def[222] = { 0, - 220, 1, 1, 3, 1, 1, 1, 1, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, + 221, 1, 1, 3, 1, 1, 1, 1, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 0 + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 0 } ; static const flex_int16_t yy_nxt[363] = @@ -706,38 +709,38 @@ static const flex_int16_t yy_nxt[363] = 10, 10, 10, 41, 42, 43, 44, 45, 46, 47, 48, 10, 10, 10, 10, 10, 10, 10, 10, 10, 49, 50, 51, 10, 52, 10, 10, 10, 10, 10, - 10, 53, 54, 55, 56, 103, 104, 105, 106, 107, - 108, 118, 215, 136, 137, 119, 138, 214, 120, 121, + 10, 53, 54, 55, 56, 104, 105, 106, 107, 108, + 109, 119, 216, 137, 138, 120, 139, 215, 121, 122, - 122, 151, 213, 210, 152, 95, 100, 211, 57, 58, + 123, 152, 214, 211, 153, 96, 101, 212, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 96, 216, 81, 133, 139, 82, 207, 217, - 83, 208, 140, 141, 84, 97, 212, 142, 98, 99, - 134, 209, 85, 86, 87, 135, 88, 89, 110, 90, - 143, 206, 111, 144, 145, 123, 112, 113, 124, 125, - 126, 114, 115, 116, 117, 101, 127, 128, 129, 154, - 130, 131, 205, 132, 146, 147, 148, 155, 218, 204, - 171, 219, 159, 149, 156, 160, 150, 157, 158, 153, + 79, 80, 97, 217, 81, 134, 140, 82, 208, 218, + 83, 209, 141, 142, 84, 98, 85, 143, 99, 100, + 135, 213, 86, 87, 88, 136, 89, 90, 111, 91, + 144, 210, 112, 145, 146, 124, 113, 114, 125, 126, + 127, 115, 116, 117, 118, 102, 128, 129, 130, 155, + 131, 132, 207, 133, 147, 148, 149, 156, 219, 206, + 205, 220, 160, 150, 157, 161, 151, 158, 159, 172, - 109, 161, 162, 102, 164, 165, 163, 166, 167, 101, - 172, 173, 168, 174, 100, 94, 93, 169, 170, 220, - 92, 175, 92, 176, 91, 177, 91, 178, 179, 180, - 181, 220, 95, 182, 183, 184, 185, 220, 220, 188, - 189, 186, 190, 220, 191, 220, 192, 187, 220, 193, - 194, 220, 220, 195, 196, 197, 198, 220, 199, 96, - 220, 200, 201, 220, 202, 203, 220, 220, 220, 220, - 220, 220, 97, 220, 220, 98, 99, 9, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, + 154, 162, 163, 110, 165, 166, 164, 167, 168, 103, + 173, 174, 169, 175, 102, 101, 95, 170, 171, 94, + 221, 176, 93, 177, 93, 178, 92, 179, 180, 181, + 182, 92, 96, 183, 184, 185, 186, 221, 221, 189, + 190, 187, 191, 221, 192, 221, 193, 188, 221, 194, + 195, 221, 221, 196, 197, 198, 199, 221, 200, 97, + 221, 201, 202, 221, 203, 204, 221, 221, 221, 221, + 221, 221, 98, 221, 221, 99, 100, 9, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220 + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221 } ; static const flex_int16_t yy_chk[363] = @@ -751,37 +754,37 @@ static const flex_int16_t yy_chk[363] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 44, 44, 44, 44, 44, - 44, 58, 98, 61, 61, 58, 61, 97, 58, 58, + 44, 58, 99, 61, 61, 58, 61, 98, 58, 58, - 58, 65, 96, 86, 65, 30, 58, 86, 3, 3, + 58, 65, 97, 87, 65, 30, 58, 87, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 30, 99, 3, 60, 62, 3, 80, 99, - 3, 80, 62, 62, 3, 30, 87, 62, 30, 30, - 60, 82, 3, 3, 3, 60, 3, 3, 57, 3, - 63, 79, 57, 63, 63, 59, 57, 57, 59, 59, + 3, 3, 30, 100, 3, 60, 62, 3, 80, 100, + 3, 80, 62, 62, 3, 30, 3, 62, 30, 30, + 60, 88, 3, 3, 3, 60, 3, 3, 57, 3, + 63, 82, 57, 63, 63, 59, 57, 57, 59, 59, 59, 57, 57, 57, 57, 59, 59, 59, 59, 67, - 59, 59, 78, 59, 64, 64, 64, 67, 204, 75, - 70, 204, 68, 64, 67, 68, 64, 67, 67, 66, + 59, 59, 79, 59, 64, 64, 64, 67, 205, 78, + 75, 205, 68, 64, 67, 68, 64, 67, 67, 70, - 56, 68, 68, 42, 69, 69, 68, 69, 69, 33, - 71, 71, 69, 71, 32, 28, 21, 69, 69, 9, - 8, 71, 7, 71, 6, 71, 5, 71, 71, 72, - 72, 0, 95, 72, 72, 72, 72, 0, 0, 73, + 66, 68, 68, 56, 69, 69, 68, 69, 69, 42, + 71, 71, 69, 71, 33, 32, 28, 69, 69, 21, + 9, 71, 8, 71, 7, 71, 6, 71, 71, 72, + 72, 5, 96, 72, 72, 72, 72, 0, 0, 73, 73, 72, 73, 0, 73, 0, 73, 72, 0, 73, - 73, 0, 0, 73, 74, 74, 74, 0, 74, 95, + 73, 0, 0, 73, 74, 74, 74, 0, 74, 96, 0, 74, 74, 0, 74, 74, 0, 0, 0, 0, - 0, 0, 95, 0, 0, 95, 95, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, + 0, 0, 96, 0, 0, 96, 96, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220 + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221 } ; /* The intent behind this definition is that it'll catch @@ -837,16 +840,17 @@ size_t setup_smarts_string(const std::string &text,yyscan_t yyscanner){ /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yysmarts_alloc(n ,yyscanner ); - if ( ! buf ) + if ( ! buf ) { smarts_lexer_error( "out of dynamic memory in yysmarts__scan_bytes()" ); + } // ltrim for(start = 0 ; start < _yybytes_len; ++start) { - if (yybytes[start] > 32) break; + if (yybytes[start] > 32) { break; } } for(end = _yybytes_len ; end > start; --end) { - if (yybytes[end] > 32) break; + if (yybytes[end] > 32) { break; } } _yybytes_len = end-start+1; @@ -856,8 +860,9 @@ size_t setup_smarts_string(const std::string &text,yyscan_t yyscanner){ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yysmarts__scan_buffer(buf,n ,yyscanner); - if ( ! b ) + if ( ! b ) { smarts_lexer_error( "bad buffer in yysmarts__scan_bytes()" ); + } /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. @@ -1183,13 +1188,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 221 ) + if ( yy_current_state >= 222 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_current_state != 220 ); + while ( yy_current_state != 221 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1420,102 +1425,110 @@ YY_RULE_SETUP { yylval->atom = new QueryAtom(); yylval->atom->setQuery(makeAtomInRingQuery()); - return RINGSIZE_ATOM_QUERY_TOKEN; + return MIN_RINGSIZE_ATOM_QUERY_TOKEN; } YY_BREAK case 122: YY_RULE_SETUP -{ return H_TOKEN; } +{ + yylval->atom = new QueryAtom(); + yylval->atom->setQuery(makeAtomInRingQuery()); + return RINGSIZE_ATOM_QUERY_TOKEN; +} YY_BREAK case 123: YY_RULE_SETUP -{ yylval->ival = 5; return ORGANIC_ATOM_TOKEN; } +{ return H_TOKEN; } YY_BREAK case 124: YY_RULE_SETUP -{ yylval->ival = 6; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 5; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 125: YY_RULE_SETUP -{ yylval->ival = 7; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 6; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 126: YY_RULE_SETUP -{ yylval->ival = 8; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 7; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 127: YY_RULE_SETUP -{ yylval->ival = 9; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 8; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 128: YY_RULE_SETUP -{ yylval->ival = 15; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 9; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 129: YY_RULE_SETUP -{ yylval->ival = 16; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 15; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 130: YY_RULE_SETUP -{ yylval->ival = 17; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 16; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 131: YY_RULE_SETUP -{ yylval->ival = 35; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 17; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 132: YY_RULE_SETUP -{ yylval->ival = 53; return ORGANIC_ATOM_TOKEN; } +{ yylval->ival = 35; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 133: YY_RULE_SETUP -{ yylval->ival = 5; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 53; return ORGANIC_ATOM_TOKEN; } YY_BREAK case 134: YY_RULE_SETUP -{ yylval->ival = 6; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 5; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 135: YY_RULE_SETUP -{ yylval->ival = 7; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 6; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 136: YY_RULE_SETUP -{ yylval->ival = 8; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 7; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 137: YY_RULE_SETUP -{ yylval->ival = 15; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 8; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 138: YY_RULE_SETUP -{ yylval->ival = 16; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 15; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 139: YY_RULE_SETUP -{ yylval->ival = 14; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 16; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 140: YY_RULE_SETUP -{ yylval->ival = 33; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 14; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 141: YY_RULE_SETUP -{ yylval->ival = 34; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 33; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 142: YY_RULE_SETUP -{ yylval->ival = 52; return AROMATIC_ATOM_TOKEN; } +{ yylval->ival = 34; return AROMATIC_ATOM_TOKEN; } YY_BREAK case 143: YY_RULE_SETUP +{ yylval->ival = 52; return AROMATIC_ATOM_TOKEN; } + YY_BREAK +case 144: +YY_RULE_SETUP { yylval->atom = new QueryAtom(); yylval->atom->setQuery(makeAtomNullQuery()); return SIMPLE_ATOM_QUERY_TOKEN; } YY_BREAK -case 144: +case 145: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1524,7 +1537,7 @@ YY_RULE_SETUP return SIMPLE_ATOM_QUERY_TOKEN; } YY_BREAK -case 145: +case 146: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1532,105 +1545,105 @@ YY_RULE_SETUP return SIMPLE_ATOM_QUERY_TOKEN; } YY_BREAK -case 146: +case 147: YY_RULE_SETUP { return COLON_TOKEN; } YY_BREAK -case 147: +case 148: YY_RULE_SETUP { return UNDERSCORE_TOKEN; } YY_BREAK -case 148: +case 149: YY_RULE_SETUP { return HASH_TOKEN; } YY_BREAK -case 149: +case 150: YY_RULE_SETUP { yylval->bond = new QueryBond(Bond::DOUBLE); yylval->bond->setQuery(makeBondOrderEqualsQuery(Bond::DOUBLE)); return BOND_TOKEN; } YY_BREAK -case 150: +case 151: YY_RULE_SETUP { yylval->bond = new QueryBond(); yylval->bond->setQuery(makeBondNullQuery()); return BOND_TOKEN; } YY_BREAK -case 151: +case 152: YY_RULE_SETUP { yylval->bond = new QueryBond(Bond::QUADRUPLE); yylval->bond->setQuery(makeBondOrderEqualsQuery(Bond::QUADRUPLE)); return BOND_TOKEN; } YY_BREAK -case 152: +case 153: YY_RULE_SETUP { yylval->bond = new QueryBond(Bond::SINGLE); yylval->bond->setBondDir(Bond::ENDDOWNRIGHT); yylval->bond->setQuery(makeSingleOrAromaticBondQuery()); return BOND_TOKEN; } YY_BREAK -case 153: +case 154: YY_RULE_SETUP { yylval->bond = new QueryBond(Bond::SINGLE); yylval->bond->setBondDir(Bond::ENDUPRIGHT); yylval->bond->setQuery(makeSingleOrAromaticBondQuery()); return BOND_TOKEN; } YY_BREAK -case 154: +case 155: YY_RULE_SETUP { yylval->bond = new QueryBond(Bond::DATIVER); return BOND_TOKEN; } YY_BREAK -case 155: +case 156: YY_RULE_SETUP { yylval->bond = new QueryBond(Bond::DATIVEL); return BOND_TOKEN; } YY_BREAK -case 156: +case 157: YY_RULE_SETUP { return MINUS_TOKEN; } YY_BREAK -case 157: +case 158: YY_RULE_SETUP { return PLUS_TOKEN; } YY_BREAK -case 158: +case 159: YY_RULE_SETUP { yy_push_state(IN_RECURSION_STATE,yyscanner); return BEGIN_RECURSE; } YY_BREAK -case 159: +case 160: YY_RULE_SETUP { yy_push_state(IN_BRANCH_STATE,yyscanner); return GROUP_OPEN_TOKEN; } YY_BREAK -case 160: +case 161: YY_RULE_SETUP { yy_pop_state(yyscanner); return GROUP_CLOSE_TOKEN; } YY_BREAK -case 161: +case 162: YY_RULE_SETUP { yy_pop_state(yyscanner); return END_RECURSE; } YY_BREAK -case 162: +case 163: YY_RULE_SETUP { return RANGE_OPEN_TOKEN; } YY_BREAK -case 163: +case 164: YY_RULE_SETUP { return RANGE_CLOSE_TOKEN; } YY_BREAK -case 164: +case 165: YY_RULE_SETUP { yy_push_state(IN_ATOM_STATE,yyscanner); return ATOM_OPEN_TOKEN; } YY_BREAK -case 165: +case 166: YY_RULE_SETUP { yy_pop_state(yyscanner); return ATOM_CLOSE_TOKEN; } YY_BREAK -case 166: +case 167: YY_RULE_SETUP { /* FIX: ??? This rule is here because otherwise recursive SMARTS queries like: @@ -1641,39 +1654,39 @@ YY_RULE_SETUP */ return ATOM_CLOSE_TOKEN; } YY_BREAK -case 167: +case 168: YY_RULE_SETUP { return SEPARATOR_TOKEN; } YY_BREAK -case 168: +case 169: YY_RULE_SETUP { return PERCENT_TOKEN; } YY_BREAK -case 169: +case 170: YY_RULE_SETUP { yylval->ival = 0; return ZERO_TOKEN; } YY_BREAK -case 170: +case 171: YY_RULE_SETUP { yylval->ival = yytext[0]-'0'; return NONZERO_DIGIT_TOKEN; } YY_BREAK -case 171: +case 172: YY_RULE_SETUP { return NOT_TOKEN; } YY_BREAK -case 172: +case 173: YY_RULE_SETUP { return SEMI_TOKEN; } YY_BREAK -case 173: +case 174: YY_RULE_SETUP { return AND_TOKEN; } YY_BREAK -case 174: +case 175: YY_RULE_SETUP { return OR_TOKEN; } YY_BREAK -case 175: +case 176: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1681,7 +1694,7 @@ YY_RULE_SETUP return HYB_TOKEN; } YY_BREAK -case 176: +case 177: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1689,7 +1702,7 @@ YY_RULE_SETUP return HYB_TOKEN; } YY_BREAK -case 177: +case 178: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1697,7 +1710,7 @@ YY_RULE_SETUP return HYB_TOKEN; } YY_BREAK -case 178: +case 179: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1705,7 +1718,7 @@ YY_RULE_SETUP return HYB_TOKEN; } YY_BREAK -case 179: +case 180: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1713,7 +1726,7 @@ YY_RULE_SETUP return HYB_TOKEN; } YY_BREAK -case 180: +case 181: YY_RULE_SETUP { yylval->atom = new QueryAtom(); @@ -1721,8 +1734,8 @@ YY_RULE_SETUP return HYB_TOKEN; } YY_BREAK -case 181: -/* rule 181 can match eol */ +case 182: +/* rule 182 can match eol */ YY_RULE_SETUP return EOS_TOKEN; YY_BREAK @@ -1732,11 +1745,11 @@ case YY_STATE_EOF(IN_BRANCH_STATE): case YY_STATE_EOF(IN_RECURSION_STATE): { return EOS_TOKEN; } YY_BREAK -case 182: +case 183: YY_RULE_SETUP return BAD_CHARACTER; YY_BREAK -case 183: +case 184: YY_RULE_SETUP YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK @@ -2037,7 +2050,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 221 ) + if ( yy_current_state >= 222 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -2066,11 +2079,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 221 ) + if ( yy_current_state >= 222 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 220); + yy_is_jam = (yy_current_state == 221); (void)yyg; return yy_is_jam ? 0 : yy_current_state; diff --git a/Code/GraphMol/SmilesParse/smarts.ll b/Code/GraphMol/SmilesParse/smarts.ll index 10c6d2ed6..1d954172c 100644 --- a/Code/GraphMol/SmilesParse/smarts.ll +++ b/Code/GraphMol/SmilesParse/smarts.ll @@ -277,9 +277,14 @@ size_t setup_smarts_string(const std::string &text,yyscan_t yyscanner){ r { yylval->atom = new QueryAtom(); yylval->atom->setQuery(makeAtomInRingQuery()); - return RINGSIZE_ATOM_QUERY_TOKEN; + return MIN_RINGSIZE_ATOM_QUERY_TOKEN; } +k { + yylval->atom = new QueryAtom(); + yylval->atom->setQuery(makeAtomInRingQuery()); + return RINGSIZE_ATOM_QUERY_TOKEN; +} H { return H_TOKEN; } diff --git a/Code/GraphMol/SmilesParse/smarts.tab.cpp.cmake b/Code/GraphMol/SmilesParse/smarts.tab.cpp.cmake index f3991412a..8c31b6a44 100644 --- a/Code/GraphMol/SmilesParse/smarts.tab.cpp.cmake +++ b/Code/GraphMol/SmilesParse/smarts.tab.cpp.cmake @@ -230,61 +230,62 @@ enum yysymbol_kind_t YYSYMBOL_ATOM_TOKEN = 8, /* ATOM_TOKEN */ YYSYMBOL_SIMPLE_ATOM_QUERY_TOKEN = 9, /* SIMPLE_ATOM_QUERY_TOKEN */ YYSYMBOL_COMPLEX_ATOM_QUERY_TOKEN = 10, /* COMPLEX_ATOM_QUERY_TOKEN */ - YYSYMBOL_RINGSIZE_ATOM_QUERY_TOKEN = 11, /* RINGSIZE_ATOM_QUERY_TOKEN */ - YYSYMBOL_RINGBOND_ATOM_QUERY_TOKEN = 12, /* RINGBOND_ATOM_QUERY_TOKEN */ - YYSYMBOL_IMPLICIT_H_ATOM_QUERY_TOKEN = 13, /* IMPLICIT_H_ATOM_QUERY_TOKEN */ - YYSYMBOL_HYB_TOKEN = 14, /* HYB_TOKEN */ - YYSYMBOL_HETERONEIGHBOR_ATOM_QUERY_TOKEN = 15, /* HETERONEIGHBOR_ATOM_QUERY_TOKEN */ - YYSYMBOL_ALIPHATIC = 16, /* ALIPHATIC */ - YYSYMBOL_ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN = 17, /* ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN */ - YYSYMBOL_ZERO_TOKEN = 18, /* ZERO_TOKEN */ - YYSYMBOL_NONZERO_DIGIT_TOKEN = 19, /* NONZERO_DIGIT_TOKEN */ - YYSYMBOL_GROUP_OPEN_TOKEN = 20, /* GROUP_OPEN_TOKEN */ - YYSYMBOL_GROUP_CLOSE_TOKEN = 21, /* GROUP_CLOSE_TOKEN */ - YYSYMBOL_SEPARATOR_TOKEN = 22, /* SEPARATOR_TOKEN */ - YYSYMBOL_RANGE_OPEN_TOKEN = 23, /* RANGE_OPEN_TOKEN */ - YYSYMBOL_RANGE_CLOSE_TOKEN = 24, /* RANGE_CLOSE_TOKEN */ - YYSYMBOL_HASH_TOKEN = 25, /* HASH_TOKEN */ - YYSYMBOL_MINUS_TOKEN = 26, /* MINUS_TOKEN */ - YYSYMBOL_PLUS_TOKEN = 27, /* PLUS_TOKEN */ - YYSYMBOL_H_TOKEN = 28, /* H_TOKEN */ - YYSYMBOL_AT_TOKEN = 29, /* AT_TOKEN */ - YYSYMBOL_PERCENT_TOKEN = 30, /* PERCENT_TOKEN */ - YYSYMBOL_ATOM_OPEN_TOKEN = 31, /* ATOM_OPEN_TOKEN */ - YYSYMBOL_ATOM_CLOSE_TOKEN = 32, /* ATOM_CLOSE_TOKEN */ - YYSYMBOL_NOT_TOKEN = 33, /* NOT_TOKEN */ - YYSYMBOL_AND_TOKEN = 34, /* AND_TOKEN */ - YYSYMBOL_OR_TOKEN = 35, /* OR_TOKEN */ - YYSYMBOL_SEMI_TOKEN = 36, /* SEMI_TOKEN */ - YYSYMBOL_BEGIN_RECURSE = 37, /* BEGIN_RECURSE */ - YYSYMBOL_END_RECURSE = 38, /* END_RECURSE */ - YYSYMBOL_COLON_TOKEN = 39, /* COLON_TOKEN */ - YYSYMBOL_UNDERSCORE_TOKEN = 40, /* UNDERSCORE_TOKEN */ - YYSYMBOL_BOND_TOKEN = 41, /* BOND_TOKEN */ - YYSYMBOL_CHI_CLASS_TOKEN = 42, /* CHI_CLASS_TOKEN */ - YYSYMBOL_BAD_CHARACTER = 43, /* BAD_CHARACTER */ - YYSYMBOL_EOS_TOKEN = 44, /* EOS_TOKEN */ - YYSYMBOL_YYACCEPT = 45, /* $accept */ - YYSYMBOL_meta_start = 46, /* meta_start */ - YYSYMBOL_bad_atom_def = 47, /* bad_atom_def */ - YYSYMBOL_mol = 48, /* mol */ - YYSYMBOL_atomd = 49, /* atomd */ - YYSYMBOL_hydrogen_atom = 50, /* hydrogen_atom */ - YYSYMBOL_atom_expr = 51, /* atom_expr */ - YYSYMBOL_point_query = 52, /* point_query */ - YYSYMBOL_recursive_query = 53, /* recursive_query */ - YYSYMBOL_atom_query = 54, /* atom_query */ - YYSYMBOL_possible_range_query = 55, /* possible_range_query */ - YYSYMBOL_simple_atom = 56, /* simple_atom */ - YYSYMBOL_bond_expr = 57, /* bond_expr */ - YYSYMBOL_bond_query = 58, /* bond_query */ - YYSYMBOL_bondd = 59, /* bondd */ - YYSYMBOL_charge_spec = 60, /* charge_spec */ - YYSYMBOL_ring_number = 61, /* ring_number */ - YYSYMBOL_number = 62, /* number */ - YYSYMBOL_nonzero_number = 63, /* nonzero_number */ - YYSYMBOL_digit = 64, /* digit */ - YYSYMBOL_branch_open_token = 65 /* branch_open_token */ + YYSYMBOL_MIN_RINGSIZE_ATOM_QUERY_TOKEN = 11, /* MIN_RINGSIZE_ATOM_QUERY_TOKEN */ + YYSYMBOL_RINGSIZE_ATOM_QUERY_TOKEN = 12, /* RINGSIZE_ATOM_QUERY_TOKEN */ + YYSYMBOL_RINGBOND_ATOM_QUERY_TOKEN = 13, /* RINGBOND_ATOM_QUERY_TOKEN */ + YYSYMBOL_IMPLICIT_H_ATOM_QUERY_TOKEN = 14, /* IMPLICIT_H_ATOM_QUERY_TOKEN */ + YYSYMBOL_HYB_TOKEN = 15, /* HYB_TOKEN */ + YYSYMBOL_HETERONEIGHBOR_ATOM_QUERY_TOKEN = 16, /* HETERONEIGHBOR_ATOM_QUERY_TOKEN */ + YYSYMBOL_ALIPHATIC = 17, /* ALIPHATIC */ + YYSYMBOL_ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN = 18, /* ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN */ + YYSYMBOL_ZERO_TOKEN = 19, /* ZERO_TOKEN */ + YYSYMBOL_NONZERO_DIGIT_TOKEN = 20, /* NONZERO_DIGIT_TOKEN */ + YYSYMBOL_GROUP_OPEN_TOKEN = 21, /* GROUP_OPEN_TOKEN */ + YYSYMBOL_GROUP_CLOSE_TOKEN = 22, /* GROUP_CLOSE_TOKEN */ + YYSYMBOL_SEPARATOR_TOKEN = 23, /* SEPARATOR_TOKEN */ + YYSYMBOL_RANGE_OPEN_TOKEN = 24, /* RANGE_OPEN_TOKEN */ + YYSYMBOL_RANGE_CLOSE_TOKEN = 25, /* RANGE_CLOSE_TOKEN */ + YYSYMBOL_HASH_TOKEN = 26, /* HASH_TOKEN */ + YYSYMBOL_MINUS_TOKEN = 27, /* MINUS_TOKEN */ + YYSYMBOL_PLUS_TOKEN = 28, /* PLUS_TOKEN */ + YYSYMBOL_H_TOKEN = 29, /* H_TOKEN */ + YYSYMBOL_AT_TOKEN = 30, /* AT_TOKEN */ + YYSYMBOL_PERCENT_TOKEN = 31, /* PERCENT_TOKEN */ + YYSYMBOL_ATOM_OPEN_TOKEN = 32, /* ATOM_OPEN_TOKEN */ + YYSYMBOL_ATOM_CLOSE_TOKEN = 33, /* ATOM_CLOSE_TOKEN */ + YYSYMBOL_NOT_TOKEN = 34, /* NOT_TOKEN */ + YYSYMBOL_AND_TOKEN = 35, /* AND_TOKEN */ + YYSYMBOL_OR_TOKEN = 36, /* OR_TOKEN */ + YYSYMBOL_SEMI_TOKEN = 37, /* SEMI_TOKEN */ + YYSYMBOL_BEGIN_RECURSE = 38, /* BEGIN_RECURSE */ + YYSYMBOL_END_RECURSE = 39, /* END_RECURSE */ + YYSYMBOL_COLON_TOKEN = 40, /* COLON_TOKEN */ + YYSYMBOL_UNDERSCORE_TOKEN = 41, /* UNDERSCORE_TOKEN */ + YYSYMBOL_BOND_TOKEN = 42, /* BOND_TOKEN */ + YYSYMBOL_CHI_CLASS_TOKEN = 43, /* CHI_CLASS_TOKEN */ + YYSYMBOL_BAD_CHARACTER = 44, /* BAD_CHARACTER */ + YYSYMBOL_EOS_TOKEN = 45, /* EOS_TOKEN */ + YYSYMBOL_YYACCEPT = 46, /* $accept */ + YYSYMBOL_meta_start = 47, /* meta_start */ + YYSYMBOL_bad_atom_def = 48, /* bad_atom_def */ + YYSYMBOL_mol = 49, /* mol */ + YYSYMBOL_atomd = 50, /* atomd */ + YYSYMBOL_hydrogen_atom = 51, /* hydrogen_atom */ + YYSYMBOL_atom_expr = 52, /* atom_expr */ + YYSYMBOL_point_query = 53, /* point_query */ + YYSYMBOL_recursive_query = 54, /* recursive_query */ + YYSYMBOL_atom_query = 55, /* atom_query */ + YYSYMBOL_possible_range_query = 56, /* possible_range_query */ + YYSYMBOL_simple_atom = 57, /* simple_atom */ + YYSYMBOL_bond_expr = 58, /* bond_expr */ + YYSYMBOL_bond_query = 59, /* bond_query */ + YYSYMBOL_bondd = 60, /* bondd */ + YYSYMBOL_charge_spec = 61, /* charge_spec */ + YYSYMBOL_ring_number = 62, /* ring_number */ + YYSYMBOL_number = 63, /* number */ + YYSYMBOL_nonzero_number = 64, /* nonzero_number */ + YYSYMBOL_digit = 65, /* digit */ + YYSYMBOL_branch_open_token = 66 /* branch_open_token */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -610,21 +611,21 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 56 +#define YYFINAL 57 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 598 +#define YYLAST 606 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 45 +#define YYNTOKENS 46 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 21 /* YYNRULES -- Number of rules. */ -#define YYNRULES 123 +#define YYNRULES 128 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 178 +#define YYNSTATES 189 /* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 299 +#define YYMAXUTOK 300 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -667,7 +668,8 @@ static const yytype_int8 yytranslate[] = 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44 + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45 }; #if YYDEBUG @@ -680,13 +682,13 @@ static const yytype_int16 yyrline[] = 425, 429, 434, 440, 449, 456, 465, 474, 488, 495, 503, 510, 515, 520, 523, 529, 530, 534, 551, 575, 576, 581, 582, 587, 588, 593, 594, 595, 596, 597, - 598, 599, 603, 607, 611, 615, 619, 623, 630, 637, - 645, 655, 665, 674, 682, 689, 695, 701, 708, 722, - 723, 730, 731, 735, 739, 743, 747, 751, 756, 764, - 776, 781, 786, 791, 796, 801, 804, 805, 813, 814, - 820, 826, 832, 837, 844, 845, 846, 847, 848, 849, - 853, 854, 855, 856, 857, 858, 859, 864, 865, 869, - 870, 879, 880, 884 + 598, 599, 600, 604, 608, 612, 616, 620, 624, 628, + 635, 642, 651, 660, 669, 679, 689, 699, 708, 716, + 723, 729, 735, 742, 756, 757, 764, 765, 769, 773, + 777, 781, 785, 790, 798, 810, 815, 820, 825, 830, + 835, 838, 839, 847, 848, 854, 860, 866, 871, 878, + 879, 880, 881, 882, 883, 887, 888, 889, 890, 891, + 892, 893, 898, 899, 903, 904, 913, 914, 918 }; #endif @@ -705,8 +707,8 @@ static const char *const yytname[] = "\"end of file\"", "error", "\"invalid token\"", "START_MOL", "START_ATOM", "START_BOND", "AROMATIC_ATOM_TOKEN", "ORGANIC_ATOM_TOKEN", "ATOM_TOKEN", "SIMPLE_ATOM_QUERY_TOKEN", "COMPLEX_ATOM_QUERY_TOKEN", - "RINGSIZE_ATOM_QUERY_TOKEN", "RINGBOND_ATOM_QUERY_TOKEN", - "IMPLICIT_H_ATOM_QUERY_TOKEN", "HYB_TOKEN", + "MIN_RINGSIZE_ATOM_QUERY_TOKEN", "RINGSIZE_ATOM_QUERY_TOKEN", + "RINGBOND_ATOM_QUERY_TOKEN", "IMPLICIT_H_ATOM_QUERY_TOKEN", "HYB_TOKEN", "HETERONEIGHBOR_ATOM_QUERY_TOKEN", "ALIPHATIC", "ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN", "ZERO_TOKEN", "NONZERO_DIGIT_TOKEN", "GROUP_OPEN_TOKEN", "GROUP_CLOSE_TOKEN", @@ -729,12 +731,12 @@ yysymbol_name (yysymbol_kind_t yysymbol) } #endif -#define YYPACT_NINF (-59) +#define YYPACT_NINF (-61) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-89) +#define YYTABLE_NINF (-94) #define yytable_value_is_error(Yyn) \ 0 @@ -743,65 +745,67 @@ yysymbol_name (yysymbol_kind_t yysymbol) STATE-NUM. */ static const yytype_int16 yypact[] = { - 171, -16, 30, 189, 87, 23, -59, -59, -59, -59, - 411, 501, -59, -59, -59, -59, 26, 243, 280, 350, - -59, 386, 423, -59, -59, 39, 122, 41, 39, 5, - 226, 263, 448, 30, 263, 39, -59, -4, 300, -59, - -59, -59, 25, 28, -59, 46, 64, -59, -59, -59, - 87, -59, -59, 7, 87, -59, -59, 31, -59, -59, - 557, 152, -59, 332, -59, -59, -59, -59, 30, 163, - -59, 116, -59, -59, 529, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, 263, -59, - 152, -59, -59, 473, -59, -59, -59, 448, 448, 448, - -59, 70, -59, 39, 39, -59, -59, -59, 87, 87, - 87, -59, -59, -59, 82, 59, -59, 39, -18, -59, - 39, 559, -59, 64, 64, -59, -59, -59, 538, 6, - 448, -59, 374, 337, 39, 43, -59, -59, -59, 45, - 158, 60, -59, 39, 83, -59, 39, -1, -59, 191, - -59, 98, 78, 205, -59, 97, -59, 100, -59, 39, - -59, 228, 64, -59, -59, 118, -59, -59, 121, -59, - 265, -59, -59, -59, 302, -59, 134, -59 + 55, -31, 46, 195, 533, 3, -61, -61, -61, -61, + 423, 516, -61, -61, -61, -61, 250, 288, 360, 397, + 435, -61, 478, 481, -61, -61, 80, 19, 5, 80, + 0, 233, 271, 461, 46, 271, 80, -61, -9, 309, + -61, -61, -61, 21, 40, -61, 64, 92, -61, -61, + -61, 533, -61, -61, 143, 533, -61, -61, 42, -61, + -61, 551, 157, -61, 342, -61, -61, -61, -61, 46, + 137, -61, 545, -61, -61, 35, -61, -61, 126, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, 271, -61, 157, -61, -61, 487, -61, -61, -61, + 461, 461, 461, -61, 162, -61, 80, 80, -61, -61, + -61, 533, 533, 533, -61, -61, -61, 199, 60, -61, + 80, -13, -61, 80, 566, -61, 92, 92, -61, -61, + -61, 96, 80, 23, 33, 461, -61, 385, 347, 80, + 88, -61, -61, -61, 56, 163, 93, -61, 80, 97, + -61, 80, 43, -61, 117, -61, 109, 129, 101, 127, + 211, -61, 122, -61, 141, -61, 80, -61, 235, -61, + -61, 171, 92, -61, -61, 187, -61, -61, 183, -61, + 273, -61, -61, -61, -61, 311, -61, 198, -61 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ -static const yytype_int8 yydefact[] = +static const yytype_uint8 yydefact[] = { - 0, 0, 0, 5, 8, 0, 12, 90, 89, 91, + 0, 0, 0, 5, 8, 0, 12, 95, 94, 96, 0, 2, 17, 27, 26, 51, 55, 58, 59, 60, - 79, 56, 57, 117, 119, 0, 109, 106, 73, 76, - 0, 0, 0, 0, 0, 77, 4, 0, 16, 43, - 45, 46, 0, 49, 74, 80, 118, 100, 99, 102, - 0, 101, 98, 7, 95, 96, 1, 0, 9, 11, - 73, 0, 49, 80, 122, 121, 123, 25, 0, 0, - 18, 0, 21, 110, 0, 61, 64, 65, 66, 62, - 63, 53, 107, 108, 104, 105, 72, 75, 0, 13, - 16, 14, 44, 0, 15, 78, 3, 0, 0, 0, - 41, 0, 52, 0, 70, 50, 120, 103, 0, 0, - 0, 6, 97, 10, 109, 106, 30, 0, 0, 28, - 0, 70, 20, 0, 0, 19, 22, 23, 0, 47, - 38, 42, 39, 40, 0, 0, 54, 71, 92, 93, - 94, 0, 34, 0, 0, 32, 0, 0, 111, 0, - 24, 0, 0, 0, 31, 0, 29, 0, 36, 0, - 112, 0, 48, 67, 68, 0, 35, 33, 0, 113, - 0, 69, 37, 114, 0, 115, 0, 116 + 61, 84, 56, 57, 122, 124, 0, 114, 111, 78, + 81, 0, 0, 0, 0, 0, 82, 4, 0, 16, + 43, 45, 46, 0, 49, 79, 85, 123, 105, 104, + 107, 0, 106, 103, 7, 100, 101, 1, 0, 9, + 11, 78, 0, 49, 85, 127, 126, 128, 25, 0, + 0, 18, 0, 21, 115, 0, 62, 65, 0, 66, + 67, 68, 63, 64, 53, 112, 113, 109, 110, 77, + 80, 0, 13, 16, 14, 44, 0, 15, 83, 3, + 0, 0, 0, 41, 0, 52, 0, 75, 50, 125, + 108, 0, 0, 0, 6, 102, 10, 114, 111, 30, + 0, 0, 28, 0, 75, 20, 0, 0, 19, 22, + 23, 0, 0, 0, 47, 38, 42, 39, 40, 0, + 0, 54, 76, 97, 98, 99, 0, 34, 0, 0, + 32, 0, 0, 116, 0, 24, 0, 0, 0, 0, + 0, 31, 0, 29, 0, 36, 0, 117, 0, 72, + 73, 0, 48, 69, 70, 0, 35, 33, 0, 118, + 0, 74, 71, 37, 119, 0, 120, 0, 121 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -59, -59, -2, 135, 16, -59, 0, 24, -59, -59, - -59, 2, 29, -59, -28, -58, 102, -10, 54, -43, - -59 + -61, -61, 2, 200, 29, -61, 18, 24, -61, -61, + -61, 20, 31, -61, -40, -60, 145, -10, 74, -45, + -61 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - 0, 5, 89, 11, 12, 13, 38, 39, 40, 41, - 42, 62, 71, 54, 55, 44, 72, 45, 46, 73, - 74 + 0, 5, 92, 11, 12, 13, 39, 40, 41, 42, + 43, 63, 72, 55, 56, 45, 73, 46, 47, 74, + 75 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -809,172 +813,175 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 63, 36, 118, 106, 14, 43, 75, 76, 77, 78, - 61, 79, 80, 14, 142, 81, 83, 85, 86, 37, - 63, 143, 107, 56, 57, 95, 112, 70, 6, 91, - 90, 158, 94, 53, 87, 14, 7, 8, 159, 9, - 96, 108, 109, 110, 23, 24, 151, 105, 101, -81, - 86, 111, 7, 8, 102, 9, 92, 23, 24, 23, - 24, 10, 100, 147, -87, 105, 58, 59, 84, 153, - 14, 103, -26, 14, 104, 113, 14, 23, 24, 108, - 148, 149, 64, 65, 122, 100, 84, 125, 23, 24, - 127, 135, 154, 136, 137, 14, 134, 130, 132, 133, - 23, 24, 163, 128, 83, 85, 161, 141, 82, 70, - 144, 137, 47, 48, 100, 156, 49, 24, 170, 106, - 50, 131, 7, 8, 152, 9, 51, 174, 52, 166, - 14, 176, 167, 155, 64, 65, 157, 138, 139, 140, - 23, 24, 171, 165, 150, -88, 69, 10, 82, 168, - 108, 109, 110, 172, 100, 177, 100, 100, 7, 8, - 15, 9, 16, 17, 18, 19, 20, 21, 93, 22, - 23, 24, 1, 126, 2, 3, 4, 25, 26, 27, - 28, 29, 123, 124, 119, 32, 97, 98, 99, 33, - 0, 120, 108, 109, 35, 7, 8, 15, 9, 16, - 17, 18, 19, 20, 21, 162, 22, 23, 24, 64, - 65, 0, 160, 0, 25, 26, 27, 28, 29, 0, - 30, 31, 32, 23, 24, 0, 33, 0, 34, 164, - 0, 35, 7, 8, 15, 9, 16, 17, 18, 19, - 20, 21, 0, 22, 23, 24, 64, 65, 0, 169, - 0, 25, 26, 27, 60, 29, 0, 88, 31, 32, - 0, 23, 24, 33, 0, 34, -84, 0, 35, 7, - 8, 15, 9, 16, 17, 18, 19, 20, 21, 0, - 22, 23, 24, 64, 65, 0, 173, 0, 25, 26, - 27, 28, 29, 0, 88, 31, 32, 0, 23, 24, - 33, 0, 34, -85, 0, 35, 7, 8, 15, 9, - 16, 17, 18, 19, 20, 21, 0, 22, 23, 24, - 64, 65, 0, 175, 0, 25, 26, 27, 28, 29, - 0, 0, 0, 32, 97, 98, 99, 33, 7, 8, - 102, 9, 35, 7, 8, 15, 9, 16, 17, 18, - 19, 20, 21, 0, 22, 23, 24, 103, 0, 0, - 121, 0, 25, 26, 27, 28, 29, 0, 23, 24, - 32, 97, 98, -86, 33, 0, 0, 0, 0, 35, - 7, 8, 15, 9, 16, 17, 18, 19, 20, 21, - 0, 22, 23, 24, 0, 0, 0, 0, 0, 25, - 26, 27, 28, 29, 23, 24, 0, 32, 97, -82, - 0, 33, 0, 0, 0, 0, 35, 7, 8, 15, - 9, 16, 17, 18, 19, 20, 21, 0, 22, 23, - 24, 0, 0, 0, 0, 0, 25, 26, 27, 60, - 29, 23, 24, 0, 32, 0, -83, 0, 33, 0, - 0, 0, 0, 35, 7, 8, 15, 9, 16, 17, - 18, 19, 20, 21, 0, 22, 23, 24, 0, 0, - 0, 0, 0, 25, 26, 27, 28, 29, 0, 7, - 8, 32, 9, 0, 0, 33, 0, 0, 0, 0, - 35, 64, 65, 66, 67, 68, 0, 0, 47, 48, - 0, 0, 49, 69, 10, 0, 50, 7, 8, 0, - 9, 129, 51, 0, 52, 0, 0, 0, 0, 64, - 65, 66, 67, 68, 0, 0, 47, 48, 0, 0, - 49, 69, 10, 0, 50, 7, 8, 0, 9, 0, - 51, 0, 52, 0, 7, 8, 0, 9, 0, 0, - 0, 0, 0, 0, 47, 48, 0, 0, 49, 0, - 10, 0, 50, 0, 0, 0, 0, 0, 51, 10, - 52, 0, 108, 109, 110, 23, 24, 23, 24, 0, - 0, 0, 0, 114, 115, 114, 115, 0, 0, 116, - 0, 145, 0, 0, 0, 0, 117, 0, 146 + 64, 121, 109, 57, 58, 37, 76, 77, 79, 80, + 81, 110, 82, 83, 6, 115, 84, 86, 88, 89, + 147, 64, 14, 44, 24, 25, 98, 148, 62, -92, + 90, 14, 38, 87, 94, 54, 99, 97, 24, 25, + 71, 7, 8, -93, 9, 104, 85, 59, 60, 93, + 157, 89, 7, 8, 14, 9, 1, 95, 2, 3, + 4, 48, 49, 103, 152, 50, 108, 10, 133, 51, + 7, 8, 105, 9, 158, 52, 165, 53, 10, 24, + 25, 153, 154, 166, 108, -26, 103, 116, 87, 14, + 106, 111, 14, 107, 140, 14, 141, 142, 125, 24, + 25, 128, 7, 8, 130, 9, 131, 86, 88, 168, + 146, 65, 66, 149, 142, 160, 14, 103, 135, 137, + 138, 25, 156, 180, 136, 71, 161, 109, 10, 159, + 163, 111, 112, 113, 169, 185, 65, 66, 162, 167, + 187, 164, 143, 144, 145, 24, 25, 171, 24, 25, + 175, 14, 173, 132, 170, 176, 178, 126, 127, 103, + 155, 103, 103, 7, 8, 15, 9, 16, 17, 18, + 19, 20, 21, 22, 177, 23, 24, 25, 111, 112, + 113, 24, 25, 26, 27, 28, 29, 30, 114, 139, + 122, 33, 100, 101, 102, 34, 181, 123, 111, 112, + 36, 7, 8, 15, 9, 16, 17, 18, 19, 20, + 21, 22, 182, 23, 24, 25, 183, 129, 24, 25, + 188, 26, 27, 28, 29, 30, 85, 31, 32, 33, + 24, 25, 172, 34, 96, 35, 174, 0, 36, 7, + 8, 15, 9, 16, 17, 18, 19, 20, 21, 22, + 0, 23, 24, 25, 65, 66, 0, 179, 0, 26, + 27, 28, 61, 30, 0, 91, 32, 33, 0, 24, + 25, 34, 0, 35, -86, 0, 36, 7, 8, 15, + 9, 16, 17, 18, 19, 20, 21, 22, 0, 23, + 24, 25, 65, 66, 0, 184, 0, 26, 27, 28, + 29, 30, 0, 91, 32, 33, 0, 24, 25, 34, + 0, 35, -89, 0, 36, 7, 8, 15, 9, 16, + 17, 18, 19, 20, 21, 22, 0, 23, 24, 25, + 65, 66, 0, 186, 0, 26, 27, 28, 29, 30, + 0, 0, 0, 33, 100, 101, 102, 34, 7, 8, + 105, 9, 36, 7, 8, 15, 9, 16, 17, 18, + 19, 20, 21, 22, 0, 23, 24, 25, 106, 0, + 0, 124, 0, 26, 27, 28, 29, 30, 0, 24, + 25, 33, 100, 101, 78, 34, 0, 0, 0, 0, + 36, 7, 8, 15, 9, 16, 17, 18, 19, 20, + 21, 22, 0, 23, 24, 25, 0, 0, 0, 0, + 0, 26, 27, 28, 29, 30, 24, 25, 0, 33, + 100, -90, 0, 34, 0, 0, 0, 0, 36, 7, + 8, 15, 9, 16, 17, 18, 19, 20, 21, 22, + 0, 23, 24, 25, 0, 0, 0, 0, 0, 26, + 27, 28, 61, 30, 24, 25, 0, 33, 0, -91, + 0, 34, 0, 0, 0, 0, 36, 7, 8, 15, + 9, 16, 17, 18, 19, 20, 21, 22, 0, 23, + 24, 25, 0, 0, 0, 0, 0, 26, 27, 28, + 29, 30, 0, 7, 8, 33, 9, 24, 25, 34, + 24, 25, -87, 0, 36, -88, 65, 66, 67, 68, + 69, 0, 0, 48, 49, 0, 0, 50, 70, 10, + 0, 51, 7, 8, 0, 9, 134, 52, 0, 53, + 0, 0, 0, 0, 0, 65, 66, 67, 68, 69, + 0, 0, 48, 49, 0, 0, 50, 70, 10, 0, + 51, 7, 8, 0, 9, 0, 52, 0, 53, 48, + 49, 0, 0, 50, 65, 66, 0, 51, 0, 0, + 24, 25, 0, 52, 0, 53, 70, 10, 117, 118, + 111, 112, 113, 0, 119, 24, 25, 0, 0, 0, + 0, 120, 0, 117, 118, 0, 0, 0, 0, 150, + 0, 0, 0, 0, 0, 0, 151 }; static const yytype_int16 yycheck[] = { - 10, 3, 60, 46, 2, 3, 16, 17, 18, 19, - 10, 21, 22, 11, 32, 25, 26, 27, 28, 3, - 30, 39, 50, 0, 1, 35, 54, 11, 44, 31, - 30, 32, 34, 4, 29, 33, 6, 7, 39, 9, - 44, 34, 35, 36, 18, 19, 40, 45, 23, 23, - 60, 44, 6, 7, 8, 9, 32, 18, 19, 18, - 19, 31, 38, 121, 23, 63, 43, 44, 27, 26, - 68, 25, 44, 71, 28, 44, 74, 18, 19, 34, - 123, 124, 18, 19, 68, 61, 27, 71, 18, 19, - 74, 101, 32, 103, 104, 93, 26, 97, 98, 99, - 18, 19, 24, 74, 114, 115, 149, 117, 26, 93, - 120, 121, 25, 26, 90, 32, 29, 19, 161, 162, - 33, 97, 6, 7, 134, 9, 39, 170, 41, 32, - 128, 174, 32, 143, 18, 19, 146, 108, 109, 110, - 18, 19, 24, 153, 128, 23, 30, 31, 26, 159, - 34, 35, 36, 32, 130, 21, 132, 133, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 33, 17, - 18, 19, 1, 71, 3, 4, 5, 25, 26, 27, - 28, 29, 19, 20, 32, 33, 34, 35, 36, 37, - -1, 39, 34, 35, 42, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 151, 17, 18, 19, 18, - 19, -1, 21, -1, 25, 26, 27, 28, 29, -1, - 31, 32, 33, 18, 19, -1, 37, -1, 39, 24, - -1, 42, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, -1, 17, 18, 19, 18, 19, -1, 21, - -1, 25, 26, 27, 28, 29, -1, 31, 32, 33, - -1, 18, 19, 37, -1, 39, 23, -1, 42, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, - 17, 18, 19, 18, 19, -1, 21, -1, 25, 26, - 27, 28, 29, -1, 31, 32, 33, -1, 18, 19, - 37, -1, 39, 23, -1, 42, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, -1, 17, 18, 19, - 18, 19, -1, 21, -1, 25, 26, 27, 28, 29, - -1, -1, -1, 33, 34, 35, 36, 37, 6, 7, - 8, 9, 42, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, -1, 17, 18, 19, 25, -1, -1, - 28, -1, 25, 26, 27, 28, 29, -1, 18, 19, - 33, 34, 35, 23, 37, -1, -1, -1, -1, 42, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - -1, 17, 18, 19, -1, -1, -1, -1, -1, 25, - 26, 27, 28, 29, 18, 19, -1, 33, 34, 23, - -1, 37, -1, -1, -1, -1, 42, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, -1, 17, 18, - 19, -1, -1, -1, -1, -1, 25, 26, 27, 28, - 29, 18, 19, -1, 33, -1, 23, -1, 37, -1, - -1, -1, -1, 42, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, -1, 17, 18, 19, -1, -1, - -1, -1, -1, 25, 26, 27, 28, 29, -1, 6, - 7, 33, 9, -1, -1, 37, -1, -1, -1, -1, - 42, 18, 19, 20, 21, 22, -1, -1, 25, 26, - -1, -1, 29, 30, 31, -1, 33, 6, 7, -1, - 9, 38, 39, -1, 41, -1, -1, -1, -1, 18, - 19, 20, 21, 22, -1, -1, 25, 26, -1, -1, - 29, 30, 31, -1, 33, 6, 7, -1, 9, -1, - 39, -1, 41, -1, 6, 7, -1, 9, -1, -1, - -1, -1, -1, -1, 25, 26, -1, -1, 29, -1, - 31, -1, 33, -1, -1, -1, -1, -1, 39, 31, - 41, -1, 34, 35, 36, 18, 19, 18, 19, -1, - -1, -1, -1, 26, 27, 26, 27, -1, -1, 32, - -1, 32, -1, -1, -1, -1, 39, -1, 39 + 10, 61, 47, 0, 1, 3, 16, 17, 18, 19, + 20, 51, 22, 23, 45, 55, 26, 27, 28, 29, + 33, 31, 2, 3, 19, 20, 36, 40, 10, 24, + 30, 11, 3, 28, 32, 4, 45, 35, 19, 20, + 11, 6, 7, 24, 9, 24, 27, 44, 45, 31, + 27, 61, 6, 7, 34, 9, 1, 33, 3, 4, + 5, 26, 27, 39, 124, 30, 46, 32, 78, 34, + 6, 7, 8, 9, 41, 40, 33, 42, 32, 19, + 20, 126, 127, 40, 64, 45, 62, 45, 28, 69, + 26, 35, 72, 29, 104, 75, 106, 107, 69, 19, + 20, 72, 6, 7, 75, 9, 75, 117, 118, 154, + 120, 19, 20, 123, 124, 27, 96, 93, 100, 101, + 102, 20, 132, 168, 100, 96, 33, 172, 32, 139, + 33, 35, 36, 37, 25, 180, 19, 20, 148, 22, + 185, 151, 111, 112, 113, 19, 20, 157, 19, 20, + 160, 131, 25, 27, 25, 33, 166, 20, 21, 135, + 131, 137, 138, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 33, 18, 19, 20, 35, 36, + 37, 19, 20, 26, 27, 28, 29, 30, 45, 27, + 33, 34, 35, 36, 37, 38, 25, 40, 35, 36, + 43, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 25, 18, 19, 20, 33, 72, 19, 20, + 22, 26, 27, 28, 29, 30, 27, 32, 33, 34, + 19, 20, 158, 38, 34, 40, 25, -1, 43, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + -1, 18, 19, 20, 19, 20, -1, 22, -1, 26, + 27, 28, 29, 30, -1, 32, 33, 34, -1, 19, + 20, 38, -1, 40, 24, -1, 43, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, -1, 18, + 19, 20, 19, 20, -1, 22, -1, 26, 27, 28, + 29, 30, -1, 32, 33, 34, -1, 19, 20, 38, + -1, 40, 24, -1, 43, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, + 19, 20, -1, 22, -1, 26, 27, 28, 29, 30, + -1, -1, -1, 34, 35, 36, 37, 38, 6, 7, + 8, 9, 43, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, -1, 18, 19, 20, 26, -1, + -1, 29, -1, 26, 27, 28, 29, 30, -1, 19, + 20, 34, 35, 36, 24, 38, -1, -1, -1, -1, + 43, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, -1, 18, 19, 20, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 19, 20, -1, 34, + 35, 24, -1, 38, -1, -1, -1, -1, 43, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + -1, 18, 19, 20, -1, -1, -1, -1, -1, 26, + 27, 28, 29, 30, 19, 20, -1, 34, -1, 24, + -1, 38, -1, -1, -1, -1, 43, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, -1, 18, + 19, 20, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, -1, 6, 7, 34, 9, 19, 20, 38, + 19, 20, 24, -1, 43, 24, 19, 20, 21, 22, + 23, -1, -1, 26, 27, -1, -1, 30, 31, 32, + -1, 34, 6, 7, -1, 9, 39, 40, -1, 42, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + -1, -1, 26, 27, -1, -1, 30, 31, 32, -1, + 34, 6, 7, -1, 9, -1, 40, -1, 42, 26, + 27, -1, -1, 30, 19, 20, -1, 34, -1, -1, + 19, 20, -1, 40, -1, 42, 31, 32, 27, 28, + 35, 36, 37, -1, 33, 19, 20, -1, -1, -1, + -1, 40, -1, 27, 28, -1, -1, -1, -1, 33, + -1, -1, -1, -1, -1, -1, 40 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 1, 3, 4, 5, 46, 44, 6, 7, 9, - 31, 48, 49, 50, 56, 8, 10, 11, 12, 13, - 14, 15, 17, 18, 19, 25, 26, 27, 28, 29, - 31, 32, 33, 37, 39, 42, 47, 49, 51, 52, - 53, 54, 55, 56, 60, 62, 63, 25, 26, 29, - 33, 39, 41, 57, 58, 59, 0, 1, 43, 44, - 28, 51, 56, 62, 18, 19, 20, 21, 22, 30, - 49, 57, 61, 64, 65, 62, 62, 62, 62, 62, - 62, 62, 26, 62, 27, 62, 62, 29, 31, 47, - 51, 47, 52, 48, 47, 62, 44, 34, 35, 36, - 52, 23, 8, 25, 28, 56, 64, 59, 34, 35, - 36, 44, 59, 44, 26, 27, 32, 39, 60, 32, - 39, 28, 49, 19, 20, 49, 61, 49, 57, 38, - 51, 52, 51, 51, 26, 62, 62, 62, 57, 57, - 57, 62, 32, 39, 62, 32, 39, 60, 64, 64, - 49, 40, 62, 26, 32, 62, 32, 62, 32, 39, - 21, 64, 63, 24, 24, 62, 32, 32, 62, 21, - 64, 24, 32, 21, 64, 21, 64, 21 + 0, 1, 3, 4, 5, 47, 45, 6, 7, 9, + 32, 49, 50, 51, 57, 8, 10, 11, 12, 13, + 14, 15, 16, 18, 19, 20, 26, 27, 28, 29, + 30, 32, 33, 34, 38, 40, 43, 48, 50, 52, + 53, 54, 55, 56, 57, 61, 63, 64, 26, 27, + 30, 34, 40, 42, 58, 59, 60, 0, 1, 44, + 45, 29, 52, 57, 63, 19, 20, 21, 22, 23, + 31, 50, 58, 62, 65, 66, 63, 63, 24, 63, + 63, 63, 63, 63, 63, 27, 63, 28, 63, 63, + 30, 32, 48, 52, 48, 53, 49, 48, 63, 45, + 35, 36, 37, 53, 24, 8, 26, 29, 57, 65, + 60, 35, 36, 37, 45, 60, 45, 27, 28, 33, + 40, 61, 33, 40, 29, 50, 20, 21, 50, 62, + 50, 58, 27, 63, 39, 52, 53, 52, 52, 27, + 63, 63, 63, 58, 58, 58, 63, 33, 40, 63, + 33, 40, 61, 65, 65, 50, 63, 27, 41, 63, + 27, 33, 63, 33, 63, 33, 40, 22, 65, 25, + 25, 63, 64, 25, 25, 63, 33, 33, 63, 22, + 65, 25, 25, 33, 22, 65, 22, 65, 22 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { - 0, 45, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, - 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, - 51, 51, 51, 51, 52, 52, 52, 53, 53, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 55, 55, 55, 55, 55, 55, 55, 55, 56, - 56, 56, 57, 57, 57, 57, 58, 58, 59, 59, - 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, - 61, 61, 61, 61, 61, 61, 61, 62, 62, 63, - 63, 64, 64, 65 + 0, 46, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, + 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, + 52, 52, 52, 52, 53, 53, 53, 54, 54, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, + 56, 56, 56, 56, 57, 57, 57, 58, 58, 58, + 58, 59, 59, 60, 60, 60, 60, 60, 60, 61, + 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, + 62, 62, 63, 63, 64, 64, 65, 65, 66 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -986,13 +993,13 @@ static const yytype_int8 yyr2[] = 3, 5, 4, 6, 4, 6, 5, 7, 3, 3, 3, 2, 3, 1, 2, 1, 1, 3, 5, 1, 2, 1, 2, 2, 3, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 5, 5, 6, - 2, 3, 2, 1, 1, 2, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 3, 3, 1, 1, 2, 1, 1, - 1, 1, 1, 2, 2, 2, 1, 2, 2, 1, - 1, 3, 4, 5, 6, 7, 8, 1, 1, 1, - 2, 1, 1, 1 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 5, + 5, 6, 5, 5, 6, 2, 3, 2, 1, 1, + 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, + 2, 1, 2, 2, 1, 1, 3, 4, 5, 6, + 7, 8, 1, 1, 1, 2, 1, 1, 1 }; @@ -1227,6 +1234,10 @@ yydestruct (const char *yymsg, { delete ((*yyvaluep).atom); } break; + case YYSYMBOL_MIN_RINGSIZE_ATOM_QUERY_TOKEN: /* MIN_RINGSIZE_ATOM_QUERY_TOKEN */ + { delete ((*yyvaluep).atom); } + break; + case YYSYMBOL_RINGSIZE_ATOM_QUERY_TOKEN: /* RINGSIZE_ATOM_QUERY_TOKEN */ { delete ((*yyvaluep).atom); } break; @@ -1917,7 +1928,7 @@ yyreduce: case 38: /* atom_expr: atom_expr AND_TOKEN atom_expr */ { (yyvsp[-2].atom)->expandQuery((yyvsp[0].atom)->getQuery()->copy(),Queries::COMPOSITE_AND,true); - if((yyvsp[-2].atom)->getChiralTag()==Atom::CHI_UNSPECIFIED) (yyvsp[-2].atom)->setChiralTag((yyvsp[0].atom)->getChiralTag()); + if ((yyvsp[-2].atom)->getChiralTag()==Atom::CHI_UNSPECIFIED) { (yyvsp[-2].atom)->setChiralTag((yyvsp[0].atom)->getChiralTag()); } SmilesParseOps::ClearAtomChemicalProps((yyvsp[-2].atom)); delete (yyvsp[0].atom); (yyval.atom) = (yyvsp[-2].atom); @@ -1927,7 +1938,7 @@ yyreduce: case 39: /* atom_expr: atom_expr OR_TOKEN atom_expr */ { (yyvsp[-2].atom)->expandQuery((yyvsp[0].atom)->getQuery()->copy(),Queries::COMPOSITE_OR,true); - if((yyvsp[-2].atom)->getChiralTag()==Atom::CHI_UNSPECIFIED) (yyvsp[-2].atom)->setChiralTag((yyvsp[0].atom)->getChiralTag()); + if ((yyvsp[-2].atom)->getChiralTag()==Atom::CHI_UNSPECIFIED) { (yyvsp[-2].atom)->setChiralTag((yyvsp[0].atom)->getChiralTag()); } SmilesParseOps::ClearAtomChemicalProps((yyvsp[-2].atom)); (yyvsp[-2].atom)->setAtomicNum(0); delete (yyvsp[0].atom); @@ -1938,7 +1949,7 @@ yyreduce: case 40: /* atom_expr: atom_expr SEMI_TOKEN atom_expr */ { (yyvsp[-2].atom)->expandQuery((yyvsp[0].atom)->getQuery()->copy(),Queries::COMPOSITE_AND,true); - if((yyvsp[-2].atom)->getChiralTag()==Atom::CHI_UNSPECIFIED) (yyvsp[-2].atom)->setChiralTag((yyvsp[0].atom)->getChiralTag()); + if ((yyvsp[-2].atom)->getChiralTag()==Atom::CHI_UNSPECIFIED) { (yyvsp[-2].atom)->setChiralTag((yyvsp[0].atom)->getChiralTag()); } SmilesParseOps::ClearAtomChemicalProps((yyvsp[-2].atom)); delete (yyvsp[0].atom); (yyval.atom) = (yyvsp[-2].atom); @@ -2042,49 +2053,56 @@ yyreduce: } break; - case 61: /* atom_query: COMPLEX_ATOM_QUERY_TOKEN number */ + case 62: /* atom_query: COMPLEX_ATOM_QUERY_TOKEN number */ { static_cast((yyvsp[-1].atom)->getQuery())->setVal((yyvsp[0].ival)); (yyval.atom) = (yyvsp[-1].atom); } break; - case 62: /* atom_query: HETERONEIGHBOR_ATOM_QUERY_TOKEN number */ + case 63: /* atom_query: HETERONEIGHBOR_ATOM_QUERY_TOKEN number */ { (yyvsp[-1].atom)->setQuery(makeAtomNumHeteroatomNbrsQuery((yyvsp[0].ival))); (yyval.atom) = (yyvsp[-1].atom); } break; - case 63: /* atom_query: ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN number */ + case 64: /* atom_query: ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN number */ { (yyvsp[-1].atom)->setQuery(makeAtomNumAliphaticHeteroatomNbrsQuery((yyvsp[0].ival))); (yyval.atom) = (yyvsp[-1].atom); } break; - case 64: /* atom_query: RINGSIZE_ATOM_QUERY_TOKEN number */ - { + case 65: /* atom_query: MIN_RINGSIZE_ATOM_QUERY_TOKEN number */ + { (yyvsp[-1].atom)->setQuery(makeAtomMinRingSizeQuery((yyvsp[0].ival))); (yyval.atom) = (yyvsp[-1].atom); } break; - case 65: /* atom_query: RINGBOND_ATOM_QUERY_TOKEN number */ + case 66: /* atom_query: RINGSIZE_ATOM_QUERY_TOKEN number */ + { + (yyvsp[-1].atom)->setQuery(makeAtomInRingOfSizeQuery((yyvsp[0].ival))); + (yyval.atom) = (yyvsp[-1].atom); +} + break; + + case 67: /* atom_query: RINGBOND_ATOM_QUERY_TOKEN number */ { (yyvsp[-1].atom)->setQuery(makeAtomRingBondCountQuery((yyvsp[0].ival))); (yyval.atom) = (yyvsp[-1].atom); } break; - case 66: /* atom_query: IMPLICIT_H_ATOM_QUERY_TOKEN number */ + case 68: /* atom_query: IMPLICIT_H_ATOM_QUERY_TOKEN number */ { (yyvsp[-1].atom)->setQuery(makeAtomImplicitHCountQuery((yyvsp[0].ival))); (yyval.atom) = (yyvsp[-1].atom); } break; - case 67: /* atom_query: possible_range_query RANGE_OPEN_TOKEN MINUS_TOKEN number RANGE_CLOSE_TOKEN */ + case 69: /* atom_query: possible_range_query RANGE_OPEN_TOKEN MINUS_TOKEN number RANGE_CLOSE_TOKEN */ { ATOM_EQUALS_QUERY *oq = static_cast((yyvsp[-4].atom)->getQuery()); ATOM_GREATEREQUAL_QUERY *nq = makeAtomSimpleQuery((yyvsp[-1].ival),oq->getDataFunc(), @@ -2094,7 +2112,7 @@ yyreduce: } break; - case 68: /* atom_query: possible_range_query RANGE_OPEN_TOKEN number MINUS_TOKEN RANGE_CLOSE_TOKEN */ + case 70: /* atom_query: possible_range_query RANGE_OPEN_TOKEN number MINUS_TOKEN RANGE_CLOSE_TOKEN */ { ATOM_EQUALS_QUERY *oq = static_cast((yyvsp[-4].atom)->getQuery()); ATOM_LESSEQUAL_QUERY *nq = makeAtomSimpleQuery((yyvsp[-2].ival),oq->getDataFunc(), @@ -2104,7 +2122,7 @@ yyreduce: } break; - case 69: /* atom_query: possible_range_query RANGE_OPEN_TOKEN number MINUS_TOKEN number RANGE_CLOSE_TOKEN */ + case 71: /* atom_query: possible_range_query RANGE_OPEN_TOKEN number MINUS_TOKEN number RANGE_CLOSE_TOKEN */ { ATOM_EQUALS_QUERY *oq = static_cast((yyvsp[-5].atom)->getQuery()); ATOM_RANGE_QUERY *nq = makeAtomRangeQuery((yyvsp[-3].ival),(yyvsp[-1].ival),false,false, @@ -2115,7 +2133,43 @@ yyreduce: } break; - case 70: /* atom_query: number H_TOKEN */ + case 72: /* atom_query: RINGSIZE_ATOM_QUERY_TOKEN RANGE_OPEN_TOKEN MINUS_TOKEN number RANGE_CLOSE_TOKEN */ + { + int lv = -1; + int uv = (yyvsp[-1].ival); + ATOM_GREATEREQUAL_QUERY *nq = makeAtomSimpleQuery(uv,[lv,uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + },std::string("greater_AtomRingSize")); + (yyvsp[-4].atom)->setQuery(nq); + (yyval.atom) = (yyvsp[-4].atom); +} + break; + + case 73: /* atom_query: RINGSIZE_ATOM_QUERY_TOKEN RANGE_OPEN_TOKEN number MINUS_TOKEN RANGE_CLOSE_TOKEN */ + { + int lv = (yyvsp[-2].ival); + int uv = -1; + ATOM_LESSEQUAL_QUERY *nq = makeAtomSimpleQuery(lv,[lv,uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + },std::string("less_AtomRingSize")); + (yyvsp[-4].atom)->setQuery(nq); + (yyval.atom) = (yyvsp[-4].atom); +} + break; + + case 74: /* atom_query: RINGSIZE_ATOM_QUERY_TOKEN RANGE_OPEN_TOKEN number MINUS_TOKEN number RANGE_CLOSE_TOKEN */ + { + int lv = (yyvsp[-3].ival); + int uv = (yyvsp[-1].ival); + ATOM_RANGE_QUERY *nq = makeAtomRangeQuery(lv,uv,false,false,[lv,uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + },std::string("range_AtomRingSize")); + (yyvsp[-5].atom)->setQuery(nq); + (yyval.atom) = (yyvsp[-5].atom); +} + break; + + case 75: /* atom_query: number H_TOKEN */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomIsotopeQuery((yyvsp[-1].ival))); @@ -2128,7 +2182,7 @@ yyreduce: } break; - case 71: /* atom_query: number H_TOKEN number */ + case 76: /* atom_query: number H_TOKEN number */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomIsotopeQuery((yyvsp[-2].ival))); @@ -2141,7 +2195,7 @@ yyreduce: } break; - case 72: /* atom_query: H_TOKEN number */ + case 77: /* atom_query: H_TOKEN number */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomHCountQuery((yyvsp[0].ival))); @@ -2153,7 +2207,7 @@ yyreduce: } break; - case 73: /* atom_query: H_TOKEN */ + case 78: /* atom_query: H_TOKEN */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomHCountQuery(1)); @@ -2164,7 +2218,7 @@ yyreduce: } break; - case 74: /* atom_query: charge_spec */ + case 79: /* atom_query: charge_spec */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomFormalChargeQuery((yyvsp[0].ival))); @@ -2174,7 +2228,7 @@ yyreduce: } break; - case 75: /* atom_query: AT_TOKEN AT_TOKEN */ + case 80: /* atom_query: AT_TOKEN AT_TOKEN */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomNullQuery()); @@ -2183,7 +2237,7 @@ yyreduce: } break; - case 76: /* atom_query: AT_TOKEN */ + case 81: /* atom_query: AT_TOKEN */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomNullQuery()); @@ -2192,7 +2246,7 @@ yyreduce: } break; - case 77: /* atom_query: CHI_CLASS_TOKEN */ + case 82: /* atom_query: CHI_CLASS_TOKEN */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomNullQuery()); @@ -2202,7 +2256,7 @@ yyreduce: } break; - case 78: /* atom_query: CHI_CLASS_TOKEN number */ + case 83: /* atom_query: CHI_CLASS_TOKEN number */ { if((yyvsp[0].ival)==0){ yyerror(input,molList,branchPoints,scanner,start_token, current_token_position, @@ -2219,7 +2273,7 @@ yyreduce: } break; - case 80: /* atom_query: number */ + case 85: /* atom_query: number */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomIsotopeQuery((yyvsp[0].ival))); @@ -2227,42 +2281,42 @@ yyreduce: } break; - case 82: /* possible_range_query: HETERONEIGHBOR_ATOM_QUERY_TOKEN */ + case 87: /* possible_range_query: HETERONEIGHBOR_ATOM_QUERY_TOKEN */ { (yyvsp[0].atom)->setQuery(makeAtomNumHeteroatomNbrsQuery(0)); (yyval.atom) = (yyvsp[0].atom); } break; - case 83: /* possible_range_query: ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN */ + case 88: /* possible_range_query: ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN */ { (yyvsp[0].atom)->setQuery(makeAtomNumAliphaticHeteroatomNbrsQuery(0)); (yyval.atom) = (yyvsp[0].atom); } break; - case 84: /* possible_range_query: RINGSIZE_ATOM_QUERY_TOKEN */ - { + case 89: /* possible_range_query: MIN_RINGSIZE_ATOM_QUERY_TOKEN */ + { (yyvsp[0].atom)->setQuery(makeAtomMinRingSizeQuery(5)); // this is going to be ignored anyway (yyval.atom) = (yyvsp[0].atom); } break; - case 85: /* possible_range_query: RINGBOND_ATOM_QUERY_TOKEN */ + case 90: /* possible_range_query: RINGBOND_ATOM_QUERY_TOKEN */ { (yyvsp[0].atom)->setQuery(makeAtomRingBondCountQuery(0)); (yyval.atom) = (yyvsp[0].atom); } break; - case 86: /* possible_range_query: IMPLICIT_H_ATOM_QUERY_TOKEN */ + case 91: /* possible_range_query: IMPLICIT_H_ATOM_QUERY_TOKEN */ { (yyvsp[0].atom)->setQuery(makeAtomImplicitHCountQuery(0)); (yyval.atom) = (yyvsp[0].atom); } break; - case 87: /* possible_range_query: PLUS_TOKEN */ + case 92: /* possible_range_query: PLUS_TOKEN */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomFormalChargeQuery(0)); @@ -2270,7 +2324,7 @@ yyreduce: } break; - case 88: /* possible_range_query: MINUS_TOKEN */ + case 93: /* possible_range_query: MINUS_TOKEN */ { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomNegativeFormalChargeQuery(0)); @@ -2278,7 +2332,7 @@ yyreduce: } break; - case 89: /* simple_atom: ORGANIC_ATOM_TOKEN */ + case 94: /* simple_atom: ORGANIC_ATOM_TOKEN */ { // // This construction (and some others) may seem odd, but the @@ -2293,7 +2347,7 @@ yyreduce: } break; - case 90: /* simple_atom: AROMATIC_ATOM_TOKEN */ + case 95: /* simple_atom: AROMATIC_ATOM_TOKEN */ { (yyval.atom) = new QueryAtom((yyvsp[0].ival)); (yyval.atom)->setIsAromatic(true); @@ -2301,7 +2355,7 @@ yyreduce: } break; - case 92: /* bond_expr: bond_expr AND_TOKEN bond_expr */ + case 97: /* bond_expr: bond_expr AND_TOKEN bond_expr */ { (yyvsp[-2].bond)->expandQuery((yyvsp[0].bond)->getQuery()->copy(),Queries::COMPOSITE_AND,true); delete (yyvsp[0].bond); @@ -2309,7 +2363,7 @@ yyreduce: } break; - case 93: /* bond_expr: bond_expr OR_TOKEN bond_expr */ + case 98: /* bond_expr: bond_expr OR_TOKEN bond_expr */ { (yyvsp[-2].bond)->expandQuery((yyvsp[0].bond)->getQuery()->copy(),Queries::COMPOSITE_OR,true); delete (yyvsp[0].bond); @@ -2317,7 +2371,7 @@ yyreduce: } break; - case 94: /* bond_expr: bond_expr SEMI_TOKEN bond_expr */ + case 99: /* bond_expr: bond_expr SEMI_TOKEN bond_expr */ { (yyvsp[-2].bond)->expandQuery((yyvsp[0].bond)->getQuery()->copy(),Queries::COMPOSITE_AND,true); delete (yyvsp[0].bond); @@ -2325,7 +2379,7 @@ yyreduce: } break; - case 97: /* bond_query: bond_query bondd */ + case 102: /* bond_query: bond_query bondd */ { (yyvsp[-1].bond)->expandQuery((yyvsp[0].bond)->getQuery()->copy(),Queries::COMPOSITE_AND,true); delete (yyvsp[0].bond); @@ -2333,7 +2387,7 @@ yyreduce: } break; - case 99: /* bondd: MINUS_TOKEN */ + case 104: /* bondd: MINUS_TOKEN */ { QueryBond *newB= new QueryBond(); newB->setBondType(Bond::SINGLE); @@ -2342,7 +2396,7 @@ yyreduce: } break; - case 100: /* bondd: HASH_TOKEN */ + case 105: /* bondd: HASH_TOKEN */ { QueryBond *newB= new QueryBond(); newB->setBondType(Bond::TRIPLE); @@ -2351,7 +2405,7 @@ yyreduce: } break; - case 101: /* bondd: COLON_TOKEN */ + case 106: /* bondd: COLON_TOKEN */ { QueryBond *newB= new QueryBond(); newB->setBondType(Bond::AROMATIC); @@ -2360,7 +2414,7 @@ yyreduce: } break; - case 102: /* bondd: AT_TOKEN */ + case 107: /* bondd: AT_TOKEN */ { QueryBond *newB= new QueryBond(); newB->setQuery(makeBondIsInRingQuery()); @@ -2368,62 +2422,62 @@ yyreduce: } break; - case 103: /* bondd: NOT_TOKEN bondd */ + case 108: /* bondd: NOT_TOKEN bondd */ { (yyvsp[0].bond)->getQuery()->setNegation(!((yyvsp[0].bond)->getQuery()->getNegation())); (yyval.bond) = (yyvsp[0].bond); } break; - case 104: /* charge_spec: PLUS_TOKEN PLUS_TOKEN */ + case 109: /* charge_spec: PLUS_TOKEN PLUS_TOKEN */ { (yyval.ival)=2; } break; - case 105: /* charge_spec: PLUS_TOKEN number */ + case 110: /* charge_spec: PLUS_TOKEN number */ { (yyval.ival)=(yyvsp[0].ival); } break; - case 106: /* charge_spec: PLUS_TOKEN */ + case 111: /* charge_spec: PLUS_TOKEN */ { (yyval.ival)=1; } break; - case 107: /* charge_spec: MINUS_TOKEN MINUS_TOKEN */ + case 112: /* charge_spec: MINUS_TOKEN MINUS_TOKEN */ { (yyval.ival)=-2; } break; - case 108: /* charge_spec: MINUS_TOKEN number */ + case 113: /* charge_spec: MINUS_TOKEN number */ { (yyval.ival)=-(yyvsp[0].ival); } break; - case 109: /* charge_spec: MINUS_TOKEN */ + case 114: /* charge_spec: MINUS_TOKEN */ { (yyval.ival)=-1; } break; - case 111: /* ring_number: PERCENT_TOKEN NONZERO_DIGIT_TOKEN digit */ + case 116: /* ring_number: PERCENT_TOKEN NONZERO_DIGIT_TOKEN digit */ { (yyval.ival) = (yyvsp[-1].ival)*10+(yyvsp[0].ival); } break; - case 112: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit GROUP_CLOSE_TOKEN */ + case 117: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit GROUP_CLOSE_TOKEN */ { (yyval.ival) = (yyvsp[-1].ival); } break; - case 113: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit GROUP_CLOSE_TOKEN */ + case 118: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit GROUP_CLOSE_TOKEN */ { (yyval.ival) = (yyvsp[-2].ival)*10+(yyvsp[-1].ival); } break; - case 114: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit digit GROUP_CLOSE_TOKEN */ + case 119: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit digit GROUP_CLOSE_TOKEN */ { (yyval.ival) = (yyvsp[-3].ival)*100+(yyvsp[-2].ival)*10+(yyvsp[-1].ival); } break; - case 115: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit digit digit GROUP_CLOSE_TOKEN */ + case 120: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit digit digit GROUP_CLOSE_TOKEN */ { (yyval.ival) = (yyvsp[-4].ival)*1000+(yyvsp[-3].ival)*100+(yyvsp[-2].ival)*10+(yyvsp[-1].ival); } break; - case 116: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit digit digit digit GROUP_CLOSE_TOKEN */ + case 121: /* ring_number: PERCENT_TOKEN GROUP_OPEN_TOKEN digit digit digit digit digit GROUP_CLOSE_TOKEN */ { (yyval.ival) = (yyvsp[-5].ival)*10000+(yyvsp[-4].ival)*1000+(yyvsp[-3].ival)*100+(yyvsp[-2].ival)*10+(yyvsp[-1].ival); } break; - case 120: /* nonzero_number: nonzero_number digit */ + case 125: /* nonzero_number: nonzero_number digit */ { if((yyvsp[-1].ival) >= std::numeric_limits::max()/10 || (yyvsp[-1].ival)*10 >= std::numeric_limits::max()-(yyvsp[0].ival) ){ @@ -2433,7 +2487,7 @@ yyreduce: (yyval.ival) = (yyvsp[-1].ival)*10 + (yyvsp[0].ival); } break; - case 123: /* branch_open_token: GROUP_OPEN_TOKEN */ + case 128: /* branch_open_token: GROUP_OPEN_TOKEN */ { (yyval.ival) = current_token_position; } break; diff --git a/Code/GraphMol/SmilesParse/smarts.tab.hpp.cmake b/Code/GraphMol/SmilesParse/smarts.tab.hpp.cmake index 198d5d76d..119ba7447 100644 --- a/Code/GraphMol/SmilesParse/smarts.tab.hpp.cmake +++ b/Code/GraphMol/SmilesParse/smarts.tab.hpp.cmake @@ -62,40 +62,41 @@ extern int yysmarts_debug; ATOM_TOKEN = 263, /* ATOM_TOKEN */ SIMPLE_ATOM_QUERY_TOKEN = 264, /* SIMPLE_ATOM_QUERY_TOKEN */ COMPLEX_ATOM_QUERY_TOKEN = 265, /* COMPLEX_ATOM_QUERY_TOKEN */ - RINGSIZE_ATOM_QUERY_TOKEN = 266, /* RINGSIZE_ATOM_QUERY_TOKEN */ - RINGBOND_ATOM_QUERY_TOKEN = 267, /* RINGBOND_ATOM_QUERY_TOKEN */ - IMPLICIT_H_ATOM_QUERY_TOKEN = 268, /* IMPLICIT_H_ATOM_QUERY_TOKEN */ - HYB_TOKEN = 269, /* HYB_TOKEN */ - HETERONEIGHBOR_ATOM_QUERY_TOKEN = 270, /* HETERONEIGHBOR_ATOM_QUERY_TOKEN */ - ALIPHATIC = 271, /* ALIPHATIC */ - ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN = 272, /* ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN */ - ZERO_TOKEN = 273, /* ZERO_TOKEN */ - NONZERO_DIGIT_TOKEN = 274, /* NONZERO_DIGIT_TOKEN */ - GROUP_OPEN_TOKEN = 275, /* GROUP_OPEN_TOKEN */ - GROUP_CLOSE_TOKEN = 276, /* GROUP_CLOSE_TOKEN */ - SEPARATOR_TOKEN = 277, /* SEPARATOR_TOKEN */ - RANGE_OPEN_TOKEN = 278, /* RANGE_OPEN_TOKEN */ - RANGE_CLOSE_TOKEN = 279, /* RANGE_CLOSE_TOKEN */ - HASH_TOKEN = 280, /* HASH_TOKEN */ - MINUS_TOKEN = 281, /* MINUS_TOKEN */ - PLUS_TOKEN = 282, /* PLUS_TOKEN */ - H_TOKEN = 283, /* H_TOKEN */ - AT_TOKEN = 284, /* AT_TOKEN */ - PERCENT_TOKEN = 285, /* PERCENT_TOKEN */ - ATOM_OPEN_TOKEN = 286, /* ATOM_OPEN_TOKEN */ - ATOM_CLOSE_TOKEN = 287, /* ATOM_CLOSE_TOKEN */ - NOT_TOKEN = 288, /* NOT_TOKEN */ - AND_TOKEN = 289, /* AND_TOKEN */ - OR_TOKEN = 290, /* OR_TOKEN */ - SEMI_TOKEN = 291, /* SEMI_TOKEN */ - BEGIN_RECURSE = 292, /* BEGIN_RECURSE */ - END_RECURSE = 293, /* END_RECURSE */ - COLON_TOKEN = 294, /* COLON_TOKEN */ - UNDERSCORE_TOKEN = 295, /* UNDERSCORE_TOKEN */ - BOND_TOKEN = 296, /* BOND_TOKEN */ - CHI_CLASS_TOKEN = 297, /* CHI_CLASS_TOKEN */ - BAD_CHARACTER = 298, /* BAD_CHARACTER */ - EOS_TOKEN = 299 /* EOS_TOKEN */ + MIN_RINGSIZE_ATOM_QUERY_TOKEN = 266, /* MIN_RINGSIZE_ATOM_QUERY_TOKEN */ + RINGSIZE_ATOM_QUERY_TOKEN = 267, /* RINGSIZE_ATOM_QUERY_TOKEN */ + RINGBOND_ATOM_QUERY_TOKEN = 268, /* RINGBOND_ATOM_QUERY_TOKEN */ + IMPLICIT_H_ATOM_QUERY_TOKEN = 269, /* IMPLICIT_H_ATOM_QUERY_TOKEN */ + HYB_TOKEN = 270, /* HYB_TOKEN */ + HETERONEIGHBOR_ATOM_QUERY_TOKEN = 271, /* HETERONEIGHBOR_ATOM_QUERY_TOKEN */ + ALIPHATIC = 272, /* ALIPHATIC */ + ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN = 273, /* ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN */ + ZERO_TOKEN = 274, /* ZERO_TOKEN */ + NONZERO_DIGIT_TOKEN = 275, /* NONZERO_DIGIT_TOKEN */ + GROUP_OPEN_TOKEN = 276, /* GROUP_OPEN_TOKEN */ + GROUP_CLOSE_TOKEN = 277, /* GROUP_CLOSE_TOKEN */ + SEPARATOR_TOKEN = 278, /* SEPARATOR_TOKEN */ + RANGE_OPEN_TOKEN = 279, /* RANGE_OPEN_TOKEN */ + RANGE_CLOSE_TOKEN = 280, /* RANGE_CLOSE_TOKEN */ + HASH_TOKEN = 281, /* HASH_TOKEN */ + MINUS_TOKEN = 282, /* MINUS_TOKEN */ + PLUS_TOKEN = 283, /* PLUS_TOKEN */ + H_TOKEN = 284, /* H_TOKEN */ + AT_TOKEN = 285, /* AT_TOKEN */ + PERCENT_TOKEN = 286, /* PERCENT_TOKEN */ + ATOM_OPEN_TOKEN = 287, /* ATOM_OPEN_TOKEN */ + ATOM_CLOSE_TOKEN = 288, /* ATOM_CLOSE_TOKEN */ + NOT_TOKEN = 289, /* NOT_TOKEN */ + AND_TOKEN = 290, /* AND_TOKEN */ + OR_TOKEN = 291, /* OR_TOKEN */ + SEMI_TOKEN = 292, /* SEMI_TOKEN */ + BEGIN_RECURSE = 293, /* BEGIN_RECURSE */ + END_RECURSE = 294, /* END_RECURSE */ + COLON_TOKEN = 295, /* COLON_TOKEN */ + UNDERSCORE_TOKEN = 296, /* UNDERSCORE_TOKEN */ + BOND_TOKEN = 297, /* BOND_TOKEN */ + CHI_CLASS_TOKEN = 298, /* CHI_CLASS_TOKEN */ + BAD_CHARACTER = 299, /* BAD_CHARACTER */ + EOS_TOKEN = 300 /* EOS_TOKEN */ }; typedef enum yytokentype yytoken_kind_t; #endif diff --git a/Code/GraphMol/SmilesParse/smarts.yy b/Code/GraphMol/SmilesParse/smarts.yy index c9084e3ea..eb2aa309e 100644 --- a/Code/GraphMol/SmilesParse/smarts.yy +++ b/Code/GraphMol/SmilesParse/smarts.yy @@ -153,7 +153,7 @@ yysmarts_error( const char *input, %token AROMATIC_ATOM_TOKEN ORGANIC_ATOM_TOKEN %token ATOM_TOKEN %token SIMPLE_ATOM_QUERY_TOKEN COMPLEX_ATOM_QUERY_TOKEN -%token RINGSIZE_ATOM_QUERY_TOKEN RINGBOND_ATOM_QUERY_TOKEN IMPLICIT_H_ATOM_QUERY_TOKEN +%token MIN_RINGSIZE_ATOM_QUERY_TOKEN RINGSIZE_ATOM_QUERY_TOKEN RINGBOND_ATOM_QUERY_TOKEN IMPLICIT_H_ATOM_QUERY_TOKEN %token HYB_TOKEN HETERONEIGHBOR_ATOM_QUERY_TOKEN ALIPHATIC ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN %token ZERO_TOKEN NONZERO_DIGIT_TOKEN %token GROUP_OPEN_TOKEN GROUP_CLOSE_TOKEN SEPARATOR_TOKEN @@ -593,6 +593,7 @@ atom_query: simple_atom | COMPLEX_ATOM_QUERY_TOKEN | HETERONEIGHBOR_ATOM_QUERY_TOKEN | ALIPHATICHETERONEIGHBOR_ATOM_QUERY_TOKEN +| MIN_RINGSIZE_ATOM_QUERY_TOKEN | RINGSIZE_ATOM_QUERY_TOKEN | RINGBOND_ATOM_QUERY_TOKEN | IMPLICIT_H_ATOM_QUERY_TOKEN @@ -608,10 +609,14 @@ atom_query: simple_atom $1->setQuery(makeAtomNumAliphaticHeteroatomNbrsQuery($2)); $$ = $1; } -| RINGSIZE_ATOM_QUERY_TOKEN number { +| MIN_RINGSIZE_ATOM_QUERY_TOKEN number { $1->setQuery(makeAtomMinRingSizeQuery($2)); $$ = $1; } +| RINGSIZE_ATOM_QUERY_TOKEN number { + $1->setQuery(makeAtomInRingOfSizeQuery($2)); + $$ = $1; +} | RINGBOND_ATOM_QUERY_TOKEN number { $1->setQuery(makeAtomRingBondCountQuery($2)); $$ = $1; @@ -642,6 +647,35 @@ atom_query: simple_atom $1->setQuery(nq); $$ = $1; } +/* "k" queries have to be handled differently */ +| RINGSIZE_ATOM_QUERY_TOKEN RANGE_OPEN_TOKEN MINUS_TOKEN number RANGE_CLOSE_TOKEN { + int lv = -1; + int uv = $4; + ATOM_GREATEREQUAL_QUERY *nq = makeAtomSimpleQuery(uv,[lv,uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + },std::string("greater_AtomRingSize")); + $1->setQuery(nq); + $$ = $1; +} +| RINGSIZE_ATOM_QUERY_TOKEN RANGE_OPEN_TOKEN number MINUS_TOKEN RANGE_CLOSE_TOKEN { + int lv = $3; + int uv = -1; + ATOM_LESSEQUAL_QUERY *nq = makeAtomSimpleQuery(lv,[lv,uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + },std::string("less_AtomRingSize")); + $1->setQuery(nq); + $$ = $1; +} +| RINGSIZE_ATOM_QUERY_TOKEN RANGE_OPEN_TOKEN number MINUS_TOKEN number RANGE_CLOSE_TOKEN { + int lv = $3; + int uv = $5; + ATOM_RANGE_QUERY *nq = makeAtomRangeQuery(lv,uv,false,false,[lv,uv](Atom const *at) { + return queryAtomIsInRingOfSize(at, lv, uv); + },std::string("range_AtomRingSize")); + $1->setQuery(nq); + $$ = $1; +} + | number H_TOKEN { QueryAtom *newQ = new QueryAtom(); newQ->setQuery(makeAtomIsotopeQuery($1)); @@ -736,7 +770,7 @@ possible_range_query : COMPLEX_ATOM_QUERY_TOKEN $1->setQuery(makeAtomNumAliphaticHeteroatomNbrsQuery(0)); $$ = $1; } -| RINGSIZE_ATOM_QUERY_TOKEN { +| MIN_RINGSIZE_ATOM_QUERY_TOKEN { $1->setQuery(makeAtomMinRingSizeQuery(5)); // this is going to be ignored anyway $$ = $1; } diff --git a/Code/GraphMol/SmilesParse/smarts_catch_tests.cpp b/Code/GraphMol/SmilesParse/smarts_catch_tests.cpp index 05e7ba305..7dc1cd0f1 100644 --- a/Code/GraphMol/SmilesParse/smarts_catch_tests.cpp +++ b/Code/GraphMol/SmilesParse/smarts_catch_tests.cpp @@ -83,4 +83,91 @@ TEST_CASE("implicit Hs from SMILES should not make it into SMARTS") { auto smarts = MolToSmarts(*m); CHECK(smarts == "[#6]-[#6@H](-[#7])-[#9]"); } -} \ No newline at end of file +} + +void checkMatches(const std::string &smarts, const std::string &smiles, + unsigned int nMatches, unsigned int lenFirst, + bool addHs = false) { + // utility function that will find the matches between a smarts and smiles + // if they match the expected values + // smarts : smarts string + // smiles : smiles string + // nMatches : expected number of matches + // lenFirst : length of the first match + // + // Return the list of all matches just in case want to do additional testing + INFO(smarts + " " + smiles); + auto matcher = v2::SmilesParse::MolFromSmarts(smarts); + REQUIRE(matcher); + // we will at the same time test the serialization: + std::string pickle; + MolPickler::pickleMol(*matcher, pickle); + ROMol matcher2(pickle); + + auto mol = v2::SmilesParse::MolFromSmiles(smiles); + REQUIRE(mol); + if (addHs) { + MolOps::addHs(*mol); + } + MolOps::findSSSR(*mol); + + MatchVectType mV; + auto matches = SubstructMatch(*mol, *matcher, mV); + CHECK(matches); + CHECK(mV.size() == lenFirst); + std::vector mVV; + auto uniquify = true; + auto matchCount = SubstructMatch(*mol, *matcher, mVV, uniquify); + CHECK(matchCount == nMatches); + CHECK(mVV[0].size() == lenFirst); + + matches = SubstructMatch(*mol, matcher2, mV); + CHECK(matches); + CHECK(mV.size() == lenFirst); + matchCount = SubstructMatch(*mol, matcher2, mVV, true); + CHECK(matchCount == nMatches); + CHECK(mVV[0].size() == lenFirst); +} + +TEST_CASE("k SMARTS extensions") { + SECTION("parsing and writing") { + auto q = "[k4]"_smarts; + REQUIRE(q); + auto smarts = MolToSmarts(*q); + CHECK(smarts == "[k4]"); + } + SECTION("matching") { + auto m = "C1CC2N1CCCCCC2"_smiles; + REQUIRE(m); + auto k4 = "[k4]"_smarts; + REQUIRE(k4); + std::vector matches; + CHECK(SubstructMatch(*m, *k4, matches)); + CHECK(matches.size() == 4); + auto q4 = "[r4]"_smarts; + REQUIRE(q4); + CHECK(SubstructMatch(*m, *q4, matches)); + CHECK(matches.size() == 4); + auto k8 = "[k8]"_smarts; + REQUIRE(k8); + CHECK(SubstructMatch(*m, *k8, matches)); + CHECK(matches.size() == 8); + auto q8 = "[r8]"_smarts; + REQUIRE(q8); + CHECK(SubstructMatch(*m, *q8, matches)); + CHECK(matches.size() == 6); + } + SECTION("ranges") { + std::string smiles = "C1CC2N1CCCCCC2C"; + std::vector> smartses = { + {"[r{4-5}]", 4}, {"[k{4-5}]", 4}, {"[k{4-}]", 10}, {"[r{4-}]", 10}, + {"[k{-5}]", 4}, {"[k{8-}]", 8}, {"[r{8-}]", 6}, {"[r{4-8}]", 10}, + {"[!r{4-5}]", 7}, {"[!k{4-5}]", 7}, {"[!k{4-}]", 1}, {"[!r{4-}]", 1}, + {"[!k{-5}]", 7}, {"[!k{8-}]", 3}, {"[!r{8-}]", 5}, {"[!r{4-8}]", 1}, + {"[k]", 10}, {"[r]", 10}, {"[!k]", 1}, {"[!r]", 1}, + }; + for (const auto &[sma, val] : smartses) { + checkMatches(sma, smiles, val, 1); + } + } +} diff --git a/Code/GraphMol/SmilesParse/smatest.cpp b/Code/GraphMol/SmilesParse/smatest.cpp index d7d40c1e1..e50c7dd37 100644 --- a/Code/GraphMol/SmilesParse/smatest.cpp +++ b/Code/GraphMol/SmilesParse/smatest.cpp @@ -65,6 +65,8 @@ void testPass() { "C%(1000)CC.C%(1000)", // github #2909 "[C;d2]", // non-hydrogen degree "C$C", // quadruple bonds + "[k]", // ring size query extensions + "[k4]", // extended chirality "C[Fe@TH](O)(Cl)F", "C[Fe@TH1](O)(Cl)F", "C[Fe@SP](O)(Cl)F", "C[Fe@SP1](O)(Cl)F", "C[Fe@TB](O)(Cl)(Br)F", "C[Fe@TB20](O)(Cl)(Br)F", diff --git a/Code/GraphMol/catch_queries.cpp b/Code/GraphMol/catch_queries.cpp index 966a3b51b..24d6c20be 100644 --- a/Code/GraphMol/catch_queries.cpp +++ b/Code/GraphMol/catch_queries.cpp @@ -36,3 +36,70 @@ TEST_CASE( CHECK(q->Match(m->getAtomWithIdx(2))); } } + +TEST_CASE("range queries for atom ring membership") { + auto m = "C1C2C1CC2C"_smiles; + REQUIRE(m); + SECTION("as range queries") { + { + std::unique_ptr q(makeAtomInRingOfSizeQuery(3, 4)); + REQUIRE(q); + CHECK(q->Match(m->getAtomWithIdx(0))); + CHECK(q->Match(m->getAtomWithIdx(1))); + CHECK(q->Match(m->getAtomWithIdx(3))); + CHECK(!q->Match(m->getAtomWithIdx(5))); + } + { + std::unique_ptr q(makeAtomInRingOfSizeQuery(4, 6)); + REQUIRE(q); + CHECK(!q->Match(m->getAtomWithIdx(0))); + CHECK(q->Match(m->getAtomWithIdx(1))); + CHECK(q->Match(m->getAtomWithIdx(3))); + CHECK(!q->Match(m->getAtomWithIdx(5))); + } + { + // this is how we use the queries in the SMARTS parser + std::unique_ptr q( + makeAtomSimpleQuery(3, [](Atom const *at) { + return queryAtomIsInRingOfSize(at, 3, -1); + })); + REQUIRE(q); + CHECK(q->Match(m->getAtomWithIdx(0))); + CHECK(q->Match(m->getAtomWithIdx(1))); + CHECK(q->Match(m->getAtomWithIdx(3))); + CHECK(!q->Match(m->getAtomWithIdx(5))); + } + { // this is how we use the queries in the SMARTS parser + std::unique_ptr q( + makeAtomSimpleQuery(3, [](Atom const *at) { + return queryAtomIsInRingOfSize(at, -1, 3); + })); + REQUIRE(q); + CHECK(q->Match(m->getAtomWithIdx(0))); + CHECK(q->Match(m->getAtomWithIdx(1))); + CHECK(!q->Match(m->getAtomWithIdx(3))); + CHECK(!q->Match(m->getAtomWithIdx(5))); + } + } + SECTION("query function") { + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(0), 3, -1) == 3); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(1), 3, -1) == 3); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(3), 3, -1) == 4); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(5), 3, -1) == -1); + + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(0), -1, 3) == 3); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(1), -1, 3) == 3); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(3), -1, 3) == + std::numeric_limits::max()); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(5), -1, 3) == + std::numeric_limits::max()); + + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(0), 3, 4) == 3); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(1), 3, 4) == 3); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(3), 3, 4) == 4); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(5), 3, 4) == -1); + + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(3), 0, 4) == 4); + CHECK(queryAtomIsInRingOfSize(m->getAtomWithIdx(5), 0, 4) == -1); + } +} \ No newline at end of file diff --git a/Docs/Book/RDKit_Book.rst b/Docs/Book/RDKit_Book.rst index b4a6df1bd..a0001e595 100644 --- a/Docs/Book/RDKit_Book.rst +++ b/Docs/Book/RDKit_Book.rst @@ -455,6 +455,7 @@ h "number of implicit hs" >0 Y H "total number of Hs" 1 r "size of smallest SSSR ring" >0 Y R "number of SSSR rings" >0 Y +k "size of SSSR ring" >0 Y extension v "total valence" 1 Y x "number of ring bonds" >0 Y X "total degree" 1 Y