expressir 0.2.5 → 0.2.10

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/.cross_rubies +30 -0
  3. data/.github/workflows/rake.yml +14 -15
  4. data/.github/workflows/release.yml +24 -16
  5. data/.gitignore +3 -1
  6. data/Gemfile +0 -2
  7. data/Rakefile +2 -8
  8. data/expressir.gemspec +7 -4
  9. data/ext/express-parser/express_parser.cpp +12 -10
  10. data/ext/express-parser/extconf.rb +48 -25
  11. data/lib/expressir/express_exp/formatter.rb +74 -23
  12. data/lib/expressir/express_exp/parser.rb +20 -2
  13. data/lib/expressir/express_exp/visitor.rb +201 -96
  14. data/lib/expressir/model.rb +3 -0
  15. data/lib/expressir/model/attribute.rb +3 -1
  16. data/lib/expressir/model/constant.rb +3 -1
  17. data/lib/expressir/model/entity.rb +12 -19
  18. data/lib/expressir/model/enumeration_item.rb +3 -1
  19. data/lib/expressir/model/expressions/aggregate_initializer.rb +2 -2
  20. data/lib/expressir/model/expressions/aggregate_item.rb +1 -1
  21. data/lib/expressir/model/expressions/attribute_reference.rb +1 -1
  22. data/lib/expressir/model/expressions/binary_expression.rb +1 -1
  23. data/lib/expressir/model/expressions/call.rb +2 -2
  24. data/lib/expressir/model/expressions/entity_constructor.rb +2 -2
  25. data/lib/expressir/model/expressions/group_reference.rb +1 -1
  26. data/lib/expressir/model/expressions/index_reference.rb +1 -1
  27. data/lib/expressir/model/expressions/interval.rb +1 -1
  28. data/lib/expressir/model/expressions/query_expression.rb +5 -3
  29. data/lib/expressir/model/expressions/simple_reference.rb +1 -1
  30. data/lib/expressir/model/expressions/unary_expression.rb +1 -1
  31. data/lib/expressir/model/function.rb +32 -38
  32. data/lib/expressir/model/identifier.rb +1 -0
  33. data/lib/expressir/model/informal_proposition.rb +13 -0
  34. data/lib/expressir/model/interface.rb +2 -2
  35. data/lib/expressir/model/literals/binary.rb +1 -1
  36. data/lib/expressir/model/literals/integer.rb +1 -1
  37. data/lib/expressir/model/literals/logical.rb +1 -1
  38. data/lib/expressir/model/literals/real.rb +1 -1
  39. data/lib/expressir/model/literals/string.rb +1 -1
  40. data/lib/expressir/model/model_element.rb +67 -0
  41. data/lib/expressir/model/parameter.rb +3 -1
  42. data/lib/expressir/model/procedure.rb +33 -39
  43. data/lib/expressir/model/renamed_ref.rb +1 -1
  44. data/lib/expressir/model/repository.rb +3 -3
  45. data/lib/expressir/model/rule.rb +35 -38
  46. data/lib/expressir/model/schema.rb +35 -46
  47. data/lib/expressir/model/scope.rb +49 -3
  48. data/lib/expressir/model/statements/alias.rb +4 -2
  49. data/lib/expressir/model/statements/assignment.rb +1 -1
  50. data/lib/expressir/model/statements/call.rb +2 -2
  51. data/lib/expressir/model/statements/case.rb +2 -2
  52. data/lib/expressir/model/statements/case_action.rb +2 -2
  53. data/lib/expressir/model/statements/compound.rb +2 -2
  54. data/lib/expressir/model/statements/escape.rb +1 -1
  55. data/lib/expressir/model/statements/if.rb +3 -3
  56. data/lib/expressir/model/statements/null.rb +1 -1
  57. data/lib/expressir/model/statements/repeat.rb +4 -2
  58. data/lib/expressir/model/statements/return.rb +1 -1
  59. data/lib/expressir/model/statements/skip.rb +1 -1
  60. data/lib/expressir/model/subtype_constraint.rb +3 -1
  61. data/lib/expressir/model/type.rb +13 -3
  62. data/lib/expressir/model/types/aggregate.rb +3 -1
  63. data/lib/expressir/model/types/array.rb +1 -1
  64. data/lib/expressir/model/types/bag.rb +1 -1
  65. data/lib/expressir/model/types/binary.rb +1 -1
  66. data/lib/expressir/model/types/boolean.rb +1 -1
  67. data/lib/expressir/model/types/enumeration.rb +3 -3
  68. data/lib/expressir/model/types/generic.rb +3 -1
  69. data/lib/expressir/model/types/generic_entity.rb +3 -1
  70. data/lib/expressir/model/types/integer.rb +1 -1
  71. data/lib/expressir/model/types/list.rb +1 -1
  72. data/lib/expressir/model/types/logical.rb +1 -1
  73. data/lib/expressir/model/types/number.rb +1 -1
  74. data/lib/expressir/model/types/real.rb +1 -1
  75. data/lib/expressir/model/types/select.rb +3 -3
  76. data/lib/expressir/model/types/set.rb +1 -1
  77. data/lib/expressir/model/types/string.rb +1 -1
  78. data/lib/expressir/model/unique.rb +4 -2
  79. data/lib/expressir/model/variable.rb +3 -1
  80. data/lib/expressir/model/where.rb +3 -1
  81. data/lib/expressir/version.rb +1 -1
  82. data/original/examples/syntax/remark.exp +64 -20
  83. data/original/examples/syntax/remark_formatted.exp +63 -24
  84. data/original/examples/syntax/simple.exp +3 -0
  85. data/original/examples/syntax/source.exp +16 -0
  86. data/original/examples/syntax/syntax.exp +194 -181
  87. data/original/examples/syntax/syntax_formatted.exp +354 -787
  88. data/rakelib/cross-ruby.rake +308 -0
  89. data/spec/expressir/express_exp/head_source_spec.rb +38 -0
  90. data/spec/expressir/express_exp/parse_multiple_spec.rb +32 -0
  91. data/spec/expressir/express_exp/parse_remark_spec.rb +122 -56
  92. data/spec/expressir/express_exp/parse_syntax_spec.rb +1619 -1569
  93. data/spec/expressir/express_exp/source_spec.rb +29 -0
  94. data/spec/expressir/model/model_element_spec.rb +59 -0
  95. data/spec/expressir/model/{find_spec.rb → scope_spec.rb} +20 -7
  96. metadata +45 -21
@@ -1,7 +1,7 @@
1
1
  module Expressir
2
2
  module Model
3
3
  module Literals
4
- class String
4
+ class String < ModelElement
5
5
  attr_accessor :value
6
6
  attr_accessor :encoded
7
7
 
@@ -0,0 +1,67 @@
1
+ module Expressir
2
+ module Model
3
+ class ModelElement
4
+ CLASS_KEY = '_class'
5
+
6
+ def to_hash(options = {})
7
+ skip_empty = options[:skip_empty]
8
+
9
+ instance_variables.select{|x| x != :@parent}.each_with_object({ CLASS_KEY => self.class.name }) do |variable, result|
10
+ key = variable.to_s.sub(/^@/, '')
11
+ value = instance_variable_get(variable)
12
+
13
+ # skip default values (nil, empty array)
14
+ if !skip_empty or !(value.nil? or (value.is_a? Array and value.count == 0))
15
+ result[key] = if value.is_a? Array
16
+ value.map do |value|
17
+ if value.is_a? ModelElement
18
+ value.to_hash(options)
19
+ else
20
+ value
21
+ end
22
+ end
23
+ elsif value.is_a? ModelElement
24
+ value.to_hash(options)
25
+ else
26
+ value
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def self.from_hash(hash)
33
+ node_class = hash[CLASS_KEY]
34
+ node_options = hash.select{|x| x != CLASS_KEY}.each_with_object({}) do |(variable, value), result|
35
+ key = variable.to_sym
36
+
37
+ result[key] = if value.is_a? Array
38
+ value.map do |value|
39
+ if value.is_a? Hash
40
+ self.from_hash(value)
41
+ else
42
+ value
43
+ end
44
+ end
45
+ elsif value.is_a? Hash
46
+ self.from_hash(value)
47
+ else
48
+ value
49
+ end
50
+ end
51
+
52
+ node = Object.const_get(node_class).new(node_options)
53
+
54
+ # attach parent
55
+ if node.class.method_defined? :children
56
+ node.children.each do |child_node|
57
+ if child_node.class.method_defined? :parent and !child_node.parent
58
+ child_node.parent = node
59
+ end
60
+ end
61
+ end
62
+
63
+ node
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,6 +1,6 @@
1
1
  module Expressir
2
2
  module Model
3
- class Parameter
3
+ class Parameter < ModelElement
4
4
  include Identifier
5
5
 
6
6
  attr_accessor :var
@@ -8,6 +8,8 @@ module Expressir
8
8
 
9
9
  def initialize(options = {})
10
10
  @id = options[:id]
11
+ @remarks = options.fetch(:remarks, [])
12
+ @source = options[:source]
11
13
 
12
14
  @var = options[:var]
13
15
  @type = options[:type]
@@ -1,58 +1,52 @@
1
1
  module Expressir
2
2
  module Model
3
- class Procedure
3
+ class Procedure < ModelElement
4
4
  include Scope
5
5
  include Identifier
6
6
 
7
7
  attr_accessor :parameters
8
- attr_accessor :declarations
8
+ attr_accessor :types
9
+ attr_accessor :entities
10
+ attr_accessor :subtype_constraints
11
+ attr_accessor :functions
12
+ attr_accessor :procedures
9
13
  attr_accessor :constants
10
14
  attr_accessor :variables
11
15
  attr_accessor :statements
12
16
 
13
17
  def initialize(options = {})
14
18
  @id = options[:id]
15
-
16
- @parameters = options[:parameters]
17
- @declarations = options[:declarations]
18
- @constants = options[:constants]
19
- @variables = options[:variables]
20
- @statements = options[:statements]
21
- end
22
-
23
- def types
24
- @declarations.select{|x| x.instance_of? Expressir::Model::Type}
25
- end
26
-
27
- def entities
28
- @declarations.select{|x| x.instance_of? Expressir::Model::Entity}
29
- end
30
-
31
- def subtype_constraints
32
- @declarations.select{|x| x.instance_of? Expressir::Model::SubtypeConstraint}
33
- end
34
-
35
- def functions
36
- @declarations.select{|x| x.instance_of? Expressir::Model::Function}
37
- end
38
-
39
- def procedures
40
- @declarations.select{|x| x.instance_of? Expressir::Model::Procedure}
19
+ @remarks = options.fetch(:remarks, [])
20
+ @source = options[:source]
21
+
22
+ @parameters = options.fetch(:parameters, [])
23
+ @types = options.fetch(:types, [])
24
+ @entities = options.fetch(:entities, [])
25
+ @subtype_constraints = options.fetch(:subtype_constraints, [])
26
+ @functions = options.fetch(:functions, [])
27
+ @procedures = options.fetch(:procedures, [])
28
+ @constants = options.fetch(:constants, [])
29
+ @variables = options.fetch(:variables, [])
30
+ @statements = options.fetch(:statements, [])
41
31
  end
42
32
 
43
33
  def children
44
34
  items = []
45
- items.push(*@parameters) if @parameters
46
- items.push(*@declarations.flat_map do |x|
47
- [
48
- x,
49
- *if x.instance_of? Expressir::Model::Type and x.type.instance_of? Expressir::Model::Types::Enumeration
50
- x.type.items
51
- end
52
- ]
53
- end) if @declarations
54
- items.push(*@constants) if @constants
55
- items.push(*@variables) if @variables
35
+ items.push(*@parameters)
36
+ items.push(*@types)
37
+ items.push(*@types.flat_map do |x|
38
+ if x.type.instance_of? Expressir::Model::Types::Enumeration
39
+ x.type.items
40
+ else
41
+ []
42
+ end
43
+ end)
44
+ items.push(*@entities)
45
+ items.push(*@subtype_constraints)
46
+ items.push(*@functions)
47
+ items.push(*@procedures)
48
+ items.push(*@constants)
49
+ items.push(*@variables)
56
50
  items
57
51
  end
58
52
  end
@@ -1,6 +1,6 @@
1
1
  module Expressir
2
2
  module Model
3
- class RenamedRef
3
+ class RenamedRef < ModelElement
4
4
  attr_accessor :ref
5
5
  attr_accessor :id
6
6
 
@@ -1,17 +1,17 @@
1
1
  module Expressir
2
2
  module Model
3
- class Repository
3
+ class Repository < ModelElement
4
4
  include Scope
5
5
 
6
6
  attr_accessor :schemas
7
7
 
8
8
  def initialize(options = {})
9
- @schemas = options[:schemas]
9
+ @schemas = options.fetch(:schemas, [])
10
10
  end
11
11
 
12
12
  def children
13
13
  items = []
14
- items.push(*@schemas) if @schemas
14
+ items.push(*@schemas)
15
15
  items
16
16
  end
17
17
  end
@@ -1,60 +1,57 @@
1
1
  module Expressir
2
2
  module Model
3
- class Rule
3
+ class Rule < ModelElement
4
4
  include Scope
5
5
  include Identifier
6
6
 
7
7
  attr_accessor :applies_to
8
- attr_accessor :declarations
8
+ attr_accessor :types
9
+ attr_accessor :entities
10
+ attr_accessor :subtype_constraints
11
+ attr_accessor :functions
12
+ attr_accessor :procedures
9
13
  attr_accessor :constants
10
14
  attr_accessor :variables
11
15
  attr_accessor :statements
12
16
  attr_accessor :where
17
+ attr_accessor :informal_propositions
13
18
 
14
19
  def initialize(options = {})
15
20
  @id = options[:id]
21
+ @remarks = options.fetch(:remarks, [])
22
+ @source = options[:source]
16
23
 
17
24
  @applies_to = options[:applies_to]
18
- @declarations = options[:declarations]
19
- @constants = options[:constants]
20
- @variables = options[:variables]
21
- @statements = options[:statements]
22
- @where = options[:where]
23
- end
24
-
25
- def types
26
- @declarations.select{|x| x.instance_of? Expressir::Model::Type}
27
- end
28
-
29
- def entities
30
- @declarations.select{|x| x.instance_of? Expressir::Model::Entity}
31
- end
32
-
33
- def subtype_constraints
34
- @declarations.select{|x| x.instance_of? Expressir::Model::SubtypeConstraint}
35
- end
36
-
37
- def functions
38
- @declarations.select{|x| x.instance_of? Expressir::Model::Function}
39
- end
40
-
41
- def procedures
42
- @declarations.select{|x| x.instance_of? Expressir::Model::Procedure}
25
+ @types = options.fetch(:types, [])
26
+ @entities = options.fetch(:entities, [])
27
+ @subtype_constraints = options.fetch(:subtype_constraints, [])
28
+ @functions = options.fetch(:functions, [])
29
+ @procedures = options.fetch(:procedures, [])
30
+ @constants = options.fetch(:constants, [])
31
+ @variables = options.fetch(:variables, [])
32
+ @statements = options.fetch(:statements, [])
33
+ @where = options.fetch(:where, [])
34
+ @informal_propositions = options.fetch(:informal_propositions, [])
43
35
  end
44
36
 
45
37
  def children
46
38
  items = []
47
- items.push(*@declarations.flat_map do |x|
48
- [
49
- x,
50
- *if x.instance_of? Expressir::Model::Type and x.type.instance_of? Expressir::Model::Types::Enumeration
51
- x.type.items
52
- end
53
- ]
54
- end) if @declarations
55
- items.push(*@constants) if @constants
56
- items.push(*@variables) if @variables
57
- items.push(*@where) if @where
39
+ items.push(*@types)
40
+ items.push(*@types.flat_map do |x|
41
+ if x.type.instance_of? Expressir::Model::Types::Enumeration
42
+ x.type.items
43
+ else
44
+ []
45
+ end
46
+ end)
47
+ items.push(*@entities)
48
+ items.push(*@subtype_constraints)
49
+ items.push(*@functions)
50
+ items.push(*@procedures)
51
+ items.push(*@constants)
52
+ items.push(*@variables)
53
+ items.push(*@where)
54
+ items.push(*@informal_propositions)
58
55
  items
59
56
  end
60
57
  end
@@ -1,65 +1,54 @@
1
1
  module Expressir
2
2
  module Model
3
- class Schema
3
+ class Schema < ModelElement
4
4
  include Scope
5
5
  include Identifier
6
6
 
7
+ attr_accessor :head_source
8
+
7
9
  attr_accessor :version
8
10
  attr_accessor :interfaces
9
11
  attr_accessor :constants
10
- attr_accessor :declarations
12
+ attr_accessor :types
13
+ attr_accessor :entities
14
+ attr_accessor :subtype_constraints
15
+ attr_accessor :functions
16
+ attr_accessor :procedures
17
+ attr_accessor :rules
11
18
 
12
19
  def initialize(options = {})
13
20
  @id = options[:id]
14
- @version = options[:version]
15
- @interfaces = options[:interfaces]
16
- @constants = options[:constants]
17
- @declarations = options[:declarations]
18
- end
19
-
20
- def use_interfaces
21
- @interfaces.select{|x| x.kind == Expressir::Model::Interface::USE}
22
- end
23
-
24
- def reference_interfaces
25
- @interfaces.select{|x| x.kind == Expressir::Model::Interface::REFERENCE}
26
- end
27
-
28
- def types
29
- @declarations.select{|x| x.instance_of? Expressir::Model::Type}
30
- end
21
+ @remarks = options.fetch(:remarks, [])
22
+ @source = options[:source]
23
+ @head_source = options[:head_source]
31
24
 
32
- def entities
33
- @declarations.select{|x| x.instance_of? Expressir::Model::Entity}
34
- end
35
-
36
- def subtype_constraints
37
- @declarations.select{|x| x.instance_of? Expressir::Model::SubtypeConstraint}
38
- end
39
-
40
- def functions
41
- @declarations.select{|x| x.instance_of? Expressir::Model::Function}
42
- end
43
-
44
- def procedures
45
- @declarations.select{|x| x.instance_of? Expressir::Model::Procedure}
46
- end
47
-
48
- def rules
49
- @declarations.select{|x| x.instance_of? Expressir::Model::Rule}
25
+ @version = options[:version]
26
+ @interfaces = options.fetch(:interfaces, [])
27
+ @constants = options.fetch(:constants, [])
28
+ @types = options.fetch(:types, [])
29
+ @entities = options.fetch(:entities, [])
30
+ @subtype_constraints = options.fetch(:subtype_constraints, [])
31
+ @functions = options.fetch(:functions, [])
32
+ @procedures = options.fetch(:procedures, [])
33
+ @rules = options.fetch(:rules, [])
50
34
  end
51
35
 
52
36
  def children
53
37
  items = []
54
- items.push(*@constants) if @constants
55
- items.push(*@declarations.flat_map do |x|
56
- [
57
- x,
58
- *if x.instance_of? Expressir::Model::Type and x.type.instance_of? Expressir::Model::Types::Enumeration
59
- x.type.items
60
- end
61
- ]
62
- end) if @declarations
38
+ items.push(*@constants)
39
+ items.push(*@types)
40
+ items.push(*@types.flat_map do |x|
41
+ if x.type.instance_of? Expressir::Model::Types::Enumeration
42
+ x.type.items
43
+ else
44
+ []
45
+ end
46
+ end)
47
+ items.push(*@entities)
48
+ items.push(*@subtype_constraints)
49
+ items.push(*@functions)
50
+ items.push(*@procedures)
51
+ items.push(*@rules)
63
52
  items
64
53
  end
65
54
  end
@@ -2,10 +2,56 @@ module Expressir
2
2
  module Model
3
3
  module Scope
4
4
  def find(path)
5
- path.downcase.split(".").reduce(self) do |acc, curr|
6
- if acc and acc.class.method_defined? :children
7
- acc.children.find{|x| x.id.downcase == curr}
5
+ current_path, _, rest = path.partition(".")
6
+
7
+ # ignore prefix
8
+ _, _, current_path = current_path.rpartition(":")
9
+
10
+ current_path = current_path.downcase
11
+ child = children.find{|x| x.id and x.id.downcase == current_path}
12
+
13
+ if !rest.empty? and child.class.method_defined? :find
14
+ child.find(rest)
15
+ else
16
+ child
17
+ end
18
+ end
19
+
20
+ def find_or_create(path)
21
+ child = find(path)
22
+
23
+ if !child
24
+ # check if path should create implicit informal proposal
25
+ # see https://github.com/lutaml/expressir/issues/50
26
+ rest, _, current_path = path.rpartition(".")
27
+
28
+ if !rest.empty?
29
+ child = find(rest)
30
+ else
31
+ child = self
32
+ end
33
+
34
+ if child.class.method_defined? :informal_propositions
35
+ # ignore prefix
36
+ _, _, current_path = current_path.rpartition(":")
37
+
38
+ # match informal proposition id
39
+ informal_proposition_id = current_path.match(/^IP\d+$/).to_a[0]
40
+
41
+ if informal_proposition_id
42
+ # create implicit informal proposition
43
+ informal_proposition = Model::InformalProposition.new({
44
+ id: informal_proposition_id
45
+ })
46
+ informal_proposition.parent = child
47
+
48
+ child.informal_propositions << informal_proposition
49
+
50
+ informal_proposition
51
+ end
8
52
  end
53
+ else
54
+ child
9
55
  end
10
56
  end
11
57