bel_parser 1.0.0.alpha.28 → 1.0.0.alpha.29

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 295069b6ea6197942707dbabab0a7b7d85b36684
4
- data.tar.gz: e40f8170bfdd3feb80c49c554a83573ce58dda70
3
+ metadata.gz: 8a28ecd294f3b135b0e991bea16baa99164d95f8
4
+ data.tar.gz: a9ccd2c7036603beebebb0789fbafcb5fcdd3f6a
5
5
  SHA512:
6
- metadata.gz: 711da9e459b181285f15155a59c6aa0ae8fc2cf7fac6ca0e8f7bed727b686b36866cb0897fa1f996b1cc07df9162417660846a4afb245feecdd1f99c0fa4567a
7
- data.tar.gz: 9c2ebc3301472e59350139a9e707d903d0f8c2895bc62cc6ffd83b9dc3dbdb4b4401a6ab7065cfabe11820ea603b07c9873655ddb5cde1369b84d017cb576f6e
6
+ metadata.gz: 35f022dd4fcb5ffe865cf46a12d69c56d8ac4bbf3de00a69b10dfcbfee9824050b599310f00d011c294b780910ca6a9a8f2df8dba08d2a0985431caa01baffcc
7
+ data.tar.gz: 4e551f7640bb5380430e1119c92fb6338842486095bd65d42758b2d978243c9a300df53e1edb90bdc51f7ff18703775319b2ac8203a2491be94d75553c572ede
data/.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  'Anthony Bargnesi',
12
12
  'Nick Bargnesi',
13
13
  ]
14
- spec.date = %q{2016-05-11}
14
+ spec.date = %q{2016-05-13}
15
15
  spec.email = %q{abargnesi@selventa.com}
16
16
  spec.files = [
17
17
  Dir.glob('lib/**/*.{rb,rl}'),
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0.alpha.28
1
+ 1.0.0.alpha.29
@@ -8,14 +8,14 @@ module BELParser
8
8
  @types = types
9
9
  end
10
10
 
11
- def each
11
+ def each(enum = @ast_enum)
12
12
  if block_given?
13
- @ast_enum.each do |(line_number, line, ast_results)|
13
+ enum.each do |(line_number, line, ast_results)|
14
14
  selected = filter(ast_results)
15
15
  yield([line_number, line, selected]) unless selected.empty?
16
16
  end
17
17
  else
18
- enum_for(:each)
18
+ enum_for(:each, enum)
19
19
  end
20
20
  end
21
21
 
@@ -27,5 +27,29 @@ module BELParser
27
27
  end
28
28
  end
29
29
  end
30
+
31
+ def self.filter
32
+ BELParser::ASTFilter.new(nil, *Filter::TYPES)
33
+ end
34
+
35
+ def self.parameter_filter
36
+ BELParser::ASTFilter.new(
37
+ nil,
38
+ BELParser::Parsers::AST::Parameter.ast_type)
39
+ end
40
+
41
+ def self.term_filter
42
+ BELParser::ASTFilter.new(
43
+ nil,
44
+ BELParser::Parsers::AST::Term.ast_type)
45
+ end
46
+
47
+ def self.statement_filter
48
+ BELParser::ASTFilter.new(
49
+ nil,
50
+ BELParser::Parsers::AST::SimpleStatement.ast_type,
51
+ BELParser::Parsers::AST::ObservedTerm.ast_type,
52
+ BELParser::Parsers::AST::NestedStatement.ast_type)
53
+ end
30
54
  end
31
55
  end
@@ -1,3 +1,4 @@
1
+ require 'bel_parser/quoting'
1
2
  require 'bel_parser/resource'
2
3
 
3
4
  module BELParser
@@ -84,6 +85,19 @@ module BELParser
84
85
  @keyword.to_s
85
86
  end
86
87
  end
88
+
89
+ module Converters
90
+ include BELParser::Quoting
91
+
92
+ def ast_to_namespace(ast)
93
+ return nil if ast.nil? ||
94
+ !ast.is_a?(BELParser::Parsers::AST::NamespaceDefinition)
95
+ keyword, domain = ast.children
96
+ # TODO Support URI when it's an available domain.
97
+ url = domain.child.string.string_literal
98
+ Namespace.new(keyword, nil, unquote(url))
99
+ end
100
+ end
87
101
  end
88
102
  end
89
103
  end
@@ -21,6 +21,12 @@ module BELParser
21
21
  @value = value
22
22
  end
23
23
 
24
+ def encoding
25
+ nsv = @namespace[@value]
26
+ return nil unless nsv
27
+ nsv.first.encodings
28
+ end
29
+
24
30
  def valid?
25
31
  return false unless @value
26
32
  return true unless @namespace
@@ -46,7 +52,7 @@ module BELParser
46
52
  end
47
53
  alias_method :eql?, :'=='
48
54
 
49
- def to_s(_)
55
+ def to_s(_ = :short)
50
56
  if @namespace
51
57
  prefix = "#{@namespace.keyword}:"
52
58
  else
@@ -55,6 +61,26 @@ module BELParser
55
61
  %Q{#{prefix}#{quote_if_needed(@value)}}
56
62
  end
57
63
  end
64
+
65
+ module Converters
66
+ include BELParser::Quoting
67
+
68
+ def ast_to_parameter(ast, namespace_hash = {})
69
+ return nil if ast.nil? ||
70
+ !ast.is_a?(BELParser::Parsers::AST::Parameter)
71
+ prefix, value = ast.children
72
+ namespace =
73
+ if prefix.identifier
74
+ keyword = prefix.identifier.string_literal
75
+ namespace_hash[keyword]
76
+ else
77
+ nil
78
+ end
79
+ Parameter.new(
80
+ namespace,
81
+ unquote(value.children[0].string_literal))
82
+ end
83
+ end
58
84
  end
59
85
  end
60
86
  end
@@ -1,3 +1,5 @@
1
+ require 'bel_parser/quoting'
2
+
1
3
  module BELParser
2
4
  module Expression
3
5
  module Model
@@ -42,6 +44,7 @@ module BELParser
42
44
  @comment = comment
43
45
 
44
46
  if @relationship && !@object
47
+ require 'pry'; binding.pry
45
48
  raise(
46
49
  ArgumentError,
47
50
  "object must be set when specifying a relationship")
@@ -109,6 +112,48 @@ module BELParser
109
112
  comment ? lbl + ' //' + comment : lbl
110
113
  end
111
114
  end
115
+
116
+ module Converters
117
+ include BELParser::Quoting
118
+ include BELParser::Parsers::AST
119
+
120
+ def ast_to_statement(ast, spec, namespaces = {})
121
+ statement =
122
+ case ast
123
+ when BELParser::Parsers::AST::Statement
124
+ ast
125
+ when ObservedTerm, SimpleStatement, NestedStatement
126
+ ast.statement
127
+ else
128
+ nil
129
+ end
130
+ return nil if statement.nil?
131
+
132
+ spec ||= BELParser::Language.latest_supported_specification
133
+
134
+ Statement.new(
135
+ ast_to_term(statement.subject.term, spec, namespaces),
136
+ convert_relationship(statement.relationship, spec),
137
+ convert_object(statement.object, spec, namespaces),
138
+ statement.comment && statement.comment.children[0])
139
+ end
140
+
141
+ def convert_relationship(ast, spec)
142
+ relationship = ast.string_literal
143
+ relationship && spec.relationship(relationship.to_sym)
144
+ end
145
+
146
+ def convert_object(ast, spec, namespaces)
147
+ case
148
+ when ast.term?
149
+ ast_to_term(ast.child, spec, namespaces)
150
+ when ast.statement?
151
+ ast_to_statement(ast.child, spec, namespaces)
152
+ else
153
+ nil
154
+ end
155
+ end
156
+ end
112
157
  end
113
158
  end
114
159
  end
@@ -1,3 +1,5 @@
1
+ require 'bel_parser/quoting'
2
+
1
3
  module BELParser
2
4
  module Expression
3
5
  module Model
@@ -46,6 +48,45 @@ module BELParser
46
48
  end
47
49
  end
48
50
  end
51
+
52
+ module Converters
53
+ include BELParser::Quoting
54
+
55
+ def ast_to_term(ast, spec, namespaces = {})
56
+ return nil if ast.nil? ||
57
+ !ast.is_a?(BELParser::Parsers::AST::Term)
58
+ spec ||= BELParser::Language.latest_supported_specification
59
+ convert = method(:convert_argument).to_proc.curry[spec][namespaces]
60
+
61
+ Term.new(
62
+ convert_function(ast.function, spec),
63
+ ast.arguments.map(&convert))
64
+ end
65
+
66
+ def convert_function(ast, spec)
67
+ func = ast.identifier.string_literal
68
+ spec_func = spec.function(func.to_sym)
69
+
70
+ unless spec_func
71
+ raise(
72
+ ArgumentError,
73
+ %(ast has invalid function "#{func}" for BEL #{spec.version}))
74
+ end
75
+ spec_func
76
+ end
77
+
78
+ def convert_argument(spec, namespaces, argument)
79
+ child = argument.child
80
+ case child
81
+ when BELParser::Parsers::AST::Parameter
82
+ ast_to_parameter(child, namespaces)
83
+ when BELParser::Parsers::AST::Term
84
+ ast_to_term(child, spec, namespaces)
85
+ else
86
+ nil
87
+ end
88
+ end
89
+ end
49
90
  end
50
91
  end
51
92
  end
@@ -1,31 +1,131 @@
1
1
  require_relative '../ast_generator'
2
+ require_relative '../language'
2
3
  require_relative '../parsers/common'
3
4
  require_relative '../parsers/expression'
5
+ require_relative '../resource'
6
+ require_relative 'filter'
7
+ require_relative 'model'
4
8
 
5
9
  module BELParser
6
10
  module Expression
7
- # Parser for BEL Expression.
11
+
12
+ def self.parse(
13
+ input,
14
+ spec = BELParser::Language.latest_supported_specification,
15
+ namespaces = {})
16
+
17
+ parser = Parser.new(input, Expression.filter, spec, namespaces)
18
+ parser.parse
19
+ end
20
+
21
+ def self.parse_parameters(
22
+ input,
23
+ spec = BELParser::Language.latest_supported_specification,
24
+ namespaces = {})
25
+
26
+ parser = Parser.new(input, Expression.parameter_filter, spec, namespaces)
27
+ parser.parse
28
+ end
29
+
30
+ def self.parse_terms(
31
+ input,
32
+ spec = BELParser::Language.latest_supported_specification,
33
+ namespaces = {})
34
+
35
+ parser = Parser.new(input, Expression.term_filter, spec, namespaces)
36
+ parser.parse
37
+ end
38
+
39
+ def self.parse_statements(
40
+ input,
41
+ spec = BELParser::Language.latest_supported_specification,
42
+ namespaces = {})
43
+
44
+ parser = Parser.new(input, Expression.statement_filter, spec, namespaces)
45
+ parser.parse
46
+ end
47
+
48
+ # Parser for BEL expressions that return common objects.
8
49
  class Parser
9
- def parse(input, &block)
10
- case input
11
- when String
12
- parse_string(input, &block)
50
+ include BELParser::Expression::Model::Converters
51
+ include BELParser::Parsers::AST
52
+
53
+ def initialize(
54
+ input,
55
+ filter = Expression.filter,
56
+ spec = BELParser::Language.latest_supported_specification,
57
+ namespaces = {})
58
+
59
+ @input = input
60
+ @filter = filter
61
+ @spec = spec
62
+ @namespaces = namespaces
63
+ end
64
+
65
+ def parse
66
+ case @input
67
+ when ::String # conflicts with ...AST::String
68
+ convert_ast(
69
+ @spec,
70
+ @namespaces,
71
+ parse_string(@input, @filter).first)
13
72
  when Array
14
- parse_array(input, &block)
73
+ convert_multiple(
74
+ parse_array(@input, @filter),
75
+ @spec,
76
+ @namespaces)
15
77
  when IO, StringIO
16
- parse_io(input, &block)
78
+ convert_stream(
79
+ parse_io(@input, @filter),
80
+ @spec,
81
+ @namespaces)
17
82
  else
18
83
  raise ArgumentError,
19
- %(expected "input" to be one of String, Array, IO: #{input.class})
84
+ %(expected "input" to be one of String, Array, IO: #{@input.class})
20
85
  end
21
86
  end
22
87
 
23
- protected
88
+ private
89
+
90
+ def convert_ast(spec, namespaces, ast)
91
+ case ast
92
+ when Parameter
93
+ ast_to_parameter(ast, namespaces)
94
+ when Term
95
+ ast_to_term(ast, spec, namespaces)
96
+ when Statement, ObservedTerm, SimpleStatement, NestedStatement
97
+ ast_to_statement(ast, spec, namespaces)
98
+ else
99
+ nil
100
+ end
101
+ end
24
102
 
25
- def parse_string(string)
26
- filter = Filter.new(
103
+ def convert_multiple(asts, spec, namespaces)
104
+ mult = method(:convert_ast).to_proc.curry[spec][namespaces]
105
+ asts.lazy.map do |ast|
106
+ if ast.respond_to?(:each)
107
+ ast.map(&mult)
108
+ else
109
+ convert_ast(spec, namespaces, ast)
110
+ end
111
+ end
112
+ end
113
+
114
+ def convert_stream(asts, spec, namespaces)
115
+ mult = method(:convert_ast).to_proc.curry[spec][namespaces]
116
+ asts.lazy.flat_map do |ast|
117
+ if ast.respond_to?(:each)
118
+ ast.map(&mult)
119
+ else
120
+ convert_ast(spec, namespaces, ast)
121
+ end
122
+ end
123
+ end
124
+
125
+ def parse_string(string, filter)
126
+ enum = filter.each(
27
127
  BELParser::ASTGenerator.new(StringIO.new(string)))
28
- num, line, results = filter.each.first
128
+ num, line, results = enum.first
29
129
  if block_given?
30
130
  yield results
31
131
  nil
@@ -34,28 +134,28 @@ module BELParser
34
134
  end
35
135
  end
36
136
 
37
- def parse_array(array)
137
+ def parse_array(array, filter)
38
138
  if block_given?
39
139
  array.each do |expression|
40
- yield parse_string(expression.to_s)
140
+ yield parse_string(expression.to_s, filter)
41
141
  end
42
142
  nil
43
143
  else
44
144
  array.map do |expression|
45
- parse_string(expression.to_s)
145
+ parse_string(expression.to_s, filter)
46
146
  end
47
147
  end
48
148
  end
49
149
 
50
- def parse_io(io)
150
+ def parse_io(io, filter)
51
151
  if block_given?
52
- filter = Filter.new(BELParser::ASTGenerator.new(io))
53
- filter.each do |(num, line, results)|
152
+ enum = filter.each(BELParser::ASTGenerator.new(io))
153
+ enum.each do |(num, line, results)|
54
154
  yield results
55
155
  end
56
156
  nil
57
157
  else
58
- enum_for(:parse_io, io)
158
+ enum_for(:parse_io, io, filter)
59
159
  end
60
160
  end
61
161
  end
@@ -63,10 +163,7 @@ module BELParser
63
163
  end
64
164
 
65
165
  if __FILE__ == $PROGRAM_NAME
66
- BELParser::Expression::Parser.new.each($stdin) do |(line_number, line, res)|
67
- puts "#{line_number}: #{line}"
68
- res.each do |ast|
69
- puts ast.to_s(1)
70
- end
166
+ BELParser::Expression.parse($stdin).each do |obj|
167
+ puts " #{obj.class.name.split('::')[-1]}: #{obj}"
71
168
  end
72
169
  end
@@ -61,6 +61,15 @@ module BELParser
61
61
  versions.max_by { |version| version.to_f }
62
62
  end
63
63
 
64
+ # Returns the latest supported specification according to the
65
+ # _MAJOR.MINOR_ pattern.
66
+ #
67
+ # @return [Specification] latest supported specification
68
+ def self.latest_supported_specification
69
+ latest_version = versions.max_by { |version| version.to_f }
70
+ specification(latest_version)
71
+ end
72
+
64
73
  # Returns all language {Specification specifications}.
65
74
  #
66
75
  # @return [Array<Specification>] BEL specifications
@@ -44,9 +44,7 @@ module BELParser
44
44
  pref_label = solution.object.to_s
45
45
  end
46
46
  end
47
- return nil unless types.any? do |type_uri|
48
- type_uri == BELV.AnnotationConceptScheme || type_uri == BELV.NamespaceConceptScheme
49
- end
47
+ return nil unless types.any?(&method(:scheme_class?))
50
48
  ConceptScheme.new(uri, domain, prefix, pref_label, types)
51
49
  end
52
50
 
@@ -74,6 +72,10 @@ module BELParser
74
72
 
75
73
  private
76
74
 
75
+ def scheme_class?(uri)
76
+ uri == BELV.AnnotationConceptScheme || uri == BELV.NamespaceConceptScheme
77
+ end
78
+
77
79
  def find_value_uris(resource_uri, value)
78
80
  VALUE_PREDICATE_ORDER.each do |predicate|
79
81
  subjects =
@@ -41,7 +41,9 @@ module BELParser
41
41
  # @param [String] resource_identifier the resource identifier
42
42
  # @return [FileResource] the file resource
43
43
  def retrieve_resource(resource_identifier)
44
- read_resource(resource_identifier)[:dataset]
44
+ dataset = read_resource(resource_identifier)[:dataset]
45
+ return nil if dataset.types.all?(&:nil?)
46
+ dataset
45
47
  end
46
48
 
47
49
  def retrieve_value_from_resource(resource_identifier, value)
@@ -54,6 +56,7 @@ module BELParser
54
56
  def retrieve_values_from_resource(resource_identifier)
55
57
  resource = read_resource(resource_identifier)
56
58
  dataset = resource[:dataset]
59
+ return nil if resource[:values].size.zero?
57
60
  resource[:values].lazy.map do |value, encoding|
58
61
  FileResourceValue.new(dataset, value, encoding)
59
62
  end
@@ -37,8 +37,10 @@ module BELParser
37
37
  sparql_query = RESOLVE_CONCEPT.result(template_binding)
38
38
  concept_scheme = retrieve_resource(resource_identifier)
39
39
  to_concept = method(:hash_to_concept).to_proc.curry[concept_scheme]
40
+ concepts = execute_select(sparql_query).map(&to_concept).compact
40
41
 
41
- execute_select(sparql_query).map(&to_concept)
42
+ return nil if concepts.empty?
43
+ concepts
42
44
  end
43
45
 
44
46
  def retrieve_values_from_resource(resource_identifier)
@@ -47,8 +49,10 @@ module BELParser
47
49
  sparql_query = RESOLVE_CONCEPTS.result(template_binding)
48
50
  concept_scheme = retrieve_resource(resource_identifier)
49
51
  to_concept = method(:hash_to_concept).to_proc.curry[concept_scheme]
52
+ concepts = execute_select(sparql_query).map(&to_concept).compact
50
53
 
51
- execute_select(sparql_query).map(&to_concept)
54
+ return nil if concepts.empty?
55
+ concepts
52
56
  end
53
57
 
54
58
  protected
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.28
4
+ version: 1.0.0.alpha.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Bargnesi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-11 00:00:00.000000000 Z
12
+ date: 2016-05-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sparql-client