activefacts 0.8.16 → 0.8.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Manifest.txt +10 -4
- data/bin/afgen +26 -20
- data/bin/cql +1 -1
- data/css/orm2.css +89 -9
- data/examples/CQL/CompanyDirectorEmployee.cql +4 -4
- data/examples/CQL/Genealogy.cql +5 -5
- data/examples/CQL/Metamodel.cql +121 -91
- data/examples/CQL/MonthInSeason.cql +2 -6
- data/examples/CQL/SeparateSubtype.cql +11 -9
- data/examples/CQL/ServiceDirector.cql +21 -33
- data/examples/CQL/Supervision.cql +0 -3
- data/examples/CQL/WindowInRoomInBldg.cql +10 -4
- data/examples/CQL/unit.cql +1 -1
- data/lib/activefacts.rb +1 -0
- data/lib/activefacts/cql/CQLParser.treetop +5 -1
- data/lib/activefacts/cql/Context.treetop +2 -7
- data/lib/activefacts/cql/Expressions.treetop +2 -2
- data/lib/activefacts/cql/FactTypes.treetop +37 -31
- data/lib/activefacts/cql/Language/English.treetop +21 -4
- data/lib/activefacts/cql/LexicalRules.treetop +59 -1
- data/lib/activefacts/cql/ObjectTypes.treetop +22 -12
- data/lib/activefacts/cql/Terms.treetop +13 -9
- data/lib/activefacts/cql/ValueTypes.treetop +30 -11
- data/lib/activefacts/cql/compiler.rb +34 -5
- data/lib/activefacts/cql/compiler/clause.rb +207 -116
- data/lib/activefacts/cql/compiler/constraint.rb +129 -105
- data/lib/activefacts/cql/compiler/entity_type.rb +49 -27
- data/lib/activefacts/cql/compiler/expression.rb +71 -42
- data/lib/activefacts/cql/compiler/fact.rb +70 -64
- data/lib/activefacts/cql/compiler/fact_type.rb +108 -57
- data/lib/activefacts/cql/compiler/query.rb +178 -0
- data/lib/activefacts/cql/compiler/shared.rb +13 -12
- data/lib/activefacts/cql/compiler/value_type.rb +10 -4
- data/lib/activefacts/cql/nodes.rb +1 -1
- data/lib/activefacts/cql/parser.rb +6 -2
- data/lib/activefacts/generate/absorption.rb +6 -3
- data/lib/activefacts/generate/cql.rb +140 -84
- data/lib/activefacts/generate/dm.rb +12 -6
- data/lib/activefacts/generate/help.rb +25 -6
- data/lib/activefacts/generate/helpers/oo.rb +195 -0
- data/lib/activefacts/generate/helpers/ordered.rb +589 -0
- data/lib/activefacts/generate/helpers/rails.rb +57 -0
- data/lib/activefacts/generate/html/glossary.rb +274 -54
- data/lib/activefacts/generate/json.rb +25 -22
- data/lib/activefacts/generate/null.rb +1 -0
- data/lib/activefacts/generate/rails/models.rb +244 -0
- data/lib/activefacts/generate/rails/schema.rb +185 -0
- data/lib/activefacts/generate/records.rb +1 -0
- data/lib/activefacts/generate/ruby.rb +51 -30
- data/lib/activefacts/generate/sql/mysql.rb +5 -3
- data/lib/activefacts/generate/sql/server.rb +8 -4
- data/lib/activefacts/generate/text.rb +1 -0
- data/lib/activefacts/generate/transform/surrogate.rb +209 -0
- data/lib/activefacts/generate/version.rb +1 -0
- data/lib/activefacts/input/orm.rb +234 -181
- data/lib/activefacts/mapping/rails.rb +122 -0
- data/lib/activefacts/persistence/columns.rb +34 -18
- data/lib/activefacts/persistence/foreignkey.rb +129 -71
- data/lib/activefacts/persistence/index.rb +42 -12
- data/lib/activefacts/persistence/reference.rb +37 -23
- data/lib/activefacts/persistence/tables.rb +53 -19
- data/lib/activefacts/registry.rb +11 -0
- data/lib/activefacts/support.rb +28 -10
- data/lib/activefacts/version.rb +1 -1
- data/lib/activefacts/vocabulary/extensions.rb +246 -117
- data/lib/activefacts/vocabulary/metamodel.rb +105 -65
- data/lib/activefacts/vocabulary/verbaliser.rb +226 -194
- data/spec/absorption_spec.rb +1 -0
- data/spec/cql/comparison_spec.rb +8 -8
- data/spec/cql/contractions_spec.rb +16 -43
- data/spec/cql/entity_type_spec.rb +2 -1
- data/spec/cql/expressions_spec.rb +2 -2
- data/spec/cql/fact_type_matching_spec.rb +4 -1
- data/spec/cql/parser/bad_literals_spec.rb +30 -30
- data/spec/cql/parser/entity_types_spec.rb +6 -6
- data/spec/cql/parser/expressions_spec.rb +25 -19
- data/spec/cql/samples_spec.rb +5 -4
- data/spec/cql_cql_spec.rb +2 -1
- data/spec/cql_dm_spec.rb +4 -0
- data/spec/cql_mysql_spec.rb +4 -0
- data/spec/cql_parse_spec.rb +2 -0
- data/spec/cql_ruby_spec.rb +4 -0
- data/spec/cql_sql_spec.rb +4 -0
- data/spec/cqldump_spec.rb +7 -4
- data/spec/helpers/parse_to_ast_matcher.rb +7 -3
- data/spec/helpers/test_parser.rb +2 -0
- data/spec/norma_cql_spec.rb +5 -2
- data/spec/norma_ruby_spec.rb +4 -1
- data/spec/norma_ruby_sql_spec.rb +4 -1
- data/spec/norma_sql_spec.rb +4 -1
- data/spec/norma_tables_spec.rb +2 -2
- data/spec/ruby_api_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/transform_surrogate_spec.rb +59 -0
- metadata +70 -60
- data/TODO +0 -308
- data/lib/activefacts/cql/compiler/join.rb +0 -162
- data/lib/activefacts/generate/oo.rb +0 -176
- data/lib/activefacts/generate/ordered.rb +0 -602
@@ -6,7 +6,7 @@
|
|
6
6
|
#
|
7
7
|
module ActiveFacts
|
8
8
|
module CQL
|
9
|
-
grammar
|
9
|
+
grammar English
|
10
10
|
|
11
11
|
# >>>>>>>>>>>>>>>>>>>> Object Types <<<<<<<<<<<<<<<<<<<<
|
12
12
|
# The pattern to introduce a Value Type
|
@@ -38,10 +38,9 @@ module ActiveFacts
|
|
38
38
|
{ def independent; !i.empty?; end }
|
39
39
|
end
|
40
40
|
|
41
|
-
rule in_which # Introduce an objectification
|
41
|
+
rule in_which # Introduce an objectification step
|
42
42
|
where / # Old syntax
|
43
43
|
in s which # preferred syntax
|
44
|
-
{ def independent; !i.empty?; end }
|
45
44
|
end
|
46
45
|
|
47
46
|
# Units conversion keyword
|
@@ -126,6 +125,10 @@ module ActiveFacts
|
|
126
125
|
s clauses s only s if s r2:clauses s c:context_note? enforcement ';'
|
127
126
|
end
|
128
127
|
|
128
|
+
rule only_if
|
129
|
+
only s if s
|
130
|
+
end
|
131
|
+
|
129
132
|
# Subset constraint using "if A then B" syntax
|
130
133
|
rule if_b_then_a
|
131
134
|
s if s clauses s then s r2:clauses s c:context_note? enforcement ';'
|
@@ -204,7 +207,18 @@ module ActiveFacts
|
|
204
207
|
id (s id)*
|
205
208
|
end
|
206
209
|
|
210
|
+
rule negative_prefix
|
211
|
+
s it s is s not s the s case s that s
|
212
|
+
end
|
213
|
+
|
214
|
+
rule agg_of of end
|
215
|
+
rule agg_in in end
|
216
|
+
rule restricted_to 'restricted' s 'to' s !alphanumeric end
|
217
|
+
# any is optionally used in an identifying role_list
|
218
|
+
rule any one / a end
|
219
|
+
|
207
220
|
# >>>>>>>>>>>>>>>>>>>> Internal vocabulary <<<<<<<<<<<<<<<<<<<<
|
221
|
+
rule a ('a' !alphanumeric /'an' !alphanumeric) end
|
208
222
|
rule all 'all' !alphanumeric end
|
209
223
|
rule ascending 'ascending' !alphanumeric end
|
210
224
|
rule at 'at' !alphanumeric end
|
@@ -240,6 +254,7 @@ module ActiveFacts
|
|
240
254
|
rule because 'because' !alphanumeric end
|
241
255
|
rule but 'but' !alphanumeric end
|
242
256
|
rule by 'by' !alphanumeric end # fix? Used in 'returning' for ordering
|
257
|
+
rule case 'case' !alphanumeric end
|
243
258
|
rule definitely 'definitely' !alphanumeric end
|
244
259
|
rule ephemera 'ephemera' !alphanumeric end
|
245
260
|
rule false 'false' !alphanumeric end
|
@@ -249,9 +264,11 @@ module ActiveFacts
|
|
249
264
|
rule in 'in' !alphanumeric end
|
250
265
|
rule import 'import' !alphanumeric end
|
251
266
|
rule independent 'independent' !alphanumeric end
|
267
|
+
rule stronglyintransitive 'stronglyintransitive' !alphanumeric end
|
252
268
|
rule intransitive 'intransitive' !alphanumeric end
|
253
269
|
rule irreflexive 'irreflexive' !alphanumeric end
|
254
270
|
rule is 'is' !alphanumeric end
|
271
|
+
rule it 'it' !alphanumeric end
|
255
272
|
rule its 'its' !alphanumeric end
|
256
273
|
rule masculine 'masculine' !alphanumeric end
|
257
274
|
rule maybe 'maybe' !alphanumeric end
|
@@ -264,13 +281,13 @@ module ActiveFacts
|
|
264
281
|
rule personal 'personal' !alphanumeric end
|
265
282
|
rule radix_point '.' end
|
266
283
|
rule reflexive 'reflexive' !alphanumeric end
|
267
|
-
rule restricted 'restricted' !alphanumeric end
|
268
284
|
rule returning 'returning' !alphanumeric end
|
269
285
|
rule separate 'separate' !alphanumeric end
|
270
286
|
rule so_that 'so' S that end
|
271
287
|
rule static 'static' !alphanumeric end
|
272
288
|
rule symmetric 'symmetric' !alphanumeric end
|
273
289
|
rule that 'that' !alphanumeric end
|
290
|
+
rule the 'the' !alphanumeric end
|
274
291
|
rule then 'then' !alphanumeric end
|
275
292
|
rule to 'to' !alphanumeric end
|
276
293
|
rule to_avoid to s 'avoid' !alphanumeric end
|
@@ -116,6 +116,7 @@ module ActiveFacts
|
|
116
116
|
rule string_char
|
117
117
|
( '\\' [befntr\\']
|
118
118
|
/ '\\' [0-7] [0-7] [0-7]
|
119
|
+
/ '\\' [\r]* [\n] [\r]*
|
119
120
|
/ '\\0'
|
120
121
|
/ '\\x' [0-9A-Fa-f] [0-9A-Fa-f]
|
121
122
|
/ '\\u' [0-9A-Fa-f] [0-9A-Fa-f] [0-9A-Fa-f] [0-9A-Fa-f]
|
@@ -157,7 +158,7 @@ module ActiveFacts
|
|
157
158
|
end
|
158
159
|
|
159
160
|
rule alpha
|
160
|
-
|
161
|
+
[[:alpha:]]
|
161
162
|
end
|
162
163
|
|
163
164
|
rule alphanumeric
|
@@ -190,6 +191,63 @@ module ActiveFacts
|
|
190
191
|
}
|
191
192
|
end
|
192
193
|
|
194
|
+
rule regular_expression
|
195
|
+
'/' !'/' regular_expression_contents '/'
|
196
|
+
{
|
197
|
+
def contents
|
198
|
+
regular_expression_contents.text_value
|
199
|
+
end
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
rule regular_expression_contents
|
204
|
+
regular_expression_alternate ( '|' regular_expression_alternate )*
|
205
|
+
end
|
206
|
+
|
207
|
+
rule regular_expression_alternate
|
208
|
+
regular_expression_sequence
|
209
|
+
end
|
210
|
+
|
211
|
+
rule regular_expression_sequence
|
212
|
+
regular_expression_atom*
|
213
|
+
end
|
214
|
+
|
215
|
+
rule regular_expression_atom
|
216
|
+
(
|
217
|
+
'[' character_classes ']'
|
218
|
+
/ regular_expression_group
|
219
|
+
/ ![*+?()|/] string_char
|
220
|
+
) regular_expression_multiplicity?
|
221
|
+
end
|
222
|
+
|
223
|
+
rule character_classes
|
224
|
+
character_class+
|
225
|
+
end
|
226
|
+
|
227
|
+
rule character_class
|
228
|
+
!']' string_char '-' !']' string_char
|
229
|
+
/ '-'
|
230
|
+
/ !']' string_char
|
231
|
+
end
|
232
|
+
|
233
|
+
rule regular_expression_multiplicity
|
234
|
+
'*' / '+' / '?'
|
235
|
+
end
|
236
|
+
|
237
|
+
rule regular_expression_group
|
238
|
+
'('
|
239
|
+
regular_expression_group_extension?
|
240
|
+
regular_expression_contents
|
241
|
+
')'
|
242
|
+
end
|
243
|
+
|
244
|
+
rule regular_expression_group_extension
|
245
|
+
'?' (
|
246
|
+
'<' ( !'>' .)+ '>' # A tag for a regular expression group
|
247
|
+
# REVISIT: Add more group extensions as needed
|
248
|
+
)
|
249
|
+
end
|
250
|
+
|
193
251
|
end
|
194
252
|
end
|
195
253
|
end
|
@@ -15,19 +15,22 @@ module ActiveFacts
|
|
15
15
|
end
|
16
16
|
|
17
17
|
rule entity_type
|
18
|
+
s each?
|
18
19
|
s term_definition_name
|
19
20
|
m1:mapping_pragmas
|
21
|
+
c:context_note?
|
20
22
|
sup:(basetype / subtype)
|
21
23
|
&{|s|
|
22
24
|
# There's an implicit type when we use an identification mode, register it:
|
23
|
-
mode = s[
|
25
|
+
mode = s[6].identification_mode
|
24
26
|
if mode
|
25
|
-
input.context.object_type(s[
|
26
|
-
input.context.object_type(s[
|
27
|
+
input.context.object_type(s[3].value+mode, "identification mode type")
|
28
|
+
input.context.object_type(s[3].value+' '+mode, "identification mode type")
|
27
29
|
end
|
28
30
|
true
|
29
31
|
}
|
30
32
|
m2:mapping_pragmas
|
33
|
+
c2:context_note?
|
31
34
|
ec:entity_clauses?
|
32
35
|
';'
|
33
36
|
{
|
@@ -36,7 +39,8 @@ module ActiveFacts
|
|
36
39
|
clauses_ast = ec.empty? ? [] : ec.ast
|
37
40
|
pragmas = m1.value+m2.value
|
38
41
|
pragmas << 'independent' if sup.independent
|
39
|
-
|
42
|
+
context_note = !c.empty? ? c.ast : (!c2.empty? ? c2.ast : nil)
|
43
|
+
Compiler::EntityType.new name, sup.supers, sup.ast, pragmas, clauses_ast, context_note
|
40
44
|
end
|
41
45
|
}
|
42
46
|
end
|
@@ -62,7 +66,7 @@ module ActiveFacts
|
|
62
66
|
end
|
63
67
|
|
64
68
|
rule supertype_list
|
65
|
-
primary:term s alternate_supertypes:( ',' s !identified_by name:term s )*
|
69
|
+
primary:term s alternate_supertypes:( (','/'and' !alpha) s !identified_by name:term s )*
|
66
70
|
{
|
67
71
|
def value
|
68
72
|
[primary.value, *alternate_supertypes.elements.map { |sup| sup.name.value } ]
|
@@ -79,7 +83,7 @@ module ActiveFacts
|
|
79
83
|
if r.empty?
|
80
84
|
value_constraint = nil
|
81
85
|
else
|
82
|
-
value_constraint = Compiler::ValueConstraint.new(r.value_constraint.
|
86
|
+
value_constraint = Compiler::ValueConstraint.new(r.value_constraint.ast, r.enforcement.ast)
|
83
87
|
end
|
84
88
|
Compiler::ReferenceMode.new(i.value, value_constraint, value_type_parameters.values)
|
85
89
|
end
|
@@ -115,7 +119,13 @@ module ActiveFacts
|
|
115
119
|
|
116
120
|
# Identified by roles... also used for constraints, beware
|
117
121
|
rule role_list
|
118
|
-
|
122
|
+
a:any? s
|
123
|
+
head:term_or_unary s
|
124
|
+
tail:(
|
125
|
+
( and S / ',' s )
|
126
|
+
any? s
|
127
|
+
term_or_unary s
|
128
|
+
)*
|
119
129
|
{
|
120
130
|
def ast
|
121
131
|
[head.ast, *tail.elements.map{|e| e.term_or_unary.ast}]
|
@@ -124,7 +134,7 @@ module ActiveFacts
|
|
124
134
|
end
|
125
135
|
|
126
136
|
rule unary_text
|
127
|
-
(s !non_phrase !term id)*
|
137
|
+
(s !any !non_phrase !term id)*
|
128
138
|
{
|
129
139
|
def node_type; :linking; end
|
130
140
|
}
|
@@ -146,11 +156,11 @@ module ActiveFacts
|
|
146
156
|
end
|
147
157
|
}
|
148
158
|
/
|
149
|
-
s !non_phrase id s &non_phrase s ss:subscript
|
159
|
+
s !non_phrase id s &non_phrase s ss:subscript?
|
150
160
|
{ # A forward-referenced entity type
|
151
161
|
# REVISIT: A change in this rule might allow forward-referencing a multi-word term
|
152
162
|
def ast
|
153
|
-
Compiler::
|
163
|
+
Compiler::Reference.new(id.text_value, nil, nil, nil, ss.empty? ? nil : ss.value)
|
154
164
|
end
|
155
165
|
}
|
156
166
|
end
|
@@ -171,10 +181,10 @@ module ActiveFacts
|
|
171
181
|
end
|
172
182
|
|
173
183
|
rule entity_clauses
|
174
|
-
(':' / where) s
|
184
|
+
(':' / where) s query_clauses
|
175
185
|
{
|
176
186
|
def ast
|
177
|
-
|
187
|
+
query_clauses.ast
|
178
188
|
end
|
179
189
|
}
|
180
190
|
end
|
@@ -25,20 +25,24 @@ module ActiveFacts
|
|
25
25
|
is s (independent s )? identified_by
|
26
26
|
/
|
27
27
|
subtype_prefix (independent s )? term_definition_name
|
28
|
-
|
28
|
+
&{|e| input.context.object_type(e[2].value, "subtype") }
|
29
29
|
end
|
30
30
|
|
31
31
|
rule prescan
|
32
|
-
s
|
32
|
+
s each?
|
33
|
+
s (
|
33
34
|
term_definition_name mapping_pragmas entity_prefix
|
34
35
|
&{|e| input.context.object_type(e[0].value, "entity type") }
|
35
36
|
/
|
36
|
-
t1:term_definition_name mapping_pragmas written_as t2:term_definition_name
|
37
|
-
&{|e|
|
38
|
-
|
37
|
+
t1:term_definition_name mapping_pragmas written_as any? s t2:term_definition_name
|
38
|
+
&{|e|
|
39
|
+
new_term = e[0].value
|
40
|
+
input.context.object_type(new_term, "value type")
|
41
|
+
base_term = e[5].value
|
42
|
+
input.context.object_type(base_term, "value type")
|
39
43
|
}
|
40
44
|
/
|
41
|
-
term_definition_name s mapping_pragmas
|
45
|
+
term_definition_name s mapping_pragmas is_where
|
42
46
|
&{|e| input.context.object_type(e[0].value, "objectified_fact_type") }
|
43
47
|
)?
|
44
48
|
prescan_rest
|
@@ -61,7 +65,7 @@ module ActiveFacts
|
|
61
65
|
/ '(' as S term_definition_name s ')' s # Prepare for a Role Name
|
62
66
|
&{|s| input.context.role_name(s[3].value) }
|
63
67
|
/ new_derived_value # Prepare for a derived term
|
64
|
-
/ new_adjective_term #
|
68
|
+
/ new_adjective_term # Prepare for an existing term with new Adjectives
|
65
69
|
# The remaining rules exist to correctly eat up anything that doesn't match the above:
|
66
70
|
/ global_term # If we see A B - C D, don't recognise B as a new adjective for C D.
|
67
71
|
/ prescan_aggregate
|
@@ -76,7 +80,7 @@ module ActiveFacts
|
|
76
80
|
|
77
81
|
# Not sure this is even needed, but it doesn't seem to hurt:
|
78
82
|
rule prescan_aggregate
|
79
|
-
aggregate_type:id s
|
83
|
+
aggregate_type:id s agg_of s global_term agg_in s &'('
|
80
84
|
end
|
81
85
|
|
82
86
|
rule new_derived_value
|
@@ -163,7 +167,7 @@ module ActiveFacts
|
|
163
167
|
/ but
|
164
168
|
/ if
|
165
169
|
/ role_list_constraint_followers
|
166
|
-
/
|
170
|
+
/ only_if
|
167
171
|
/ or
|
168
172
|
/ quantifier
|
169
173
|
/ returning
|
@@ -8,15 +8,19 @@ module ActiveFacts
|
|
8
8
|
module CQL
|
9
9
|
grammar ValueTypes
|
10
10
|
rule value_type
|
11
|
+
s each?
|
11
12
|
s term_definition_name
|
12
13
|
m1:mapping_pragmas
|
13
14
|
# REVISIT: ORM2 would allow (subtype_prefix term)?
|
14
15
|
written_as
|
16
|
+
any? s
|
15
17
|
base:(term/implicit_value_type_name) s
|
16
18
|
value_type_parameters
|
17
19
|
u:units?
|
20
|
+
c:context_note?
|
18
21
|
r:(value_constraint enforcement)?
|
19
22
|
m2:mapping_pragmas
|
23
|
+
c2:context_note?
|
20
24
|
s ';' s
|
21
25
|
{
|
22
26
|
def ast
|
@@ -24,11 +28,12 @@ module ActiveFacts
|
|
24
28
|
params = value_type_parameters.values
|
25
29
|
value_constraint = nil
|
26
30
|
unless r.empty?
|
27
|
-
value_constraint = Compiler::ValueConstraint.new(r.value_constraint.
|
31
|
+
value_constraint = Compiler::ValueConstraint.new(r.value_constraint.ast, r.enforcement.ast)
|
28
32
|
end
|
29
33
|
units = u.empty? ? [] : u.value
|
30
34
|
pragmas = m1.value+m2.value
|
31
|
-
|
35
|
+
context_note = !c.empty? ? c.ast : (!c2.empty? ? c2.ast : nil)
|
36
|
+
Compiler::ValueType.new name, base.value, params, units, value_constraint, pragmas, context_note
|
32
37
|
end
|
33
38
|
}
|
34
39
|
end
|
@@ -125,7 +130,7 @@ module ActiveFacts
|
|
125
130
|
end
|
126
131
|
|
127
132
|
rule non_unit
|
128
|
-
|
133
|
+
restricted_to / conversion / approximately / ephemera
|
129
134
|
end
|
130
135
|
|
131
136
|
rule unit
|
@@ -146,20 +151,34 @@ module ActiveFacts
|
|
146
151
|
end
|
147
152
|
|
148
153
|
rule value_constraint
|
149
|
-
|
154
|
+
restricted_to restricted_values c:context_note?
|
150
155
|
{
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
def units
|
156
|
-
u.empty? ? nil : u.value
|
156
|
+
def ast
|
157
|
+
v = restricted_values.values
|
158
|
+
c[:context_note] = c.ast unless c.empty?
|
159
|
+
v
|
157
160
|
end
|
158
161
|
}
|
159
162
|
# REVISIT: "where the possible value/s of that <Term> is/are value (, ...)"
|
160
163
|
end
|
161
164
|
|
162
|
-
|
165
|
+
rule restricted_values
|
166
|
+
range_list s u:units?
|
167
|
+
{
|
168
|
+
def values
|
169
|
+
{ :ranges => range_list.ranges,
|
170
|
+
:units => u.empty? ? nil : u.value
|
171
|
+
}
|
172
|
+
end
|
173
|
+
}
|
174
|
+
/
|
175
|
+
regular_expression
|
176
|
+
{
|
177
|
+
def values
|
178
|
+
{ :regular_expression => contents }
|
179
|
+
end
|
180
|
+
}
|
181
|
+
end
|
163
182
|
|
164
183
|
rule range_list
|
165
184
|
'{' s
|
@@ -12,17 +12,24 @@ require 'activefacts/cql/compiler/fact_type'
|
|
12
12
|
require 'activefacts/cql/compiler/expression'
|
13
13
|
require 'activefacts/cql/compiler/fact'
|
14
14
|
require 'activefacts/cql/compiler/constraint'
|
15
|
-
require 'activefacts/cql/compiler/
|
15
|
+
require 'activefacts/cql/compiler/query'
|
16
16
|
|
17
17
|
module ActiveFacts
|
18
18
|
module CQL
|
19
19
|
class Compiler < ActiveFacts::CQL::Parser
|
20
|
+
LANGUAGES = {
|
21
|
+
'en' => 'English',
|
22
|
+
'fr' => 'French',
|
23
|
+
'cn' => 'Mandarin'
|
24
|
+
}
|
20
25
|
attr_reader :vocabulary
|
21
26
|
|
22
|
-
def initialize
|
23
|
-
@filename =
|
27
|
+
def initialize *a
|
28
|
+
@filename = a.shift || "stdio"
|
29
|
+
super *a
|
24
30
|
@constellation = ActiveFacts::API::Constellation.new(ActiveFacts::Metamodel)
|
25
|
-
|
31
|
+
@language = nil
|
32
|
+
debug :file, "Parsing '#{@filename}'"
|
26
33
|
end
|
27
34
|
|
28
35
|
def compile_file filename
|
@@ -35,8 +42,25 @@ module ActiveFacts
|
|
35
42
|
@vocabulary
|
36
43
|
end
|
37
44
|
|
45
|
+
# Load the appropriate natural language module
|
46
|
+
def detect_language
|
47
|
+
@filename =~ /.*\.(..)\.cql$/i
|
48
|
+
language_code = $1
|
49
|
+
@language = LANGUAGES[language_code] || 'English'
|
50
|
+
end
|
51
|
+
|
52
|
+
def include_language
|
53
|
+
detect_language unless @langage
|
54
|
+
require 'activefacts/cql/Language/'+@language
|
55
|
+
language_module = ActiveFacts::CQL.const_get(@language)
|
56
|
+
extend language_module
|
57
|
+
end
|
58
|
+
|
38
59
|
def compile input
|
60
|
+
include_language
|
61
|
+
|
39
62
|
@string = input
|
63
|
+
|
40
64
|
# The syntax tree created from each parsed CQL statement gets passed to the block.
|
41
65
|
# parse_all returns an array of the block's non-nil return values.
|
42
66
|
ok = parse_all(@string, :definition) do |node|
|
@@ -69,9 +93,12 @@ module ActiveFacts
|
|
69
93
|
def compile_import file, aliases
|
70
94
|
saved_index = @index
|
71
95
|
saved_block = @block
|
96
|
+
saved_string = @string
|
97
|
+
saved_input_length = @input_length
|
72
98
|
old_filename = @filename
|
73
|
-
@filename = file+'.cql'
|
99
|
+
@filename = file+'.cql' # REVISIT: Use File.dirname(@filename)+@filename ?
|
74
100
|
|
101
|
+
# REVISIT: Save and use another @vocabulary for this file?
|
75
102
|
File.open(@filename) do |f|
|
76
103
|
ok = parse_all(f.read, nil, &@block)
|
77
104
|
end
|
@@ -83,6 +110,8 @@ module ActiveFacts
|
|
83
110
|
ensure
|
84
111
|
@block = saved_block
|
85
112
|
@index = saved_index
|
113
|
+
@input_length = saved_input_length
|
114
|
+
@string = saved_string
|
86
115
|
@filename = old_filename
|
87
116
|
nil
|
88
117
|
end
|