~ubuntu-branches/ubuntu/wily/grass/wily

« back to all changes in this revision

Viewing changes to lib/python/temporal/temporal_operator.py

Tags: 7.0.0~rc1+ds1-1~exp1
* New upstream release candidate.
* Repack upstream tarball, remove precompiled Python objects.
* Add upstream metadata.
* Update gbp.conf and Vcs-Git URL to use the experimental branch.
* Update watch file for GRASS 7.0.
* Drop build dependencies for Tcl/Tk, add build dependencies:
  python-numpy, libnetcdf-dev, netcdf-bin, libblas-dev, liblapack-dev
* Update Vcs-Browser URL to use cgit instead of gitweb.
* Update paths to use grass70.
* Add configure options: --with-netcdf, --with-blas, --with-lapack,
  remove --with-tcltk-includes.
* Update patches for GRASS 7.
* Update copyright file, changes:
  - Update copyright years
  - Group files by license
  - Remove unused license sections
* Add patches for various typos.
* Fix desktop file with patch instead of d/rules.
* Use minimal dh rules.
* Bump Standards-Version to 3.9.6, no changes.
* Use dpkg-maintscript-helper to replace directories with symlinks.
  (closes: #776349)
* Update my email to use @debian.org address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""@package grass.temporal
 
2
 
 
3
Temporal operator evaluation with PLY
 
4
 
 
5
(C) 2013 by the GRASS Development Team
 
6
This program is free software under the GNU General Public
 
7
License (>=v2). Read the file COPYING that comes with GRASS
 
8
for details.
 
9
 
 
10
:authors: Thomas Leppelt and Soeren Gebbert
 
11
 
 
12
.. code-block:: python
 
13
 
 
14
    >>> p = TemporalOperatorParser()
 
15
    >>> expression =  "{equal| during}"
 
16
    >>> p.parse(expression, optype = 'relation')
 
17
    >>> print(p.relations, p.temporal, p.function)
 
18
    (['equal', 'during'], None, None)
 
19
    >>> p = TemporalOperatorParser()    
 
20
    >>> expression =  "{contains | starts}"
 
21
    >>> p.parse(expression)
 
22
    >>> print(p.relations, p.temporal, p.function)
 
23
    (['contains', 'starts'], None, None)
 
24
    >>> p = TemporalOperatorParser()    
 
25
    >>> expression =  "{&&, during}"
 
26
    >>> p.parse(expression, optype = 'boolean')
 
27
    >>> print(p.relations, p.temporal, p.function,p.aggregate)
 
28
    (['during'], 'l', '&&', '&')
 
29
    >>> p = TemporalOperatorParser()    
 
30
    >>> expression =  "{||, equal | during}"
 
31
    >>> p.parse(expression, optype = 'boolean')
 
32
    >>> print(p.relations, p.temporal, p.function,p.aggregate)
 
33
    (['equal', 'during'], 'l', '||', '|')
 
34
    >>> p = TemporalOperatorParser()    
 
35
    >>> expression =  "{||, equal | during, &}"
 
36
    >>> p.parse(expression, optype = 'boolean')
 
37
    >>> print(p.relations, p.temporal, p.function,p.aggregate)
 
38
    (['equal', 'during'], 'l', '||', '&')
 
39
    >>> p = TemporalOperatorParser()    
 
40
    >>> expression =  "{&&, during, |}"
 
41
    >>> p.parse(expression, optype = 'boolean')
 
42
    >>> print(p.relations, p.temporal, p.function,p.aggregate)
 
43
    (['during'], 'l', '&&', '|')
 
44
    >>> p = TemporalOperatorParser()    
 
45
    >>> expression =  "{&&, during, |, r}"
 
46
    >>> p.parse(expression, optype = 'boolean')
 
47
    >>> print(p.relations, p.temporal, p.function,p.aggregate)
 
48
    (['during'], 'r', '&&', '|')
 
49
    >>> p = TemporalOperatorParser()    
 
50
    >>> expression =  "{&&, during, u}"
 
51
    >>> p.parse(expression, optype = 'boolean')
 
52
    >>> print(p.relations, p.temporal, p.function,p.aggregate)
 
53
    (['during'], 'u', '&&', '&')
 
54
    >>> p = TemporalOperatorParser()    
 
55
    >>> expression =  "{:, during, r}"
 
56
    >>> p.parse(expression, optype = 'select')
 
57
    >>> print(p.relations, p.temporal, p.function)
 
58
    (['during'], 'r', ':')
 
59
    >>> p = TemporalOperatorParser()    
 
60
    >>> expression =  "{!:, equal | contains, d}"
 
61
    >>> p.parse(expression, optype = 'select')
 
62
    >>> print(p.relations, p.temporal, p.function)
 
63
    (['equal', 'contains'], 'd', '!:')
 
64
    >>> p = TemporalOperatorParser()    
 
65
    >>> expression =  "{#, during, r}"
 
66
    >>> p.parse(expression, optype = 'hash')
 
67
    >>> print(p.relations, p.temporal, p.function)
 
68
    (['during'], 'r', '#')
 
69
    >>> p = TemporalOperatorParser()    
 
70
    >>> expression =  "{#, equal | contains}"
 
71
    >>> p.parse(expression, optype = 'hash')
 
72
    >>> print(p.relations, p.temporal, p.function)
 
73
    (['equal', 'contains'], 'l', '#')
 
74
    >>> p = TemporalOperatorParser()    
 
75
    >>> expression =  "{+, during, r}"
 
76
    >>> p.parse(expression, optype = 'raster')
 
77
    >>> print(p.relations, p.temporal, p.function)
 
78
    (['during'], 'r', '+')
 
79
    >>> p = TemporalOperatorParser()    
 
80
    >>> expression =  "{/, equal | contains}"
 
81
    >>> p.parse(expression, optype = 'raster')
 
82
    >>> print(p.relations, p.temporal, p.function)
 
83
    (['equal', 'contains'], 'l', '/')
 
84
    >>> p = TemporalOperatorParser()    
 
85
    >>> expression =  "{+, equal | contains,intersect}"
 
86
    >>> p.parse(expression, optype = 'raster')
 
87
    >>> print(p.relations, p.temporal, p.function)
 
88
    (['equal', 'contains'], 'i', '+')
 
89
    >>> p = TemporalOperatorParser()    
 
90
    >>> expression =  "{*, contains,disjoint}"
 
91
    >>> p.parse(expression, optype = 'raster')
 
92
    >>> print(p.relations, p.temporal, p.function)
 
93
    (['contains'], 'd', '*')
 
94
    >>> p = TemporalOperatorParser()    
 
95
    >>> expression =  "{~, equal,left}"
 
96
    >>> p.parse(expression, optype = 'overlay')
 
97
    >>> print(p.relations, p.temporal, p.function)
 
98
    (['equal'], 'l', '~')
 
99
    >>> p = TemporalOperatorParser()    
 
100
    >>> expression =  "{^, over,right}"
 
101
    >>> p.parse(expression, optype = 'overlay')
 
102
    >>> print(p.relations, p.temporal, p.function)
 
103
    (['overlaps', 'overlapped'], 'r', '^')
 
104
 
 
105
"""
 
106
 
 
107
try:
 
108
    import ply.lex as lex
 
109
    import ply.yacc as yacc
 
110
except:
 
111
    pass
 
112
 
 
113
class TemporalOperatorLexer(object):
 
114
    """Lexical analyzer for the GRASS GIS temporal operator"""
 
115
 
 
116
    # Functions that defines topological relations.
 
117
    relations = {
 
118
        'equal'      : "EQUAL",
 
119
        'follows'    : "FOLLOWS",
 
120
        'precedes'   : "PRECEDES",
 
121
        'overlaps'   : "OVERLAPS",
 
122
        'overlapped' : "OVERLAPPED",
 
123
        'during'     : "DURING",
 
124
        'starts'     : "STARTS",
 
125
        'finishes'   : "FINISHES",
 
126
        'contains'   : "CONTAINS",
 
127
        'started'    : "STARTED",
 
128
        'finished'   : "FINISHED",
 
129
        'over'       : "OVER"
 
130
        }
 
131
 
 
132
    # This is the list of token names.
 
133
    tokens = (
 
134
        'COMMA',
 
135
        'LEFTREF',
 
136
        'RIGHTREF',
 
137
        'UNION', 
 
138
        'DISJOINT',
 
139
        'INTERSECT',
 
140
        'HASH',
 
141
        'OR',
 
142
        'AND',
 
143
        'DISOR',
 
144
        'XOR',
 
145
        'NOT',        
 
146
        'MOD',
 
147
        'DIV',
 
148
        'MULT',
 
149
        'ADD',      
 
150
        'SUB',
 
151
        'T_SELECT',
 
152
        'T_NOT_SELECT',
 
153
        'CLPAREN',
 
154
        'CRPAREN',
 
155
    )
 
156
 
 
157
    # Build the token list
 
158
    tokens = tokens + tuple(relations.values())
 
159
 
 
160
    # Regular expression rules for simple tokens
 
161
    t_T_SELECT                = r':'
 
162
    t_T_NOT_SELECT        = r'!:'
 
163
    t_COMMA                    = r','
 
164
    t_LEFTREF                  = '^[l|left]'
 
165
    t_RIGHTREF                ='^[r|right]'
 
166
    t_UNION                     = '^[u|union]'
 
167
    t_DISJOINT                 = '^[d|disjoint]'
 
168
    t_INTERSECT             = '^[i|intersect]'
 
169
    t_HASH                      = r'\#'
 
170
    t_OR                          = r'[\|]'
 
171
    t_AND                        = r'[&]'
 
172
    t_DISOR                     = r'\+'
 
173
    t_XOR                         = r'\^'
 
174
    t_NOT                         = r'\~'    
 
175
    t_MOD                       = r'[\%]'
 
176
    t_DIV                         = r'[\/]'
 
177
    t_MULT                      = r'[\*]'
 
178
    t_ADD                       = r'[\+]'
 
179
    t_SUB                        = r'[-]'
 
180
    t_CLPAREN                = r'\{'
 
181
    t_CRPAREN                = r'\}'
 
182
 
 
183
    # These are the things that should be ignored.
 
184
    t_ignore = ' \t'
 
185
 
 
186
    # Track line numbers.
 
187
    def t_newline(self, t):
 
188
        r'\n+'
 
189
        t.lineno += len(t.value)
 
190
 
 
191
    def t_NAME(self, t):
 
192
        r'[a-zA-Z_][a-zA-Z_0-9]*'
 
193
        self.temporal_symbol(t)
 
194
        return t
 
195
 
 
196
    # Parse symbols
 
197
    def temporal_symbol(self, t):
 
198
        # Check for reserved words
 
199
        if t.value in TemporalOperatorLexer.relations.keys():
 
200
            t.type = TemporalOperatorLexer.relations.get(t.value)
 
201
        elif t.value == 'l' or t.value == 'left':
 
202
            t.value = 'l'
 
203
            t.type = 'LEFTREF'
 
204
        elif t.value == 'r' or t.value == 'right':
 
205
            t.value = 'r'
 
206
            t.type = 'RIGHTREF'
 
207
        elif t.value == 'u' or t.value == 'union':
 
208
            t.value = 'u'
 
209
            t.type = 'UNION'
 
210
        elif t.value == 'd' or t.value == 'disjoint':
 
211
            t.value = 'd'
 
212
            t.type = 'DISJOINT'
 
213
        elif t.value == 'i' or t.value == 'intersect':
 
214
            t.value = 'i'
 
215
            t.type = 'INTERSECT'
 
216
        #else:
 
217
        #    t.type = 'NAME'
 
218
        return(t)
 
219
 
 
220
    # Handle errors.
 
221
    def t_error(self, t):
 
222
        raise SyntaxError("syntax error on line %d near '%s'" %
 
223
            (t.lineno, t.value))
 
224
 
 
225
    # Build the lexer
 
226
    def build(self,**kwargs):
 
227
        self.lexer = lex.lex(module=self, **kwargs)
 
228
 
 
229
    # Just for testing
 
230
    def test(self,data):
 
231
        self.name_list = {}
 
232
        print(data)
 
233
        self.lexer.input(data)
 
234
        while True:
 
235
             tok = self.lexer.token()
 
236
             if not tok: break
 
237
             print tok
 
238
 
 
239
###############################################################################
 
240
 
 
241
class TemporalOperatorParser(object):
 
242
    """The temporal operator class"""
 
243
 
 
244
    def __init__(self):
 
245
        self.lexer = TemporalOperatorLexer()
 
246
        self.lexer.build()
 
247
        self.parser = yacc.yacc(module=self)
 
248
        self.relations = None
 
249
        self.temporal  = None
 
250
        self.function  = None
 
251
        self.aggregate = None
 
252
 
 
253
    def parse(self, expression,  optype = 'relation'):
 
254
        self.optype = optype        
 
255
        self.parser.parse(expression)
 
256
        # The parameter optype can be of type: select {:, during, r}, boolean{&&, contains, |}, 
 
257
        #                                                            raster{*, equal, |}, vector {|, starts, &},
 
258
        #                                                            hash{#, during, l} or relation {during}.
 
259
    
 
260
    # Error rule for syntax errors.
 
261
    def p_error(self, t):
 
262
        raise SyntaxError("Unexpected syntax error")
 
263
 
 
264
    # Get the tokens from the lexer class
 
265
    tokens = TemporalOperatorLexer.tokens
 
266
 
 
267
    def p_relation_operator(self, t):
 
268
        # The expression should always return a list of maps.
 
269
        """
 
270
        operator : CLPAREN relation CRPAREN
 
271
                 | CLPAREN relationlist CRPAREN
 
272
        """
 
273
        # Check for correct type.
 
274
        if not self.optype == 'relation':
 
275
            raise SyntaxError("invalid syntax")
 
276
        else:
 
277
            # Set three operator components.
 
278
            if isinstance(t[2], list):
 
279
                self.relations = t[2]
 
280
            else:
 
281
                self.relations = [t[2]]
 
282
            self.temporal  = None
 
283
            self.function  = None
 
284
 
 
285
            t[0] = t[2]
 
286
 
 
287
    def p_relation_bool_operator(self, t):
 
288
        # The expression should always return a list of maps.
 
289
        """
 
290
        operator : CLPAREN OR OR COMMA relation CRPAREN
 
291
                | CLPAREN AND AND COMMA relation CRPAREN
 
292
                | CLPAREN OR OR COMMA relationlist CRPAREN
 
293
                | CLPAREN AND AND COMMA relationlist CRPAREN
 
294
        """
 
295
        if not self.optype == 'boolean':
 
296
            raise SyntaxError("invalid syntax")
 
297
        else:        
 
298
            # Set three operator components.
 
299
            if isinstance(t[5], list):
 
300
                self.relations = t[5]
 
301
            else:
 
302
                self.relations = [t[5]]
 
303
            self.temporal  = "l"
 
304
            self.function  = t[2] + t[3]
 
305
            self.aggregate = t[2]
 
306
            
 
307
            t[0] = t[2]
 
308
 
 
309
    def p_relation_bool_combi_operator(self, t):
 
310
        # The expression should always return a list of maps.
 
311
        """
 
312
        operator : CLPAREN OR OR COMMA relation COMMA OR CRPAREN
 
313
                | CLPAREN OR OR COMMA relation COMMA AND CRPAREN
 
314
                | CLPAREN AND AND COMMA relation COMMA OR CRPAREN
 
315
                | CLPAREN AND AND COMMA relation COMMA AND CRPAREN
 
316
                | CLPAREN OR OR COMMA relationlist COMMA OR CRPAREN
 
317
                | CLPAREN OR OR COMMA relationlist COMMA AND CRPAREN
 
318
                | CLPAREN AND AND COMMA relationlist COMMA OR CRPAREN
 
319
                | CLPAREN AND AND COMMA relationlist COMMA AND CRPAREN
 
320
        """
 
321
        if not self.optype == 'boolean':
 
322
            raise SyntaxError("invalid syntax")
 
323
        else:        
 
324
            # Set three operator components.
 
325
            if isinstance(t[5], list):
 
326
                self.relations = t[5]
 
327
            else:
 
328
                self.relations = [t[5]]
 
329
            self.temporal  = "l"
 
330
            self.function  = t[2] + t[3]
 
331
            self.aggregate = t[7]
 
332
            
 
333
            t[0] = t[2]
 
334
 
 
335
    def p_relation_bool_combi_operator2(self, t):
 
336
        # The expression should always return a list of maps.
 
337
        """
 
338
        operator : CLPAREN OR OR COMMA relation COMMA temporal CRPAREN
 
339
                | CLPAREN AND AND COMMA relation COMMA temporal CRPAREN
 
340
                | CLPAREN OR OR COMMA relationlist COMMA temporal CRPAREN
 
341
                | CLPAREN AND AND COMMA relationlist COMMA temporal CRPAREN
 
342
        """
 
343
        if not self.optype == 'boolean':
 
344
            raise SyntaxError("invalid syntax")
 
345
        else:        
 
346
            # Set three operator components.
 
347
            if isinstance(t[5], list):
 
348
                self.relations = t[5]
 
349
            else:
 
350
                self.relations = [t[5]]
 
351
            self.temporal  = t[7]
 
352
            self.function  = t[2] + t[3]
 
353
            self.aggregate = t[2]
 
354
            
 
355
            t[0] = t[2]
 
356
    
 
357
    def p_relation_bool_combi_operator3(self, t):
 
358
        # The expression should always return a list of maps.
 
359
        """
 
360
        operator : CLPAREN OR OR COMMA relation COMMA OR COMMA temporal CRPAREN
 
361
                | CLPAREN OR OR COMMA relation COMMA AND COMMA temporal CRPAREN
 
362
                | CLPAREN AND AND COMMA relation COMMA OR COMMA temporal CRPAREN
 
363
                | CLPAREN AND AND COMMA relation COMMA AND COMMA temporal CRPAREN
 
364
                | CLPAREN OR OR COMMA relationlist COMMA OR COMMA temporal CRPAREN
 
365
                | CLPAREN OR OR COMMA relationlist COMMA AND COMMA temporal CRPAREN
 
366
                | CLPAREN AND AND COMMA relationlist COMMA OR COMMA temporal CRPAREN
 
367
                | CLPAREN AND AND COMMA relationlist COMMA AND COMMA temporal CRPAREN
 
368
        """
 
369
        if not self.optype == 'boolean':
 
370
            raise SyntaxError("invalid syntax")
 
371
        else:        
 
372
            # Set three operator components.
 
373
            if isinstance(t[5], list):
 
374
                self.relations = t[5]
 
375
            else:
 
376
                self.relations = [t[5]]
 
377
            self.temporal  = t[9]
 
378
            self.function  = t[2] + t[3]
 
379
            self.aggregate = t[7]
 
380
            
 
381
            t[0] = t[2]
 
382
    
 
383
    def p_select_relation_operator(self, t):
 
384
        # The expression should always return a list of maps.
 
385
        """
 
386
        operator : CLPAREN select CRPAREN
 
387
                    | CLPAREN select COMMA relation CRPAREN
 
388
                    | CLPAREN select COMMA relationlist CRPAREN
 
389
                    | CLPAREN select COMMA relation COMMA temporal CRPAREN
 
390
                    | CLPAREN select COMMA relationlist COMMA temporal CRPAREN
 
391
        """
 
392
        if not self.optype == 'select':
 
393
            raise SyntaxError("invalid syntax")
 
394
        else:
 
395
            if len(t) == 4:
 
396
                # Set three operator components.
 
397
                self.relations = ['equal']
 
398
                self.temporal  = "l"
 
399
                self.function  = t[2]
 
400
            elif len(t) == 5:
 
401
                self.relations = ['equal']
 
402
                self.temporal  = t[3]
 
403
                self.function  = t[2]
 
404
            elif len(t) == 6:
 
405
                if isinstance(t[4], list):
 
406
                    self.relations = t[4]
 
407
                else:
 
408
                    self.relations = [t[4]]
 
409
                self.temporal  = "l"
 
410
                self.function  = t[2]
 
411
            elif len(t) == 8:
 
412
                if isinstance(t[4], list):
 
413
                    self.relations = t[4]
 
414
                else:
 
415
                    self.relations = [t[4]]
 
416
                self.temporal  = t[6]
 
417
                self.function  = t[2]
 
418
            t[0] = t[2]
 
419
 
 
420
    def p_hash_relation_operator(self, t):
 
421
        # The expression should always return a list of maps.
 
422
        """
 
423
        operator : CLPAREN HASH CRPAREN
 
424
                    | CLPAREN HASH COMMA relation CRPAREN
 
425
                    | CLPAREN HASH COMMA relationlist CRPAREN
 
426
                    | CLPAREN HASH COMMA relation COMMA temporal CRPAREN
 
427
                    | CLPAREN HASH COMMA relationlist COMMA temporal CRPAREN
 
428
        """
 
429
        if not self.optype == 'hash':
 
430
            raise SyntaxError("invalid syntax")
 
431
        else:
 
432
            if len(t) == 4:
 
433
                # Set three operator components.
 
434
                self.relations = ['equal']
 
435
                self.temporal  = "l"
 
436
                self.function  = t[2]
 
437
            elif len(t) == 5:
 
438
                self.relations = ['equal']
 
439
                self.temporal  = t[3]
 
440
                self.function  = t[2]
 
441
            elif len(t) == 6:
 
442
                if isinstance(t[4], list):
 
443
                    self.relations = t[4]
 
444
                else:
 
445
                    self.relations = [t[4]]
 
446
                self.temporal  = "l"
 
447
                self.function  = t[2]
 
448
            elif len(t) == 8:
 
449
                if isinstance(t[4], list):
 
450
                    self.relations = t[4]
 
451
                else:
 
452
                    self.relations = [t[4]]
 
453
                self.temporal  = t[6]
 
454
                self.function  = t[2]
 
455
            t[0] = t[2]
 
456
 
 
457
    def p_raster_relation_operator(self, t):
 
458
        # The expression should always return a list of maps.
 
459
        """
 
460
        operator : CLPAREN arithmetic CRPAREN
 
461
                    | CLPAREN arithmetic COMMA relation CRPAREN
 
462
                    | CLPAREN arithmetic COMMA relationlist CRPAREN
 
463
                    | CLPAREN arithmetic COMMA relation COMMA temporal CRPAREN
 
464
                    | CLPAREN arithmetic COMMA relationlist COMMA temporal CRPAREN
 
465
        """
 
466
        if not self.optype == 'raster':
 
467
            raise SyntaxError("invalid syntax")
 
468
        else:
 
469
            if len(t) == 4:
 
470
                # Set three operator components.
 
471
                self.relations = ['equal']
 
472
                self.temporal  = "l"
 
473
                self.function  = t[2]
 
474
            elif len(t) == 5:
 
475
                self.relations = ['equal']
 
476
                self.temporal  = t[3]
 
477
                self.function  = t[2]
 
478
            elif len(t) == 6:
 
479
                if isinstance(t[4], list):
 
480
                    self.relations = t[4]
 
481
                else:
 
482
                    self.relations = [t[4]]
 
483
                self.temporal  = "l"
 
484
                self.function  = t[2]
 
485
            elif len(t) == 8:
 
486
                if isinstance(t[4], list):
 
487
                    self.relations = t[4]
 
488
                else:
 
489
                    self.relations = [t[4]]
 
490
                self.temporal  = t[6]
 
491
                self.function  = t[2]
 
492
            t[0] = t[2]
 
493
 
 
494
    def p_overlay_relation_operator(self, t):
 
495
        # The expression should always return a list of maps.
 
496
        """
 
497
        operator : CLPAREN overlay CRPAREN
 
498
                    | CLPAREN overlay COMMA relation CRPAREN
 
499
                    | CLPAREN overlay COMMA relationlist CRPAREN
 
500
                    | CLPAREN overlay COMMA relation COMMA temporal CRPAREN
 
501
                    | CLPAREN overlay COMMA relationlist COMMA temporal CRPAREN
 
502
        """
 
503
        if not self.optype == 'overlay':
 
504
            raise SyntaxError("invalid syntax")
 
505
        else:
 
506
            if len(t) == 4:
 
507
                # Set three operator components.
 
508
                self.relations = ['equal']
 
509
                self.temporal  = "l"
 
510
                self.function  = t[2]
 
511
            elif len(t) == 5:
 
512
                self.relations = ['equal']
 
513
                self.temporal  = t[3]
 
514
                self.function  = t[2]
 
515
            elif len(t) == 6:
 
516
                if isinstance(t[4], list):
 
517
                    self.relations = t[4]
 
518
                else:
 
519
                    self.relations = [t[4]]
 
520
                self.temporal  = "l"
 
521
                self.function  = t[2]
 
522
            elif len(t) == 8:
 
523
                if isinstance(t[4], list):
 
524
                    self.relations = t[4]
 
525
                else:
 
526
                    self.relations = [t[4]]
 
527
                self.temporal  = t[6]
 
528
                self.function  = t[2]
 
529
            t[0] = t[2]
 
530
 
 
531
    def p_relation(self, t):
 
532
        # The list of relations.
 
533
        """
 
534
        relation : EQUAL
 
535
                 | FOLLOWS
 
536
                 | PRECEDES
 
537
                 | OVERLAPS
 
538
                 | OVERLAPPED
 
539
                 | DURING
 
540
                 | STARTS
 
541
                 | FINISHES
 
542
                 | CONTAINS
 
543
                 | STARTED
 
544
                 | FINISHED
 
545
        """
 
546
        t[0] = t[1]
 
547
 
 
548
    def p_over(self, t):
 
549
        # The list of relations.
 
550
        """
 
551
        relation : OVER
 
552
        """
 
553
        over_list = ["overlaps", "overlapped"]
 
554
        t[0] = over_list
 
555
 
 
556
    def p_relationlist(self, t):
 
557
        # The list of relations.
 
558
        """
 
559
        relationlist : relation OR relation
 
560
                     | relation OR relationlist
 
561
        """
 
562
        rel_list = []
 
563
        rel_list.append(t[1])
 
564
        if isinstance(t[3], list):
 
565
            rel_list = rel_list + t[3]
 
566
        else:
 
567
            rel_list.append(t[3])
 
568
        t[0] =  rel_list
 
569
 
 
570
    def p_temporal_operator(self, t):
 
571
        # The list of relations.
 
572
        """
 
573
        temporal : LEFTREF
 
574
                | RIGHTREF
 
575
                | UNION
 
576
                | DISJOINT
 
577
                | INTERSECT
 
578
        """
 
579
        t[0] = t[1]
 
580
 
 
581
    def p_select_operator(self, t):
 
582
        # The list of relations.
 
583
        """
 
584
        select : T_SELECT
 
585
               | T_NOT_SELECT
 
586
        """
 
587
        t[0] = t[1]
 
588
 
 
589
    def p_arithmetic_operator(self, t):
 
590
        # The list of relations.
 
591
        """
 
592
        arithmetic : MOD
 
593
                   | DIV
 
594
                   | MULT
 
595
                   | ADD
 
596
                   | SUB
 
597
        """
 
598
        t[0] = t[1]
 
599
 
 
600
    def p_overlay_operator(self, t):
 
601
        # The list of relations.
 
602
        """
 
603
        overlay : AND
 
604
                   | OR
 
605
                   | XOR
 
606
                   | DISOR
 
607
                   | NOT
 
608
        """
 
609
        t[0] = t[1]
 
610
###############################################################################
 
611
 
 
612
if __name__ == "__main__":
 
613
    import doctest
 
614
    doctest.testmod()
 
615