bel_parser 1.0.0.alpha.13 → 1.0.0.alpha.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/bel_parser/language/apply_namespace_encoding.rb +5 -2
  4. data/lib/bel_parser/language/expression_validator.rb +25 -7
  5. data/lib/bel_parser/language/syntax/undefined_namespace_value.rb +5 -6
  6. data/lib/bel_parser/language.rb +8 -0
  7. data/lib/bel_parser/parsers/ast/node.rb +30 -3
  8. data/lib/bel_parser/parsers/bel_script/define_annotation.rb +1732 -1288
  9. data/lib/bel_parser/parsers/bel_script/set.rb +1424 -972
  10. data/lib/bel_parser/parsers/bel_script/set_document.rb +2735 -2100
  11. data/lib/bel_parser/parsers/common/list.rb +708 -462
  12. data/lib/bel_parser/parsers/common/list.rl +6 -4
  13. data/lib/bel_parser/resource/eager_reader.rb +9 -9
  14. data/lib/bel_parser/resource/http_cache.rb +26 -8
  15. data/lib/bel_parser/resource/resource_file_reader.rb +1 -0
  16. data/lib/bel_parser/resource/sparql_reader.rb +1 -0
  17. data/lib/bel_parser/script/state/annotation_definition.rb +62 -0
  18. data/lib/bel_parser/script/state/bel_version.rb +35 -0
  19. data/lib/bel_parser/script/state/document_property.rb +29 -0
  20. data/lib/bel_parser/script/state/namespace_definition.rb +32 -0
  21. data/lib/bel_parser/script/state/set.rb +57 -0
  22. data/lib/bel_parser/script/state/unset.rb +43 -0
  23. data/lib/bel_parser/script/state_function.rb +10 -0
  24. data/lib/bel_parser/script/syntax/expression_validation.rb +46 -0
  25. data/lib/bel_parser/script/syntax/invalid_regex_pattern.rb +49 -0
  26. data/lib/bel_parser/script/syntax/undefined_annotation.rb +60 -0
  27. data/lib/bel_parser/script/syntax/undefined_annotation_value.rb +83 -0
  28. data/lib/bel_parser/script/syntax/unresolvable_namespace.rb +55 -0
  29. data/lib/bel_parser/script/syntax/unsupported_bel_version.rb +58 -0
  30. data/lib/bel_parser/script/validator.rb +153 -0
  31. metadata +15 -1
@@ -25,9 +25,11 @@
25
25
 
26
26
  action append_list {
27
27
  # Append list argument if its value is not empty.
28
- list_arg_value = @buffers[:list_arg].children[0].children[0]
29
- if list_arg_value != ''
30
- @buffers[:list] <<= @buffers[:list_arg]
28
+ if @buffers[:list_arg]
29
+ list_arg_value = @buffers[:list_arg].children[0].children[0]
30
+ if list_arg_value != ''
31
+ @buffers[:list] <<= @buffers[:list_arg]
32
+ end
31
33
  end
32
34
  }
33
35
 
@@ -60,7 +62,7 @@
60
62
  (
61
63
  STRING %string $err(error_list_string) |
62
64
  IDENT %ident $err(error_list_ident)
63
- ) $err(append_list) %append_list
65
+ )? $err(append_list) %append_list
64
66
  SP*
65
67
  (
66
68
  ',' @clear
@@ -34,7 +34,7 @@ module BELParser
34
34
  return cached_concept if cached_concept
35
35
  end
36
36
 
37
- EMPTY_ARRAY
37
+ nil
38
38
  end
39
39
 
40
40
  def retrieve_values_from_resource(resource_identifier)
@@ -52,17 +52,17 @@ module BELParser
52
52
  if lock.try_lock
53
53
  Thread.new do
54
54
  value_hash = {
55
- :name => Hash.new { |hash, key| hash[key] = [] },
56
- :identifier => Hash.new { |hash, key| hash[key] = [] },
57
- :title => Hash.new { |hash, key| hash[key] = [] },
58
- :synonyms => Hash.new { |hash, key| hash[key] = [] }
55
+ :name => {},
56
+ :identifier => {},
57
+ :title => {},
58
+ :synonyms => {}
59
59
  }
60
60
  retrieve_values_from_resource(identifier).each do |concept|
61
- value_hash[:name][concept.name] << concept
62
- value_hash[:identifier][concept.identifier] << concept
63
- value_hash[:title][concept.title] << concept
61
+ value_hash[:name][concept.name] = concept
62
+ value_hash[:identifier][concept.identifier] = concept
63
+ value_hash[:title][concept.title] = concept
64
64
  concept.synonyms.each do |synonym|
65
- value_hash[:synonyms][synonym] << concept
65
+ value_hash[:synonyms][synonym] = concept
66
66
  end
67
67
  end
68
68
  resources[identifier] = value_hash
@@ -32,24 +32,42 @@ module BELParser
32
32
  end
33
33
  else
34
34
  uri = URI.parse(url)
35
- cached_file = File.open(cached_url_path, 'w')
36
35
  begin
37
36
  Net::HTTP.start(uri.host, uri.port) do |http|
38
37
  http.request(Net::HTTP::Get.new(uri)) do |response|
38
+
39
39
  if block_given?
40
- response.read_body do |chunk|
41
- cached_file.write(chunk)
42
- yield StringIO.new(chunk)
40
+ if response.is_a?(Net::HTTPOK)
41
+ cached_file = File.open(cached_url_path, 'w')
42
+ response.read_body do |chunk|
43
+ cached_file.write(chunk)
44
+ yield StringIO.new(chunk)
45
+ end
46
+ else
47
+ yield nil
43
48
  end
44
49
  else
45
- content = response.read_body
46
- cached_file.write(content)
47
- return StringIO.new(content)
50
+ if response.is_a?(Net::HTTPOK)
51
+ cached_file = File.open(cached_url_path, 'w')
52
+ content = response.read_body
53
+ cached_file.write(content)
54
+ return StringIO.new(content)
55
+ else
56
+ return nil
57
+ end
48
58
  end
49
59
  end
50
60
  end
61
+ rescue SocketError
62
+ if block_given?
63
+ yield nil
64
+ else
65
+ return nil
66
+ end
51
67
  ensure
52
- cached_file.close
68
+ if defined? cached_file
69
+ cached_file.close
70
+ end
53
71
  end
54
72
  end
55
73
  end
@@ -74,6 +74,7 @@ module BELParser
74
74
 
75
75
  def read_resource(url)
76
76
  io = @http_cache.get(url)
77
+ return nil unless io
77
78
 
78
79
  type, name, keyword, domain = nil
79
80
  io.each_line do |line|
@@ -60,6 +60,7 @@ module BELParser
60
60
  end
61
61
 
62
62
  def hash_to_concept_scheme(resource_identifier, hash)
63
+ return nil if hash[:types].value.empty?
63
64
  ConceptScheme.new(resource_identifier,
64
65
  *hash.values_at(:domain, :prefix, :prefLabel, :types))
65
66
  end
@@ -0,0 +1,62 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/quoting'
3
+ require 'bel_parser/parsers/ast/node'
4
+ require 'concurrent/hash'
5
+ require_relative '../state_function'
6
+
7
+ module BELParser
8
+ module Script
9
+ module State
10
+ class AnnotationDefinition
11
+ extend StateFunction
12
+ extend BELParser::Quoting
13
+
14
+ TARGET_NODE = BELParser::Parsers::AST::AnnotationDefinition
15
+
16
+ def self.consume(ast_node, script_context)
17
+ return nil unless ast_node.is_a?(TARGET_NODE)
18
+ resource_reader = script_context[:resource_reader]
19
+
20
+ keyword, domain = ast_node.children
21
+ prefix = keyword.identifier.string_literal
22
+ case
23
+ when domain.list?
24
+ handle_list(prefix, domain.child, script_context)
25
+ when domain.url?
26
+ handle_url(prefix, domain.child, script_context)
27
+ when domain.pattern?
28
+ handle_pattern(prefix, domain.child, script_context)
29
+ end
30
+ end
31
+
32
+ def self.handle_list(prefix, list_node, script_context)
33
+ script_context[:annotation_definitions] ||= Concurrent::Hash.new
34
+ script_context[:annotation_definitions][prefix] = [
35
+ :list,
36
+ list_node.list_items.map do |li|
37
+ unquote(li.children[0].string_literal)
38
+ end
39
+ ]
40
+ end
41
+ private_class_method :handle_list
42
+
43
+ def self.handle_pattern(prefix, pattern_node, script_context)
44
+ script_context[:annotation_definitions] ||= Concurrent::Hash.new
45
+ script_context[:annotation_definitions][prefix] = [
46
+ :pattern,
47
+ unquote(pattern_node.string)
48
+ ]
49
+ end
50
+ private_class_method :handle_pattern
51
+
52
+ def self.handle_url(prefix, url_node, script_context)
53
+ url = unquote(url_node.string.string_literal)
54
+ dataset = script_context[:resource_reader].retrieve_resource(url)
55
+ script_context[:annotation_definitions] ||= Concurrent::Hash.new
56
+ script_context[:annotation_definitions][prefix] = [:url, dataset]
57
+ end
58
+ private_class_method :handle_url
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,35 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/parsers/ast/node'
3
+ require 'bel_parser/quoting'
4
+ require 'concurrent/hash'
5
+ require_relative '../state_function'
6
+
7
+ module BELParser
8
+ module Script
9
+ module State
10
+ class BELVersion
11
+ extend StateFunction
12
+ extend BELParser::Quoting
13
+
14
+ TARGET_NODE = BELParser::Parsers::AST::DocumentProperty
15
+ BEL_VERSION_REGEX = /#{Regexp.escape('bel_version')}/i
16
+ DEFAULT_BEL_VERSION = '2.0'
17
+
18
+ def self.consume(ast_node, script_context)
19
+ return unless ast_node.is_a?(TARGET_NODE)
20
+ name, value = ast_node.children
21
+ name_string = name.identifier.string_literal
22
+ return unless name_string =~ BEL_VERSION_REGEX
23
+
24
+ value_string = unquote(value.children[0].string_literal)
25
+ begin
26
+ spec = BELParser::Language.specification(value_string)
27
+ rescue ArgumentError
28
+ spec = BELParser::Language.specification(DEFAULT_BEL_VERSION)
29
+ end
30
+ script_context[:specification] = spec
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ require 'bel_parser/parsers/ast/node'
2
+ require 'bel_parser/quoting'
3
+ require 'concurrent/hash'
4
+ require_relative '../state_function'
5
+
6
+ module BELParser
7
+ module Script
8
+ module State
9
+ class DocumentProperty
10
+ extend StateFunction
11
+ extend BELParser::Quoting
12
+
13
+ TARGET_NODE = BELParser::Parsers::AST::DocumentProperty
14
+
15
+ def self.consume(ast_node, script_context)
16
+ return nil unless ast_node.is_a?(TARGET_NODE)
17
+ hash = script_context[:document_properties] ||= Concurrent::Hash.new
18
+
19
+ name, value = ast_node.children
20
+ if name && value
21
+ name_string = name.identifier.string_literal
22
+ value_string = value.children[0].string_literal
23
+ hash[name_string] = unquote(value_string)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/quoting'
3
+ require 'bel_parser/parsers/ast/node'
4
+ require 'concurrent/hash'
5
+ require_relative '../state_function'
6
+
7
+ module BELParser
8
+ module Script
9
+ module State
10
+ class NamespaceDefinition
11
+ extend StateFunction
12
+ extend BELParser::Quoting
13
+
14
+ TARGET_NODE = BELParser::Parsers::AST::NamespaceDefinition
15
+
16
+ def self.consume(ast_node, script_context)
17
+ return nil unless ast_node.is_a?(TARGET_NODE)
18
+ resource_reader = script_context[:resource_reader]
19
+
20
+ keyword, domain = ast_node.children
21
+ if domain.url?
22
+ prefix = keyword.identifier.string_literal
23
+ url = unquote(domain.child.string.string_literal)
24
+ dataset = resource_reader.retrieve_resource(url)
25
+ script_context[:namespace_definitions] ||= Concurrent::Hash.new
26
+ script_context[:namespace_definitions][prefix] = dataset
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,57 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/quoting'
3
+ require 'bel_parser/parsers/ast/node'
4
+ require 'concurrent/hash'
5
+ require_relative '../state_function'
6
+
7
+ module BELParser
8
+ module Script
9
+ module State
10
+ class Set
11
+ extend StateFunction
12
+ extend BELParser::Quoting
13
+
14
+ TARGET_NODE = BELParser::Parsers::AST::Set
15
+ LIST_NODE = BELParser::Parsers::AST::List
16
+
17
+ def self.consume(ast_node, script_context)
18
+ return nil unless ast_node.is_a?(TARGET_NODE)
19
+ name, value = ast_node.children
20
+ name_string = name.identifier.string_literal
21
+ value_node = ast_node.value.children[0]
22
+ if value_node.is_a?(LIST_NODE)
23
+ value_node
24
+ .list_items.map { |li| li.children[0].string_literal }
25
+ .each do |string|
26
+ handle_annotation(name_string, string, script_context)
27
+ end
28
+ else
29
+ value_string = value_node.string_literal
30
+ case name_string
31
+ when /\ASTATEMENT_GROUP\Z/
32
+ handle_statement_group(value_string, script_context)
33
+ else
34
+ handle_annotation(name_string, value_string, script_context)
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.handle_annotation(name, value, script_context)
40
+ # add to annotation state
41
+ script_context[:annotations] ||= Concurrent::Hash.new
42
+ script_context[:annotations][name] = value
43
+ end
44
+ private_class_method :handle_annotation
45
+
46
+ def self.handle_statement_group(value, script_context)
47
+ script_context[:statement_group] = value
48
+
49
+ # clear annotation state
50
+ script_context[:annotations] ||= Concurrent::Hash.new
51
+ script_context[:annotations].clear
52
+ end
53
+ private_class_method :handle_statement_group
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,43 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/quoting'
3
+ require 'bel_parser/parsers/ast/node'
4
+ require 'concurrent/hash'
5
+ require_relative '../state_function'
6
+
7
+ module BELParser
8
+ module Script
9
+ module State
10
+ class Unset
11
+ extend StateFunction
12
+ extend BELParser::Quoting
13
+
14
+ TARGET_NODE = BELParser::Parsers::AST::Unset
15
+
16
+ def self.consume(ast_node, script_context)
17
+ return nil unless ast_node.is_a?(TARGET_NODE)
18
+ name_string = ast_node.name.identifier.string_literal
19
+ case name_string
20
+ when /\ASTATEMENT_GROUP\Z/
21
+ handle_statement_group(script_context)
22
+ else
23
+ handle_annotation(name_string, script_context)
24
+ end
25
+ end
26
+
27
+ def self.handle_annotation(name, script_context)
28
+ script_context[:annotations] ||= Concurrent::Hash.new
29
+ script_context[:annotations].delete(name)
30
+ end
31
+ private_class_method :handle_annotation
32
+
33
+ def self.handle_statement_group(script_context)
34
+ script_context.delete(:statement_group)
35
+
36
+ script_context[:annotations] ||= Concurrent::Hash.new
37
+ script_context[:annotations].clear
38
+ end
39
+ private_class_method :handle_statement_group
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ module BELParser
2
+ module Script
3
+ module StateFunction
4
+ # @abstract Extend {StateFunction} and override {#consume}.
5
+ def consume(ast_node, script_context)
6
+ raise NotImplementedError, "#{__method__} is not implemented."
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/language/expression_validator'
3
+ require 'bel_parser/language/syntax_function'
4
+ require 'bel_parser/language/syntax_warning'
5
+ require 'bel_parser/quoting'
6
+ require 'bel_parser/parsers/ast/node'
7
+ require 'concurrent/hash'
8
+
9
+ module BELParser
10
+ module Script
11
+ module Syntax
12
+ class ExpressionValidation
13
+ extend BELParser::Language::Syntax::SyntaxFunction
14
+ extend BELParser::Quoting
15
+
16
+ TARGET_NODES = [
17
+ BELParser::Parsers::AST::ObservedTerm,
18
+ BELParser::Parsers::AST::SimpleStatement,
19
+ BELParser::Parsers::AST::NestedStatement
20
+ ]
21
+ EXP_VALIDATOR = BELParser::Language::ExpressionValidator
22
+
23
+ def self.map(ast_node, script_context)
24
+ return nil unless TARGET_NODES.include?(ast_node.class)
25
+ return nil unless script_context.key?(:specification)
26
+
27
+ validator = expression_validator(script_context)
28
+ validator.validate(ast_node).select(&:failure?)
29
+ end
30
+
31
+ def self.expression_validator(script_context)
32
+ unless defined? @expression_validator
33
+ spec, namespaces, reader =
34
+ script_context
35
+ .values_at(
36
+ :specification,
37
+ :namespace_definitions,
38
+ :resource_reader)
39
+ @expression_validator = EXP_VALIDATOR.new(spec, namespaces, reader)
40
+ end
41
+ @expression_validator
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/language/syntax_function'
3
+ require 'bel_parser/language/syntax_error'
4
+ require 'bel_parser/quoting'
5
+ require 'bel_parser/parsers/ast/node'
6
+ require 'concurrent/hash'
7
+
8
+ module BELParser
9
+ module Script
10
+ module Syntax
11
+ class InvalidRegexPattern
12
+ extend BELParser::Language::Syntax::SyntaxFunction
13
+ extend BELParser::Quoting
14
+
15
+ TARGET_NODE = BELParser::Parsers::AST::Pattern
16
+
17
+ def self.map(ast_node, script_context)
18
+ return nil unless ast_node.is_a?(TARGET_NODE)
19
+ pattern = unquote(ast_node.string.string_literal)
20
+ begin
21
+ Regexp.new(pattern)
22
+ nil
23
+ rescue RegexpError => error
24
+ InvalidRegexPatternError.new(ast_node, pattern, error.to_s)
25
+ end
26
+ end
27
+ end
28
+
29
+ # InvalidRegexPattern indicates that a pattern represented an invalid
30
+ # regular expression.
31
+ class InvalidRegexPatternError < BELParser::Language::Syntax::SyntaxError
32
+ # Gets the invalid pattern.
33
+ attr_reader :pattern
34
+
35
+ def initialize(pattern_node, pattern, error_msg)
36
+ super(pattern_node, nil)
37
+ @pattern = pattern
38
+ @error_msg = error_msg
39
+ end
40
+
41
+ def msg
42
+ <<-MSG.gsub(/^ +/, '').delete("\n")
43
+ "#@pattern" is not a valid regular expression (#@error_msg).
44
+ MSG
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,60 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/language/syntax_function'
3
+ require 'bel_parser/language/syntax_error'
4
+ require 'bel_parser/quoting'
5
+ require 'bel_parser/parsers/ast/node'
6
+ require 'concurrent/hash'
7
+
8
+ module BELParser
9
+ module Script
10
+ module Syntax
11
+ class UndefinedAnnotation
12
+ extend BELParser::Language::Syntax::SyntaxFunction
13
+
14
+ TARGET_NODE = BELParser::Parsers::AST::Set
15
+ IMPLICIT_KEYWORDS = ['Citation', 'Evidence', 'STATEMENT_GROUP']
16
+
17
+ def self.map(ast_node, script_context)
18
+ return nil unless ast_node.is_a?(TARGET_NODE)
19
+ name_string = ast_node.name.identifier.string_literal
20
+ annotation_definitions =
21
+ script_context[:annotation_definitions] ||= Concurrent::Hash.new
22
+
23
+ return nil if IMPLICIT_KEYWORDS.include?(name_string)
24
+ return nil if annotation_definitions.key?(name_string)
25
+ UndefinedAnnotationError.new(
26
+ ast_node,
27
+ name_string,
28
+ script_context[:annotation_definitions])
29
+ end
30
+ end
31
+
32
+ # UndefinedAnnotationError represents an undefined annotation seen when
33
+ # checking a SET annotation.
34
+ class UndefinedAnnotationError < BELParser::Language::Syntax::SyntaxError
35
+ # Gets the undefined prefix.
36
+ attr_reader :prefix
37
+
38
+ def initialize(set_node, prefix, annotation_definitions)
39
+ super(set_node, nil)
40
+ @prefix = prefix
41
+ @annotation_definitions = annotation_definitions
42
+ end
43
+
44
+ def msg
45
+ defined_annotations =
46
+ if @annotation_definitions.empty?
47
+ 'No annotations are defined.'
48
+ else
49
+ annotation_prefixes = @annotation_definitions.keys.join(', ')
50
+ "Defined annotations: #{annotation_prefixes}"
51
+ end
52
+ <<-MSG.gsub(/^ +/, '').delete("\n")
53
+ Annotation definition is missing for "#@prefix".
54
+ #{defined_annotations}
55
+ MSG
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,83 @@
1
+ require 'bel_parser/language'
2
+ require 'bel_parser/language/syntax_function'
3
+ require 'bel_parser/language/syntax_warning'
4
+ require 'bel_parser/quoting'
5
+ require 'bel_parser/parsers/ast/node'
6
+ require 'concurrent/hash'
7
+
8
+ module BELParser
9
+ module Script
10
+ module Syntax
11
+ class UndefinedAnnotationValue
12
+ extend BELParser::Language::Syntax::SyntaxFunction
13
+ extend BELParser::Quoting
14
+
15
+ TARGET_NODE = BELParser::Parsers::AST::Set
16
+ LIST_NODE = BELParser::Parsers::AST::List
17
+ IMPLICIT_KEYWORDS = ['Citation', 'Evidence', 'STATEMENT_GROUP']
18
+
19
+ def self.map(ast_node, script_context)
20
+ return nil unless ast_node.is_a?(TARGET_NODE)
21
+ name, value = ast_node.children
22
+ name_string = ast_node.name.identifier.string_literal
23
+
24
+ return nil if IMPLICIT_KEYWORDS.include?(name_string)
25
+ dataset = annotation(name_string, script_context)
26
+ return nil unless dataset
27
+
28
+ rr = script_context[:resource_reader]
29
+ value_node = ast_node.value.children[0]
30
+ if value_node.is_a?(LIST_NODE)
31
+ value_node
32
+ .list_items.map { |li| li.children[0].string_literal }
33
+ .map do |string|
34
+ map_value(ast_node, name_string, string, dataset.identifier, rr)
35
+ end
36
+ else
37
+ map_value(
38
+ ast_node,
39
+ name_string,
40
+ value_node.string_literal,
41
+ dataset.identifier,
42
+ rr)
43
+ end
44
+ end
45
+
46
+ def self.annotation(name_string, script_context)
47
+ hash =
48
+ script_context[:annotation_definitions] ||= Concurrent::Hash.new
49
+ type, definition = hash[name_string]
50
+ type == :url ? definition : nil
51
+ end
52
+
53
+ def self.map_value(ast_node, name_string, value_string, identifier, rr)
54
+ value_string = unquote(value_string)
55
+ value = rr.retrieve_value_from_resource(identifier, value_string)
56
+ UndefinedAnnotationValueWarning.new(
57
+ ast_node,
58
+ name_string,
59
+ value_string) unless value
60
+ end
61
+ end
62
+
63
+ # UndefinedAnnotationValueWarning represents an undefined annotation value
64
+ # while checking a SET annotation.
65
+ class UndefinedAnnotationValueWarning < BELParser::Language::Syntax::SyntaxWarning
66
+ # Gets the prefix.
67
+ attr_reader :prefix
68
+ # Gets the undefined annotation value.
69
+ attr_reader :value
70
+
71
+ def initialize(set_node, prefix, value)
72
+ super(set_node, nil)
73
+ @prefix = prefix
74
+ @value = value
75
+ end
76
+
77
+ def msg
78
+ %(Undefined annotation value "#@value" for annotation "#@prefix".)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end