inspire-query-parser 0.0.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # This file is part of INSPIRE.
4
+ # Copyright (C) 2014-2017 CERN.
5
+ #
6
+ # INSPIRE is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # INSPIRE is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with INSPIRE. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+ # In applying this license, CERN does not waive the privileges and immunities
20
+ # granted to it by virtue of its status as an Intergovernmental Organization
21
+ # or submit itself to any jurisdiction.
22
+ """A PEG-based query parser for INSPIRE."""
23
+
24
+ from __future__ import absolute_import, print_function
25
+
26
+ from inspire_query_parser import config # noqa: F401
27
+ from inspire_query_parser.parsing_driver import parse_query # noqa: F401
@@ -0,0 +1,221 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # This file is part of INSPIRE.
4
+ # Copyright (C) 2014-2017 CERN.
5
+ #
6
+ # INSPIRE is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # INSPIRE is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with INSPIRE. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+ # In applying this license, CERN does not waive the privileges and immunities
20
+ # granted to it by virtue of its status as an Intergovernmental Organization
21
+ # or submit itself to any jurisdiction.
22
+ """AbstractSyntaxTree classes along with their concrete ones.
23
+
24
+ The module defines a generic AST element along with four AST node
25
+ categories (which act as a basis for all the concrete AST nodes) and
26
+ finally, the concrete classes which represent the output of the parsing
27
+ process.
28
+
29
+ The generic AST node categories are: - Leaf - UnaryOp -
30
+ BinaryOp - ListOp
31
+
32
+ The concrete AST nodes, represent higher level (domain specific) nodes.
33
+ """
34
+
35
+ from __future__ import unicode_literals
36
+
37
+
38
+ # #### Abstract Syntax Tree classes ####
39
+ class ASTElement(object):
40
+ """Root AbstractSyntaxTree node that acts as a stub for calling the
41
+ Visitor's `visit` dispatcher method."""
42
+
43
+ def accept(self, visitor, *args, **kwargs):
44
+ return visitor.visit(self, *args, **kwargs)
45
+
46
+
47
+ class Leaf(ASTElement):
48
+ def __init__(self, value=None):
49
+ self.value = value
50
+
51
+ def __eq__(self, other):
52
+ return type(self) is type(other) and self.value == other.value
53
+
54
+ def __repr__(self):
55
+ return '%s(%r)' % (self.__class__.__name__, self.value)
56
+
57
+ def __hash__(self):
58
+ return hash(self.value)
59
+
60
+
61
+ class UnaryOp(ASTElement):
62
+ def __init__(self, op):
63
+ self.op = op
64
+
65
+ def __eq__(self, other):
66
+ return type(self) is type(other) and self.op == other.op
67
+
68
+ def __repr__(self):
69
+ return "%s(%r)" % (self.__class__.__name__, self.op)
70
+
71
+ def __hash__(self):
72
+ return hash(self.op)
73
+
74
+
75
+ class BinaryOp(ASTElement):
76
+ def __init__(self, left, right):
77
+ self.left = left
78
+ self.right = right
79
+
80
+ def __eq__(self, other):
81
+ return (
82
+ (type(self) is type(other))
83
+ and (self.left == other.left)
84
+ and (self.right == other.right)
85
+ )
86
+
87
+ def __repr__(self):
88
+ return "%s(%s, %s)" % (
89
+ self.__class__.__name__,
90
+ repr(self.left),
91
+ repr(self.right),
92
+ )
93
+
94
+ def __hash__(self):
95
+ return hash((self.left, self.right))
96
+
97
+
98
+ class ListOp(ASTElement):
99
+ def __init__(self, children):
100
+ try:
101
+ iter(children)
102
+ except TypeError:
103
+ self.children = [children]
104
+ else:
105
+ self.children = children
106
+
107
+ def __eq__(self, other):
108
+ return type(self) is type(other) and self.children == other.children
109
+
110
+ def __repr__(self):
111
+ return "%s(%r)" % (self.__class__.__name__, self.children)
112
+
113
+ def __hash__(self):
114
+ return hash(tuple(self.children))
115
+
116
+
117
+ # Concrete Syntax Tree classes
118
+ class AndOp(BinaryOp):
119
+ pass
120
+
121
+
122
+ class OrOp(BinaryOp):
123
+ pass
124
+
125
+
126
+ class KeywordOp(BinaryOp):
127
+ pass
128
+
129
+
130
+ class NotOp(UnaryOp):
131
+ pass
132
+
133
+
134
+ class NestedKeywordOp(BinaryOp):
135
+ pass
136
+
137
+
138
+ class ValueOp(UnaryOp):
139
+ pass
140
+
141
+
142
+ class QueryWithMalformedPart(BinaryOp):
143
+ """A combination of recognized part of a query (with a parse tree) and some
144
+ malformed input.
145
+
146
+ Its left child is the recognized parse tree, while its right child
147
+ has the :class:`MalformedQuery`.
148
+ """
149
+
150
+ pass
151
+
152
+
153
+ class MalformedQuery(ListOp):
154
+ """A :class:`ListOp` with children the unrecognized words of the parser's
155
+ input."""
156
+
157
+ pass
158
+
159
+
160
+ class RangeOp(BinaryOp):
161
+ pass
162
+
163
+
164
+ class GreaterEqualThanOp(UnaryOp):
165
+ pass
166
+
167
+
168
+ class GreaterThanOp(UnaryOp):
169
+ pass
170
+
171
+
172
+ class LessThanOp(UnaryOp):
173
+ pass
174
+
175
+
176
+ class LessEqualThanOp(UnaryOp):
177
+ pass
178
+
179
+
180
+ # #### Leafs ####
181
+ class Keyword(Leaf):
182
+ pass
183
+
184
+
185
+ class GenericValue(Leaf):
186
+ """Represents a generic value, which might contain a wildcard."""
187
+
188
+ WILDCARD_TOKEN = '*'
189
+
190
+ def __init__(self, value, contains_wildcard=False):
191
+ super(GenericValue, self).__init__(value)
192
+ self.contains_wildcard = contains_wildcard
193
+
194
+ def __eq__(self, other):
195
+ return (
196
+ super(GenericValue, self).__eq__(other)
197
+ and self.contains_wildcard == other.contains_wildcard
198
+ )
199
+
200
+ def __hash__(self):
201
+ return hash((super(GenericValue, self).__hash__(), self.contains_wildcard))
202
+
203
+
204
+ class Value(GenericValue):
205
+ pass
206
+
207
+
208
+ class ExactMatchValue(Leaf):
209
+ pass
210
+
211
+
212
+ class PartialMatchValue(GenericValue):
213
+ pass
214
+
215
+
216
+ class RegexValue(Leaf):
217
+ pass
218
+
219
+
220
+ class EmptyQuery(Leaf):
221
+ pass
@@ -0,0 +1,238 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # This file is part of INSPIRE.
4
+ # Copyright (C) 2014-2017 CERN.
5
+ #
6
+ # INSPIRE is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # INSPIRE is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with INSPIRE. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+ # In applying this license, CERN does not waive the privileges and immunities
20
+ # granted to it by virtue of its status as an Intergovernmental Organization
21
+ # or submit itself to any jurisdiction.
22
+ """A collection of INSPIRE related keywords.
23
+
24
+ This dictionary has a twofold use. Primarily, the parser uses its keys
25
+ to generate INSPIRE related keywords (i.e. qualifiers) and secondly,
26
+ provides a normalization of the shortened keywords to their full
27
+ version.
28
+ """
29
+ from __future__ import unicode_literals
30
+
31
+ INSPIRE_PARSER_NONDATE_KEYWORDS = {
32
+ # Abstract
33
+ 'abstract': 'abstract',
34
+ # Address
35
+ 'address': 'address',
36
+ # Affiliation
37
+ 'affiliation': 'affiliation',
38
+ 'affil': 'affiliation',
39
+ 'aff': 'affiliation',
40
+ 'af': 'affiliation',
41
+ 'institution': 'affiliation',
42
+ 'inst': 'affiliation',
43
+ # Affiliation Id
44
+ 'affid': 'affiliation-id',
45
+ 'affiliation-id': 'affiliation-id',
46
+ # Author
47
+ 'author': 'author',
48
+ 'au': 'author',
49
+ 'a': 'author',
50
+ 'name': 'author',
51
+ # Author-Count
52
+ 'author-count': 'author-count',
53
+ 'authorcount': 'author-count',
54
+ 'ac': 'author-count',
55
+ # Cataloguer
56
+ 'cat': 'cataloguer',
57
+ # Caption
58
+ 'caption': 'caption',
59
+ # Cite, i.e. records that cite the given search term
60
+ # Cite and c: SPIRES syntax while reference is INVENIO syntax
61
+ 'cite': 'cite',
62
+ 'c': 'cite',
63
+ 'reference': 'cite',
64
+ # Citedby related
65
+ 'citedby': 'citedby', # nested keyword query
66
+ # Cited by excluding self sites, e.g. citedbyexcludingselfcites:author:M.E.Peskin.1
67
+ 'citedbyexcludingselfcites': 'citedbyexcludingselfcites',
68
+ 'citedbyx': 'citedbyexcludingselfcites',
69
+ # Cited excluding self sites, e.g. citedexcludingselfcites:50+
70
+ 'citedexcludingselfcites': 'citedexcludingselfcites',
71
+ 'cx': 'citedexcludingselfcites',
72
+ # Collaboration
73
+ 'collaboration': 'collaboration',
74
+ 'cn': 'collaboration',
75
+ # Conference number
76
+ 'cnum': 'confnumber',
77
+ # Control number
78
+ 'control_number': 'control_number',
79
+ 'recid': 'control_number',
80
+ # Country
81
+ 'country': 'country',
82
+ 'cc': 'country',
83
+ # DOI
84
+ 'doi': 'doi',
85
+ # ePrint
86
+ 'bb': 'eprint',
87
+ 'bull': 'eprint',
88
+ 'eprint': 'eprint',
89
+ 'arxiv': 'eprint',
90
+ 'arXiv': 'eprint',
91
+ # Exact-Author
92
+ 'exact-author': 'exact-author',
93
+ 'exactauthor': 'exact-author',
94
+ 'ea': 'exact-author',
95
+ # Experiment
96
+ 'experiment': 'experiment',
97
+ 'exp': 'experiment',
98
+ # Field-code
99
+ 'fc': 'field-code',
100
+ 'field-code': 'field-code',
101
+ # First-Author
102
+ 'first-author': 'first_author',
103
+ 'firstauthor': 'first_author',
104
+ 'fa': 'first_author',
105
+ # Fulltext
106
+ 'fulltext': 'fulltext',
107
+ 'ft': 'fulltext',
108
+ # SPIRES identifiers
109
+ 'irn': 'irn',
110
+ # Journal related
111
+ 'coden': 'journal',
112
+ 'journal': 'journal',
113
+ 'j': 'journal',
114
+ 'published_in': 'journal',
115
+ 'volume': 'volume',
116
+ 'vol': 'volume',
117
+ # Keyword
118
+ # keyword is Invenio style, while the rest are from SPIRES syntax.
119
+ 'keyword': 'keyword',
120
+ 'keywords': 'keyword',
121
+ 'kw': 'keyword',
122
+ 'k': 'keyword',
123
+ # Primary archive
124
+ 'primarch': 'primary_arxiv_category',
125
+ # rawref
126
+ 'rawref': 'rawref',
127
+ # Reference
128
+ 'citation': 'reference',
129
+ 'jour-vol-page': 'reference',
130
+ 'jvp': 'reference',
131
+ # Refersto operator
132
+ # Nested keyword query
133
+ 'refersto': 'refersto',
134
+ # Refers to excluding self cites,
135
+ # e.g. referstoexcludingselfcites:author:M.E.Peskin.1
136
+ # Nested keyword queries
137
+ 'referstoexcludingselfcites': 'referstoexcludingselfcites',
138
+ 'referstox': 'referstoexcludingselfcites',
139
+ # Report number
140
+ 'reportnumber': 'reportnumber',
141
+ 'report-num': 'reportnumber',
142
+ 'report': 'reportnumber',
143
+ 'rept': 'reportnumber',
144
+ 'rn': 'reportnumber',
145
+ 'r': 'reportnumber',
146
+ # Subject
147
+ 'subject': 'subject',
148
+ # Title
149
+ 'title': 'title',
150
+ 'ti': 'title',
151
+ 't': 'title',
152
+ # texkey
153
+ 'texkey': 'texkeys.raw',
154
+ # Topcite, i.e. citation count
155
+ # Cited used to be for Invenio style syntax while topcite for SPIRES
156
+ 'cited': 'topcite',
157
+ 'topcit': 'topcite',
158
+ 'topcite': 'topcite',
159
+ # Type-Code
160
+ 'type-code': 'type-code',
161
+ 'type': 'type-code',
162
+ 'tc': 'type-code',
163
+ 'ty': 'type-code',
164
+ 'scl': 'type-code',
165
+ 'ps': 'type-code',
166
+ 'collection': 'type-code',# Queries for this one include "collection published" only
167
+ }
168
+
169
+ INSPIRE_PARSER_DATE_KEYWORDS = {
170
+ # Date
171
+ 'date': 'date',
172
+ 'd': 'date',
173
+ # From queries dataset, users seem to use year and date interchangeably.
174
+ 'year': 'date',
175
+ # Date added
176
+ 'date-added': 'date-added',
177
+ 'dadd': 'date-added',
178
+ 'da': 'date-added',
179
+ # Date earliest
180
+ 'date-earliest': 'date-earliest',
181
+ 'de': 'date-earliest',
182
+ # Date updated
183
+ 'date-updated': 'date-updated',
184
+ 'dupd': 'date-updated',
185
+ 'du': 'date-updated',
186
+ # Journal year
187
+ 'journal-year': 'publication_info.year',
188
+ 'jy': 'publication_info.year',
189
+ }
190
+
191
+ INSPIRE_PARSER_KEYWORDS = INSPIRE_PARSER_NONDATE_KEYWORDS.copy()
192
+ INSPIRE_PARSER_KEYWORDS.update(INSPIRE_PARSER_DATE_KEYWORDS)
193
+ INSPIRE_KEYWORDS_SET = set(INSPIRE_PARSER_KEYWORDS.values())
194
+
195
+ # #### Date specifiers #####
196
+ DATE_TODAY_REGEX_PATTERN = 'today'
197
+ DATE_YESTERDAY_REGEX_PATTERN = 'yesterday'
198
+ DATE_LAST_MONTH_REGEX_PATTERN = 'last\s+month'
199
+ DATE_THIS_MONTH_REGEX_PATTERN = 'this\s+month'
200
+
201
+ DATE_SPECIFIERS_COLLECTION = (
202
+ DATE_TODAY_REGEX_PATTERN,
203
+ DATE_YESTERDAY_REGEX_PATTERN,
204
+ DATE_THIS_MONTH_REGEX_PATTERN,
205
+ DATE_LAST_MONTH_REGEX_PATTERN,
206
+ )
207
+ MONTH_REGEX = "|".join(
208
+ [
209
+ "january",
210
+ "jan",
211
+ "february",
212
+ "feb",
213
+ "march",
214
+ "mar",
215
+ "april",
216
+ "apr",
217
+ "may",
218
+ "june",
219
+ 'jun',
220
+ "july",
221
+ "jul",
222
+ "august",
223
+ "aug",
224
+ "september",
225
+ "sep",
226
+ "october",
227
+ "oct",
228
+ "november",
229
+ "nov",
230
+ "december",
231
+ "dec",
232
+ ]
233
+ )
234
+ # #####
235
+
236
+ ES_MUST_QUERY = "must"
237
+ ES_SHOULD_QUERY = "should"
238
+ DEFAULT_ES_OPERATOR_FOR_MALFORMED_QUERIES = ES_MUST_QUERY