expressir 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +1 -7
- data/expressir.gemspec +2 -2
- data/lib/expressir/express_exp/formatter.rb +2 -6
- data/lib/expressir/express_exp/parser.rb +14 -1
- data/lib/expressir/express_exp/visitor.rb +79 -43
- data/lib/expressir/model.rb +1 -0
- data/lib/expressir/model/entity.rb +3 -0
- data/lib/expressir/model/informal_proposition.rb +11 -0
- data/lib/expressir/model/rule.rb +3 -0
- data/lib/expressir/model/schema.rb +2 -0
- data/lib/expressir/model/scope.rb +43 -9
- data/lib/expressir/model/type.rb +8 -0
- data/lib/expressir/version.rb +1 -1
- data/original/examples/syntax/remark.exp +63 -20
- data/original/examples/syntax/remark_formatted.exp +62 -19
- data/original/examples/syntax/source.exp +16 -0
- data/original/examples/syntax/syntax.exp +4 -1
- data/original/examples/syntax/syntax_formatted.exp +9 -0
- data/spec/expressir/express_exp/head_source_spec.rb +41 -0
- data/spec/expressir/express_exp/parse_multiple_spec.rb +32 -0
- data/spec/expressir/express_exp/parse_remark_spec.rb +115 -50
- data/spec/expressir/express_exp/parse_syntax_spec.rb +40 -0
- data/spec/expressir/express_exp/source_spec.rb +1 -1
- data/spec/expressir/model/find_spec.rb +19 -6
- metadata +10 -7
- data/spec/expressir/express_exp/find_spec.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d468b9de5531056db0a2a7866e32b8c8a0ab502ee39210744b6a3685f9e123dc
|
4
|
+
data.tar.gz: 567601eb16b95b8dac82ec9482393e0e0929da046a6e6dbc748378ec5fab384d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a966c457428d2b01bb4fc797118bf9c5ca944ab05358882a76370f23005b719a1b1d73369b9a088133128317b0b95040e869ceae7d364b402114261a88a2a78
|
7
|
+
data.tar.gz: 8e71c8226ab6088a7d7ad92945443c35247d2cc7abcb06cc94a0073c3486be688ba094bc6b979d93185decfb3d3f68e376a53967ab1eaca8996409ddba2ae99b
|
@@ -74,16 +74,10 @@ jobs:
|
|
74
74
|
RUBYGEMS_API_KEY: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }}
|
75
75
|
run: |
|
76
76
|
mkdir -p ~/.gem
|
77
|
-
echo "---"
|
78
77
|
cat > ~/.gem/credentials << EOF
|
79
78
|
---
|
80
79
|
:rubygems_api_key: ${RUBYGEMS_API_KEY}
|
81
80
|
EOF
|
82
|
-
echo "---"
|
83
81
|
chmod 0600 ~/.gem/credentials
|
84
|
-
|
85
|
-
ls -la ~/.gem
|
86
|
-
echo "---"
|
87
|
-
gem signin --debug
|
88
|
-
echo "---"
|
82
|
+
gem signin
|
89
83
|
for gem in pkg/*.gem; do gem push $gem -V; done
|
data/expressir.gemspec
CHANGED
@@ -32,11 +32,11 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_runtime_dependency "nokogiri", "~> 1.10"
|
34
34
|
spec.add_runtime_dependency "thor", "~> 1.0"
|
35
|
-
spec.add_runtime_dependency "rice", "~>
|
35
|
+
spec.add_runtime_dependency "rice", "~> 3"
|
36
36
|
spec.add_development_dependency "antlr4-native", "~> 1.1.0"
|
37
37
|
spec.add_development_dependency "bundler", "~> 2.0"
|
38
38
|
spec.add_development_dependency "pry", "~> 0.12.2"
|
39
|
-
spec.add_development_dependency "rake", "~>
|
39
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
40
40
|
spec.add_development_dependency "rake-compiler", "~> 1.1"
|
41
41
|
spec.add_development_dependency "rake-compiler-dock", "~> 1.1"
|
42
42
|
spec.add_development_dependency "rspec", "~> 3.0"
|
@@ -395,7 +395,7 @@ module Expressir
|
|
395
395
|
"\n",
|
396
396
|
INDENT,
|
397
397
|
'(',
|
398
|
-
node.items.map{|x| format(x)},
|
398
|
+
node.items.map{|x| format(x)}.join(', '),
|
399
399
|
')'
|
400
400
|
].join('')
|
401
401
|
end,
|
@@ -1437,11 +1437,7 @@ module Expressir
|
|
1437
1437
|
[
|
1438
1438
|
*format_remarks(node),
|
1439
1439
|
*if node.class.method_defined? :children
|
1440
|
-
node.children.
|
1441
|
-
if x != node
|
1442
|
-
format_scope_remarks(x)
|
1443
|
-
end
|
1444
|
-
end
|
1440
|
+
node.children.select{|x| x.parent == node}.flat_map{|x| format_scope_remarks(x)}
|
1445
1441
|
end
|
1446
1442
|
]
|
1447
1443
|
end
|
@@ -9,7 +9,7 @@ require 'expressir/express_exp/visitor'
|
|
9
9
|
module Expressir
|
10
10
|
module ExpressExp
|
11
11
|
class Parser
|
12
|
-
def self.
|
12
|
+
def self.from_file(file)
|
13
13
|
input = File.read(file)
|
14
14
|
|
15
15
|
=begin
|
@@ -36,6 +36,19 @@ module Expressir
|
|
36
36
|
|
37
37
|
repo
|
38
38
|
end
|
39
|
+
|
40
|
+
def self.from_files(files)
|
41
|
+
schemas = files.map{|file| self.from_file(file).schemas}.flatten
|
42
|
+
|
43
|
+
Model::Repository.new({
|
44
|
+
schemas: schemas
|
45
|
+
})
|
46
|
+
end
|
47
|
+
|
48
|
+
# deprecated
|
49
|
+
def self.from_exp(file)
|
50
|
+
self.from_file(file)
|
51
|
+
end
|
39
52
|
end
|
40
53
|
end
|
41
54
|
end
|
@@ -5,10 +5,8 @@ rescue LoadError
|
|
5
5
|
require_relative "express_parser"
|
6
6
|
end
|
7
7
|
require "expressir/model"
|
8
|
+
require "set"
|
8
9
|
|
9
|
-
# static shorthands are unwrapped
|
10
|
-
# - entity attributes, function/procedure parameters, local variables
|
11
|
-
#
|
12
10
|
# reference type is not recognized
|
13
11
|
# see note in A.1.5 Interpreted identifiers
|
14
12
|
# > It is expected that identifiers matching these syntax rules are known to an implementation.
|
@@ -25,6 +23,9 @@ require "expressir/model"
|
|
25
23
|
# > A syntactic construct such as ARRAY[1:3] OF REAL satisfies two syntactic productions —
|
26
24
|
# > aggregation_type and general_aggregation_type. It is considered to be instantiable no matter which
|
27
25
|
# > production it is required to satisfy in the syntax.
|
26
|
+
#
|
27
|
+
# static shorthands are unwrapped
|
28
|
+
# - entity attributes, function/procedure parameters, local variables
|
28
29
|
|
29
30
|
module Expressir
|
30
31
|
module ExpressExp
|
@@ -33,7 +34,7 @@ module Expressir
|
|
33
34
|
|
34
35
|
def initialize(tokens)
|
35
36
|
@tokens = tokens
|
36
|
-
@
|
37
|
+
@attached_remark_tokens = ::Set.new
|
37
38
|
|
38
39
|
super()
|
39
40
|
end
|
@@ -58,6 +59,14 @@ module Expressir
|
|
58
59
|
ctx.map{|ctx2| visit(ctx2)}.flatten if ctx
|
59
60
|
end
|
60
61
|
|
62
|
+
def get_tokens_source(tokens)
|
63
|
+
if tokens.last.text == '<EOF>'
|
64
|
+
tokens.pop
|
65
|
+
end
|
66
|
+
|
67
|
+
tokens.map{|x| x.text}.join('').force_encoding('UTF-8')
|
68
|
+
end
|
69
|
+
|
61
70
|
def get_tokens(ctx)
|
62
71
|
start_index, stop_index = if ctx.instance_of? ::ExpressParser::SyntaxContext
|
63
72
|
[0, @tokens.size - 1]
|
@@ -68,66 +77,93 @@ module Expressir
|
|
68
77
|
@tokens[start_index..stop_index]
|
69
78
|
end
|
70
79
|
|
80
|
+
def get_head_tokens(ctx)
|
81
|
+
start_index, stop_index = if ctx.instance_of? ::ExpressParser::SchemaDeclContext
|
82
|
+
start_index = ctx.start.token_index
|
83
|
+
stop_index = if ctx.schema_body.interface_specification.length > 0
|
84
|
+
ctx.schema_body.interface_specification.last.stop.token_index
|
85
|
+
elsif ctx.schema_version_id
|
86
|
+
ctx.schema_version_id.stop.token_index + 1
|
87
|
+
else
|
88
|
+
ctx.schema_id.stop.token_index + 1
|
89
|
+
end
|
90
|
+
|
91
|
+
[start_index, stop_index]
|
92
|
+
end
|
93
|
+
|
94
|
+
if start_index and stop_index
|
95
|
+
@tokens[start_index..stop_index]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
71
99
|
def attach_source(ctx, node)
|
72
100
|
if node.class.method_defined? :source
|
73
|
-
|
74
|
-
node.source =
|
101
|
+
tokens = get_tokens(ctx)
|
102
|
+
node.source = get_tokens_source(tokens)
|
103
|
+
end
|
104
|
+
|
105
|
+
if node.class.method_defined? :head_source
|
106
|
+
tokens = get_head_tokens(ctx)
|
107
|
+
node.head_source = get_tokens_source(tokens)
|
75
108
|
end
|
76
109
|
end
|
77
110
|
|
78
111
|
def attach_parent(ctx, node)
|
79
112
|
if node.class.method_defined? :children
|
80
113
|
node.children.each do |child_node|
|
81
|
-
if child_node.class.method_defined? :parent
|
114
|
+
if child_node.class.method_defined? :parent and !child_node.parent
|
82
115
|
child_node.parent = node
|
83
116
|
end
|
84
117
|
end
|
85
118
|
end
|
86
119
|
end
|
87
120
|
|
121
|
+
def find_remark_target(node, path)
|
122
|
+
current_node = node
|
123
|
+
target_node = nil
|
124
|
+
|
125
|
+
if current_node.class.method_defined? :find_or_create
|
126
|
+
target_node = current_node.find_or_create(path)
|
127
|
+
end
|
128
|
+
while !target_node and current_node.class.method_defined? :parent and current_node.parent.class.method_defined? :find_or_create
|
129
|
+
current_node = current_node.parent
|
130
|
+
target_node = current_node.find_or_create(path)
|
131
|
+
end
|
132
|
+
|
133
|
+
target_node
|
134
|
+
end
|
135
|
+
|
88
136
|
def attach_remarks(ctx, node)
|
89
137
|
remark_tokens = get_tokens(ctx).select{|x| x.channel == REMARK_CHANNEL}
|
90
|
-
if remark_tokens
|
91
|
-
remark_tokens.each do |remark_token|
|
92
|
-
remark_text = remark_token.text
|
93
|
-
|
94
|
-
# check if it is tagged remark
|
95
|
-
match = if remark_text.start_with?('--')
|
96
|
-
remark_text[2..-1].match(/^"([^"]*)"(.*)$/)
|
97
|
-
elsif remark_text.start_with?('(*') and remark_text.end_with?('*)')
|
98
|
-
remark_text[2..-3].match(/^"([^"]*)"(.*)$/m)
|
99
|
-
end
|
100
|
-
if !match
|
101
|
-
next
|
102
|
-
end
|
103
138
|
|
104
|
-
|
105
|
-
|
106
|
-
next
|
107
|
-
end
|
139
|
+
# skip already attached remarks
|
140
|
+
remark_tokens = remark_tokens.select{|x| !@attached_remark_tokens.include?(x)}
|
108
141
|
|
109
|
-
|
110
|
-
|
111
|
-
|
142
|
+
# parse remarks, find remark targets
|
143
|
+
tagged_remark_tokens = remark_tokens.map do |remark_token|
|
144
|
+
_, remark_tag, remark_text = if remark_token.text.start_with?('--')
|
145
|
+
remark_token.text.match(/^--"([^"]*)"(.*)$/).to_a
|
146
|
+
else
|
147
|
+
remark_token.text.match(/^\(\*"([^"]*)"(.*)\*\)$/m).to_a
|
148
|
+
end
|
112
149
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
current_node = current_node.parent
|
120
|
-
target_node = current_node.find(remark_tag)
|
121
|
-
end
|
150
|
+
if remark_tag
|
151
|
+
remark_target = find_remark_target(node, remark_tag)
|
152
|
+
end
|
153
|
+
if remark_text
|
154
|
+
remark_text = remark_text.strip.force_encoding('UTF-8')
|
155
|
+
end
|
122
156
|
|
123
|
-
|
124
|
-
|
125
|
-
target_node.remarks << remark_content
|
157
|
+
[remark_token, remark_target, remark_text]
|
158
|
+
end.select{|x| x[1]}
|
126
159
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
160
|
+
tagged_remark_tokens.each do |remark_token, remark_target, remark_text|
|
161
|
+
# attach remark
|
162
|
+
remark_target.remarks ||= []
|
163
|
+
remark_target.remarks << remark_text
|
164
|
+
|
165
|
+
# mark remark as attached, so that it is not attached again at higher nesting level
|
166
|
+
@attached_remark_tokens << remark_token
|
131
167
|
end
|
132
168
|
end
|
133
169
|
|
data/lib/expressir/model.rb
CHANGED
@@ -6,6 +6,7 @@ require 'expressir/model/constant'
|
|
6
6
|
require 'expressir/model/entity'
|
7
7
|
require 'expressir/model/enumeration_item'
|
8
8
|
require 'expressir/model/function'
|
9
|
+
require 'expressir/model/informal_proposition'
|
9
10
|
require 'expressir/model/interface'
|
10
11
|
require 'expressir/model/parameter'
|
11
12
|
require 'expressir/model/procedure'
|
@@ -10,6 +10,7 @@ module Expressir
|
|
10
10
|
attr_accessor :attributes
|
11
11
|
attr_accessor :unique
|
12
12
|
attr_accessor :where
|
13
|
+
attr_accessor :informal_propositions
|
13
14
|
|
14
15
|
def initialize(options = {})
|
15
16
|
@id = options[:id]
|
@@ -20,6 +21,7 @@ module Expressir
|
|
20
21
|
@attributes = options[:attributes]
|
21
22
|
@unique = options[:unique]
|
22
23
|
@where = options[:where]
|
24
|
+
@informal_propositions = options[:informal_propositions]
|
23
25
|
end
|
24
26
|
|
25
27
|
def explicit_attributes
|
@@ -39,6 +41,7 @@ module Expressir
|
|
39
41
|
items.push(*@attributes) if @attributes
|
40
42
|
items.push(*@unique) if @unique
|
41
43
|
items.push(*@where) if @where
|
44
|
+
items.push(*@informal_propositions) if @informal_propositions
|
42
45
|
items
|
43
46
|
end
|
44
47
|
end
|
data/lib/expressir/model/rule.rb
CHANGED
@@ -10,6 +10,7 @@ module Expressir
|
|
10
10
|
attr_accessor :variables
|
11
11
|
attr_accessor :statements
|
12
12
|
attr_accessor :where
|
13
|
+
attr_accessor :informal_propositions
|
13
14
|
|
14
15
|
def initialize(options = {})
|
15
16
|
@id = options[:id]
|
@@ -20,6 +21,7 @@ module Expressir
|
|
20
21
|
@variables = options[:variables]
|
21
22
|
@statements = options[:statements]
|
22
23
|
@where = options[:where]
|
24
|
+
@informal_propositions = options[:informal_propositions]
|
23
25
|
end
|
24
26
|
|
25
27
|
def types
|
@@ -55,6 +57,7 @@ module Expressir
|
|
55
57
|
items.push(*@constants) if @constants
|
56
58
|
items.push(*@variables) if @variables
|
57
59
|
items.push(*@where) if @where
|
60
|
+
items.push(*@informal_propositions) if @informal_propositions
|
58
61
|
items
|
59
62
|
end
|
60
63
|
end
|
@@ -4,20 +4,54 @@ module Expressir
|
|
4
4
|
attr_accessor :source
|
5
5
|
|
6
6
|
def find(path)
|
7
|
-
|
7
|
+
current_path, _, rest = path.partition(".")
|
8
8
|
|
9
|
-
# ignore
|
10
|
-
|
11
|
-
|
9
|
+
# ignore prefix
|
10
|
+
_, _, current_path = current_path.rpartition(":")
|
11
|
+
|
12
|
+
current_path = current_path.downcase
|
13
|
+
child = children.find{|x| x.id and x.id.downcase == current_path}
|
14
|
+
|
15
|
+
if !rest.empty? and child.class.method_defined? :find
|
16
|
+
child.find(rest)
|
17
|
+
else
|
18
|
+
child
|
12
19
|
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_or_create(path)
|
23
|
+
child = find(path)
|
13
24
|
|
14
|
-
child
|
25
|
+
if !child
|
26
|
+
# check if path should create implicit informal proposal
|
27
|
+
# see https://github.com/lutaml/expressir/issues/50
|
28
|
+
rest, _, current_path = path.rpartition(".")
|
15
29
|
|
16
|
-
|
17
|
-
|
18
|
-
child.find(rest)
|
30
|
+
if !rest.empty?
|
31
|
+
child = find(rest)
|
19
32
|
else
|
20
|
-
|
33
|
+
child = self
|
34
|
+
end
|
35
|
+
|
36
|
+
if child.class.method_defined? :informal_propositions
|
37
|
+
# ignore prefix
|
38
|
+
_, _, current_path = current_path.rpartition(":")
|
39
|
+
|
40
|
+
# match informal proposition id
|
41
|
+
informal_proposition_id = current_path.match(/^IP\d+$/).to_a[0]
|
42
|
+
|
43
|
+
if informal_proposition_id
|
44
|
+
# create implicit informal proposition
|
45
|
+
informal_proposition = Model::InformalProposition.new({
|
46
|
+
id: informal_proposition_id
|
47
|
+
})
|
48
|
+
informal_proposition.parent = child
|
49
|
+
|
50
|
+
child.informal_propositions ||= []
|
51
|
+
child.informal_propositions << informal_proposition
|
52
|
+
|
53
|
+
informal_proposition
|
54
|
+
end
|
21
55
|
end
|
22
56
|
else
|
23
57
|
child
|
data/lib/expressir/model/type.rb
CHANGED
@@ -6,17 +6,25 @@ module Expressir
|
|
6
6
|
|
7
7
|
attr_accessor :type
|
8
8
|
attr_accessor :where
|
9
|
+
attr_accessor :informal_propositions
|
9
10
|
|
10
11
|
def initialize(options = {})
|
11
12
|
@id = options[:id]
|
12
13
|
|
13
14
|
@type = options[:type]
|
14
15
|
@where = options[:where]
|
16
|
+
@informal_propositions = options[:informal_propositions]
|
15
17
|
end
|
16
18
|
|
17
19
|
def children
|
18
20
|
items = []
|
21
|
+
items.push(*[
|
22
|
+
*if @type.instance_of? Expressir::Model::Types::Enumeration
|
23
|
+
@type.items
|
24
|
+
end
|
25
|
+
])
|
19
26
|
items.push(*@where) if @where
|
27
|
+
items.push(*@informal_propositions) if @informal_propositions
|
20
28
|
items
|
21
29
|
end
|
22
30
|
end
|