expressir 2.2.0 → 2.3.0

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.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.rubocop_todo.yml +254 -77
  4. data/Gemfile +4 -1
  5. data/README.adoc +63 -26
  6. data/benchmark/srl_benchmark.rb +386 -0
  7. data/benchmark/srl_native_benchmark.rb +142 -0
  8. data/benchmark/srl_ruby_benchmark.rb +130 -0
  9. data/expressir.gemspec +4 -2
  10. data/lib/expressir/benchmark.rb +1 -1
  11. data/lib/expressir/changes/item_change.rb +0 -1
  12. data/lib/expressir/changes/mapping_change.rb +0 -1
  13. data/lib/expressir/changes/schema_change.rb +0 -2
  14. data/lib/expressir/changes/version_change.rb +0 -3
  15. data/lib/expressir/changes.rb +5 -6
  16. data/lib/expressir/cli.rb +10 -24
  17. data/lib/expressir/commands/base.rb +2 -9
  18. data/lib/expressir/commands/changes.rb +0 -2
  19. data/lib/expressir/commands/changes_import_eengine.rb +0 -3
  20. data/lib/expressir/commands/changes_validate.rb +0 -2
  21. data/lib/expressir/commands/format.rb +5 -3
  22. data/lib/expressir/commands/manifest.rb +0 -7
  23. data/lib/expressir/commands/package.rb +93 -101
  24. data/lib/expressir/commands/validate.rb +0 -2
  25. data/lib/expressir/commands/validate_ascii.rb +2 -4
  26. data/lib/expressir/commands/validate_load.rb +8 -5
  27. data/lib/expressir/commands.rb +20 -0
  28. data/lib/expressir/config.rb +0 -2
  29. data/lib/expressir/coverage.rb +11 -4
  30. data/lib/expressir/eengine/arm_compare_report.rb +1 -4
  31. data/lib/expressir/eengine/changes_section.rb +1 -3
  32. data/lib/expressir/eengine/compare_report.rb +1 -13
  33. data/lib/expressir/eengine/mim_compare_report.rb +1 -4
  34. data/lib/expressir/eengine/modified_object.rb +1 -2
  35. data/lib/expressir/eengine.rb +9 -0
  36. data/lib/expressir/errors.rb +113 -0
  37. data/lib/expressir/express/builder.rb +22 -7
  38. data/lib/expressir/express/builder_registry.rb +411 -0
  39. data/lib/expressir/express/builders/attribute_decl_builder.rb +0 -6
  40. data/lib/expressir/express/builders/built_in_builder.rb +1 -16
  41. data/lib/expressir/express/builders/constant_builder.rb +4 -19
  42. data/lib/expressir/express/builders/declaration_builder.rb +0 -4
  43. data/lib/expressir/express/builders/derive_clause_builder.rb +0 -2
  44. data/lib/expressir/express/builders/derived_attr_builder.rb +0 -2
  45. data/lib/expressir/express/builders/domain_rule_builder.rb +0 -2
  46. data/lib/expressir/express/builders/entity_decl_builder.rb +7 -13
  47. data/lib/expressir/express/builders/explicit_attr_builder.rb +5 -8
  48. data/lib/expressir/express/builders/expression_builder.rb +31 -67
  49. data/lib/expressir/express/builders/function_decl_builder.rb +20 -18
  50. data/lib/expressir/express/builders/interface_builder.rb +0 -20
  51. data/lib/expressir/express/builders/inverse_attr_builder.rb +0 -2
  52. data/lib/expressir/express/builders/inverse_attr_type_builder.rb +0 -6
  53. data/lib/expressir/express/builders/inverse_clause_builder.rb +0 -2
  54. data/lib/expressir/express/builders/literal_builder.rb +1 -15
  55. data/lib/expressir/express/builders/procedure_decl_builder.rb +20 -19
  56. data/lib/expressir/express/builders/qualifier_builder.rb +0 -27
  57. data/lib/expressir/express/builders/reference_builder.rb +1 -10
  58. data/lib/expressir/express/builders/rule_decl_builder.rb +21 -19
  59. data/lib/expressir/express/builders/schema_body_decl_builder.rb +0 -4
  60. data/lib/expressir/express/builders/schema_decl_builder.rb +7 -13
  61. data/lib/expressir/express/builders/schema_version_builder.rb +0 -6
  62. data/lib/expressir/express/builders/simple_id_builder.rb +1 -10
  63. data/lib/expressir/express/builders/statement_builder.rb +4 -32
  64. data/lib/expressir/express/builders/subtype_constraint_builder.rb +6 -30
  65. data/lib/expressir/express/builders/syntax_builder.rb +60 -7
  66. data/lib/expressir/express/builders/type_builder.rb +3 -45
  67. data/lib/expressir/express/builders/type_decl_builder.rb +1 -7
  68. data/lib/expressir/express/builders/unique_clause_builder.rb +1 -3
  69. data/lib/expressir/express/builders/unique_rule_builder.rb +0 -2
  70. data/lib/expressir/express/builders/where_clause_builder.rb +1 -3
  71. data/lib/expressir/express/builders.rb +47 -35
  72. data/lib/expressir/express/error.rb +0 -3
  73. data/lib/expressir/express/formatter.rb +17 -19
  74. data/lib/expressir/express/formatters/data_types_formatter.rb +295 -293
  75. data/lib/expressir/express/formatters/declarations_formatter.rb +617 -615
  76. data/lib/expressir/express/formatters/expressions_formatter.rb +146 -144
  77. data/lib/expressir/express/formatters/literals_formatter.rb +35 -33
  78. data/lib/expressir/express/formatters/references_formatter.rb +34 -32
  79. data/lib/expressir/express/formatters/remark_formatter.rb +176 -209
  80. data/lib/expressir/express/formatters/remark_item_formatter.rb +18 -16
  81. data/lib/expressir/express/formatters/statements_formatter.rb +190 -188
  82. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +41 -39
  83. data/lib/expressir/express/formatters.rb +22 -0
  84. data/lib/expressir/express/parser.rb +40 -41
  85. data/lib/expressir/express/pretty_formatter.rb +68 -47
  86. data/lib/expressir/express/remark_attacher.rb +210 -147
  87. data/lib/expressir/express/streaming_builder.rb +0 -3
  88. data/lib/expressir/express/transformer/remark_handling.rb +1 -2
  89. data/lib/expressir/express.rb +29 -0
  90. data/lib/expressir/manifest/resolver.rb +0 -3
  91. data/lib/expressir/manifest/validator.rb +0 -3
  92. data/lib/expressir/manifest.rb +6 -0
  93. data/lib/expressir/model/cache.rb +1 -1
  94. data/lib/expressir/model/concerns.rb +19 -0
  95. data/lib/expressir/model/data_types/aggregate.rb +1 -1
  96. data/lib/expressir/model/data_types/array.rb +1 -1
  97. data/lib/expressir/model/data_types/bag.rb +1 -1
  98. data/lib/expressir/model/data_types/binary.rb +1 -1
  99. data/lib/expressir/model/data_types/boolean.rb +1 -1
  100. data/lib/expressir/model/data_types/enumeration.rb +1 -1
  101. data/lib/expressir/model/data_types/enumeration_item.rb +1 -1
  102. data/lib/expressir/model/data_types/generic.rb +1 -1
  103. data/lib/expressir/model/data_types/generic_entity.rb +1 -1
  104. data/lib/expressir/model/data_types/integer.rb +1 -1
  105. data/lib/expressir/model/data_types/list.rb +1 -1
  106. data/lib/expressir/model/data_types/logical.rb +1 -1
  107. data/lib/expressir/model/data_types/number.rb +1 -1
  108. data/lib/expressir/model/data_types/real.rb +1 -1
  109. data/lib/expressir/model/data_types/select.rb +1 -1
  110. data/lib/expressir/model/data_types/set.rb +1 -1
  111. data/lib/expressir/model/data_types/string.rb +1 -1
  112. data/lib/expressir/model/data_types.rb +25 -0
  113. data/lib/expressir/model/declarations/attribute.rb +1 -1
  114. data/lib/expressir/model/declarations/constant.rb +1 -1
  115. data/lib/expressir/model/declarations/derived_attribute.rb +1 -1
  116. data/lib/expressir/model/declarations/entity.rb +4 -1
  117. data/lib/expressir/model/declarations/function.rb +3 -1
  118. data/lib/expressir/model/declarations/informal_proposition_rule.rb +2 -1
  119. data/lib/expressir/model/declarations/interface.rb +1 -1
  120. data/lib/expressir/model/declarations/interface_item.rb +1 -1
  121. data/lib/expressir/model/declarations/interfaced_item.rb +1 -1
  122. data/lib/expressir/model/declarations/inverse_attribute.rb +1 -1
  123. data/lib/expressir/model/declarations/parameter.rb +1 -1
  124. data/lib/expressir/model/declarations/procedure.rb +3 -1
  125. data/lib/expressir/model/declarations/remark_item.rb +1 -1
  126. data/lib/expressir/model/declarations/rule.rb +4 -1
  127. data/lib/expressir/model/declarations/schema.rb +2 -1
  128. data/lib/expressir/model/declarations/schema_version.rb +1 -1
  129. data/lib/expressir/model/declarations/schema_version_item.rb +1 -1
  130. data/lib/expressir/model/declarations/subtype_constraint.rb +1 -1
  131. data/lib/expressir/model/declarations/type.rb +4 -1
  132. data/lib/expressir/model/declarations/unique_rule.rb +1 -1
  133. data/lib/expressir/model/declarations/variable.rb +1 -1
  134. data/lib/expressir/model/declarations/where_rule.rb +1 -1
  135. data/lib/expressir/model/declarations.rb +31 -0
  136. data/lib/expressir/model/dependency_resolver.rb +0 -2
  137. data/lib/expressir/model/exp_file.rb +38 -0
  138. data/lib/expressir/model/expressions/aggregate_initializer.rb +1 -1
  139. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +1 -1
  140. data/lib/expressir/model/expressions/binary_expression.rb +1 -1
  141. data/lib/expressir/model/expressions/entity_constructor.rb +1 -1
  142. data/lib/expressir/model/expressions/function_call.rb +1 -1
  143. data/lib/expressir/model/expressions/interval.rb +1 -1
  144. data/lib/expressir/model/expressions/query_expression.rb +1 -1
  145. data/lib/expressir/model/expressions/unary_expression.rb +1 -1
  146. data/lib/expressir/model/expressions.rb +18 -0
  147. data/lib/expressir/model/identifier.rb +5 -1
  148. data/lib/expressir/model/indexes.rb +11 -0
  149. data/lib/expressir/model/literals/binary.rb +1 -1
  150. data/lib/expressir/model/literals/integer.rb +1 -1
  151. data/lib/expressir/model/literals/logical.rb +1 -1
  152. data/lib/expressir/model/literals/real.rb +1 -1
  153. data/lib/expressir/model/literals/string.rb +1 -1
  154. data/lib/expressir/model/literals.rb +13 -0
  155. data/lib/expressir/model/model_element.rb +7 -15
  156. data/lib/expressir/model/references/attribute_reference.rb +1 -1
  157. data/lib/expressir/model/references/group_reference.rb +1 -1
  158. data/lib/expressir/model/references/index_reference.rb +1 -1
  159. data/lib/expressir/model/references/simple_reference.rb +1 -1
  160. data/lib/expressir/model/references.rb +12 -0
  161. data/lib/expressir/model/remark_info.rb +1 -7
  162. data/lib/expressir/model/repository.rb +72 -36
  163. data/lib/expressir/model/repository_validator.rb +0 -2
  164. data/lib/expressir/model/search_engine.rb +6 -30
  165. data/lib/expressir/model/statements/alias.rb +1 -1
  166. data/lib/expressir/model/statements/assignment.rb +1 -1
  167. data/lib/expressir/model/statements/case.rb +1 -1
  168. data/lib/expressir/model/statements/case_action.rb +1 -1
  169. data/lib/expressir/model/statements/compound.rb +1 -1
  170. data/lib/expressir/model/statements/escape.rb +1 -1
  171. data/lib/expressir/model/statements/if.rb +1 -1
  172. data/lib/expressir/model/statements/null.rb +1 -1
  173. data/lib/expressir/model/statements/procedure_call.rb +1 -1
  174. data/lib/expressir/model/statements/repeat.rb +1 -1
  175. data/lib/expressir/model/statements/return.rb +1 -1
  176. data/lib/expressir/model/statements/skip.rb +1 -1
  177. data/lib/expressir/model/statements.rb +20 -0
  178. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +1 -1
  179. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +1 -1
  180. data/lib/expressir/model/supertype_expressions.rb +12 -0
  181. data/lib/expressir/model.rb +28 -4
  182. data/lib/expressir/package/builder.rb +33 -4
  183. data/lib/expressir/package/metadata.rb +0 -1
  184. data/lib/expressir/package/reader.rb +0 -1
  185. data/lib/expressir/package.rb +8 -0
  186. data/lib/expressir/schema_manifest.rb +5 -6
  187. data/lib/expressir/schema_manifest_entry.rb +3 -4
  188. data/lib/expressir/transformer.rb +7 -0
  189. data/lib/expressir/version.rb +1 -1
  190. data/lib/expressir.rb +23 -173
  191. metadata +64 -9
  192. data/lib/expressir/express/builders/token_builder.rb +0 -15
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds rule declaration nodes.
9
7
  class RuleDeclBuilder
10
- include Helpers
11
-
12
8
  def call(ast_data)
13
9
  head = ast_data[:rule_head]
14
10
  algorithm_head = ast_data[:algorithm_head]
@@ -23,28 +19,36 @@ module Expressir
23
19
  declarations = Builder.build_children(algorithm_head[:declaration])
24
20
  end
25
21
 
26
- types = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Type) }
27
- entities = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Entity) }
28
- subtype_constraints = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::SubtypeConstraint) }
29
- functions = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Function) }
30
- procedures = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Procedure) }
31
- constants = build_constant_decl(algorithm_head[:constant_decl]) if algorithm_head.is_a?(Hash) && algorithm_head[:constant_decl]
32
- variables = build_local_decl(algorithm_head[:local_decl]) if algorithm_head.is_a?(Hash) && algorithm_head[:local_decl]
22
+ types = declarations.grep(Expressir::Model::Declarations::Type)
23
+ entities = declarations.grep(Expressir::Model::Declarations::Entity)
24
+ subtype_constraints = declarations.grep(Expressir::Model::Declarations::SubtypeConstraint)
25
+ functions = declarations.grep(Expressir::Model::Declarations::Function)
26
+ procedures = declarations.grep(Expressir::Model::Declarations::Procedure)
27
+ constants = if algorithm_head.is_a?(Hash) && algorithm_head[:constant_decl]
28
+ build_constant_decl(algorithm_head[:constant_decl])
29
+ else
30
+ []
31
+ end
32
+ variables = if algorithm_head.is_a?(Hash) && algorithm_head[:local_decl]
33
+ build_local_decl(algorithm_head[:local_decl])
34
+ else
35
+ []
36
+ end
33
37
  statements = Builder.build_children(stmts)
34
38
  where_rules = where_clause ? Builder.build({ where_clause: where_clause }) : []
35
39
 
36
40
  Expressir::Model::Declarations::Rule.new(
37
41
  id: id,
38
- applies_to: [applies_to].flatten.compact,
42
+ applies_to: Builder.ensure_array(applies_to),
39
43
  types: types,
40
44
  entities: entities,
41
45
  subtype_constraints: subtype_constraints,
42
46
  functions: functions,
43
47
  procedures: procedures,
44
- constants: [constants].flatten.compact,
45
- variables: [variables].flatten.compact,
48
+ constants: constants,
49
+ variables: variables,
46
50
  statements: statements.compact,
47
- where_rules: [where_rules].flatten.compact,
51
+ where_rules: [where_rules].flatten,
48
52
  )
49
53
  end
50
54
 
@@ -70,7 +74,7 @@ module Expressir
70
74
  refs << Builder.build({ entity_ref: entity_refs[:entity_ref] })
71
75
  end
72
76
  if entity_refs[:item]
73
- [entity_refs[:item]].flatten.each do |item|
77
+ Builder.ensure_array(entity_refs[:item]).each do |item|
74
78
  if item[:entity_ref]
75
79
  refs << Builder.build({ entity_ref: item[:entity_ref] })
76
80
  end
@@ -85,11 +89,9 @@ module Expressir
85
89
  end
86
90
 
87
91
  def build_local_decl(data)
88
- Builder.build_children(data[:local_variable]).flatten.compact
92
+ Builder.build_children(data[:local_variable])
89
93
  end
90
94
  end
91
95
  end
92
96
  end
93
97
  end
94
-
95
- Builder.register(:rule_decl, Expressir::Express::Builders::RuleDeclBuilder.new)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
@@ -18,5 +16,3 @@ module Expressir
18
16
  end
19
17
  end
20
18
  end
21
-
22
- Builder.register(:schema_body_declaration, Expressir::Express::Builders::SchemaBodyDeclBuilder.new)
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds schema_decl nodes into Schema objects.
9
7
  class SchemaDeclBuilder
10
- include Helpers
11
-
12
8
  def call(ast_data)
13
9
  id = Builder.build_optional(ast_data[:schema_id])
14
10
  version = if ast_data[:schema_version_id]
@@ -26,18 +22,18 @@ module Expressir
26
22
  declarations = Builder.build_children(body_decls) if body_decls
27
23
  end
28
24
 
29
- types = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Type) }
30
- entities = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Entity) }
31
- subtype_constraints = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::SubtypeConstraint) }
32
- functions = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Function) }
33
- rules = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Rule) }
34
- procedures = declarations.select { |x| x.is_a?(Expressir::Model::Declarations::Procedure) }
25
+ types = declarations.grep(Expressir::Model::Declarations::Type)
26
+ entities = declarations.grep(Expressir::Model::Declarations::Entity)
27
+ subtype_constraints = declarations.grep(Expressir::Model::Declarations::SubtypeConstraint)
28
+ functions = declarations.grep(Expressir::Model::Declarations::Function)
29
+ rules = declarations.grep(Expressir::Model::Declarations::Rule)
30
+ procedures = declarations.grep(Expressir::Model::Declarations::Procedure)
35
31
 
36
32
  Expressir::Model::Declarations::Schema.new(
37
33
  id: id,
38
34
  version: version,
39
35
  interfaces: interfaces.compact,
40
- constants: [constants].flatten.compact,
36
+ constants: [constants].flatten,
41
37
  types: types,
42
38
  entities: entities,
43
39
  subtype_constraints: subtype_constraints,
@@ -58,5 +54,3 @@ module Expressir
58
54
  end
59
55
  end
60
56
  end
61
-
62
- Builder.register(:schema_decl, Expressir::Express::Builders::SchemaDeclBuilder.new)
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds schema_version_id nodes into SchemaVersion objects.
9
7
  class SchemaVersionBuilder
10
- include Helpers
11
-
12
8
  def call(ast_data)
13
9
  string_val = Builder.build_optional(ast_data[:string_literal])
14
10
  value = string_val.is_a?(Expressir::Model::Literals::String) ? string_val.value : string_val.to_s
@@ -36,5 +32,3 @@ module Expressir
36
32
  end
37
33
  end
38
34
  end
39
-
40
- Builder.register(:schema_version_id, Expressir::Express::Builders::SchemaVersionBuilder.new)
@@ -1,14 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds simple ID nodes (simple_id, schema_id, entity_id, etc.)
9
7
  # These return a string, not a Model object.
10
8
  class SimpleIdBuilder
11
- include Helpers
9
+ include ::Expressir::Express::Builders::Helpers
12
10
 
13
11
  def call(ast_data)
14
12
  extract_text(ast_data[:str]) || extract_text(ast_data[:simple_id]&.dig(:str))
@@ -17,10 +15,3 @@ module Expressir
17
15
  end
18
16
  end
19
17
  end
20
-
21
- # Register for all ID types
22
- %i[simple_id schema_id entity_id type_id function_id procedure_id
23
- rule_id rule_label_id constant_id parameter_id variable_id
24
- enumeration_id subtype_constraint_id type_label_id attribute_id].each do |id_type|
25
- Builder.register(id_type, Expressir::Express::Builders::SimpleIdBuilder.new)
26
- end
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds statement nodes (assignment, if, case, repeat, etc.).
9
7
  class StatementBuilder
10
- include Helpers
8
+ include ::Expressir::Express::Builders::Helpers
11
9
 
12
10
  # stmt - choice dispatcher
13
11
  def build_stmt(ast_data)
@@ -41,7 +39,7 @@ module Expressir
41
39
  expression = Builder.build_optional(ast_data[:expression])
42
40
 
43
41
  if ast_data[:qualifier]
44
- [ast_data[:qualifier]].flatten.compact.each do |qual|
42
+ Builder.ensure_array(ast_data[:qualifier]).each do |qual|
45
43
  qual_result = Builder.build({ qualifier: qual })
46
44
  ref = apply_qualifier(ref, qual_result)
47
45
  end
@@ -57,7 +55,7 @@ module Expressir
57
55
  statements = Builder.build_children(ast_data[:stmt])
58
56
 
59
57
  if ast_data[:qualifier] && expression
60
- [ast_data[:qualifier]].flatten.compact.each do |qual|
58
+ Builder.ensure_array(ast_data[:qualifier]).each do |qual|
61
59
  qual_result = Builder.build({ qualifier: qual })
62
60
  expression = apply_qualifier(expression, qual_result)
63
61
  end
@@ -202,7 +200,7 @@ module Expressir
202
200
 
203
201
  Expressir::Model::Statements::ProcedureCall.new(
204
202
  procedure: proc_ref,
205
- parameters: [params].flatten.compact,
203
+ parameters: Builder.ensure_array(params),
206
204
  )
207
205
  end
208
206
 
@@ -222,29 +220,3 @@ module Expressir
222
220
  end
223
221
  end
224
222
  end
225
-
226
- builder = Expressir::Express::Builders::StatementBuilder.new
227
-
228
- Builder.register(:stmt) { |d| builder.build_stmt(d) }
229
- Builder.register(:assignment_stmt) { |d| builder.build_assignment_stmt(d) }
230
- Builder.register(:alias_stmt) { |d| builder.build_alias_stmt(d) }
231
- Builder.register(:if_stmt) { |d| builder.build_if_stmt(d) }
232
- Builder.register(:case_stmt) { |d| builder.build_case_stmt(d) }
233
- Builder.register(:selector) { |d| builder.build_selector(d) }
234
- Builder.register(:case_action) { |d| builder.build_case_action(d) }
235
- Builder.register(:case_label) { |d| builder.build_case_label(d) }
236
- Builder.register(:compound_stmt) { |d| builder.build_compound_stmt(d) }
237
- Builder.register(:repeat_stmt) { |d| builder.build_repeat_stmt(d) }
238
- Builder.register(:increment_control) { |d| builder.build_increment_control(d) }
239
- Builder.register(:increment) { |d| builder.build_increment(d) }
240
- Builder.register(:while_control) { |d| builder.build_while_control(d) }
241
- Builder.register(:until_control) { |d| builder.build_until_control(d) }
242
- Builder.register(:return_stmt) { |d| builder.build_return_stmt(d) }
243
- Builder.register(:escape_stmt) { |d| builder.build_escape_stmt(d) }
244
- Builder.register(:skip_stmt) { |d| builder.build_skip_stmt(d) }
245
- Builder.register(:null_stmt) { |d| builder.build_null_stmt(d) }
246
- Builder.register(:procedure_call_stmt) do |d|
247
- builder.build_procedure_call_stmt(d)
248
- end
249
- Builder.register(:type_label) { |d| builder.build_type_label(d) }
250
- Builder.register(:type_label_ref) { |d| builder.build_type_label_ref(d) }
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds subtype constraint and supertype expression nodes.
9
7
  class SubtypeConstraintBuilder
10
- include Helpers
11
-
12
8
  def build_subtype_constraint_decl(ast_data)
13
9
  head = ast_data[:subtype_constraint_head]
14
10
  body = ast_data[:subtype_constraint_body]
@@ -25,7 +21,7 @@ module Expressir
25
21
  if body.is_a?(Hash)
26
22
  abstract = !body[:abstract_supertype].nil?
27
23
  if body[:total_over].is_a?(Hash)
28
- total_over = Builder.build_children([body[:total_over][:entity_ref]].flatten.compact)
24
+ total_over = Builder.build_children(Builder.ensure_array(body[:total_over][:entity_ref]))
29
25
  end
30
26
  # Wrap supertype_expression in its node type so Builder.build dispatches correctly
31
27
  supertype_expression = if body[:supertype_expression]
@@ -55,10 +51,10 @@ module Expressir
55
51
  # Handle both formats:
56
52
  # - With item wrapper: {item: {operator: {...}, supertype_factor: {...}}}
57
53
  # - Without item wrapper: {operator: {...}, supertype_factor: {...}}
58
- factors = [base_factor] + (ast_data[:rhs] || []).filter_map do |r|
54
+ factors = [base_factor] + Builder.ensure_array(ast_data[:rhs]).filter_map do |r|
59
55
  r[:item]&.dig(:supertype_factor) || r[:supertype_factor]
60
56
  end
61
- operators = (ast_data[:rhs] || []).map do |r|
57
+ operators = Builder.ensure_array(ast_data[:rhs]).map do |r|
62
58
  (r[:item]&.dig(:operator) || r[:operator])&.values&.first
63
59
  end
64
60
 
@@ -83,10 +79,10 @@ module Expressir
83
79
  # Handle both formats:
84
80
  # - With item wrapper: {item: {operator: {...}, supertype_term: {...}}}
85
81
  # - Without item wrapper: {operator: {...}, supertype_term: {...}}
86
- terms = [base_term] + (ast_data[:rhs] || []).filter_map do |r|
82
+ terms = [base_term] + Builder.ensure_array(ast_data[:rhs]).filter_map do |r|
87
83
  r[:item]&.dig(:supertype_term) || r[:supertype_term]
88
84
  end
89
- operators = (ast_data[:rhs] || []).map do |r|
85
+ operators = Builder.ensure_array(ast_data[:rhs]).map do |r|
90
86
  (r[:item]&.dig(:operator) || r[:operator])&.values&.first
91
87
  end
92
88
 
@@ -160,29 +156,9 @@ module Expressir
160
156
 
161
157
  def build_subtype_declaration(ast_data)
162
158
  refs = ast_data[:entity_ref] || ast_data[:list_of_entity_ref]&.dig(:entity_ref)
163
- Builder.build_children([refs].flatten.compact)
159
+ Builder.build_children(Builder.ensure_array(refs))
164
160
  end
165
161
  end
166
162
  end
167
163
  end
168
164
  end
169
-
170
- builder = Expressir::Express::Builders::SubtypeConstraintBuilder.new
171
-
172
- Builder.register(:subtype_constraint_decl) do |d|
173
- builder.build_subtype_constraint_decl(d)
174
- end
175
- Builder.register(:total_over) { |d| builder.build_total_over(d) }
176
- Builder.register(:supertype_expression) do |d|
177
- builder.build_supertype_expression(d)
178
- end
179
- Builder.register(:supertype_factor) { |d| builder.build_supertype_factor(d) }
180
- Builder.register(:supertype_term) { |d| builder.build_supertype_term(d) }
181
- Builder.register(:one_of) { |d| builder.build_one_of(d) }
182
- Builder.register(:supertype_rule) { |d| builder.build_supertype_rule(d) }
183
- Builder.register(:subtype_constraint) do |d|
184
- builder.build_subtype_constraint(d)
185
- end
186
- Builder.register(:subtype_declaration) do |d|
187
- builder.build_subtype_declaration(d)
188
- end
@@ -1,19 +1,72 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
- # Builds syntax (top-level) nodes into Repository objects.
6
+ # Builds syntax (top-level) nodes into ExpFile objects.
7
+ # Each parsed EXPRESS file is represented as an ExpFile containing schemas.
9
8
  class SyntaxBuilder
9
+ # Build ExpFile from AST data
10
+ # @param ast_data [Hash, Array] The parsed AST with syntax node
11
+ # - Ruby parser: Hash with :schema_decl key
12
+ # - Native parser: Hash with :syntax wrapper containing :schemaDecl
13
+ # @return [Model::ExpFile] ExpFile containing the parsed schemas
10
14
  def call(ast_data)
11
- schemas = Builder.build_children(ast_data[:schema_decl])
12
- Expressir::Model::Repository.new(schemas: schemas.compact)
15
+ # Handle both formats:
16
+ # - Ruby parser: ast_data is a merged Hash {:schema_decl => [...], :spaces => {...}}
17
+ # - Native parser: ast_data is {:syntax => {:spaces, :schemaDecl => [...], :trailer}}
18
+ schema_decl_data = extract_schema_decls(ast_data)
19
+
20
+ schemas = Builder.build_children(schema_decl_data)
21
+ Expressir::Model::ExpFile.new(schemas: schemas.compact)
22
+ end
23
+
24
+ private
25
+
26
+ # Extract schema declarations from AST data.
27
+ # Handles both Ruby (snake_case) and native (camelCase) formats.
28
+ def extract_schema_decls(ast_data)
29
+ if ast_data.is_a?(Hash)
30
+ # Check for :syntax wrapper (native parser format)
31
+ if ast_data.key?(:syntax)
32
+ inner = ast_data[:syntax]
33
+ return inner[:schemaDecl] || inner[:schema_decl] if inner.is_a?(Hash)
34
+ end
35
+
36
+ # Ruby parser format: snake_case
37
+ return ast_data[:schema_decl] if ast_data.key?(:schema_decl)
38
+
39
+ # Native parser format: camelCase at top level (legacy)
40
+ return ast_data[:schemaDecl] if ast_data.key?(:schemaDecl)
41
+ elsif ast_data.is_a?(Array)
42
+ # Legacy native parser format: Array of Hashes
43
+ merged = {}
44
+ ast_data.each do |item|
45
+ if item.is_a?(Hash)
46
+ item.each do |_key, value|
47
+ if value.is_a?(Array)
48
+ value.each do |sub|
49
+ if sub.is_a?(Hash)
50
+ sub.each do |k, v|
51
+ snake_key = k.to_s
52
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
53
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
54
+ .downcase
55
+ .to_sym
56
+ merged[snake_key] ||= []
57
+ merged[snake_key] = v if v.is_a?(Array)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ return merged[:schema_decl]
66
+ end
67
+ nil
13
68
  end
14
69
  end
15
70
  end
16
71
  end
17
72
  end
18
-
19
- Builder.register(:syntax, Expressir::Express::Builders::SyntaxBuilder.new)
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds data type nodes (enumeration, select, array, bag, list, set, etc.).
9
7
  class TypeBuilder
10
- include Helpers
8
+ include ::Expressir::Express::Builders::Helpers
11
9
 
12
10
  # Simple types
13
11
  {
@@ -128,7 +126,7 @@ module Expressir
128
126
  if items_data
129
127
  items_data = items_data[:enumeration_item] if items_data.is_a?(Hash) && items_data[:enumeration_item]
130
128
  items_data = [items_data] unless items_data.is_a?(Array)
131
- items = items_data.flatten.compact.filter_map do |item|
129
+ items = items_data.filter_map do |item|
132
130
  actual_item = item.is_a?(Hash) ? (item[:enumeration_item] || item) : item
133
131
  Builder.build({ enumeration_item: actual_item })
134
132
  end
@@ -144,7 +142,7 @@ module Expressir
144
142
  if items_data
145
143
  items_data = items_data[:enumeration_item] if items_data.is_a?(Hash) && items_data[:enumeration_item]
146
144
  items_data = [items_data] unless items_data.is_a?(Array)
147
- items = items_data.flatten.compact.filter_map do |item|
145
+ items = items_data.filter_map do |item|
148
146
  actual_item = item.is_a?(Hash) ? (item[:enumeration_item] || item) : item
149
147
  Builder.build({ enumeration_item: actual_item })
150
148
  end
@@ -222,43 +220,3 @@ module Expressir
222
220
  end
223
221
  end
224
222
  end
225
-
226
- builder = Expressir::Express::Builders::TypeBuilder.new
227
-
228
- # Simple types
229
- %i[boolean_type integer_type logical_type number_type].each do |type|
230
- Builder.register(type) { |d| builder.send(:"build_#{type}", d) }
231
- end
232
- Builder.register(:generic_type) { |_d| Expressir::Model::DataTypes::Generic.new }
233
- Builder.register(:generic_entity_type) { |_d| Expressir::Model::DataTypes::GenericEntity.new }
234
- Builder.register(:aggregate_type) { |_d| Expressir::Model::DataTypes::Aggregate.new }
235
- Builder.register(:general_set_type) { |d| builder.build_general_set_type(d) }
236
- Builder.register(:general_list_type) { |d| builder.build_general_list_type(d) }
237
- Builder.register(:general_bag_type) { |d| builder.build_general_bag_type(d) }
238
- Builder.register(:general_array_type) { |d| builder.build_general_array_type(d) }
239
-
240
- Builder.register(:string_type) { |d| builder.build_string_type(d) }
241
- Builder.register(:binary_type) { |d| builder.build_binary_type(d) }
242
- Builder.register(:real_type) { |d| builder.build_real_type(d) }
243
- Builder.register(:array_type) { |d| builder.build_array_type(d) }
244
- Builder.register(:bag_type) { |d| builder.build_bag_type(d) }
245
- Builder.register(:list_type) { |d| builder.build_list_type(d) }
246
- Builder.register(:set_type) { |d| builder.build_set_type(d) }
247
- Builder.register(:enumeration_type) { |d| builder.build_enumeration_type(d) }
248
- Builder.register(:enumeration_item) { |d| builder.build_enumeration_item(d) }
249
- Builder.register(:select_type) { |d| builder.build_select_type(d) }
250
-
251
- # Type wrappers
252
- %i[concrete_types simple_types aggregation_types constructed_types
253
- generalized_types named_types instantiable_type parameter_type
254
- underlying_type general_aggregation_types].each do |type|
255
- Builder.register(type) { |d| builder.build_type_wrapper(d) }
256
- end
257
-
258
- # Bound handlers
259
- Builder.register(:bound1) { |d| Builder.build_optional(d[:numeric_expression]) }
260
- Builder.register(:bound2) { |d| Builder.build_optional(d[:numeric_expression]) }
261
- Builder.register(:width_spec) do |d|
262
- { width: Builder.build_optional(d[:width]), fixed: !d[:t_fixed].nil? }
263
- end
264
- Builder.register(:width) { |d| Builder.build_optional(d[:numeric_expression]) }
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helpers"
4
-
5
3
  module Expressir
6
4
  module Express
7
5
  module Builders
8
6
  # Builds type_decl nodes.
9
7
  class TypeDeclBuilder
10
- include Helpers
11
-
12
8
  def call(ast_data)
13
9
  id = Builder.build_optional(ast_data[:type_id])
14
10
  underlying_type = Builder.build_optional(ast_data[:underlying_type])
@@ -21,12 +17,10 @@ module Expressir
21
17
  Expressir::Model::Declarations::Type.new(
22
18
  id: id,
23
19
  underlying_type: underlying_type,
24
- where_rules: [where_rules].flatten.compact,
20
+ where_rules: [where_rules].flatten,
25
21
  )
26
22
  end
27
23
  end
28
24
  end
29
25
  end
30
26
  end
31
-
32
- Builder.register(:type_decl, Expressir::Express::Builders::TypeDeclBuilder.new)
@@ -10,7 +10,7 @@ module Expressir
10
10
  return [] unless rules_data
11
11
 
12
12
  rules_data = [rules_data] if rules_data.is_a?(Hash)
13
- rules_data.flatten.compact.filter_map do |rule|
13
+ Builder.ensure_array(rules_data).filter_map do |rule|
14
14
  Builder.build({ unique_rule: rule })
15
15
  end
16
16
  end
@@ -18,5 +18,3 @@ module Expressir
18
18
  end
19
19
  end
20
20
  end
21
-
22
- Builder.register(:unique_clause, Expressir::Express::Builders::UniqueClauseBuilder.new)
@@ -32,5 +32,3 @@ module Expressir
32
32
  end
33
33
  end
34
34
  end
35
-
36
- Builder.register(:unique_rule, Expressir::Express::Builders::UniqueRuleBuilder.new)
@@ -10,7 +10,7 @@ module Expressir
10
10
  return [] unless rules_data
11
11
 
12
12
  rules_data = [rules_data] if rules_data.is_a?(Hash)
13
- rules_data.flatten.compact.filter_map do |rule|
13
+ Builder.ensure_array(rules_data).filter_map do |rule|
14
14
  Builder.build({ domain_rule: rule })
15
15
  end
16
16
  end
@@ -18,5 +18,3 @@ module Expressir
18
18
  end
19
19
  end
20
20
  end
21
-
22
- Builder.register(:where_clause, Expressir::Express::Builders::WhereClauseBuilder.new)
@@ -5,39 +5,51 @@
5
5
  # Each builder class registers itself with Builder.register.
6
6
 
7
7
  # Ensure Expressir module and autoloads are set up first
8
- require_relative "../../expressir"
8
+ module Expressir
9
+ module Express
10
+ module Builders
11
+ autoload :Helpers, "#{__dir__}/builders/helpers"
9
12
 
10
- require_relative "builders/helpers"
11
- require_relative "builders/token_builder"
12
- require_relative "builders/simple_id_builder"
13
- require_relative "builders/syntax_builder"
14
- require_relative "builders/schema_version_builder"
15
- require_relative "builders/declaration_builder"
16
- require_relative "builders/schema_body_decl_builder"
17
- require_relative "builders/schema_decl_builder"
18
- require_relative "builders/entity_decl_builder"
19
- require_relative "builders/explicit_attr_builder"
20
- require_relative "builders/attribute_decl_builder"
21
- require_relative "builders/derive_clause_builder"
22
- require_relative "builders/derived_attr_builder"
23
- require_relative "builders/inverse_clause_builder"
24
- require_relative "builders/inverse_attr_builder"
25
- require_relative "builders/inverse_attr_type_builder"
26
- require_relative "builders/unique_clause_builder"
27
- require_relative "builders/unique_rule_builder"
28
- require_relative "builders/where_clause_builder"
29
- require_relative "builders/domain_rule_builder"
30
- require_relative "builders/reference_builder"
31
- require_relative "builders/literal_builder"
32
- require_relative "builders/type_decl_builder"
33
- require_relative "builders/type_builder"
34
- require_relative "builders/expression_builder"
35
- require_relative "builders/statement_builder"
36
- require_relative "builders/function_decl_builder"
37
- require_relative "builders/procedure_decl_builder"
38
- require_relative "builders/rule_decl_builder"
39
- require_relative "builders/subtype_constraint_builder"
40
- require_relative "builders/interface_builder"
41
- require_relative "builders/constant_builder"
42
- require_relative "builders/qualifier_builder"
43
- require_relative "builders/built_in_builder"
13
+ autoload :TokenBuilder, "#{__dir__}/builders/token_builder"
14
+ autoload :SimpleIdBuilder, "#{__dir__}/builders/simple_id_builder"
15
+ autoload :SyntaxBuilder, "#{__dir__}/builders/syntax_builder"
16
+ autoload :SchemaVersionBuilder,
17
+ "#{__dir__}/builders/schema_version_builder"
18
+ autoload :DeclarationBuilder, "#{__dir__}/builders/declaration_builder"
19
+ autoload :SchemaBodyDeclBuilder,
20
+ "#{__dir__}/builders/schema_body_decl_builder"
21
+ autoload :SchemaDeclBuilder, "#{__dir__}/builders/schema_decl_builder"
22
+ autoload :EntityDeclBuilder, "#{__dir__}/builders/entity_decl_builder"
23
+ autoload :ExplicitAttrBuilder, "#{__dir__}/builders/explicit_attr_builder"
24
+ autoload :AttributeDeclBuilder,
25
+ "#{__dir__}/builders/attribute_decl_builder"
26
+ autoload :DeriveClauseBuilder, "#{__dir__}/builders/derive_clause_builder"
27
+ autoload :DerivedAttrBuilder, "#{__dir__}/builders/derived_attr_builder"
28
+ autoload :InverseClauseBuilder,
29
+ "#{__dir__}/builders/inverse_clause_builder"
30
+ autoload :InverseAttrBuilder, "#{__dir__}/builders/inverse_attr_builder"
31
+ autoload :InverseAttrTypeBuilder,
32
+ "#{__dir__}/builders/inverse_attr_type_builder"
33
+ autoload :UniqueClauseBuilder, "#{__dir__}/builders/unique_clause_builder"
34
+ autoload :UniqueRuleBuilder, "#{__dir__}/builders/unique_rule_builder"
35
+ autoload :WhereClauseBuilder, "#{__dir__}/builders/where_clause_builder"
36
+ autoload :DomainRuleBuilder, "#{__dir__}/builders/domain_rule_builder"
37
+ autoload :ReferenceBuilder, "#{__dir__}/builders/reference_builder"
38
+ autoload :LiteralBuilder, "#{__dir__}/builders/literal_builder"
39
+ autoload :TypeDeclBuilder, "#{__dir__}/builders/type_decl_builder"
40
+ autoload :TypeBuilder, "#{__dir__}/builders/type_builder"
41
+ autoload :ExpressionBuilder, "#{__dir__}/builders/expression_builder"
42
+ autoload :StatementBuilder, "#{__dir__}/builders/statement_builder"
43
+ autoload :FunctionDeclBuilder, "#{__dir__}/builders/function_decl_builder"
44
+ autoload :ProcedureDeclBuilder,
45
+ "#{__dir__}/builders/procedure_decl_builder"
46
+ autoload :RuleDeclBuilder, "#{__dir__}/builders/rule_decl_builder"
47
+ autoload :SubtypeConstraintBuilder,
48
+ "#{__dir__}/builders/subtype_constraint_builder"
49
+ autoload :InterfaceBuilder, "#{__dir__}/builders/interface_builder"
50
+ autoload :ConstantBuilder, "#{__dir__}/builders/constant_builder"
51
+ autoload :QualifierBuilder, "#{__dir__}/builders/qualifier_builder"
52
+ autoload :BuiltInBuilder, "#{__dir__}/builders/built_in_builder"
53
+ end
54
+ end
55
+ end