kodexa 7.4.414781565138__py3-none-any.whl → 8.0.14958192442__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.
- kodexa/dataclasses/__init__.py +1 -1
- kodexa/model/__init__.py +2 -2
- kodexa/model/utils.py +1 -1
- kodexa/pipeline/pipeline.py +1 -1
- kodexa/platform/client.py +1 -2
- kodexa/selectors/__init__.py +1 -1
- kodexa/selectors/ast.py +371 -98
- kodexa/selectors/error.py +29 -0
- kodexa/selectors/kodexa-ast-visitor.py +268 -0
- kodexa/selectors/parser.py +91 -0
- kodexa/selectors/resources/KodexaSelector.interp +99 -0
- kodexa/selectors/resources/KodexaSelector.tokens +56 -0
- kodexa/selectors/resources/KodexaSelectorLexer.interp +119 -0
- kodexa/selectors/resources/KodexaSelectorLexer.py +204 -0
- kodexa/selectors/resources/KodexaSelectorLexer.tokens +56 -0
- kodexa/selectors/resources/KodexaSelectorListener.py +570 -0
- kodexa/selectors/resources/KodexaSelectorParser.py +3246 -0
- kodexa/selectors/resources/KodexaSelectorVisitor.py +323 -0
- kodexa/selectors/visitor.py +265 -0
- kodexa/steps/__init__.py +4 -2
- kodexa/steps/common.py +0 -68
- kodexa/testing/test_utils.py +1 -1
- {kodexa-7.4.414781565138.dist-info → kodexa-8.0.14958192442.dist-info}/METADATA +3 -1
- kodexa-8.0.14958192442.dist-info/RECORD +53 -0
- {kodexa-7.4.414781565138.dist-info → kodexa-8.0.14958192442.dist-info}/WHEEL +1 -1
- kodexa/model/model.py +0 -3259
- kodexa/model/persistence.py +0 -2017
- kodexa/selectors/core.py +0 -124
- kodexa/selectors/lexrules.py +0 -137
- kodexa/selectors/lextab.py +0 -83
- kodexa/selectors/lextab.pyi +0 -1
- kodexa/selectors/parserules.py +0 -414
- kodexa/selectors/parserules.pyi +0 -1
- kodexa/selectors/parsetab.py +0 -90
- kodexa/selectors/parsetab.pyi +0 -1
- kodexa-7.4.414781565138.dist-info/RECORD +0 -51
- {kodexa-7.4.414781565138.dist-info → kodexa-8.0.14958192442.dist-info}/LICENSE +0 -0
@@ -0,0 +1,323 @@
|
|
1
|
+
# Generated from resources/KodexaSelector.g4 by ANTLR 4.13.1
|
2
|
+
from antlr4 import *
|
3
|
+
if "." in __name__:
|
4
|
+
from .KodexaSelectorParser import KodexaSelectorParser
|
5
|
+
else:
|
6
|
+
from KodexaSelectorParser import KodexaSelectorParser
|
7
|
+
|
8
|
+
# This class defines a complete generic visitor for a parse tree produced by KodexaSelectorParser.
|
9
|
+
|
10
|
+
class KodexaSelectorVisitor(ParseTreeVisitor):
|
11
|
+
|
12
|
+
# Visit a parse tree produced by KodexaSelectorParser#xpath.
|
13
|
+
def visitXpath(self, ctx:KodexaSelectorParser.XpathContext):
|
14
|
+
return self.visitChildren(ctx)
|
15
|
+
|
16
|
+
|
17
|
+
# Visit a parse tree produced by KodexaSelectorParser#equalsExpr.
|
18
|
+
def visitEqualsExpr(self, ctx:KodexaSelectorParser.EqualsExprContext):
|
19
|
+
return self.visitChildren(ctx)
|
20
|
+
|
21
|
+
|
22
|
+
# Visit a parse tree produced by KodexaSelectorParser#subtractExpr.
|
23
|
+
def visitSubtractExpr(self, ctx:KodexaSelectorParser.SubtractExprContext):
|
24
|
+
return self.visitChildren(ctx)
|
25
|
+
|
26
|
+
|
27
|
+
# Visit a parse tree produced by KodexaSelectorParser#intersectExpr.
|
28
|
+
def visitIntersectExpr(self, ctx:KodexaSelectorParser.IntersectExprContext):
|
29
|
+
return self.visitChildren(ctx)
|
30
|
+
|
31
|
+
|
32
|
+
# Visit a parse tree produced by KodexaSelectorParser#directNameTest.
|
33
|
+
def visitDirectNameTest(self, ctx:KodexaSelectorParser.DirectNameTestContext):
|
34
|
+
return self.visitChildren(ctx)
|
35
|
+
|
36
|
+
|
37
|
+
# Visit a parse tree produced by KodexaSelectorParser#orExpr.
|
38
|
+
def visitOrExpr(self, ctx:KodexaSelectorParser.OrExprContext):
|
39
|
+
return self.visitChildren(ctx)
|
40
|
+
|
41
|
+
|
42
|
+
# Visit a parse tree produced by KodexaSelectorParser#absolutePathExpr.
|
43
|
+
def visitAbsolutePathExpr(self, ctx:KodexaSelectorParser.AbsolutePathExprContext):
|
44
|
+
return self.visitChildren(ctx)
|
45
|
+
|
46
|
+
|
47
|
+
# Visit a parse tree produced by KodexaSelectorParser#funcCallExpr.
|
48
|
+
def visitFuncCallExpr(self, ctx:KodexaSelectorParser.FuncCallExprContext):
|
49
|
+
return self.visitChildren(ctx)
|
50
|
+
|
51
|
+
|
52
|
+
# Visit a parse tree produced by KodexaSelectorParser#unionExpr.
|
53
|
+
def visitUnionExpr(self, ctx:KodexaSelectorParser.UnionExprContext):
|
54
|
+
return self.visitChildren(ctx)
|
55
|
+
|
56
|
+
|
57
|
+
# Visit a parse tree produced by KodexaSelectorParser#relationalExpr.
|
58
|
+
def visitRelationalExpr(self, ctx:KodexaSelectorParser.RelationalExprContext):
|
59
|
+
return self.visitChildren(ctx)
|
60
|
+
|
61
|
+
|
62
|
+
# Visit a parse tree produced by KodexaSelectorParser#pipelineExpr.
|
63
|
+
def visitPipelineExpr(self, ctx:KodexaSelectorParser.PipelineExprContext):
|
64
|
+
return self.visitChildren(ctx)
|
65
|
+
|
66
|
+
|
67
|
+
# Visit a parse tree produced by KodexaSelectorParser#relativePathExpr.
|
68
|
+
def visitRelativePathExpr(self, ctx:KodexaSelectorParser.RelativePathExprContext):
|
69
|
+
return self.visitChildren(ctx)
|
70
|
+
|
71
|
+
|
72
|
+
# Visit a parse tree produced by KodexaSelectorParser#rootNameTest.
|
73
|
+
def visitRootNameTest(self, ctx:KodexaSelectorParser.RootNameTestContext):
|
74
|
+
return self.visitChildren(ctx)
|
75
|
+
|
76
|
+
|
77
|
+
# Visit a parse tree produced by KodexaSelectorParser#unaryMinusExpr.
|
78
|
+
def visitUnaryMinusExpr(self, ctx:KodexaSelectorParser.UnaryMinusExprContext):
|
79
|
+
return self.visitChildren(ctx)
|
80
|
+
|
81
|
+
|
82
|
+
# Visit a parse tree produced by KodexaSelectorParser#abbrevAbsPathExpr.
|
83
|
+
def visitAbbrevAbsPathExpr(self, ctx:KodexaSelectorParser.AbbrevAbsPathExprContext):
|
84
|
+
return self.visitChildren(ctx)
|
85
|
+
|
86
|
+
|
87
|
+
# Visit a parse tree produced by KodexaSelectorParser#addExpr.
|
88
|
+
def visitAddExpr(self, ctx:KodexaSelectorParser.AddExprContext):
|
89
|
+
return self.visitChildren(ctx)
|
90
|
+
|
91
|
+
|
92
|
+
# Visit a parse tree produced by KodexaSelectorParser#filterExpression.
|
93
|
+
def visitFilterExpression(self, ctx:KodexaSelectorParser.FilterExpressionContext):
|
94
|
+
return self.visitChildren(ctx)
|
95
|
+
|
96
|
+
|
97
|
+
# Visit a parse tree produced by KodexaSelectorParser#booleanLiteralExpr.
|
98
|
+
def visitBooleanLiteralExpr(self, ctx:KodexaSelectorParser.BooleanLiteralExprContext):
|
99
|
+
return self.visitChildren(ctx)
|
100
|
+
|
101
|
+
|
102
|
+
# Visit a parse tree produced by KodexaSelectorParser#pathBinaryExpr.
|
103
|
+
def visitPathBinaryExpr(self, ctx:KodexaSelectorParser.PathBinaryExprContext):
|
104
|
+
return self.visitChildren(ctx)
|
105
|
+
|
106
|
+
|
107
|
+
# Visit a parse tree produced by KodexaSelectorParser#andExpr.
|
108
|
+
def visitAndExpr(self, ctx:KodexaSelectorParser.AndExprContext):
|
109
|
+
return self.visitChildren(ctx)
|
110
|
+
|
111
|
+
|
112
|
+
# Visit a parse tree produced by KodexaSelectorParser#rootOnly.
|
113
|
+
def visitRootOnly(self, ctx:KodexaSelectorParser.RootOnlyContext):
|
114
|
+
return self.visitChildren(ctx)
|
115
|
+
|
116
|
+
|
117
|
+
# Visit a parse tree produced by KodexaSelectorParser#rootPath.
|
118
|
+
def visitRootPath(self, ctx:KodexaSelectorParser.RootPathContext):
|
119
|
+
return self.visitChildren(ctx)
|
120
|
+
|
121
|
+
|
122
|
+
# Visit a parse tree produced by KodexaSelectorParser#abbreviatedAbsoluteLocationPath.
|
123
|
+
def visitAbbreviatedAbsoluteLocationPath(self, ctx:KodexaSelectorParser.AbbreviatedAbsoluteLocationPathContext):
|
124
|
+
return self.visitChildren(ctx)
|
125
|
+
|
126
|
+
|
127
|
+
# Visit a parse tree produced by KodexaSelectorParser#singleStep.
|
128
|
+
def visitSingleStep(self, ctx:KodexaSelectorParser.SingleStepContext):
|
129
|
+
return self.visitChildren(ctx)
|
130
|
+
|
131
|
+
|
132
|
+
# Visit a parse tree produced by KodexaSelectorParser#pathStep.
|
133
|
+
def visitPathStep(self, ctx:KodexaSelectorParser.PathStepContext):
|
134
|
+
return self.visitChildren(ctx)
|
135
|
+
|
136
|
+
|
137
|
+
# Visit a parse tree produced by KodexaSelectorParser#abbrevPathStep.
|
138
|
+
def visitAbbrevPathStep(self, ctx:KodexaSelectorParser.AbbrevPathStepContext):
|
139
|
+
return self.visitChildren(ctx)
|
140
|
+
|
141
|
+
|
142
|
+
# Visit a parse tree produced by KodexaSelectorParser#nodeTestStep.
|
143
|
+
def visitNodeTestStep(self, ctx:KodexaSelectorParser.NodeTestStepContext):
|
144
|
+
return self.visitChildren(ctx)
|
145
|
+
|
146
|
+
|
147
|
+
# Visit a parse tree produced by KodexaSelectorParser#nodeTestPredStep.
|
148
|
+
def visitNodeTestPredStep(self, ctx:KodexaSelectorParser.NodeTestPredStepContext):
|
149
|
+
return self.visitChildren(ctx)
|
150
|
+
|
151
|
+
|
152
|
+
# Visit a parse tree produced by KodexaSelectorParser#axisNodeTestStep.
|
153
|
+
def visitAxisNodeTestStep(self, ctx:KodexaSelectorParser.AxisNodeTestStepContext):
|
154
|
+
return self.visitChildren(ctx)
|
155
|
+
|
156
|
+
|
157
|
+
# Visit a parse tree produced by KodexaSelectorParser#axisNodeTestPredStep.
|
158
|
+
def visitAxisNodeTestPredStep(self, ctx:KodexaSelectorParser.AxisNodeTestPredStepContext):
|
159
|
+
return self.visitChildren(ctx)
|
160
|
+
|
161
|
+
|
162
|
+
# Visit a parse tree produced by KodexaSelectorParser#selfStep.
|
163
|
+
def visitSelfStep(self, ctx:KodexaSelectorParser.SelfStepContext):
|
164
|
+
return self.visitChildren(ctx)
|
165
|
+
|
166
|
+
|
167
|
+
# Visit a parse tree produced by KodexaSelectorParser#parentStep.
|
168
|
+
def visitParentStep(self, ctx:KodexaSelectorParser.ParentStepContext):
|
169
|
+
return self.visitChildren(ctx)
|
170
|
+
|
171
|
+
|
172
|
+
# Visit a parse tree produced by KodexaSelectorParser#fullAxis.
|
173
|
+
def visitFullAxis(self, ctx:KodexaSelectorParser.FullAxisContext):
|
174
|
+
return self.visitChildren(ctx)
|
175
|
+
|
176
|
+
|
177
|
+
# Visit a parse tree produced by KodexaSelectorParser#attrAxis.
|
178
|
+
def visitAttrAxis(self, ctx:KodexaSelectorParser.AttrAxisContext):
|
179
|
+
return self.visitChildren(ctx)
|
180
|
+
|
181
|
+
|
182
|
+
# Visit a parse tree produced by KodexaSelectorParser#nameTestNode.
|
183
|
+
def visitNameTestNode(self, ctx:KodexaSelectorParser.NameTestNodeContext):
|
184
|
+
return self.visitChildren(ctx)
|
185
|
+
|
186
|
+
|
187
|
+
# Visit a parse tree produced by KodexaSelectorParser#anyNameTest.
|
188
|
+
def visitAnyNameTest(self, ctx:KodexaSelectorParser.AnyNameTestContext):
|
189
|
+
return self.visitChildren(ctx)
|
190
|
+
|
191
|
+
|
192
|
+
# Visit a parse tree produced by KodexaSelectorParser#prefixedAnyNameTest.
|
193
|
+
def visitPrefixedAnyNameTest(self, ctx:KodexaSelectorParser.PrefixedAnyNameTestContext):
|
194
|
+
return self.visitChildren(ctx)
|
195
|
+
|
196
|
+
|
197
|
+
# Visit a parse tree produced by KodexaSelectorParser#qNameTest.
|
198
|
+
def visitQNameTest(self, ctx:KodexaSelectorParser.QNameTestContext):
|
199
|
+
return self.visitChildren(ctx)
|
200
|
+
|
201
|
+
|
202
|
+
# Visit a parse tree produced by KodexaSelectorParser#prefixedName.
|
203
|
+
def visitPrefixedName(self, ctx:KodexaSelectorParser.PrefixedNameContext):
|
204
|
+
return self.visitChildren(ctx)
|
205
|
+
|
206
|
+
|
207
|
+
# Visit a parse tree produced by KodexaSelectorParser#simpleName.
|
208
|
+
def visitSimpleName(self, ctx:KodexaSelectorParser.SimpleNameContext):
|
209
|
+
return self.visitChildren(ctx)
|
210
|
+
|
211
|
+
|
212
|
+
# Visit a parse tree produced by KodexaSelectorParser#funcCallFilter.
|
213
|
+
def visitFuncCallFilter(self, ctx:KodexaSelectorParser.FuncCallFilterContext):
|
214
|
+
return self.visitChildren(ctx)
|
215
|
+
|
216
|
+
|
217
|
+
# Visit a parse tree produced by KodexaSelectorParser#booleanFilter.
|
218
|
+
def visitBooleanFilter(self, ctx:KodexaSelectorParser.BooleanFilterContext):
|
219
|
+
return self.visitChildren(ctx)
|
220
|
+
|
221
|
+
|
222
|
+
# Visit a parse tree produced by KodexaSelectorParser#groupedFilter.
|
223
|
+
def visitGroupedFilter(self, ctx:KodexaSelectorParser.GroupedFilterContext):
|
224
|
+
return self.visitChildren(ctx)
|
225
|
+
|
226
|
+
|
227
|
+
# Visit a parse tree produced by KodexaSelectorParser#predicatedFilter.
|
228
|
+
def visitPredicatedFilter(self, ctx:KodexaSelectorParser.PredicatedFilterContext):
|
229
|
+
return self.visitChildren(ctx)
|
230
|
+
|
231
|
+
|
232
|
+
# Visit a parse tree produced by KodexaSelectorParser#numberFilter.
|
233
|
+
def visitNumberFilter(self, ctx:KodexaSelectorParser.NumberFilterContext):
|
234
|
+
return self.visitChildren(ctx)
|
235
|
+
|
236
|
+
|
237
|
+
# Visit a parse tree produced by KodexaSelectorParser#varRefFilter.
|
238
|
+
def visitVarRefFilter(self, ctx:KodexaSelectorParser.VarRefFilterContext):
|
239
|
+
return self.visitChildren(ctx)
|
240
|
+
|
241
|
+
|
242
|
+
# Visit a parse tree produced by KodexaSelectorParser#literalFilter.
|
243
|
+
def visitLiteralFilter(self, ctx:KodexaSelectorParser.LiteralFilterContext):
|
244
|
+
return self.visitChildren(ctx)
|
245
|
+
|
246
|
+
|
247
|
+
# Visit a parse tree produced by KodexaSelectorParser#singlePredicate.
|
248
|
+
def visitSinglePredicate(self, ctx:KodexaSelectorParser.SinglePredicateContext):
|
249
|
+
return self.visitChildren(ctx)
|
250
|
+
|
251
|
+
|
252
|
+
# Visit a parse tree produced by KodexaSelectorParser#multiplePredicate.
|
253
|
+
def visitMultiplePredicate(self, ctx:KodexaSelectorParser.MultiplePredicateContext):
|
254
|
+
return self.visitChildren(ctx)
|
255
|
+
|
256
|
+
|
257
|
+
# Visit a parse tree produced by KodexaSelectorParser#exprPredicate.
|
258
|
+
def visitExprPredicate(self, ctx:KodexaSelectorParser.ExprPredicateContext):
|
259
|
+
return self.visitChildren(ctx)
|
260
|
+
|
261
|
+
|
262
|
+
# Visit a parse tree produced by KodexaSelectorParser#variableReference.
|
263
|
+
def visitVariableReference(self, ctx:KodexaSelectorParser.VariableReferenceContext):
|
264
|
+
return self.visitChildren(ctx)
|
265
|
+
|
266
|
+
|
267
|
+
# Visit a parse tree produced by KodexaSelectorParser#number.
|
268
|
+
def visitNumber(self, ctx:KodexaSelectorParser.NumberContext):
|
269
|
+
return self.visitChildren(ctx)
|
270
|
+
|
271
|
+
|
272
|
+
# Visit a parse tree produced by KodexaSelectorParser#booleanLiteral.
|
273
|
+
def visitBooleanLiteral(self, ctx:KodexaSelectorParser.BooleanLiteralContext):
|
274
|
+
return self.visitChildren(ctx)
|
275
|
+
|
276
|
+
|
277
|
+
# Visit a parse tree produced by KodexaSelectorParser#functionCall.
|
278
|
+
def visitFunctionCall(self, ctx:KodexaSelectorParser.FunctionCallContext):
|
279
|
+
return self.visitChildren(ctx)
|
280
|
+
|
281
|
+
|
282
|
+
# Visit a parse tree produced by KodexaSelectorParser#trueFunction.
|
283
|
+
def visitTrueFunction(self, ctx:KodexaSelectorParser.TrueFunctionContext):
|
284
|
+
return self.visitChildren(ctx)
|
285
|
+
|
286
|
+
|
287
|
+
# Visit a parse tree produced by KodexaSelectorParser#falseFunction.
|
288
|
+
def visitFalseFunction(self, ctx:KodexaSelectorParser.FalseFunctionContext):
|
289
|
+
return self.visitChildren(ctx)
|
290
|
+
|
291
|
+
|
292
|
+
# Visit a parse tree produced by KodexaSelectorParser#funcQName.
|
293
|
+
def visitFuncQName(self, ctx:KodexaSelectorParser.FuncQNameContext):
|
294
|
+
return self.visitChildren(ctx)
|
295
|
+
|
296
|
+
|
297
|
+
# Visit a parse tree produced by KodexaSelectorParser#emptyArgs.
|
298
|
+
def visitEmptyArgs(self, ctx:KodexaSelectorParser.EmptyArgsContext):
|
299
|
+
return self.visitChildren(ctx)
|
300
|
+
|
301
|
+
|
302
|
+
# Visit a parse tree produced by KodexaSelectorParser#argsList.
|
303
|
+
def visitArgsList(self, ctx:KodexaSelectorParser.ArgsListContext):
|
304
|
+
return self.visitChildren(ctx)
|
305
|
+
|
306
|
+
|
307
|
+
# Visit a parse tree produced by KodexaSelectorParser#singleArg.
|
308
|
+
def visitSingleArg(self, ctx:KodexaSelectorParser.SingleArgContext):
|
309
|
+
return self.visitChildren(ctx)
|
310
|
+
|
311
|
+
|
312
|
+
# Visit a parse tree produced by KodexaSelectorParser#multipleArgs.
|
313
|
+
def visitMultipleArgs(self, ctx:KodexaSelectorParser.MultipleArgsContext):
|
314
|
+
return self.visitChildren(ctx)
|
315
|
+
|
316
|
+
|
317
|
+
# Visit a parse tree produced by KodexaSelectorParser#pathSep.
|
318
|
+
def visitPathSep(self, ctx:KodexaSelectorParser.PathSepContext):
|
319
|
+
return self.visitChildren(ctx)
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
del KodexaSelectorParser
|
@@ -0,0 +1,265 @@
|
|
1
|
+
from antlr4 import *
|
2
|
+
from kodexa.selectors.resources.KodexaSelectorParser import KodexaSelectorParser
|
3
|
+
from kodexa.selectors.resources.KodexaSelectorVisitor import KodexaSelectorVisitor
|
4
|
+
import kodexa.selectors.ast as ast
|
5
|
+
class KodexaASTVisitor(KodexaSelectorVisitor):
|
6
|
+
"""
|
7
|
+
Visitor implementation for building an AST from an ANTLR parse tree.
|
8
|
+
This converts the ANTLR parse tree to the same AST structure used in the original code.
|
9
|
+
"""
|
10
|
+
|
11
|
+
def visitOrExpr(self, ctx:KodexaSelectorParser.OrExprContext):
|
12
|
+
left = self.visit(ctx.expr(0))
|
13
|
+
right = self.visit(ctx.expr(1))
|
14
|
+
return ast.BinaryExpression(left, 'or', right)
|
15
|
+
|
16
|
+
def visitAndExpr(self, ctx:KodexaSelectorParser.AndExprContext):
|
17
|
+
left = self.visit(ctx.expr(0))
|
18
|
+
right = self.visit(ctx.expr(1))
|
19
|
+
return ast.BinaryExpression(left, 'and', right)
|
20
|
+
|
21
|
+
def visitEqualsExpr(self, ctx:KodexaSelectorParser.EqualsExprContext):
|
22
|
+
left = self.visit(ctx.expr(0))
|
23
|
+
right = self.visit(ctx.expr(1))
|
24
|
+
op = ctx.EQUALS().getText()
|
25
|
+
return ast.BinaryExpression(left, op, right)
|
26
|
+
|
27
|
+
def visitRelationalExpr(self, ctx:KodexaSelectorParser.RelationalExprContext):
|
28
|
+
left = self.visit(ctx.expr(0))
|
29
|
+
right = self.visit(ctx.expr(1))
|
30
|
+
op = ctx.REL_OP().getText()
|
31
|
+
return ast.BinaryExpression(left, op, right)
|
32
|
+
|
33
|
+
def visitAddExpr(self, ctx:KodexaSelectorParser.AddExprContext):
|
34
|
+
left = self.visit(ctx.expr(0))
|
35
|
+
right = self.visit(ctx.expr(1))
|
36
|
+
return ast.BinaryExpression(left, '+', right)
|
37
|
+
|
38
|
+
def visitSubtractExpr(self, ctx:KodexaSelectorParser.SubtractExprContext):
|
39
|
+
left = self.visit(ctx.expr(0))
|
40
|
+
right = self.visit(ctx.expr(1))
|
41
|
+
return ast.BinaryExpression(left, '-', right)
|
42
|
+
|
43
|
+
def visitUnionExpr(self, ctx:KodexaSelectorParser.UnionExprContext):
|
44
|
+
left = self.visit(ctx.expr(0))
|
45
|
+
right = self.visit(ctx.expr(1))
|
46
|
+
return ast.BinaryExpression(left, '|', right)
|
47
|
+
|
48
|
+
def visitIntersectExpr(self, ctx:KodexaSelectorParser.IntersectExprContext):
|
49
|
+
left = self.visit(ctx.expr(0))
|
50
|
+
right = self.visit(ctx.expr(1))
|
51
|
+
return ast.BinaryExpression(left, 'intersect', right)
|
52
|
+
|
53
|
+
def visitUnaryMinusExpr(self, ctx:KodexaSelectorParser.UnaryMinusExprContext):
|
54
|
+
operand = self.visit(ctx.expr())
|
55
|
+
return ast.UnaryExpression('-', operand)
|
56
|
+
|
57
|
+
def visitPipelineExpr(self, ctx:KodexaSelectorParser.PipelineExprContext):
|
58
|
+
left = self.visit(ctx.expr(0))
|
59
|
+
right = self.visit(ctx.expr(1))
|
60
|
+
return ast.PipelineExpression(left, 'stream', right)
|
61
|
+
|
62
|
+
def visitPathBinaryExpr(self, ctx:KodexaSelectorParser.PathBinaryExprContext):
|
63
|
+
left = self.visit(ctx.filterExpr())
|
64
|
+
op = self.visit(ctx.pathSep())
|
65
|
+
right = self.visit(ctx.relativeLocationPath())
|
66
|
+
return ast.BinaryExpression(left, op, right)
|
67
|
+
|
68
|
+
def visitBooleanLiteralExpr(self, ctx:KodexaSelectorParser.BooleanLiteralExprContext):
|
69
|
+
return self.visit(ctx.booleanLiteral())
|
70
|
+
|
71
|
+
def visitRootOnly(self, ctx:KodexaSelectorParser.RootOnlyContext):
|
72
|
+
return ast.AbsolutePath('/')
|
73
|
+
|
74
|
+
def visitRootPath(self, ctx:KodexaSelectorParser.RootPathContext):
|
75
|
+
relative = self.visit(ctx.relativeLocationPath())
|
76
|
+
return ast.AbsolutePath('/', relative)
|
77
|
+
|
78
|
+
def visitAbbreviatedAbsoluteLocationPath(self, ctx:KodexaSelectorParser.AbbreviatedAbsoluteLocationPathContext):
|
79
|
+
relative = self.visit(ctx.relativeLocationPath())
|
80
|
+
return ast.AbsolutePath('//', relative)
|
81
|
+
|
82
|
+
def visitSingleStep(self, ctx:KodexaSelectorParser.SingleStepContext):
|
83
|
+
return self.visit(ctx.step())
|
84
|
+
|
85
|
+
def visitPathStep(self, ctx:KodexaSelectorParser.PathStepContext):
|
86
|
+
left = self.visit(ctx.relativeLocationPath())
|
87
|
+
right = self.visit(ctx.step())
|
88
|
+
return ast.BinaryExpression(left, '/', right)
|
89
|
+
|
90
|
+
def visitAbbrevPathStep(self, ctx:KodexaSelectorParser.AbbrevPathStepContext):
|
91
|
+
left = self.visit(ctx.relativeLocationPath())
|
92
|
+
right = self.visit(ctx.step())
|
93
|
+
return ast.BinaryExpression(left, '//', right)
|
94
|
+
|
95
|
+
def visitNodeTestStep(self, ctx:KodexaSelectorParser.NodeTestStepContext):
|
96
|
+
node_test = self.visit(ctx.nodeTest())
|
97
|
+
return ast.Step(None, node_test, [])
|
98
|
+
|
99
|
+
def visitNodeTestPredStep(self, ctx:KodexaSelectorParser.NodeTestPredStepContext):
|
100
|
+
node_test = self.visit(ctx.nodeTest())
|
101
|
+
predicates = self.visit(ctx.predicateList())
|
102
|
+
return ast.Step(None, node_test, predicates)
|
103
|
+
|
104
|
+
def visitAxisNodeTestStep(self, ctx:KodexaSelectorParser.AxisNodeTestStepContext):
|
105
|
+
axis = self.visit(ctx.axisSpecifier())
|
106
|
+
node_test = self.visit(ctx.nodeTest())
|
107
|
+
return ast.Step(axis, node_test, [])
|
108
|
+
|
109
|
+
def visitAxisNodeTestPredStep(self, ctx:KodexaSelectorParser.AxisNodeTestPredStepContext):
|
110
|
+
axis = self.visit(ctx.axisSpecifier())
|
111
|
+
node_test = self.visit(ctx.nodeTest())
|
112
|
+
predicates = self.visit(ctx.predicateList())
|
113
|
+
return ast.Step(axis, node_test, predicates)
|
114
|
+
|
115
|
+
def visitSelfStep(self, ctx:KodexaSelectorParser.SelfStepContext):
|
116
|
+
return ast.AbbreviatedStep('.')
|
117
|
+
|
118
|
+
def visitParentStep(self, ctx:KodexaSelectorParser.ParentStepContext):
|
119
|
+
return ast.AbbreviatedStep('..')
|
120
|
+
|
121
|
+
def visitFullAxis(self, ctx:KodexaSelectorParser.FullAxisContext):
|
122
|
+
return ctx.AXISNAME().getText()
|
123
|
+
|
124
|
+
def visitAttrAxis(self, ctx:KodexaSelectorParser.AttrAxisContext):
|
125
|
+
return '@'
|
126
|
+
|
127
|
+
def visitNameTestNode(self, ctx:KodexaSelectorParser.NameTestNodeContext):
|
128
|
+
return self.visit(ctx.nameTest())
|
129
|
+
|
130
|
+
def visitAnyNameTest(self, ctx:KodexaSelectorParser.AnyNameTestContext):
|
131
|
+
return ast.NameTest(None, '*')
|
132
|
+
|
133
|
+
def visitPrefixedAnyNameTest(self, ctx:KodexaSelectorParser.PrefixedAnyNameTestContext):
|
134
|
+
prefix = ctx.NCNAME().getText()
|
135
|
+
return ast.NameTest(prefix, '*')
|
136
|
+
|
137
|
+
def visitQNameTest(self, ctx:KodexaSelectorParser.QNameTestContext):
|
138
|
+
qname = self.visit(ctx.qName())
|
139
|
+
return ast.NameTest(qname[0], qname[1])
|
140
|
+
|
141
|
+
def visitPrefixedName(self, ctx:KodexaSelectorParser.PrefixedNameContext):
|
142
|
+
prefix = ctx.NCNAME(0).getText()
|
143
|
+
name = ctx.NCNAME(1).getText()
|
144
|
+
return (prefix, name)
|
145
|
+
|
146
|
+
def visitSimpleName(self, ctx:KodexaSelectorParser.SimpleNameContext):
|
147
|
+
return (None, ctx.NCNAME().getText())
|
148
|
+
|
149
|
+
def visitVarRefFilter(self, ctx:KodexaSelectorParser.VarRefFilterContext):
|
150
|
+
return self.visit(ctx.variableReference())
|
151
|
+
|
152
|
+
def visitLiteralFilter(self, ctx:KodexaSelectorParser.LiteralFilterContext):
|
153
|
+
literal = ctx.LITERAL().getText()
|
154
|
+
return literal[1:-1] # Remove quotes
|
155
|
+
|
156
|
+
def visitBooleanFilter(self, ctx:KodexaSelectorParser.BooleanFilterContext):
|
157
|
+
return self.visit(ctx.booleanLiteral())
|
158
|
+
|
159
|
+
def visitBooleanLiteral(self, ctx:KodexaSelectorParser.BooleanLiteralContext):
|
160
|
+
if ctx.TRUE() is not None:
|
161
|
+
return True
|
162
|
+
else:
|
163
|
+
return False
|
164
|
+
|
165
|
+
def visitNumberFilter(self, ctx:KodexaSelectorParser.NumberFilterContext):
|
166
|
+
return self.visit(ctx.number())
|
167
|
+
|
168
|
+
def visitFuncCallFilter(self, ctx:KodexaSelectorParser.FuncCallFilterContext):
|
169
|
+
return self.visit(ctx.functionCall())
|
170
|
+
|
171
|
+
def visitGroupedFilter(self, ctx:KodexaSelectorParser.GroupedFilterContext):
|
172
|
+
return self.visit(ctx.expr())
|
173
|
+
|
174
|
+
def visitPredicatedFilter(self, ctx:KodexaSelectorParser.PredicatedFilterContext):
|
175
|
+
base = self.visit(ctx.filterExpr())
|
176
|
+
predicate = self.visit(ctx.predicate())
|
177
|
+
|
178
|
+
if not hasattr(base, 'append_predicate'):
|
179
|
+
base = ast.PredicatedExpression(base)
|
180
|
+
|
181
|
+
base.append_predicate(predicate)
|
182
|
+
return base
|
183
|
+
|
184
|
+
def visitSinglePredicate(self, ctx:KodexaSelectorParser.SinglePredicateContext):
|
185
|
+
return [self.visit(ctx.predicate())]
|
186
|
+
|
187
|
+
def visitMultiplePredicate(self, ctx:KodexaSelectorParser.MultiplePredicateContext):
|
188
|
+
predicates = self.visit(ctx.predicateList())
|
189
|
+
predicates.append(self.visit(ctx.predicate()))
|
190
|
+
return predicates
|
191
|
+
|
192
|
+
def visitPredicate(self, ctx:KodexaSelectorParser.PredicateContext):
|
193
|
+
return self.visit(ctx.expr())
|
194
|
+
|
195
|
+
def visitVariableReference(self, ctx:KodexaSelectorParser.VariableReferenceContext):
|
196
|
+
qname = self.visit(ctx.qName())
|
197
|
+
return ast.VariableReference(qname)
|
198
|
+
|
199
|
+
def visitNumber(self, ctx:KodexaSelectorParser.NumberContext):
|
200
|
+
if ctx.FLOAT() is not None:
|
201
|
+
return float(ctx.FLOAT().getText())
|
202
|
+
else:
|
203
|
+
return int(ctx.INTEGER().getText())
|
204
|
+
|
205
|
+
def visitFuncQName(self, ctx:KodexaSelectorParser.FuncQNameContext):
|
206
|
+
# Extract the function name from the context
|
207
|
+
func_name = ctx.getText()
|
208
|
+
# Return as (prefix, name) tuple with no prefix
|
209
|
+
return (None, func_name)
|
210
|
+
|
211
|
+
def visitTrueFunction(self, ctx:KodexaSelectorParser.TrueFunctionContext):
|
212
|
+
args = self.visit(ctx.formalArguments())
|
213
|
+
return ast.FunctionCall(None, "true", args)
|
214
|
+
|
215
|
+
def visitFalseFunction(self, ctx:KodexaSelectorParser.FalseFunctionContext):
|
216
|
+
args = self.visit(ctx.formalArguments())
|
217
|
+
return ast.FunctionCall(None, "false", args)
|
218
|
+
|
219
|
+
def visitFunctionCall(self, ctx:KodexaSelectorParser.FunctionCallContext):
|
220
|
+
if hasattr(ctx, 'builtInFunctionCall') and ctx.builtInFunctionCall() is not None:
|
221
|
+
return self.visit(ctx.builtInFunctionCall())
|
222
|
+
else:
|
223
|
+
qname = self.visit(ctx.funcQName())
|
224
|
+
args = self.visit(ctx.formalArguments())
|
225
|
+
return ast.FunctionCall(qname[0], qname[1], args)
|
226
|
+
|
227
|
+
def visitEmptyArgs(self, ctx:KodexaSelectorParser.EmptyArgsContext):
|
228
|
+
return []
|
229
|
+
|
230
|
+
def visitArgsList(self, ctx:KodexaSelectorParser.ArgsListContext):
|
231
|
+
return self.visit(ctx.argumentList())
|
232
|
+
|
233
|
+
def visitSingleArg(self, ctx:KodexaSelectorParser.SingleArgContext):
|
234
|
+
return [self.visit(ctx.expr())]
|
235
|
+
|
236
|
+
def visitMultipleArgs(self, ctx:KodexaSelectorParser.MultipleArgsContext):
|
237
|
+
args = self.visit(ctx.argumentList())
|
238
|
+
args.append(self.visit(ctx.expr()))
|
239
|
+
return args
|
240
|
+
|
241
|
+
def visitPathSep(self, ctx:KodexaSelectorParser.PathSepContext):
|
242
|
+
if ctx.PATH_SEP() is not None:
|
243
|
+
return '/'
|
244
|
+
else:
|
245
|
+
return '//'
|
246
|
+
|
247
|
+
def visitFuncCallExpr(self, ctx:KodexaSelectorParser.FuncCallExprContext):
|
248
|
+
return self.visit(ctx.functionCall())
|
249
|
+
|
250
|
+
# Add default implementations for any missing visit methods
|
251
|
+
def visitChildren(self, ctx):
|
252
|
+
result = self.defaultResult()
|
253
|
+
n = ctx.getChildCount()
|
254
|
+
for i in range(n):
|
255
|
+
if not ctx.getChild(i).getText() in ['{', '}', ';']:
|
256
|
+
c = ctx.getChild(i)
|
257
|
+
childResult = c.accept(self)
|
258
|
+
result = self.aggregateResult(result, childResult)
|
259
|
+
return result
|
260
|
+
|
261
|
+
def defaultResult(self):
|
262
|
+
return None
|
263
|
+
|
264
|
+
def aggregateResult(self, aggregate, nextResult):
|
265
|
+
return nextResult if nextResult is not None else aggregate
|
kodexa/steps/__init__.py
CHANGED
kodexa/steps/common.py
CHANGED
@@ -21,74 +21,6 @@ class KodexaProcessingException(Exception):
|
|
21
21
|
def __str__(self):
|
22
22
|
return f"{self.message} {self.description}"
|
23
23
|
|
24
|
-
|
25
|
-
class NodeTagger:
|
26
|
-
"""A node tagger allows you to provide a type and content regular expression and then
|
27
|
-
tag content in all matching nodes.
|
28
|
-
|
29
|
-
It allows for multiple matching groups to be defined, also the ability to use all content
|
30
|
-
and also just tag the node (ignoring the matching groups)
|
31
|
-
"""
|
32
|
-
|
33
|
-
def __init__(
|
34
|
-
self,
|
35
|
-
selector,
|
36
|
-
tag_to_apply,
|
37
|
-
content_re=".*",
|
38
|
-
use_all_content=True,
|
39
|
-
node_only=False,
|
40
|
-
node_tag_uuid=None,
|
41
|
-
):
|
42
|
-
self.selector = selector
|
43
|
-
"""The selector to use to find the node(s) to tag"""
|
44
|
-
self.content_re = content_re
|
45
|
-
"""A regular expression used to match the content in the identified nodes"""
|
46
|
-
self.use_all_content = use_all_content
|
47
|
-
"""A flag that will assume that all content should be tagged (there will be no start/end)"""
|
48
|
-
self.tag_to_apply = tag_to_apply
|
49
|
-
"""The tag to apply to the node(s)"""
|
50
|
-
self.node_only = node_only
|
51
|
-
"""Tag the node only and no content"""
|
52
|
-
self.node_tag_uuid = node_tag_uuid
|
53
|
-
"""The UUID to use on the tag"""
|
54
|
-
|
55
|
-
def process(self, document):
|
56
|
-
""" """
|
57
|
-
document.content_node.tag(
|
58
|
-
selector=self.selector,
|
59
|
-
tag_to_apply=self.tag_to_apply,
|
60
|
-
content_re=self.content_re,
|
61
|
-
use_all_content=self.use_all_content,
|
62
|
-
node_only=self.node_only,
|
63
|
-
tag_uuid=self.node_tag_uuid,
|
64
|
-
)
|
65
|
-
|
66
|
-
return document
|
67
|
-
|
68
|
-
|
69
|
-
class NodeTagCopy:
|
70
|
-
"""The NodeTagCopy action allows you select nodes specified by the selector and create copies of the existing_tag (if it exists) with the new_tag_name.
|
71
|
-
If a tag with the 'existing_tag_name' does not exist on a selected node, no action is taken for that node.
|
72
|
-
"""
|
73
|
-
|
74
|
-
def __init__(self, selector, existing_tag_name, new_tag_name):
|
75
|
-
self.selector = selector
|
76
|
-
"""The selector to match the nodes"""
|
77
|
-
self.existing_tag_name = existing_tag_name
|
78
|
-
"""The existing tag name that will be the source"""
|
79
|
-
self.new_tag_name = new_tag_name
|
80
|
-
"""The new tag name that will be the destination"""
|
81
|
-
|
82
|
-
def process(self, document):
|
83
|
-
""" """
|
84
|
-
document.content_node.copy_tag(
|
85
|
-
selector=self.selector,
|
86
|
-
existing_tag_name=self.existing_tag_name,
|
87
|
-
new_tag_name=self.new_tag_name,
|
88
|
-
)
|
89
|
-
return document
|
90
|
-
|
91
|
-
|
92
24
|
class TextParser:
|
93
25
|
"""Parser to load a source file as a text document. The text from the document may be placed on the root ContentNode or on the root's child nodes (controlled by lines_as_child_nodes)."""
|
94
26
|
|
kodexa/testing/test_utils.py
CHANGED
@@ -215,7 +215,7 @@ class AssistantTestHarness:
|
|
215
215
|
)
|
216
216
|
if document is not None:
|
217
217
|
pipeline = assistant_pipeline.pipeline
|
218
|
-
from
|
218
|
+
from kodexa_document.model import ContentObjectReference
|
219
219
|
|
220
220
|
pipeline.connector = [
|
221
221
|
ContentObjectReference(
|