activefacts-cql 1.9.6 → 1.9.7
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.
- checksums.yaml +4 -4
- data/Rakefile +19 -0
- data/activefacts-cql.gemspec +5 -3
- data/lib/activefacts/cql/parser.rb +4 -0
- data/lib/activefacts/cql/version.rb +1 -1
- metadata +19 -21
- data/lib/activefacts/cql/Rakefile +0 -14
- data/lib/activefacts/cql/parser/CQLParser.treetop +0 -258
- data/lib/activefacts/cql/parser/Context.treetop +0 -46
- data/lib/activefacts/cql/parser/Expressions.treetop +0 -67
- data/lib/activefacts/cql/parser/FactTypes.treetop +0 -371
- data/lib/activefacts/cql/parser/Language/English.treetop +0 -329
- data/lib/activefacts/cql/parser/Language/French.treetop +0 -325
- data/lib/activefacts/cql/parser/Language/Mandarin.treetop +0 -305
- data/lib/activefacts/cql/parser/LexicalRules.treetop +0 -253
- data/lib/activefacts/cql/parser/ObjectTypes.treetop +0 -209
- data/lib/activefacts/cql/parser/Terms.treetop +0 -197
- data/lib/activefacts/cql/parser/TransformRules.treetop +0 -226
- data/lib/activefacts/cql/parser/ValueTypes.treetop +0 -244
@@ -1,67 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# ActiveFacts CQL Parser.
|
3
|
-
# Parse rules relating to Expressions
|
4
|
-
#
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
6
|
-
#
|
7
|
-
module ActiveFacts
|
8
|
-
module CQL
|
9
|
-
grammar Expressions
|
10
|
-
rule expression
|
11
|
-
sum
|
12
|
-
end
|
13
|
-
|
14
|
-
rule sum
|
15
|
-
t0:product s tail:( op:add_op s t1:product s )*
|
16
|
-
{
|
17
|
-
def ast
|
18
|
-
if tail.elements.empty?
|
19
|
-
t0.ast
|
20
|
-
else
|
21
|
-
Compiler::Sum.new(t0.ast, *tail.elements.map{|e| e.op.text_value == '-' ? Compiler::Negate.new(e.t1.ast) : e.t1.ast})
|
22
|
-
end
|
23
|
-
end
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
rule add_op
|
28
|
-
'+' / '-'
|
29
|
-
end
|
30
|
-
|
31
|
-
rule product
|
32
|
-
f0:factor s tail:( op:mul_op s f1:factor s )*
|
33
|
-
{
|
34
|
-
def ast
|
35
|
-
if tail.elements.empty?
|
36
|
-
f0.ast
|
37
|
-
else
|
38
|
-
Compiler::Product.new(f0.ast, *tail.elements.map{|e| e.op.text_value != '*' ? Compiler::Reciprocal.new(e.op.text_value, e.f1.ast) : e.f1.ast})
|
39
|
-
end
|
40
|
-
end
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
rule factor
|
45
|
-
literal u:unit? s
|
46
|
-
{
|
47
|
-
def ast
|
48
|
-
Compiler::Literal.new(literal.value, u.empty? ? nil : u.text_value)
|
49
|
-
end
|
50
|
-
}
|
51
|
-
/ derived_variable
|
52
|
-
/ !context_note '(' s sum s ')' s { def ast; sum.ast; end }
|
53
|
-
end
|
54
|
-
|
55
|
-
rule derived_variable
|
56
|
-
derived:term s role_id:(role_name / subscript )?
|
57
|
-
{
|
58
|
-
def ast quantifier = nil, value_constraint = nil, literal = nil, nested_clauses = nil
|
59
|
-
role_name = role_id.empty? ? nil : role_id.value
|
60
|
-
derived.ast(quantifier, nil, role_name, value_constraint, literal, nested_clauses)
|
61
|
-
end
|
62
|
-
}
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,371 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# ActiveFacts CQL Parser.
|
3
|
-
# Parse rules relating to FactType definitions.
|
4
|
-
#
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
6
|
-
#
|
7
|
-
module ActiveFacts
|
8
|
-
module CQL
|
9
|
-
grammar FactTypes
|
10
|
-
rule query
|
11
|
-
s query_clauses r:returning_clause? '?'
|
12
|
-
{
|
13
|
-
def ast
|
14
|
-
Compiler::FactType.new nil, [], query_clauses.ast, (r.empty? ? nil : r)
|
15
|
-
end
|
16
|
-
}
|
17
|
-
end
|
18
|
-
|
19
|
-
rule fact_type
|
20
|
-
s each:(each)? # Chew the "each" or it will get accepted as a quantifier
|
21
|
-
name:(s term_definition_name mapping_pragmas is_where)? # Name of objectifying entity type
|
22
|
-
anonymous_fact_type
|
23
|
-
{
|
24
|
-
def ast
|
25
|
-
ft = anonymous_fact_type.ast
|
26
|
-
if !name.empty?
|
27
|
-
# "each" is often used, and doesn't imply uniqueness
|
28
|
-
ft.name = name.term_definition_name.value
|
29
|
-
pragmas = name.mapping_pragmas.value
|
30
|
-
pragmas << 'independent' if name.is_where.independent
|
31
|
-
ft.pragmas = pragmas
|
32
|
-
elsif !each.empty?
|
33
|
-
# Handle the implied mandatory constraint on the appropriate role
|
34
|
-
first_reading = ft.clauses[0]
|
35
|
-
refs = first_reading.refs
|
36
|
-
raise "Ambiguous 'each' implies mandatory on fact type of arity #{refs.size}" unless refs.size == 2
|
37
|
-
q = refs[-1].quantifier
|
38
|
-
if q
|
39
|
-
q.min = 1 # Make the existing quantifier mandatory
|
40
|
-
else
|
41
|
-
refs[-1].quantifier = q = Compiler::Quantifier.new(1, nil)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
ft
|
45
|
-
end
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
rule anonymous_fact_type
|
50
|
-
query_clauses
|
51
|
-
ctail:( (':' / where) s a:query_clauses s)?
|
52
|
-
returning_clause?
|
53
|
-
s ';'
|
54
|
-
{
|
55
|
-
def ast
|
56
|
-
clauses_ast = query_clauses.ast
|
57
|
-
conditions = !ctail.empty? ? ctail.a.ast : []
|
58
|
-
returning = respond_to?(:returning_clause) ? returning_clause.ast : nil
|
59
|
-
value_derivation = clauses_ast.detect{|r| r.is_equality_comparison}
|
60
|
-
if !value_derivation and
|
61
|
-
conditions.empty? and
|
62
|
-
clauses_ast.detect{|r| r.includes_literals}
|
63
|
-
raise "Fact instances may not contain conditions" unless conditions.empty? && !returning
|
64
|
-
Compiler::Fact.new clauses_ast
|
65
|
-
elsif (clauses_ast.size == 1 &&
|
66
|
-
clauses_ast[0].phrases.size == 1 &&
|
67
|
-
(popname = clauses_ast[0].phrases[0]) &&
|
68
|
-
!popname.is_a?(Compiler::Reference) &&
|
69
|
-
conditions.detect{|r| r.includes_literals}
|
70
|
-
)
|
71
|
-
Compiler::Fact.new conditions, popname
|
72
|
-
else
|
73
|
-
Compiler::FactType.new nil, clauses_ast, conditions, returning
|
74
|
-
end
|
75
|
-
end
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
rule query_clauses
|
80
|
-
qualified_clauses
|
81
|
-
# REVISIT: This creates no precedence between and/or, which could cause confusion.
|
82
|
-
# Should disallow mixed conjunctions - using a sempred?
|
83
|
-
ftail:( conjunction:(',' / and / or ) s qualified_clauses s )*
|
84
|
-
{
|
85
|
-
def ast
|
86
|
-
clauses_ast = qualified_clauses.ast
|
87
|
-
ftail.elements.each{|e|
|
88
|
-
conjunction = e.conjunction.text_value
|
89
|
-
# conjunction = 'and' if conjunction == ',' # ',' means AND, but disallows left-contractions
|
90
|
-
clauses_ast += e.qualified_clauses.ast(conjunction)
|
91
|
-
}
|
92
|
-
clauses_ast
|
93
|
-
end
|
94
|
-
}
|
95
|
-
end
|
96
|
-
|
97
|
-
rule returning_clause
|
98
|
-
returning s return (s ',' s return)*
|
99
|
-
end
|
100
|
-
|
101
|
-
rule return
|
102
|
-
ordering_prefix? phrase+
|
103
|
-
end
|
104
|
-
|
105
|
-
rule qualified_clauses
|
106
|
-
s certainty s contracted_clauses s p:post_qualifiers? s c:context_note?
|
107
|
-
{
|
108
|
-
def ast(conjunction = nil)
|
109
|
-
r = contracted_clauses.ast # An array of clause asts
|
110
|
-
r[0].conjunction = conjunction
|
111
|
-
# pre-qualifiers apply to the first clause, post_qualifiers and context_note to the last
|
112
|
-
# REVISIT: This may be incorrect where the last is a nested clause
|
113
|
-
r[0].certainty = certainty.value
|
114
|
-
r[-1].qualifiers += p.list unless p.empty?
|
115
|
-
r[-1].context_note = c.ast unless c.empty?
|
116
|
-
r
|
117
|
-
end
|
118
|
-
}
|
119
|
-
end
|
120
|
-
|
121
|
-
rule certainty
|
122
|
-
negative_prefix { def value; false; end }
|
123
|
-
/
|
124
|
-
maybe { def value; nil; end }
|
125
|
-
/
|
126
|
-
definitely { def value; true; end }
|
127
|
-
/
|
128
|
-
'' { def value; true; end }
|
129
|
-
end
|
130
|
-
|
131
|
-
rule post_qualifiers
|
132
|
-
'[' s q0:post_qualifier tail:( s ',' s q1:post_qualifier )* s ']' s
|
133
|
-
{
|
134
|
-
def list
|
135
|
-
[q0.text_value, *tail.elements.map{|e| e.q1.text_value}]
|
136
|
-
end
|
137
|
-
}
|
138
|
-
end
|
139
|
-
|
140
|
-
rule post_qualifier
|
141
|
-
static / transient /
|
142
|
-
intransitive / stronglyintransitive / transitive / acyclic / symmetric / asymmetric / antisymmetric / reflexive / irreflexive
|
143
|
-
end
|
144
|
-
|
145
|
-
rule clauses_list
|
146
|
-
clauses tail:( ',' s clauses )*
|
147
|
-
{
|
148
|
-
def ast
|
149
|
-
[clauses.ast, *tail.elements.map{|e| e.clauses.ast }]
|
150
|
-
end
|
151
|
-
}
|
152
|
-
end
|
153
|
-
|
154
|
-
rule clauses
|
155
|
-
contracted_clauses s tail:( and s contracted_clauses s )*
|
156
|
-
{
|
157
|
-
def ast
|
158
|
-
clauses = contracted_clauses.ast
|
159
|
-
tail.elements.map{|e| clauses += e.contracted_clauses.ast }
|
160
|
-
clauses
|
161
|
-
end
|
162
|
-
}
|
163
|
-
end
|
164
|
-
|
165
|
-
rule contracted_clauses
|
166
|
-
comparison
|
167
|
-
/
|
168
|
-
(
|
169
|
-
contraction # A contraction will terminate this repetition by eating to the end
|
170
|
-
/
|
171
|
-
phrase
|
172
|
-
)+
|
173
|
-
{
|
174
|
-
def ast
|
175
|
-
asts = elements.map{ |r| r.ast }
|
176
|
-
contracted_clauses = []
|
177
|
-
qualifiers = []
|
178
|
-
if asts[-1].is_a?(Array) # A contraction (Array of [role, qualifiers, *clauses])
|
179
|
-
contracted_clauses = asts.pop # Pull off the contracted_clauses
|
180
|
-
contracted_role = contracted_clauses.shift
|
181
|
-
qualifiers = contracted_clauses.shift
|
182
|
-
asts.push(contracted_role) # And replace it by the role removed from the contracted_clauses
|
183
|
-
end
|
184
|
-
clause_ast = Compiler::Clause.new(asts, qualifiers)
|
185
|
-
[clause_ast] + contracted_clauses
|
186
|
-
end
|
187
|
-
}
|
188
|
-
end
|
189
|
-
|
190
|
-
rule contraction
|
191
|
-
reading_contraction /
|
192
|
-
condition_contraction
|
193
|
-
end
|
194
|
-
|
195
|
-
rule reading_contraction
|
196
|
-
role p:post_qualifiers? conjunction:(that/who) s certainty s contracted_clauses s
|
197
|
-
{
|
198
|
-
def ast
|
199
|
-
# contracted_clauses.ast will return an array of Clauses, but the first clause is special. We must:
|
200
|
-
# * prepend a new role (we get the Role to build *two* ast nodes)
|
201
|
-
# * attach the qualifiers
|
202
|
-
clauses_ast = contracted_clauses.ast
|
203
|
-
clauses_ast[0].conjunction = conjunction.text_value
|
204
|
-
clauses_ast[0].phrases.unshift(role.ast)
|
205
|
-
clauses_ast[0].certainty = certainty.value
|
206
|
-
|
207
|
-
# A contraction returns an array containing:
|
208
|
-
# * a role AST
|
209
|
-
# * a qualifiers array
|
210
|
-
# * an array of Clauses
|
211
|
-
[role.ast, p.empty? ? [] : p.list] + clauses_ast
|
212
|
-
end
|
213
|
-
}
|
214
|
-
end
|
215
|
-
|
216
|
-
rule condition_contraction
|
217
|
-
role pq:post_qualifiers? certainty s comparator s e2:expression
|
218
|
-
!phrase # The contracted_clauses must not continue here!
|
219
|
-
{
|
220
|
-
def ast
|
221
|
-
c = Compiler::Comparison.new(comparator.text_value, role.ast, e2.ast, certainty.value)
|
222
|
-
c.conjunction = comparator.text_value
|
223
|
-
[ role.ast, pq.empty? ? [] : pq.list, c ]
|
224
|
-
end
|
225
|
-
}
|
226
|
-
end
|
227
|
-
|
228
|
-
rule comparison
|
229
|
-
e1:expression s certainty s comparator s contraction p:post_qualifiers?
|
230
|
-
{
|
231
|
-
def ast
|
232
|
-
role, qualifiers, *clauses_ast = *contraction.ast
|
233
|
-
clauses_ast[0].qualifiers += p.list unless p.empty? # apply post_qualifiers to the contracted clause
|
234
|
-
# clauses_ast[0].conjunction = 'and' # AND is implicit for a contraction
|
235
|
-
c = Compiler::Comparison.new(comparator.text_value, e1.ast, role, certainty.value)
|
236
|
-
[c] + clauses_ast
|
237
|
-
end
|
238
|
-
}
|
239
|
-
/
|
240
|
-
certainty e1:expression s comparator s e2:expression # comparisons have no post-qualifiers: p:post_qualifiers?
|
241
|
-
{
|
242
|
-
def ast
|
243
|
-
c = Compiler::Comparison.new(comparator.text_value, e1.ast, e2.ast, certainty.value)
|
244
|
-
[c]
|
245
|
-
end
|
246
|
-
}
|
247
|
-
end
|
248
|
-
|
249
|
-
rule comparator
|
250
|
-
'<=' / '<>' / '<' / '=' / '>=' / '>' / '!='
|
251
|
-
end
|
252
|
-
|
253
|
-
rule phrase
|
254
|
-
role # A role reference containing a term, perhaps with attached paraphernalia
|
255
|
-
/ # A hyphenated non-term. Important: no embedded spaces
|
256
|
-
id tail:('-' !term id)+ s
|
257
|
-
{
|
258
|
-
def ast
|
259
|
-
[id.value, *tail.elements.map{|e| e.id.value}]*"-"
|
260
|
-
end
|
261
|
-
def node_type; :linking; end
|
262
|
-
}
|
263
|
-
/ # A normal non-term
|
264
|
-
!non_phrase id s
|
265
|
-
{
|
266
|
-
def ast
|
267
|
-
id.value
|
268
|
-
end
|
269
|
-
def node_type; :linking; end
|
270
|
-
}
|
271
|
-
end
|
272
|
-
|
273
|
-
rule role
|
274
|
-
aggregate
|
275
|
-
/
|
276
|
-
simple_role
|
277
|
-
end
|
278
|
-
|
279
|
-
rule aggregate
|
280
|
-
aggregate:id s
|
281
|
-
agg_of s term_or_unary s agg_in s # REVISIT: this term may need to pre-scanned in the qualified_clauses
|
282
|
-
'(' qualified_clauses s ')' # REVISIT: Need to test to verify this is the right level (not query_clauses, etc)
|
283
|
-
{
|
284
|
-
def ast
|
285
|
-
raise "Not implemented: AST for '#{aggregate.text_value} of #{term_or_unary.text_value}'"
|
286
|
-
# This returns just the role with the nested clauses, which doesn't even work:
|
287
|
-
term.ast(
|
288
|
-
nil, # No quantifier
|
289
|
-
nil, # No function call
|
290
|
-
nil, # No role_name
|
291
|
-
nil, # No value_constraint
|
292
|
-
nil, # No literal
|
293
|
-
qualified_clauses.ast
|
294
|
-
)
|
295
|
-
end
|
296
|
-
}
|
297
|
-
end
|
298
|
-
|
299
|
-
rule role_quantifier
|
300
|
-
quantifier mapping_pragmas enforcement cn:context_note?
|
301
|
-
{
|
302
|
-
def ast
|
303
|
-
Compiler::Quantifier.new(
|
304
|
-
quantifier.value[0],
|
305
|
-
quantifier.value[1],
|
306
|
-
enforcement.ast,
|
307
|
-
cn.empty? ? nil : cn.ast,
|
308
|
-
mapping_pragmas.value
|
309
|
-
)
|
310
|
-
end
|
311
|
-
}
|
312
|
-
end
|
313
|
-
|
314
|
-
# This is the rule that causes most back-tracking. I think you can see why.
|
315
|
-
rule simple_role
|
316
|
-
q:role_quantifier?
|
317
|
-
player:derived_variable
|
318
|
-
lr:(
|
319
|
-
literal u:unit?
|
320
|
-
/
|
321
|
-
value_constraint enforcement
|
322
|
-
)?
|
323
|
-
oj:objectification_step?
|
324
|
-
{
|
325
|
-
def ast
|
326
|
-
if !q.empty? && q.quantifier.value
|
327
|
-
quantifier = q.ast
|
328
|
-
end
|
329
|
-
if !lr.empty?
|
330
|
-
if lr.respond_to?(:literal)
|
331
|
-
literal = Compiler::Literal.new(lr.literal.value, lr.u.empty? ? nil : lr.u.text_value)
|
332
|
-
end
|
333
|
-
value_constraint = Compiler::ValueConstraint.new(lr.value_constraint.ast, lr.enforcement.ast) if lr.respond_to?(:value_constraint)
|
334
|
-
raise "It is not permitted to provide both a literal value and a value constraint" if value_constraint and literal
|
335
|
-
end
|
336
|
-
|
337
|
-
nested_clauses =
|
338
|
-
if oj.empty?
|
339
|
-
nil
|
340
|
-
else
|
341
|
-
ast = oj.ast
|
342
|
-
ast[0].conjunction = 'where'
|
343
|
-
ast
|
344
|
-
end
|
345
|
-
player.ast(quantifier, value_constraint, literal, nested_clauses)
|
346
|
-
end
|
347
|
-
}
|
348
|
-
end
|
349
|
-
|
350
|
-
rule objectification_step
|
351
|
-
'(' s in_which s facts:query_clauses s ')' s
|
352
|
-
{
|
353
|
-
def ast
|
354
|
-
facts.ast
|
355
|
-
end
|
356
|
-
}
|
357
|
-
end
|
358
|
-
|
359
|
-
rule role_name
|
360
|
-
'(' s as S r:term s ')' s
|
361
|
-
{ def value; r.value; end }
|
362
|
-
end
|
363
|
-
|
364
|
-
rule subscript
|
365
|
-
'(' s i:([1-9] [0-9]*) s ')' s
|
366
|
-
{ def value; i.text_value.to_i; end }
|
367
|
-
end
|
368
|
-
|
369
|
-
end
|
370
|
-
end
|
371
|
-
end
|
@@ -1,329 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# ActiveFacts CQL Parser.
|
3
|
-
# Parse rules the English syntax of CQL.
|
4
|
-
#
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
6
|
-
#
|
7
|
-
module ActiveFacts
|
8
|
-
module CQL
|
9
|
-
grammar English
|
10
|
-
|
11
|
-
# >>>>>>>>>>>>>>>>>>>> Object Types <<<<<<<<<<<<<<<<<<<<
|
12
|
-
# The pattern to introduce a Value Type
|
13
|
-
rule written_as
|
14
|
-
s 'is' s 'written' S as s
|
15
|
-
end
|
16
|
-
|
17
|
-
rule auto_assignment
|
18
|
-
'auto-assigned' S at s time:('assert' / 'commit') !alphanumeric s
|
19
|
-
{
|
20
|
-
def auto_assigned_at
|
21
|
-
time.text_value
|
22
|
-
end
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
# The pattern to introduce an Entity Type
|
27
|
-
rule identified_by
|
28
|
-
identified s by s
|
29
|
-
end
|
30
|
-
|
31
|
-
rule basetype_expression
|
32
|
-
is s i:( independent s )? identification
|
33
|
-
end
|
34
|
-
|
35
|
-
# The pattern to introduce an Entity Subtype
|
36
|
-
rule subtype_prefix
|
37
|
-
'is' s 'a' s ('kind'/'subtype') s 'of' S
|
38
|
-
end
|
39
|
-
|
40
|
-
rule subtype_expression
|
41
|
-
subtype_prefix i:( independent s )? supertype_list ident:identification?
|
42
|
-
end
|
43
|
-
|
44
|
-
# The pattern to introduce an objectified fact type with implicit identification
|
45
|
-
rule is_where
|
46
|
-
is s i:(independent s)? where
|
47
|
-
{ def independent; !i.empty?; end }
|
48
|
-
end
|
49
|
-
|
50
|
-
rule in_which # Introduce an objectification step
|
51
|
-
where / # Old syntax
|
52
|
-
in s which # preferred syntax
|
53
|
-
end
|
54
|
-
|
55
|
-
# Units conversion keyword
|
56
|
-
rule conversion
|
57
|
-
converts s a:(approximately s)? to s
|
58
|
-
{
|
59
|
-
def approximate?
|
60
|
-
!a.empty?
|
61
|
-
end
|
62
|
-
}
|
63
|
-
end
|
64
|
-
|
65
|
-
# >>>>>>>>>>>>>>>>>>>> Constraints <<<<<<<<<<<<<<<<<<<<
|
66
|
-
# External presence constraint syntax:
|
67
|
-
rule each_occurs_in_clauses
|
68
|
-
s 'each' s ('combination' S)? role_list s occurs s quantifier s 'time' 's'? s enforcement 'in' s
|
69
|
-
clauses_list s c:context_note? ';'
|
70
|
-
{
|
71
|
-
def role_list_ast
|
72
|
-
role_list.ast
|
73
|
-
end
|
74
|
-
def quantifier_ast
|
75
|
-
quantifier.ast
|
76
|
-
end
|
77
|
-
def clauses_ast
|
78
|
-
clauses_list.ast
|
79
|
-
end
|
80
|
-
}
|
81
|
-
end
|
82
|
-
|
83
|
-
# Alternate external presence constraint syntax:
|
84
|
-
rule either_or
|
85
|
-
s either? s r1:clauses s or s r2:clauses c:context_note? enforcement ';'
|
86
|
-
{
|
87
|
-
def role_list_ast
|
88
|
-
nil
|
89
|
-
end
|
90
|
-
def quantifier_ast
|
91
|
-
Compiler::Quantifier.new(1, nil)
|
92
|
-
end
|
93
|
-
def clauses_ast
|
94
|
-
[r1.ast, r2.ast]
|
95
|
-
end
|
96
|
-
}
|
97
|
-
end
|
98
|
-
|
99
|
-
# Exclusion (at most one) and mandatory exclusion (exactly one) constraint syntax:
|
100
|
-
rule for_each_how_many
|
101
|
-
s 'for' s 'each' s role_list s quantifier s 'of' s 'these' s 'holds' s enforcement ':' s
|
102
|
-
clauses_list s c:context_note? ';'
|
103
|
-
{
|
104
|
-
def role_list_ast
|
105
|
-
role_list.ast
|
106
|
-
end
|
107
|
-
def quantifier_ast
|
108
|
-
quantifier.ast
|
109
|
-
end
|
110
|
-
def clauses_ast
|
111
|
-
clauses_list.ast
|
112
|
-
end
|
113
|
-
}
|
114
|
-
end
|
115
|
-
|
116
|
-
# Alternate mandatory exclusion constraint syntax:
|
117
|
-
rule either_or_not_both
|
118
|
-
s either? s r1:clauses s or s r2:clauses but s not s both s c:context_note? enforcement ';'
|
119
|
-
{
|
120
|
-
def role_list_ast
|
121
|
-
nil
|
122
|
-
end
|
123
|
-
def quantifier_ast
|
124
|
-
Compiler::Quantifier.new(1, 1)
|
125
|
-
end
|
126
|
-
def clauses_ast
|
127
|
-
[r1.ast, r2.ast]
|
128
|
-
end
|
129
|
-
}
|
130
|
-
end
|
131
|
-
|
132
|
-
# Subset constraint using "A only if B" syntax
|
133
|
-
rule a_only_if_b
|
134
|
-
s clauses:query_clauses s only s if s r2:query_clauses s c:context_note? enforcement ';'
|
135
|
-
end
|
136
|
-
|
137
|
-
rule only_if
|
138
|
-
only s if s
|
139
|
-
end
|
140
|
-
|
141
|
-
# Subset constraint using "if A then B" syntax
|
142
|
-
rule if_b_then_a
|
143
|
-
s if s clauses s then s r2:clauses s c:context_note? enforcement ';'
|
144
|
-
end
|
145
|
-
|
146
|
-
# Equality constraint syntax:
|
147
|
-
rule if_and_only_if
|
148
|
-
s clauses s tail:( if s and s only s if s clauses s)+
|
149
|
-
c:context_note? enforcement ';'
|
150
|
-
end
|
151
|
-
|
152
|
-
# During the prescan we need to know where terms in a role list finish.
|
153
|
-
# This rule matches any non-term expressions that may follow a role list.
|
154
|
-
rule role_list_constraint_followers
|
155
|
-
occurs s quantifier s 'time'
|
156
|
-
end
|
157
|
-
|
158
|
-
# >>>>>>>>>>>>>>>>>>>> Quantifiers <<<<<<<<<<<<<<<<<<<<
|
159
|
-
rule quantifier
|
160
|
-
quantifier1
|
161
|
-
{
|
162
|
-
def ast
|
163
|
-
v = value
|
164
|
-
Compiler::Quantifier.new(v[0], v[1])
|
165
|
-
end
|
166
|
-
}
|
167
|
-
end
|
168
|
-
|
169
|
-
rule quantifier1
|
170
|
-
(some s { def value; nil; end })
|
171
|
-
# REVISIT: "Some" means that any prior occurrence of this role player is to be ignored; this is a new occurrence
|
172
|
-
# "that" on the other hand means that this role player was *previously* designated using "some".
|
173
|
-
# These distinctions are lost here
|
174
|
-
/ (that s { def value; nil; end })
|
175
|
-
/ (which s { def value; nil; end })
|
176
|
-
/ (one s { def value; [1, 1]; end })
|
177
|
-
/ (no s { def value; [0, 0]; end })
|
178
|
-
/ (exactly s quantity { def value; q = quantity.value; [q, q]; end })
|
179
|
-
/ (at s least s quantity most:( and s at s most s q:quantity )?
|
180
|
-
{ def value;
|
181
|
-
[ quantity.value,
|
182
|
-
most.empty? ? nil : most.q.value
|
183
|
-
]
|
184
|
-
end
|
185
|
-
}
|
186
|
-
)
|
187
|
-
/ (at s most s quantity { def value; [ nil, quantity.value ]; end })
|
188
|
-
/ (from s numeric_range s { def value; numeric_range.value; end })
|
189
|
-
# / (either_all_or_none s { def value; [ -1, 1 ]; end })
|
190
|
-
end
|
191
|
-
|
192
|
-
# rule either_all_or_none either s all s or s ( none / no ) end
|
193
|
-
|
194
|
-
rule quantity
|
195
|
-
one s { def value; 1; end }
|
196
|
-
/ number s { def value; number.value; end }
|
197
|
-
end
|
198
|
-
|
199
|
-
# >>>>>>>>>>>>>>>>>>>> Context Notes <<<<<<<<<<<<<<<<<<<<
|
200
|
-
rule as_agreed_by
|
201
|
-
s as s 'agreed' s d:('on' S date)? by s agents
|
202
|
-
{ def value; [ d.empty? ? nil : d.date.value, agents.value ]; end }
|
203
|
-
end
|
204
|
-
|
205
|
-
rule date
|
206
|
-
s d:(!(by/')') .)+
|
207
|
-
{ def value; d.text_value.strip; end }
|
208
|
-
end
|
209
|
-
|
210
|
-
rule agents
|
211
|
-
s h:agent s t:(',' s !context_type agent s)*
|
212
|
-
{
|
213
|
-
def value; [h.text_value] + t.elements.map{|e| e.agent.text_value }; end
|
214
|
-
def node_type; :linking; end
|
215
|
-
}
|
216
|
-
end
|
217
|
-
|
218
|
-
rule agent
|
219
|
-
id (s id)*
|
220
|
-
end
|
221
|
-
|
222
|
-
rule negative_prefix
|
223
|
-
s it s is s not s the s case s that s
|
224
|
-
end
|
225
|
-
|
226
|
-
rule agg_of of end
|
227
|
-
rule agg_in in end
|
228
|
-
rule restricted_to restricted s 'to' s !alphanumeric end
|
229
|
-
# any is optionally used in an identifying role_list
|
230
|
-
rule any one / a end
|
231
|
-
|
232
|
-
# >>>>>>>>>>>>>>>>>>>> Internal vocabulary <<<<<<<<<<<<<<<<<<<<
|
233
|
-
rule a ('a' !alphanumeric /'an' !alphanumeric) end
|
234
|
-
rule all 'all' !alphanumeric end
|
235
|
-
rule ascending 'ascending' !alphanumeric end
|
236
|
-
rule at 'at' !alphanumeric end
|
237
|
-
rule both 'both' !alphanumeric end
|
238
|
-
rule converts 'converts' !alphanumeric end
|
239
|
-
rule descending 'descending' !alphanumeric end
|
240
|
-
rule each 'each' !alphanumeric end
|
241
|
-
rule either 'either' !alphanumeric end
|
242
|
-
rule entity 'entity' !alphanumeric end
|
243
|
-
rule exactly 'exactly' !alphanumeric end
|
244
|
-
rule from 'from' !alphanumeric end
|
245
|
-
rule includes 'includes' !alphanumeric end
|
246
|
-
rule least 'least' !alphanumeric end
|
247
|
-
rule matches 'matches' !alphanumeric end
|
248
|
-
rule most 'most' !alphanumeric end
|
249
|
-
rule no 'no' !alphanumeric end
|
250
|
-
rule none 'none' !alphanumeric end
|
251
|
-
rule not 'not' !alphanumeric end
|
252
|
-
rule occurs 'occurs' !alphanumeric end
|
253
|
-
rule one 'one' !alphanumeric end
|
254
|
-
rule some 'some' !alphanumeric end
|
255
|
-
|
256
|
-
# >>>>>>>>>>>>>>>>>>>> External vocabulary <<<<<<<<<<<<<<<<<<<<
|
257
|
-
rule accepts 'accepts' !alphanumeric end
|
258
|
-
rule according_to 'according' S to end
|
259
|
-
rule acyclic 'acyclic' !alphanumeric end
|
260
|
-
rule alias 'alias' !alphanumeric end
|
261
|
-
rule and 'and' !alphanumeric end
|
262
|
-
rule antisymmetric 'antisymmetric' !alphanumeric end
|
263
|
-
rule approximately 'approximately' !alphanumeric end
|
264
|
-
rule as 'as' !alphanumeric end
|
265
|
-
rule as_opposed_to as s 'opposed' S to end
|
266
|
-
rule asymmetric 'asymmetric' !alphanumeric end
|
267
|
-
rule because 'because' !alphanumeric end
|
268
|
-
rule but 'but' !alphanumeric end
|
269
|
-
rule by 'by' !alphanumeric end # fix? Used in 'returning' for ordering
|
270
|
-
rule case 'case' !alphanumeric end
|
271
|
-
rule definitely 'definitely' !alphanumeric end
|
272
|
-
rule ephemera 'ephemera' !alphanumeric end
|
273
|
-
rule false 'false' !alphanumeric end
|
274
|
-
rule feminine 'feminine' !alphanumeric end
|
275
|
-
rule identified ('known'/'identified') !alphanumeric end
|
276
|
-
rule if 'if' !alphanumeric end
|
277
|
-
rule in 'in' !alphanumeric end
|
278
|
-
rule import 'import' !alphanumeric end
|
279
|
-
rule independent 'independent' !alphanumeric end
|
280
|
-
rule stronglyintransitive 'strongly' s 'intransitive' !alphanumeric end
|
281
|
-
rule informally [Ii] 'nformally' !alphanumeric end
|
282
|
-
rule intransitive 'intransitive' !alphanumeric end
|
283
|
-
rule irreflexive 'irreflexive' !alphanumeric end
|
284
|
-
rule is 'is' !alphanumeric end
|
285
|
-
rule it 'it' !alphanumeric end
|
286
|
-
rule its 'its' !alphanumeric end
|
287
|
-
rule masculine 'masculine' !alphanumeric end
|
288
|
-
rule max 'max' !alphanumeric end
|
289
|
-
rule maybe 'maybe' !alphanumeric end
|
290
|
-
rule min 'min' !alphanumeric end
|
291
|
-
rule only 'only' !alphanumeric end
|
292
|
-
rule or 'or' !alphanumeric end
|
293
|
-
rule of 'of' !alphanumeric end
|
294
|
-
rule ordering_prefix by s (ascending/descending)? s end
|
295
|
-
rule otherwise 'otherwise' !alphanumeric end
|
296
|
-
rule partitioned 'partitioned' !alphanumeric end
|
297
|
-
rule personal 'personal' !alphanumeric end
|
298
|
-
rule radix_point '.' end
|
299
|
-
rule reflexive 'reflexive' !alphanumeric end
|
300
|
-
rule restricted 'restricted' !alphanumeric end
|
301
|
-
rule restricts 'restricts' !alphanumeric end
|
302
|
-
rule returning 'returning' !alphanumeric end
|
303
|
-
rule schema 'schema' !alphanumeric end
|
304
|
-
rule separate 'separate' !alphanumeric end
|
305
|
-
rule so_that 'so' S that end
|
306
|
-
rule static 'static' !alphanumeric end
|
307
|
-
rule symmetric 'symmetric' !alphanumeric end
|
308
|
-
rule that 'that' !alphanumeric end
|
309
|
-
rule the 'the' !alphanumeric end
|
310
|
-
rule then 'then' !alphanumeric end
|
311
|
-
rule to 'to' !alphanumeric end
|
312
|
-
rule to_avoid to s 'avoid' !alphanumeric end
|
313
|
-
rule topic 'topic' !alphanumeric end
|
314
|
-
rule transform 'transform' !alphanumeric end
|
315
|
-
rule transient 'transient' !alphanumeric end
|
316
|
-
rule transitive 'transitive' !alphanumeric end
|
317
|
-
rule true 'true' !alphanumeric end
|
318
|
-
rule version 'version' !alphanumeric end
|
319
|
-
rule vocabulary 'vocabulary' !alphanumeric end
|
320
|
-
rule was 'was' !alphanumeric end
|
321
|
-
rule when 'when' !alphanumeric end
|
322
|
-
rule where 'where' !alphanumeric end
|
323
|
-
rule which 'which' !alphanumeric end
|
324
|
-
rule who 'who' !alphanumeric end
|
325
|
-
rule with 'with' !alphanumeric end
|
326
|
-
|
327
|
-
end
|
328
|
-
end
|
329
|
-
end
|