activefacts 0.8.9 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/.gemtest +0 -0
  2. data/Manifest.txt +28 -33
  3. data/Rakefile +11 -12
  4. data/bin/cql +90 -46
  5. data/examples/CQL/Blog.cql +2 -1
  6. data/examples/CQL/CompanyDirectorEmployee.cql +2 -2
  7. data/examples/CQL/Death.cql +1 -1
  8. data/examples/CQL/Diplomacy.cql +9 -9
  9. data/examples/CQL/Genealogy.cql +3 -2
  10. data/examples/CQL/Insurance.cql +10 -7
  11. data/examples/CQL/JoinEquality.cql +2 -2
  12. data/examples/CQL/Marriage.cql +1 -1
  13. data/examples/CQL/Metamodel.cql +73 -53
  14. data/examples/CQL/MetamodelNext.cql +89 -67
  15. data/examples/CQL/OneToOnes.cql +2 -2
  16. data/examples/CQL/ServiceDirector.cql +10 -5
  17. data/examples/CQL/Supervision.cql +3 -3
  18. data/examples/CQL/Tests.Test5.Load.cql +1 -1
  19. data/examples/CQL/Warehousing.cql +4 -2
  20. data/lib/activefacts/cql/CQLParser.treetop +26 -60
  21. data/lib/activefacts/cql/Context.treetop +12 -2
  22. data/lib/activefacts/cql/Expressions.treetop +14 -30
  23. data/lib/activefacts/cql/FactTypes.treetop +165 -110
  24. data/lib/activefacts/cql/Language/English.treetop +167 -54
  25. data/lib/activefacts/cql/LexicalRules.treetop +16 -2
  26. data/lib/activefacts/cql/{Concepts.treetop → ObjectTypes.treetop} +36 -37
  27. data/lib/activefacts/cql/Terms.treetop +57 -27
  28. data/lib/activefacts/cql/ValueTypes.treetop +39 -13
  29. data/lib/activefacts/cql/compiler.rb +5 -3
  30. data/lib/activefacts/cql/compiler/{reading.rb → clause.rb} +407 -285
  31. data/lib/activefacts/cql/compiler/constraint.rb +178 -275
  32. data/lib/activefacts/cql/compiler/entity_type.rb +73 -64
  33. data/lib/activefacts/cql/compiler/expression.rb +418 -0
  34. data/lib/activefacts/cql/compiler/fact.rb +146 -145
  35. data/lib/activefacts/cql/compiler/fact_type.rb +197 -80
  36. data/lib/activefacts/cql/compiler/join.rb +159 -0
  37. data/lib/activefacts/cql/compiler/shared.rb +51 -23
  38. data/lib/activefacts/cql/compiler/value_type.rb +56 -2
  39. data/lib/activefacts/cql/parser.rb +15 -4
  40. data/lib/activefacts/generate/absorption.rb +7 -7
  41. data/lib/activefacts/generate/cql.rb +100 -37
  42. data/lib/activefacts/generate/oo.rb +28 -51
  43. data/lib/activefacts/generate/ordered.rb +60 -36
  44. data/lib/activefacts/generate/ruby.rb +6 -6
  45. data/lib/activefacts/generate/sql/server.rb +4 -4
  46. data/lib/activefacts/input/orm.rb +71 -53
  47. data/lib/activefacts/persistence.rb +1 -1
  48. data/lib/activefacts/persistence/columns.rb +27 -23
  49. data/lib/activefacts/persistence/foreignkey.rb +6 -6
  50. data/lib/activefacts/persistence/index.rb +17 -17
  51. data/lib/activefacts/persistence/{concept.rb → object_type.rb} +9 -9
  52. data/lib/activefacts/persistence/reference.rb +61 -36
  53. data/lib/activefacts/persistence/tables.rb +61 -59
  54. data/lib/activefacts/support.rb +54 -29
  55. data/lib/activefacts/version.rb +1 -1
  56. data/lib/activefacts/vocabulary/extensions.rb +99 -54
  57. data/lib/activefacts/vocabulary/metamodel.rb +43 -37
  58. data/lib/activefacts/vocabulary/verbaliser.rb +134 -109
  59. data/spec/absorption_spec.rb +8 -8
  60. data/spec/cql/comparison_spec.rb +91 -0
  61. data/spec/cql/contractions_spec.rb +251 -0
  62. data/spec/cql/entity_type_spec.rb +319 -0
  63. data/spec/cql/expressions_spec.rb +63 -0
  64. data/spec/cql/fact_type_matching_spec.rb +283 -0
  65. data/spec/cql/french_spec.rb +21 -0
  66. data/spec/cql/parser/bad_literals_spec.rb +86 -0
  67. data/spec/cql/parser/constraints_spec.rb +19 -0
  68. data/spec/cql/parser/entity_types_spec.rb +106 -0
  69. data/spec/cql/parser/expressions_spec.rb +179 -0
  70. data/spec/cql/parser/fact_types_spec.rb +41 -0
  71. data/spec/cql/parser/literals_spec.rb +312 -0
  72. data/spec/cql/parser/pragmas_spec.rb +89 -0
  73. data/spec/cql/parser/value_types_spec.rb +42 -0
  74. data/spec/cql/role_matching_spec.rb +147 -0
  75. data/spec/cql/samples_spec.rb +9 -9
  76. data/spec/cql_cql_spec.rb +1 -1
  77. data/spec/cql_dm_spec.rb +116 -0
  78. data/spec/cql_mysql_spec.rb +1 -1
  79. data/spec/cql_ruby_spec.rb +1 -1
  80. data/spec/cql_sql_spec.rb +3 -3
  81. data/spec/cql_symbol_tables_spec.rb +30 -30
  82. data/spec/cqldump_spec.rb +4 -4
  83. data/spec/helpers/array_matcher.rb +32 -27
  84. data/spec/helpers/diff_matcher.rb +6 -26
  85. data/spec/helpers/file_matcher.rb +41 -32
  86. data/spec/helpers/parse_to_ast_matcher.rb +76 -0
  87. data/spec/helpers/string_matcher.rb +32 -31
  88. data/spec/norma_cql_spec.rb +1 -1
  89. data/spec/norma_ruby_spec.rb +1 -1
  90. data/spec/norma_ruby_sql_spec.rb +1 -1
  91. data/spec/norma_sql_spec.rb +3 -1
  92. data/spec/norma_tables_spec.rb +1 -1
  93. data/spec/ruby_api_spec.rb +23 -0
  94. data/spec/spec_helper.rb +5 -4
  95. metadata +66 -66
  96. data/examples/CQL/OrienteeringER.cql +0 -58
  97. data/lib/activefacts/api.rb +0 -44
  98. data/lib/activefacts/api/concept.rb +0 -410
  99. data/lib/activefacts/api/constellation.rb +0 -128
  100. data/lib/activefacts/api/entity.rb +0 -256
  101. data/lib/activefacts/api/instance.rb +0 -60
  102. data/lib/activefacts/api/instance_index.rb +0 -80
  103. data/lib/activefacts/api/numeric.rb +0 -167
  104. data/lib/activefacts/api/role.rb +0 -80
  105. data/lib/activefacts/api/role_proxy.rb +0 -70
  106. data/lib/activefacts/api/role_values.rb +0 -117
  107. data/lib/activefacts/api/standard_types.rb +0 -87
  108. data/lib/activefacts/api/support.rb +0 -65
  109. data/lib/activefacts/api/value.rb +0 -135
  110. data/lib/activefacts/api/vocabulary.rb +0 -82
  111. data/spec/api/autocounter.rb +0 -82
  112. data/spec/api/constellation.rb +0 -130
  113. data/spec/api/entity_type.rb +0 -103
  114. data/spec/api/instance.rb +0 -461
  115. data/spec/api/roles.rb +0 -124
  116. data/spec/api/value_type.rb +0 -112
  117. data/spec/api_spec.rb +0 -13
  118. data/spec/cql/matching_spec.rb +0 -517
  119. data/spec/cql/unit_spec.rb +0 -394
  120. data/spec/spec.opts +0 -1
@@ -8,18 +8,136 @@ module ActiveFacts
8
8
  module CQL
9
9
  grammar Language
10
10
 
11
- rule subtype_prefix
12
- 'is' s 'a' s ('kind'/'subtype') s 'of' S
13
- end
14
-
11
+ # >>>>>>>>>>>>>>>>>>>> Object Types <<<<<<<<<<<<<<<<<<<<
12
+ # The pattern to introduce a Value Type
15
13
  rule written_as
16
14
  s 'is' s 'written' S as s
17
15
  end
18
16
 
17
+ # The pattern to introduce an Entity Type
19
18
  rule identified_by
20
19
  identified s by s
21
20
  end
22
21
 
22
+ rule basetype_expression
23
+ is s i:( independent s )? identification
24
+ end
25
+
26
+ # The pattern to introduce an Entity Subtype
27
+ rule subtype_prefix
28
+ 'is' s 'a' s ('kind'/'subtype') s 'of' S
29
+ end
30
+
31
+ rule subtype_expression
32
+ subtype_prefix i:( independent s )? supertype_list ident:identification?
33
+ end
34
+
35
+ # The pattern to introduce an objectified fact type with implicit identification
36
+ rule is_where
37
+ is s i:(independent s)? where
38
+ { def independent; !i.empty?; end }
39
+ end
40
+
41
+ # Units conversion keyword
42
+ rule conversion
43
+ converts s a:(approximately s)? to s
44
+ {
45
+ def approximate?
46
+ !a.empty?
47
+ end
48
+ }
49
+ end
50
+
51
+ # >>>>>>>>>>>>>>>>>>>> Constraints <<<<<<<<<<<<<<<<<<<<
52
+ # External presence constraint syntax:
53
+ rule each_occurs_in_clauses
54
+ s 'each' s ('combination' S)? role_list s occurs s quantifier s 'time' 's'? s enforcement 'in' s
55
+ clauses_list s c:context_note? ';'
56
+ {
57
+ def role_list_ast
58
+ role_list.ast
59
+ end
60
+ def quantifier_ast
61
+ quantifier.ast
62
+ end
63
+ def clauses_ast
64
+ clauses_list.ast
65
+ end
66
+ }
67
+ end
68
+
69
+ # Alternate external presence constraint syntax:
70
+ rule either_or
71
+ s either? s r1:clauses s or s r2:clauses c:context_note? enforcement ';'
72
+ {
73
+ def role_list_ast
74
+ nil
75
+ end
76
+ def quantifier_ast
77
+ Compiler::Quantifier.new(1, nil)
78
+ end
79
+ def clauses_ast
80
+ [r1.ast, r2.ast]
81
+ end
82
+ }
83
+ end
84
+
85
+ # Exclusion (at most one) and mandatory exclusion (exactly one) constraint syntax:
86
+ rule for_each_how_many
87
+ s 'for' s 'each' s role_list s quantifier s 'of' s 'these' s 'holds' s enforcement ':' s
88
+ clauses_list s c:context_note? ';'
89
+ {
90
+ def role_list_ast
91
+ role_list.ast
92
+ end
93
+ def quantifier_ast
94
+ quantifier.ast
95
+ end
96
+ def clauses_ast
97
+ clauses_list.ast
98
+ end
99
+ }
100
+ end
101
+
102
+ # Alternate mandatory exclusion constraint syntax:
103
+ rule either_or_not_both
104
+ s either? s r1:clauses s or s r2:clauses but s not s both s c:context_note? enforcement ';'
105
+ {
106
+ def role_list_ast
107
+ nil
108
+ end
109
+ def quantifier_ast
110
+ Compiler::Quantifier.new(1, 1)
111
+ end
112
+ def clauses_ast
113
+ [r1.ast, r2.ast]
114
+ end
115
+ }
116
+ end
117
+
118
+ # Subset constraint using "A only if B" syntax
119
+ rule a_only_if_b
120
+ s clauses s only s if s r2:clauses s c:context_note? enforcement ';'
121
+ end
122
+
123
+ # Subset constraint using "if A then B" syntax
124
+ rule if_b_then_a
125
+ s if s clauses s then s r2:clauses s c:context_note? enforcement ';'
126
+ end
127
+
128
+ # Equality constraint syntax:
129
+ rule if_and_only_if
130
+ s clauses s tail:( if s and s only s if s clauses s)+
131
+ c:context_note? enforcement ';'
132
+ end
133
+
134
+ # During the prescan we need to know where terms in a role list finish.
135
+ # This rule matches any non-term expressions that may follow a role list.
136
+ rule role_list_constraint_followers
137
+ occurs s quantifier s 'time'
138
+ end
139
+
140
+ # >>>>>>>>>>>>>>>>>>>> Quantifiers <<<<<<<<<<<<<<<<<<<<
23
141
  rule quantifier
24
142
  (
25
143
  each s { def value; [1, nil]; end }
@@ -40,7 +158,7 @@ module ActiveFacts
40
158
  }
41
159
  / at s most s quantity { def value; [ nil, quantity.value ]; end }
42
160
  / from s numeric_range s { def value; numeric_range.value; end }
43
- / either_all_or_none s { def value; [ -1, 1 ]; end }
161
+ # / either_all_or_none s { def value; [ -1, 1 ]; end }
44
162
  )
45
163
  {
46
164
  def ast
@@ -50,31 +168,14 @@ module ActiveFacts
50
168
  }
51
169
  end
52
170
 
171
+ # rule either_all_or_none either s all s or s ( none / no ) end
172
+
53
173
  rule quantity
54
174
  one s { def value; 1; end }
55
175
  / number s { def value; number.value; end }
56
176
  end
57
177
 
58
- rule according_to
59
- 'according' S to
60
- end
61
-
62
- rule because
63
- 'because' S
64
- end
65
-
66
- rule as_opposed_to
67
- as S 'opposed' S to
68
- end
69
-
70
- rule so_that
71
- 'so' S that
72
- end
73
-
74
- rule to_avoid
75
- to s 'avoid' !alphanumeric
76
- end
77
-
178
+ # >>>>>>>>>>>>>>>>>>>> Context Notes <<<<<<<<<<<<<<<<<<<<
78
179
  rule as_agreed_by
79
180
  s as s 'agreed' s d:('on' S date)? by s agents
80
181
  { def value; [ d.empty? ? nil : d.date.value, agents.value ]; end }
@@ -87,78 +188,90 @@ module ActiveFacts
87
188
 
88
189
  rule agents
89
190
  s h:agent s t:(',' s !context_type agent s)*
90
- { def value; [h.text_value] + t.elements.map{|e| e.agent.text_value }; end }
191
+ {
192
+ def value; [h.text_value] + t.elements.map{|e| e.agent.text_value }; end
193
+ def node_type; :linking; end
194
+ }
91
195
  end
92
196
 
93
197
  rule agent
94
198
  id (s id)*
95
199
  end
96
200
 
97
- # An enforcement action, like SMS, email, log, alarm, etc.
98
- rule action
99
- id
100
- end
201
+ # >>>>>>>>>>>>>>>>>>>> Internal vocabulary <<<<<<<<<<<<<<<<<<<<
202
+ rule all 'all' !alphanumeric end
203
+ rule ascending 'ascending' !alphanumeric end
204
+ rule at 'at' !alphanumeric end
205
+ rule both 'both' !alphanumeric end
206
+ rule converts 'converts' !alphanumeric end
207
+ rule descending 'descending' !alphanumeric end
208
+ rule each 'each' !alphanumeric end
209
+ rule either 'either' !alphanumeric end
210
+ rule entity 'entity' !alphanumeric end
211
+ rule exactly 'exactly' !alphanumeric end
212
+ rule from 'from' !alphanumeric end
213
+ rule includes 'includes' !alphanumeric end
214
+ rule least 'least' !alphanumeric end
215
+ rule matches 'matches' !alphanumeric end
216
+ rule most 'most' !alphanumeric end
217
+ rule no 'no' !alphanumeric end
218
+ rule none 'none' !alphanumeric end
219
+ rule not 'not' !alphanumeric end
220
+ rule occurs 'occurs' !alphanumeric end
221
+ rule one 'one' !alphanumeric end
222
+ rule some 'some' !alphanumeric end
101
223
 
224
+ # >>>>>>>>>>>>>>>>>>>> External vocabulary <<<<<<<<<<<<<<<<<<<<
225
+ rule according_to 'according' S to end
102
226
  rule acyclic 'acyclic' !alphanumeric end
103
- rule antisymmetric 'antisymmetric' !alphanumeric end
104
- rule asymmetric 'asymmetric' !alphanumeric end
105
227
  rule alias 'alias' !alphanumeric end
106
- rule all 'all' !alphanumeric end
107
228
  rule and 'and' !alphanumeric end
229
+ rule antisymmetric 'antisymmetric' !alphanumeric end
108
230
  rule approximately 'approximately' !alphanumeric end
109
231
  rule as 'as' !alphanumeric end
110
- rule at 'at' !alphanumeric end
111
- rule both 'both' !alphanumeric end
232
+ rule as_opposed_to as s 'opposed' S to end
233
+ rule asymmetric 'asymmetric' !alphanumeric end
234
+ rule because 'because' !alphanumeric end
112
235
  rule but 'but' !alphanumeric end
113
- rule by 'by' !alphanumeric end
114
- rule converts 'converts' !alphanumeric end
236
+ rule by 'by' !alphanumeric end # fix? Used in 'returning' for ordering
115
237
  rule definitely 'definitely' !alphanumeric end
116
- rule each 'each' !alphanumeric end
117
- rule either 'either' !alphanumeric end
118
- rule entity 'entity' !alphanumeric end
119
238
  rule ephemera 'ephemera' !alphanumeric end
120
- rule exactly 'exactly' !alphanumeric end
121
239
  rule false 'false' !alphanumeric end
122
240
  rule feminine 'feminine' !alphanumeric end
123
- rule from 'from' !alphanumeric end
124
241
  rule identified ('known'/'identified') !alphanumeric end
125
- rule independent 'independent' !alphanumeric end
126
242
  rule if 'if' !alphanumeric end
127
243
  rule import 'import' !alphanumeric end
128
- rule includes 'includes' !alphanumeric end
244
+ rule independent 'independent' !alphanumeric end
129
245
  rule intransitive 'intransitive' !alphanumeric end
130
246
  rule irreflexive 'irreflexive' !alphanumeric end
131
247
  rule is 'is' !alphanumeric end
132
248
  rule its 'its' !alphanumeric end
133
- rule least 'least' !alphanumeric end
134
249
  rule masculine 'masculine' !alphanumeric end
135
- rule matches 'matches' !alphanumeric end
136
250
  rule maybe 'maybe' !alphanumeric end
137
- rule most 'most' !alphanumeric end
138
- rule no 'no' !alphanumeric end
139
- rule none 'none' !alphanumeric end
140
- rule not 'not' !alphanumeric end
141
- rule either_all_or_none either s all s or s ( none / no ) end
142
- rule one 'one' !alphanumeric end
143
251
  rule only 'only' !alphanumeric end
144
252
  rule or 'or' !alphanumeric end
253
+ rule ordering_prefix by s (ascending/descending)? s end
145
254
  rule otherwise 'otherwise' !alphanumeric end
146
255
  rule partitioned 'partitioned' !alphanumeric end
147
256
  rule personal 'personal' !alphanumeric end
148
- rule restricted 'restricted' !alphanumeric end
257
+ rule radix_point '.' end
149
258
  rule reflexive 'reflexive' !alphanumeric end
259
+ rule restricted 'restricted' !alphanumeric end
150
260
  rule returning 'returning' !alphanumeric end
151
261
  rule separate 'separate' !alphanumeric end
152
- rule some 'some' !alphanumeric end
262
+ rule so_that 'so' S that end
153
263
  rule static 'static' !alphanumeric end
154
264
  rule symmetric 'symmetric' !alphanumeric end
155
265
  rule that 'that' !alphanumeric end
266
+ rule then 'then' !alphanumeric end
156
267
  rule to 'to' !alphanumeric end
268
+ rule to_avoid to s 'avoid' !alphanumeric end
157
269
  rule transient 'transient' !alphanumeric end
158
270
  rule transitive 'transitive' !alphanumeric end
159
271
  rule true 'true' !alphanumeric end
160
272
  rule vocabulary 'vocabulary' !alphanumeric end
161
273
  rule where 'where' !alphanumeric end
274
+ rule who 'who' !alphanumeric end
162
275
 
163
276
  end
164
277
  end
@@ -9,7 +9,10 @@ module ActiveFacts
9
9
  grammar LexicalRules
10
10
 
11
11
  rule range
12
- numeric_range / string_range
12
+ (numeric_range / string_range)
13
+ {
14
+ def node_type; :literal; end
15
+ }
13
16
  end
14
17
 
15
18
  rule numeric_range
@@ -57,6 +60,9 @@ module ActiveFacts
57
60
  rule url
58
61
  # url_scheme ':' (user ( ':' !(port '/') password )? '@' )? hostname ( ':' port )? '/' path query? fragment?
59
62
  ( !(white / ';') .)+
63
+ {
64
+ def node_type; :literal; end
65
+ }
60
66
  end
61
67
 
62
68
  rule literal
@@ -68,6 +74,7 @@ module ActiveFacts
68
74
  def value
69
75
  elements[0].value
70
76
  end
77
+ def node_type; :literal; end
71
78
  }
72
79
  end
73
80
 
@@ -100,6 +107,7 @@ module ActiveFacts
100
107
  def value
101
108
  eval(text_value)
102
109
  end
110
+ def node_type; :literal; end
103
111
  }
104
112
  end
105
113
 
@@ -124,7 +132,7 @@ module ActiveFacts
124
132
  end
125
133
 
126
134
  rule fraction
127
- '.' [0-9]+
135
+ radix_point [0-9]+
128
136
  end
129
137
 
130
138
  rule exponent
@@ -170,10 +178,16 @@ module ActiveFacts
170
178
 
171
179
  rule comment_to_eol
172
180
  '//' (!"\n" .)*
181
+ {
182
+ def node_type; :comment; end
183
+ }
173
184
  end
174
185
 
175
186
  rule comment_c_style
176
187
  '/*' (!'*/' . )* '*/'
188
+ {
189
+ def node_type; :comment; end
190
+ }
177
191
  end
178
192
 
179
193
  end
@@ -1,13 +1,13 @@
1
1
  #
2
2
  # ActiveFacts CQL Parser.
3
- # Parse rules relating to Concept definitions.
3
+ # Parse rules relating to ObjectType definitions.
4
4
  #
5
5
  # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
6
  #
7
7
  module ActiveFacts
8
8
  module CQL
9
- grammar Concepts
10
- rule concept
9
+ grammar ObjectTypes
10
+ rule object_type
11
11
  value_type
12
12
  / entity_type
13
13
  / named_fact_type
@@ -16,55 +16,51 @@ module ActiveFacts
16
16
 
17
17
  rule entity_type
18
18
  s term_definition_name
19
+ m1:mapping_pragmas
19
20
  sup:(basetype / subtype)
20
21
  &{|s|
21
22
  # There's an implicit type when we use an identification mode, register it:
22
- mode = s[2].identification_mode
23
+ mode = s[3].identification_mode
23
24
  if mode
24
25
  input.context.object_type(s[1].value+mode, "identification mode type")
25
26
  input.context.object_type(s[1].value+' '+mode, "identification mode type")
26
27
  end
27
28
  true
28
29
  }
29
- mapping_pragmas
30
- ec:entity_conditions?
30
+ m2:mapping_pragmas
31
+ ec:entity_clauses?
31
32
  ';'
32
33
  {
33
34
  def ast
34
35
  name = term_definition_name.value
35
- readings = ec.empty? ? [] : ec.ast
36
- Compiler::EntityType.new name, sup.supers, sup.ast, mapping_pragmas.value, readings
36
+ clauses_ast = ec.empty? ? [] : ec.ast
37
+ pragmas = m1.value+m2.value
38
+ pragmas << 'independent' if sup.independent
39
+ Compiler::EntityType.new name, sup.supers, sup.ast, pragmas, clauses_ast
37
40
  end
38
41
  }
39
42
  end
40
43
 
41
44
  rule basetype
42
- is s
43
- # independency?
44
- identification
45
+ basetype_expression
45
46
  {
46
47
  def ast; identification.ast; end
47
48
  def supers; []; end
48
49
  def identification_mode; identification.mode; end
50
+ def independent; !i.empty?; end
49
51
  }
50
52
  end
51
53
 
52
54
  rule subtype
53
- subtype_prefix
54
- # independency?
55
- supertype_list ident:identification?
55
+ subtype_expression
56
56
  {
57
57
  def ast; ident.empty? ? nil : ident.ast; end
58
58
  def supers; supertype_list.value; end
59
59
  def identification_mode; ident.empty? ? nil : ident.mode; end
60
+ def independent; !i.empty?; end
60
61
  }
61
62
  end
62
63
 
63
- # REVISIT: This doesn't work, and I don't know why.
64
- rule independency
65
- ('independent' S / 'separate' S / 'partitioned' S)
66
- end
67
-
68
64
  rule supertype_list
69
65
  primary:term s alternate_supertypes:( ',' s !identified_by name:term s )*
70
66
  {
@@ -76,14 +72,14 @@ module ActiveFacts
76
72
 
77
73
  rule identification
78
74
  # REVISIT: Consider distinguishing "-Id" from just "Id", and not prepending the entity type name if no "-"
79
- identified_by its s i:(term/id) value_type_parameters
75
+ identified_by its s i:(term/implicit_value_type_name) value_type_parameters
80
76
  r:(value_constraint enforcement)? # Reference Mode; value_constraint may be needed for the ValueType
81
77
  {
82
78
  def ast
83
79
  if r.empty?
84
80
  value_constraint = nil
85
81
  else
86
- value_constraint = Compiler::ValueConstraint.new(r.value_constraint.ranges, r.enforcement.ast)
82
+ value_constraint = Compiler::ValueConstraint.new(r.value_constraint.ranges, r.value_constraint.units, r.enforcement.ast)
87
83
  end
88
84
  Compiler::ReferenceMode.new(i.value, value_constraint, value_type_parameters.values)
89
85
  end
@@ -97,10 +93,10 @@ module ActiveFacts
97
93
  &{|s|
98
94
  role_list = s[-1]
99
95
  forwards = role_list.ast.
100
- map do |role_ref|
101
- next nil if role_ref.is_a?(Compiler::Reading) # Can't forward-reference unaries
102
- next nil if role_ref.leading_adjective or role_ref.trailing_adjective
103
- role_ref.term
96
+ map do |role|
97
+ next nil if role.is_a?(Compiler::Clause) # Can't forward-reference unaries
98
+ next nil if role.leading_adjective or role.trailing_adjective
99
+ role.term
104
100
  end.
105
101
  compact
106
102
  input.context.allowed_forward_terms(forwards)
@@ -127,8 +123,15 @@ module ActiveFacts
127
123
  }
128
124
  end
129
125
 
126
+ rule unary_text
127
+ (s !non_phrase !term id)*
128
+ {
129
+ def node_type; :linking; end
130
+ }
131
+ end
132
+
130
133
  rule term_or_unary
131
- pre_text:(s !non_role_word !term id)* s term post_text:(s !non_role_word !term id)* s ss:subscript?
134
+ pre_text:unary_text s term post_text:unary_text s ss:subscript?
132
135
  {
133
136
  def ast
134
137
  t = term.ast
@@ -138,16 +141,16 @@ module ActiveFacts
138
141
  else
139
142
  pre_words = pre_text.elements.map{|w| w.id.text_value}
140
143
  post_words = post_text.elements.map{|w| w.id.text_value}
141
- Compiler::Reading.new(pre_words + [t] + post_words, [], nil)
144
+ Compiler::Clause.new(pre_words + [t] + post_words, [], nil)
142
145
  end
143
146
  end
144
147
  }
145
148
  /
146
- s !non_role_word id s &non_role_word s ss:subscript
149
+ s !non_phrase id s &non_phrase s ss:subscript
147
150
  { # A forward-referenced entity type
148
151
  # REVISIT: A change in this rule might allow forward-referencing a multi-word term
149
152
  def ast
150
- Compiler::RoleRef.new(id.text_value, nil, nil, nil, ss.empty? ? nil : ss.value)
153
+ Compiler::VarRef.new(id.text_value, nil, nil, nil, ss.empty? ? nil : ss.value)
151
154
  end
152
155
  }
153
156
  end
@@ -156,7 +159,7 @@ module ActiveFacts
156
159
  '[' s h:mapping_pragma t:(s ',' s mapping_pragma)* s ']' s
157
160
  { def value; t.elements.inject([h.value]) { |a, e| a << e.mapping_pragma.value }; end }
158
161
  /
159
- ''
162
+ s
160
163
  { def value; []; end }
161
164
  end
162
165
 
@@ -165,16 +168,12 @@ module ActiveFacts
165
168
  { def value; text_value; end }
166
169
  end
167
170
 
168
- rule entity_conditions
169
- (':' / where) s c:conditions?
171
+ rule entity_clauses
172
+ (':' / where) s joined_clauses
170
173
  {
171
174
  def ast
172
- c.empty? ? [] : c.ast
175
+ joined_clauses.ast
173
176
  end
174
-
175
- def conditions
176
- c.empty? ? [] : c.condition_list
177
- end
178
177
  }
179
178
  end
180
179