bel_parser 1.0.0.alpha.18 → 1.0.0.alpha.19

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1256e007aca2d5c8449272250647c0cea918c777
4
- data.tar.gz: b2744bba741552fd30975cf554f4b91b1d79f9a6
3
+ metadata.gz: 64448dc49f150b92a0dd2571bfd9f97eff32eda9
4
+ data.tar.gz: 674d470b18c5195e21570cf3ae28ef75d111a0ff
5
5
  SHA512:
6
- metadata.gz: a71abfc3ac43e9c87d72d6a5622333b6fbc48d5c15d0944a4addb267d339f638474754068f838147883ead4c913039e78c225e890b34e5684fdd7d7976e59eb3
7
- data.tar.gz: c79f00f01c91e3ca4430744e7a2ab9548954c5663129c2947b82cbb47fe78c0c99d1b496d518d46d922c964bd8d8e9f771519737050ef38d3121502c9ea41608
6
+ metadata.gz: a8854636248e1dd75114b5131920a227bbfacd2d3f2deea6cdc0cd4873d2771b4751c6d4de792e644d671ccfa9213fcc7660d61ecf3ad6f04e90750595e8c1b9
7
+ data.tar.gz: 880b9595a4daa995594861f84891085762d6ae2b80de61573ac23db73ddb21bb5f5546fbd72e3e397789da559dca7381c4daf76a7f7be1a1e74eb13c2c753551
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0.alpha.18
1
+ 1.0.0.alpha.19
@@ -55,28 +55,6 @@ io =
55
55
  $stdin
56
56
  end
57
57
 
58
- def select(list, cls)
59
- list.select { |item| item.is_a?(cls) }
60
- end
61
-
62
- def report(line_number, ast, errors, warnings)
63
- log = !errors.empty? || !warnings.empty?
64
- if log
65
- puts "On line #{line_number} for #{ast.type}"
66
- puts " Errors:"
67
- errors.each do |err|
68
- puts " #{err}"
69
- end
70
- puts " Warnings:"
71
- warnings.each do |warn|
72
- puts " #{warn}"
73
- end
74
- end
75
- end
76
-
77
- SYN_ERR = BELParser::Language::Syntax::SyntaxError
78
- SYN_WARN = BELParser::Language::Syntax::SyntaxWarning
79
- SEM_WARN = BELParser::Language::Semantics::SemanticsWarning
80
58
 
81
59
  rr = BELParser::Resource::ResourceURLReader.new(options[:reuse])
82
60
  namespaces = Hash[
@@ -93,18 +71,63 @@ initial_state = {
93
71
  namespace_definitions: namespaces
94
72
  }
95
73
 
96
- BELParser::Script::Validator
97
- .new(initial_state)
98
- .each(io) do |(line_number, line, ast, syntax_results, state)|
99
- errors = select(syntax_results, SYN_ERR)
100
- warnings =
101
- select(syntax_results, SYN_WARN) +
102
- select(syntax_results, SEM_WARN)
103
-
104
- report(line_number, ast, errors, warnings)
105
-
106
- unless errors.empty?
107
- puts "Exiting due to error on line #{line_number}: #{line}"
108
- exit 1
74
+ module BELParser
75
+ module Script
76
+ # Reader assembles a BEL Script reader using the following pipeline:
77
+ #
78
+ # Generate -> Filter -> Pick One -> Aggregate State -> Validate Syntax
79
+ class Reader
80
+ SYN_ERR = BELParser::Language::Syntax::SyntaxError
81
+ SYN_WARN = BELParser::Language::Syntax::SyntaxWarning
82
+ SEM_WARN = BELParser::Language::Semantics::SemanticsWarning
83
+
84
+ def initialize(initial_state, io)
85
+ @validator =
86
+ Validator.new(
87
+ StateAggregator.new(
88
+ FirstNode.new(Filter.new(ASTGenerator.new(io))),
89
+ initial_state))
90
+ end
91
+
92
+ def read
93
+ @validator.each do |(line_number, line, ast_node, _)|
94
+ syntax_errors = ast_node.syntax_errors
95
+ errors = select(syntax_errors, SYN_ERR)
96
+ warnings =
97
+ select(syntax_errors, SYN_WARN) +
98
+ select(syntax_errors, SEM_WARN)
99
+
100
+ report(line_number, ast_node, errors, warnings)
101
+
102
+ unless errors.empty?
103
+ puts "Exiting due to error on line #{line_number}: #{line}"
104
+ exit 1
105
+ end
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def select(list, cls)
112
+ list.select { |item| item.is_a?(cls) }
113
+ end
114
+
115
+ def report(line_number, ast, errors, warnings)
116
+ log = !errors.empty? || !warnings.empty?
117
+ if log
118
+ puts "On line #{line_number} for #{ast.type}"
119
+ puts " Errors:"
120
+ errors.each do |err|
121
+ puts " #{err}"
122
+ end
123
+ puts " Warnings:"
124
+ warnings.each do |warn|
125
+ puts " #{warn}"
126
+ end
127
+ end
128
+ end
129
+ end
109
130
  end
110
131
  end
132
+
133
+ BELParser::Script::Reader.new(initial_state, io).read
@@ -0,0 +1,35 @@
1
+ # Requires the "bel" gem.
2
+ # This is for the BelScript translator intended to be plugged into bel.rb.
3
+ require 'bel/translator'
4
+
5
+ module BEL::Translator::Plugins
6
+ module BelScript
7
+ # BelScriptTranslator defines a {BEL::Translator} that can read/write
8
+ # BEL Script using the Nanopub model.
9
+ class BelScriptTranslator
10
+ include ::BEL::Translator
11
+
12
+ def read(data, options = {})
13
+ # EvidenceYielder.new(data, options)
14
+ end
15
+
16
+ def write(objects, writer = StringIO.new, options = {})
17
+ # if block_given?
18
+ # BelYielder.new(objects, options).each { |bel_part|
19
+ # yield bel_part
20
+ # }
21
+ # else
22
+ # if writer
23
+ # BelYielder.new(objects, options).each { |bel_part|
24
+ # writer << "#{bel_part}"
25
+ # writer.flush
26
+ # }
27
+ # writer
28
+ # else
29
+ # BelYielder.new(objects, options)
30
+ # end
31
+ # end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ module BEL::Translator::Plugins
2
+ # BELScript plugs a translator for BEL Script into bel.rb.
3
+ # Supports multiple BEL specifications by using the
4
+ # {BELParser::Language::ExpressionValidator expression validator}.
5
+ module BelScript
6
+ ID = :bel_script
7
+ NAME = 'BEL Script Translator'
8
+ DESCRIPTION = 'A translator that can read/write evidence to BEL Script.'
9
+ MEDIA_TYPES = %i(application/bel)
10
+ EXTENSIONS = %i(bel)
11
+
12
+ def self.create_translator(options = {})
13
+ require 'bel'
14
+ require_relative 'bel_script/translator'
15
+ BelScriptTranslator.new
16
+ end
17
+
18
+ def self.id
19
+ ID
20
+ end
21
+
22
+ def self.name
23
+ NAME
24
+ end
25
+
26
+ def self.description
27
+ DESCRIPTION
28
+ end
29
+
30
+ def self.media_types
31
+ MEDIA_TYPES
32
+ end
33
+
34
+ def self.file_extensions
35
+ EXTENSIONS
36
+ end
37
+ end
38
+ end
@@ -3,18 +3,19 @@ require_relative 'parsers/ast/node'
3
3
  module BELParser
4
4
  # ASTFilter filters types of {BELParser::Parsers::AST::Node}.
5
5
  class ASTFilter
6
- def initialize(*types)
7
- @types = types
6
+ def initialize(ast_enum, *types)
7
+ @ast_enum = ast_enum
8
+ @types = types
8
9
  end
9
10
 
10
- def each(ast_source)
11
+ def each
11
12
  if block_given?
12
- ast_source.each do |(line_number, line, ast_results)|
13
+ @ast_enum.each do |(line_number, line, ast_results)|
13
14
  selected = filter(ast_results)
14
15
  yield([line_number, line, selected]) unless selected.empty?
15
16
  end
16
17
  else
17
- enum_for(:each, ast_source)
18
+ enum_for(:each)
18
19
  end
19
20
  end
20
21
 
@@ -18,6 +18,10 @@ module BELParser
18
18
  map_const.call(BELParser::Parsers::BELScript)
19
19
  ].flatten!
20
20
 
21
+ def initialize(io)
22
+ @io = io
23
+ end
24
+
21
25
  # Yields AST results for each line of the IO.
22
26
  #
23
27
  # @example Receive AST results in given block.
@@ -42,9 +46,9 @@ module BELParser
42
46
  # object is returned if a block is given, otherwise an
43
47
  # {Enumerator} object is returned that can be iterated with
44
48
  # {Enumerator#each}
45
- def each(io) # rubocop:disable MethodLength
49
+ def each # rubocop:disable MethodLength
46
50
  if block_given?
47
- line_enumerator = map_lines(io.each_line.lazy)
51
+ line_enumerator = map_lines(@io.each_line.lazy)
48
52
 
49
53
  line_number = 1
50
54
  loop do
@@ -62,7 +66,7 @@ module BELParser
62
66
  end
63
67
  end
64
68
  else
65
- enum_for(:each, io)
69
+ enum_for(:each)
66
70
  end
67
71
  end
68
72
  end
@@ -0,0 +1,35 @@
1
+ module BELParser
2
+ module Script
3
+ # Filter will enumerate {BELParser::Parsers::AST::Node AST nodes} that are
4
+ # relevant to lines in a BEL Script document. It selects the relevant nodes
5
+ # from an {BELParser::Parsers::AST::Node AST node} enumerator.
6
+ class Filter
7
+ # Represents the BEL Script AST Node type.
8
+ # TODO These could be AST::Node subclasses instead.
9
+ TYPES = [
10
+ :simple_statement,
11
+ :observed_term,
12
+ :nested_statement,
13
+ :annotation_definition,
14
+ :namespace_definition,
15
+ :set,
16
+ :document_property,
17
+ :unset,
18
+ :blank_line,
19
+ :comment_line
20
+ ]
21
+
22
+ def initialize(ast_enum)
23
+ @ast_filter = BELParser::ASTFilter.new(ast_enum, *TYPES)
24
+ end
25
+
26
+ def each(&block)
27
+ if block_given?
28
+ @ast_filter.each(&block)
29
+ else
30
+ enum_for(:each)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ module BELParser
2
+ module Script
3
+ # FirstNode will return the first node from the set of
4
+ # {BELParser::Parsers::AST::Node AST nodes} provided.
5
+ class FirstNode
6
+ def initialize(ast_enum)
7
+ @ast_enum = ast_enum
8
+ end
9
+
10
+ def each
11
+ if block_given?
12
+ @ast_enum.each do |(line_number, line, ast_nodes)|
13
+ yield [line_number, line, ast_nodes.first]
14
+ end
15
+ else
16
+ enum_for(:each)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ module BELParser
2
+ module Script
3
+ class NanopubMapper
4
+
5
+
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,49 @@
1
+ module BELParser
2
+ module Script
3
+ # StateAggregator aggregates BEL Script state for each
4
+ # {BELParser::Parsers::AST::Node AST node} it processes.
5
+ class StateAggregator
6
+
7
+ STATE_PATH = 'state'
8
+
9
+ def initialize(ast_enum, options = {})
10
+ @ast_enum = ast_enum
11
+ @script_context = {}.merge(options)
12
+
13
+ StateAggregator.require_script_path
14
+ @state_functions = StateAggregator.state_constants(State)
15
+ end
16
+
17
+ def each
18
+ if block_given?
19
+ @ast_enum.each do |(line_number, line, ast_node)|
20
+ ast_node.traverse.each do |node|
21
+ @state_functions.each do |func|
22
+ func.consume(node, @script_context)
23
+ end
24
+ end
25
+ yield [line_number, line, ast_node, @script_context]
26
+ end
27
+ else
28
+ enum_for(:each)
29
+ end
30
+ end
31
+
32
+ def self.require_script_path
33
+ base_path = File.expand_path(File.dirname(__FILE__)) + File::SEPARATOR
34
+ Dir[File.join(base_path, STATE_PATH, '*.rb')]
35
+ .each do |ruby_file|
36
+ ruby_file.sub!(/^#{Regexp.escape(base_path)}/, '')
37
+ require_relative ruby_file
38
+ end
39
+ end
40
+
41
+ def self.state_constants(mod)
42
+ mod.constants.collect do |symbol|
43
+ const = mod.const_get(symbol)
44
+ const if const.respond_to?(:consume)
45
+ end.compact
46
+ end
47
+ end
48
+ end
49
+ end
@@ -12,58 +12,34 @@ require_relative '../language/syntax_function'
12
12
 
13
13
  module BELParser
14
14
  module Script
15
+ # Validator defines a BEL Script syntax validator. This validator
16
+ # expects to receive the BEL Script state for each node. This is
17
+ # accomplished by initializing with a {StateAggregator} that this
18
+ # will enumerate.
15
19
  class Validator
16
- include BELParser::Parsers::Common
17
- include BELParser::Parsers::Expression
18
- include BELParser::Parsers::BELScript
19
20
 
20
- FILTER = BELParser::ASTFilter.new(
21
- :simple_statement,
22
- :observed_term,
23
- :nested_statement,
24
- :annotation_definition,
25
- :namespace_definition,
26
- :set,
27
- :document_property,
28
- :unset,
29
- :blank_line,
30
- :comment_line
31
- )
32
-
33
- def initialize(options = {})
34
- @script_context = Concurrent::Hash.new.merge(options)
21
+ def initialize(state_aggregator)
22
+ @state_aggregator = state_aggregator
35
23
 
36
24
  Validator.require_script_path
37
- @state_functions = Validator.state_constants(State)
38
25
  @syntax_functions = Validator.syntax_constants(Syntax)
39
26
  end
40
27
 
41
- def each(io)
28
+ def each
42
29
  if block_given?
43
- filtered_ast = FILTER.each(BELParser::ASTGenerator.new.each(io))
44
- filtered_ast.each do |results|
45
- line_number, line, ast_results = results
46
- ast_node = ast_results.first
47
-
48
- syntax_results =
49
- ast_node.traverse.flat_map do |node|
50
- @syntax_functions.flat_map do |func|
51
- func.map(node, @script_context)
52
- end
53
- end.compact
54
-
55
- if syntax_results.empty?
56
- ast_node.traverse.each do |node|
57
- @state_functions.each do |func|
58
- func.consume(node, @script_context)
59
- end
30
+ @state_aggregator.each do |(line_number, line, ast_node, state)|
31
+ ast_node.traverse.flat_map do |node|
32
+ @syntax_functions.flat_map do |func|
33
+ func.map(node, state)
60
34
  end
35
+ end.compact.each do |syntax_result|
36
+ ast_node.add_syntax_error(syntax_result)
61
37
  end
62
38
 
63
- yield [line_number, line, ast_node, syntax_results, @script_context]
39
+ yield [line_number, line, ast_node, state]
64
40
  end
65
41
  else
66
- enum_for(:each, io)
42
+ enum_for(:each)
67
43
  end
68
44
  end
69
45
 
@@ -78,13 +54,6 @@ module BELParser
78
54
  end
79
55
  end
80
56
 
81
- def self.state_constants(mod)
82
- mod.constants.collect do |symbol|
83
- const = mod.const_get(symbol)
84
- const if const.respond_to?(:consume)
85
- end.compact
86
- end
87
-
88
57
  def self.syntax_constants(mod)
89
58
  mod.constants.collect do |symbol|
90
59
  const = mod.const_get(symbol)
@@ -94,62 +63,3 @@ module BELParser
94
63
  end
95
64
  end
96
65
  end
97
-
98
- if __FILE__ == $PROGRAM_NAME
99
- $LOAD_PATH.unshift(
100
- File.join(File.expand_path(File.dirname(__FILE__)), '..', '..'))
101
-
102
- require 'bel_parser/language'
103
- require 'bel_parser/resource/resource_url_reader'
104
-
105
- initial_state = {
106
- resource_reader: BELParser::Resource::ResourceURLReader.new,
107
- specification: BELParser::Language.specification(
108
- BELParser::Language.latest_supported_version
109
- )
110
- }
111
-
112
- BELParser::Script::Validator
113
- .new(initial_state)
114
- .each($stdin) do |(line_number, line, ast, syntax_results, state)|
115
- puts "#{line_number}: #{line}"
116
- puts ast.to_s(1)
117
-
118
- puts "Syntax errors:"
119
- syntax_results
120
- .select do |res|
121
- res.is_a?(BELParser::Language::Syntax::SyntaxError)
122
- end
123
- .each do |res|
124
- puts " #{res}"
125
- end
126
-
127
- puts "Syntax warnings:"
128
- syntax_results
129
- .select do |res|
130
- res.is_a?(BELParser::Language::Syntax::SyntaxWarning)
131
- end
132
- .each do |res|
133
- puts " #{res}"
134
- end
135
-
136
- puts "Semantics warnings:"
137
- syntax_results
138
- .select do |res|
139
- res.is_a?(BELParser::Language::Semantics::SemanticsWarning)
140
- end
141
- .each do |res|
142
- puts " #{res}"
143
- end
144
-
145
- puts "State:"
146
- state.each do |key, value|
147
- case value
148
- when Hash
149
- puts " #{key}: #{value.keys}"
150
- else
151
- puts " #{key}: #{value}"
152
- end
153
- end
154
- end
155
- end
@@ -1,5 +1,8 @@
1
1
  require_relative 'script/keywords'
2
2
  require_relative 'script/state_function'
3
3
 
4
- require_relative 'script/parser'
4
+ require_relative 'script/filter'
5
+ require_relative 'script/first_node'
6
+ require_relative 'script/state_aggregator'
5
7
  require_relative 'script/validator'
8
+ require_relative 'script/nanopub_mapper'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bel_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.18
4
+ version: 1.0.0.alpha.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Bargnesi
@@ -26,6 +26,8 @@ files:
26
26
  - VERSION
27
27
  - bin/bel2_validator
28
28
  - bin/bel_script_reader
29
+ - lib/bel/translator/plugins/bel_script.rb
30
+ - lib/bel/translator/plugins/bel_script/translator.rb
29
31
  - lib/bel_parser.rb
30
32
  - lib/bel_parser/ast_filter.rb
31
33
  - lib/bel_parser/ast_generator.rb
@@ -253,7 +255,6 @@ files:
253
255
  - lib/bel_parser/language/version2_0/value_encodings/rna_abundance.rb
254
256
  - lib/bel_parser/mixin/line_continuator.rb
255
257
  - lib/bel_parser/mixin/line_mapping.rb
256
- - lib/bel_parser/parser.rb
257
258
  - lib/bel_parser/parsers/ast/node.rb
258
259
  - lib/bel_parser/parsers/ast/sexp.rb
259
260
  - lib/bel_parser/parsers/bel_script.rb
@@ -314,7 +315,10 @@ files:
314
315
  - lib/bel_parser/resource/sparql_reader.rb
315
316
  - lib/bel_parser/resource/value.rb
316
317
  - lib/bel_parser/script.rb
318
+ - lib/bel_parser/script/filter.rb
319
+ - lib/bel_parser/script/first_node.rb
317
320
  - lib/bel_parser/script/keywords.rb
321
+ - lib/bel_parser/script/nanopub_mapper.rb
318
322
  - lib/bel_parser/script/parser.rb
319
323
  - lib/bel_parser/script/state/annotation_definition.rb
320
324
  - lib/bel_parser/script/state/bel_version.rb
@@ -322,6 +326,7 @@ files:
322
326
  - lib/bel_parser/script/state/namespace_definition.rb
323
327
  - lib/bel_parser/script/state/set.rb
324
328
  - lib/bel_parser/script/state/unset.rb
329
+ - lib/bel_parser/script/state_aggregator.rb
325
330
  - lib/bel_parser/script/state_function.rb
326
331
  - lib/bel_parser/script/syntax/expression_validation.rb
327
332
  - lib/bel_parser/script/syntax/invalid_regex_pattern.rb
@@ -1,54 +0,0 @@
1
- require_relative 'ast_filter'
2
- require_relative 'ast_generator'
3
- require_relative 'parsers/common'
4
- require_relative 'parsers/expression'
5
- require_relative 'parsers/bel_script'
6
-
7
- module BELParser
8
- # Parser is a line parser that supports recognition using all ragel parsers.
9
- class Parser
10
- include BELParser::Parsers::Common
11
- include BELParser::Parsers::Expression
12
- include BELParser::Parsers::BELScript
13
-
14
- FILTER = BELParser::ASTFilter.new(
15
- :blank_line,
16
- :comment_line,
17
- :identifier,
18
- :string,
19
- :list,
20
- :comment,
21
- :parameter,
22
- :term,
23
- :relationship,
24
- :observed_term,
25
- :simple_statement,
26
- :nested_statement,
27
- :annotation_definition,
28
- :namespace_definition,
29
- :set,
30
- :document_property,
31
- :unset
32
- )
33
-
34
- def each(io)
35
- if block_given?
36
- filtered_ast = FILTER.each(BELParser::ASTGenerator.new.each(io))
37
- filtered_ast.each do |results|
38
- yield results
39
- end
40
- else
41
- enum_for(:each, io)
42
- end
43
- end
44
- end
45
- end
46
-
47
- if __FILE__ == $PROGRAM_NAME
48
- BELParser::Parser.new.each($stdin) do |(line_number, line, results)|
49
- puts "#{line_number}: #{line}"
50
- results.each do |ast|
51
- puts ast.to_s(1)
52
- end
53
- end
54
- end