From 95a1b8aca626f4a4825af7b7aed79489c4d451b4 Mon Sep 17 00:00:00 2001 From: ninjalu <46543912+ninjalu@users.noreply.github.com> Date: Wed, 27 Jul 2022 12:16:44 +0100 Subject: [PATCH] add additional REL_OP (#10371) * add additional REL_OP * change to condition and new rel_op symbols * add operators to docs * add the anchor while we're in here * add tests Co-authored-by: Peter Baumgartner <5107405+pmbaumgartner@users.noreply.github.com> --- spacy/matcher/dependencymatcher.pyx | 20 +++++++++++++++++++ .../tests/matcher/test_dependency_matcher.py | 14 +++++++++++++ website/docs/api/dependencymatcher.md | 7 ++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/spacy/matcher/dependencymatcher.pyx b/spacy/matcher/dependencymatcher.pyx index a602ba737..74c2d002f 100644 --- a/spacy/matcher/dependencymatcher.pyx +++ b/spacy/matcher/dependencymatcher.pyx @@ -82,6 +82,10 @@ cdef class DependencyMatcher: "$-": self._imm_left_sib, "$++": self._right_sib, "$--": self._left_sib, + ">++": self._right_child, + ">--": self._left_child, + "<++": self._right_parent, + "<--": self._left_parent, } def __reduce__(self): @@ -423,6 +427,22 @@ cdef class DependencyMatcher: def _left_sib(self, doc, node): return [doc[child.i] for child in doc[node].head.children if child.i < node] + def _right_child(self, doc, node): + return [doc[child.i] for child in doc[node].children if child.i > node] + + def _left_child(self, doc, node): + return [doc[child.i] for child in doc[node].children if child.i < node] + + def _right_parent(self, doc, node): + if doc[node].head.i > node: + return [doc[node].head] + return [] + + def _left_parent(self, doc, node): + if doc[node].head.i < node: + return [doc[node].head] + return [] + def _normalize_key(self, key): if isinstance(key, str): return self.vocab.strings.add(key) diff --git a/spacy/tests/matcher/test_dependency_matcher.py b/spacy/tests/matcher/test_dependency_matcher.py index 1728c82af..b4e19d69d 100644 --- a/spacy/tests/matcher/test_dependency_matcher.py +++ b/spacy/tests/matcher/test_dependency_matcher.py @@ -316,6 +316,20 @@ def test_dependency_matcher_precedence_ops(en_vocab, op, num_matches): ("the", "brown", "$--", 0), ("brown", "the", "$--", 1), ("brown", "brown", "$--", 0), + ("quick", "fox", "<++", 1), + ("quick", "over", "<++", 0), + ("over", "jumped", "<++", 0), + ("the", "fox", "<++", 2), + ("brown", "fox", "<--", 0), + ("fox", "jumped", "<--", 0), + ("fox", "over", "<--", 1), + ("jumped", "over", ">++", 1), + ("fox", "lazy", ">++", 0), + ("over", "the", ">++", 0), + ("brown", "fox", ">--", 0), + ("fox", "brown", ">--", 1), + ("jumped", "fox", ">--", 1), + ("fox", "the", ">--", 2), ], ) def test_dependency_matcher_ops(en_vocab, doc, left, right, op, num_matches): diff --git a/website/docs/api/dependencymatcher.md b/website/docs/api/dependencymatcher.md index 356adcda7..cae4221bf 100644 --- a/website/docs/api/dependencymatcher.md +++ b/website/docs/api/dependencymatcher.md @@ -62,7 +62,7 @@ of relations, see the usage guide on -### Operators +### Operators {#operators} The following operators are supported by the `DependencyMatcher`, most of which come directly from @@ -82,6 +82,11 @@ come directly from | `A $- B` | `B` is a left immediate sibling of `A`, i.e. `A` and `B` have the same parent and `A.i == B.i + 1`. | | `A $++ B` | `B` is a right sibling of `A`, i.e. `A` and `B` have the same parent and `A.i < B.i`. | | `A $-- B` | `B` is a left sibling of `A`, i.e. `A` and `B` have the same parent and `A.i > B.i`. | +| `A >++ B` | `B` is a right child of `A`, i.e. `A` is a parent of `B` and `A.i < B.i` _(not in Semgrex)_. | +| `A >-- B` | `B` is a left child of `A`, i.e. `A` is a parent of `B` and `A.i > B.i` _(not in Semgrex)_. | +| `A <++ B` | `B` is a right parent of `A`, i.e. `A` is a child of `B` and `A.i < B.i` _(not in Semgrex)_. | +| `A <-- B` | `B` is a left parent of `A`, i.e. `A` is a child of `B` and `A.i > B.i` _(not in Semgrex)_. | + ## DependencyMatcher.\_\_init\_\_ {#init tag="method"}