bel_parser 1.1.3 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/VERSION +1 -1
- data/bin/bel2_completion +127 -0
- data/lib/bel_parser/completion.rb +78 -54
- data/lib/bel_parser/language/expression_validator.rb +9 -2
- data/lib/bel_parser/language/semantics/deeply_nested_statement.rb +1 -1
- data/lib/bel_parser/language/semantics/function_deprecation.rb +1 -1
- data/lib/bel_parser/language/semantics/list_function_subject.rb +1 -1
- data/lib/bel_parser/language/semantics/multiple_subject_object.rb +1 -1
- data/lib/bel_parser/language/semantics/nested_statement_without_object.rb +1 -1
- data/lib/bel_parser/language/semantics/non_causal_nested_statement.rb +1 -1
- data/lib/bel_parser/language/semantics/non_object_list.rb +1 -1
- data/lib/bel_parser/language/semantics/relationship_deprecation.rb +1 -1
- data/lib/bel_parser/language/semantics/relationship_not_listable.rb +1 -1
- data/lib/bel_parser/language/semantics/signature_mapping.rb +26 -8
- data/lib/bel_parser/language/semantics_ast.rb +40 -34
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52ff97d323a2e5d4f6af24258fb93e2b6724035b
|
4
|
+
data.tar.gz: 07073491b8e133f737c3608259f14fdff605a70b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddf4fd6055cfaf2024ee46c05a6e88e29d0ba93221e49d39d52865da04469f34058ed465c38535be22cce38be7cf70d3dbe802555cb9954b832f1c2a38d8f9c0
|
7
|
+
data.tar.gz: 8cc8275d4987da9b926c264d05bec26ac897e0cfc6be8258728db67a543dba547ba717ff4e589df9c5636bb61b13f894a82324d03edc1d6252df406d9dcc9cd0
|
data/README.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.4
|
data/bin/bel2_completion
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift(
|
3
|
+
File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
|
4
|
+
|
5
|
+
require 'optparse'
|
6
|
+
require 'bel_parser'
|
7
|
+
require 'bel_parser/parsers/expression/statement_autocomplete'
|
8
|
+
require 'bel_parser/expression/validator'
|
9
|
+
require 'bel_parser/resource/resource_url_reader'
|
10
|
+
|
11
|
+
options = {
|
12
|
+
uri_reader: BELParser::Resource.default_uri_reader,
|
13
|
+
url_reader: BELParser::Resource.default_url_reader,
|
14
|
+
spec: BELParser::Language.specification(
|
15
|
+
BELParser::Language.latest_supported_version),
|
16
|
+
will_match_partial: false
|
17
|
+
}
|
18
|
+
OptionParser.new do |opts|
|
19
|
+
opts.banner = <<-USAGE.gsub(/^ {4}/, '')
|
20
|
+
Provides completions for BEL expressions.
|
21
|
+
|
22
|
+
Read from standard input.
|
23
|
+
usage: #$PROGRAM_NAME
|
24
|
+
USAGE
|
25
|
+
|
26
|
+
opts.on(
|
27
|
+
'-v',
|
28
|
+
'--[no-]verbose',
|
29
|
+
'Enable verbose logging.') do |verbose|
|
30
|
+
options[:verbose] = verbose
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on(
|
34
|
+
'-s',
|
35
|
+
'--specification VERSION',
|
36
|
+
'BEL specification version (e.g. 1.0, 2.0).') do |spec|
|
37
|
+
unless BELParser::Language.defines_version?(spec)
|
38
|
+
$stderr.puts %(Invalid BEL specification "#{spec}")
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
|
42
|
+
options[:spec] = BELParser::Language.specification(spec)
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on(
|
46
|
+
'-p',
|
47
|
+
'--[no-]match-partial',
|
48
|
+
'Partial semantic matches are allowed.') do |will_match_partial|
|
49
|
+
options[:will_match_partial] = will_match_partial
|
50
|
+
end
|
51
|
+
|
52
|
+
if RUBY_ENGINE =~ /^jruby/i
|
53
|
+
opts.on(
|
54
|
+
'-t',
|
55
|
+
'--read-jena-tdb DIRECTORY',
|
56
|
+
'Jena TDB directory containing BEL RDF resources.') do |tdb|
|
57
|
+
|
58
|
+
require 'bel_parser/resource/jena_tdb_reader'
|
59
|
+
options[:uri_reader] = BELParser::Resource::JenaTDBReader.new(tdb)
|
60
|
+
BELParser::Resource.default_uri_reader = options[:uri_reader]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end.parse!
|
64
|
+
|
65
|
+
io = $stdin
|
66
|
+
|
67
|
+
class ::AST::Node
|
68
|
+
|
69
|
+
def _metadata
|
70
|
+
ivars = instance_variables - [:@type, :@children, :@hash]
|
71
|
+
ivars.map { |iv| [iv, instance_variable_get(iv)] }.to_s
|
72
|
+
end
|
73
|
+
private :_metadata
|
74
|
+
|
75
|
+
def to_sexp(indent=0)
|
76
|
+
indented = " " * indent
|
77
|
+
sexp = "#{indented}(#{fancy_type} #{_metadata}"
|
78
|
+
|
79
|
+
first_node_child = children.index do |child|
|
80
|
+
child.is_a?(::AST::Node) || child.is_a?(Array)
|
81
|
+
end || children.count
|
82
|
+
|
83
|
+
children.each_with_index do |child, idx|
|
84
|
+
if child.is_a?(::AST::Node) && idx >= first_node_child
|
85
|
+
sexp << "\n#{child.to_sexp(indent + 1)}"
|
86
|
+
else
|
87
|
+
sexp << " #{child.inspect}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
sexp << ")"
|
92
|
+
|
93
|
+
sexp
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#uri_reader, url_reader = options.values_at(:uri_reader, :url_reader)
|
98
|
+
|
99
|
+
namespaces = Hash[
|
100
|
+
ARGV.map do |ns|
|
101
|
+
keyword, identifier = ns.split('=')
|
102
|
+
if identifier.end_with?('.belns')
|
103
|
+
[keyword, BELParser::Expression::Model::Namespace.new(keyword, nil, identifier)]
|
104
|
+
else
|
105
|
+
[keyword, BELParser::Expression::Model::Namespace.new(keyword, identifier, nil)]
|
106
|
+
end
|
107
|
+
end.compact
|
108
|
+
]
|
109
|
+
|
110
|
+
autocomplete = BELParser::Parsers::Expression::StatementAutocomplete
|
111
|
+
validator = BELParser::Language::ExpressionValidator.new(
|
112
|
+
BELParser::Language.specification('2.0'),
|
113
|
+
namespaces,
|
114
|
+
BELParser::Resource.default_uri_reader,
|
115
|
+
BELParser::Resource.default_url_reader,
|
116
|
+
options[:will_match_partial]
|
117
|
+
)
|
118
|
+
|
119
|
+
io.each_line do |line|
|
120
|
+
line.strip!
|
121
|
+
ast, _ = autocomplete.parse("#{line}\n", line.length)
|
122
|
+
puts "AST:\n#{ast.to_sexp(1)}"
|
123
|
+
term_result = validator.validate(ast.subject.term)
|
124
|
+
puts " Syntax: #{term_result.valid_syntax?}"
|
125
|
+
puts " Semantics: #{term_result.valid_semantics?}"
|
126
|
+
puts term_result
|
127
|
+
end
|
@@ -11,7 +11,8 @@ module BELParser
|
|
11
11
|
extend BELParser::Parsers::AST::Sexp
|
12
12
|
extend BELParser::Parsers
|
13
13
|
|
14
|
-
def self.complete(input, spec, search, namespaces,
|
14
|
+
def self.complete(input, spec, search, namespaces,
|
15
|
+
caret_position = input.length, include_invalid_semantics = false)
|
15
16
|
# Algorithm
|
16
17
|
# 1. Parse AST using statement_autocomplete ragel FSM.
|
17
18
|
# 2. Given cursor find node to complete.
|
@@ -39,77 +40,100 @@ module BELParser
|
|
39
40
|
[]
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
will_match_partial = true
|
44
|
+
urir = BELParser::Resource.default_uri_reader
|
45
|
+
urlr = BELParser::Resource.default_url_reader
|
46
|
+
|
47
|
+
validator =
|
48
|
+
BELParser::Language::ExpressionValidator.new(
|
49
|
+
spec, namespaces, urir, urlr, will_match_partial
|
50
|
+
)
|
45
51
|
|
46
52
|
validated_completions =
|
47
53
|
completions
|
48
54
|
.map { |(completion_ast, completion_result)|
|
49
|
-
message = ''
|
50
|
-
terms = completion_ast.traverse.select { |node| node.type == :term }.to_a
|
51
|
-
semantics_functions =
|
52
|
-
BELParser::Language::Semantics.semantics_functions.reject { |fun|
|
53
|
-
fun == BELParser::Language::Semantics::SignatureMapping
|
54
|
-
}
|
55
|
-
|
56
|
-
semantic_warnings =
|
57
|
-
completion_ast
|
58
|
-
.traverse
|
59
|
-
.flat_map { |node|
|
60
|
-
semantics_functions.flat_map { |func|
|
61
|
-
func.map(node, spec, namespaces)
|
62
|
-
}
|
63
|
-
}
|
64
|
-
.compact
|
65
55
|
|
66
|
-
if
|
67
|
-
|
56
|
+
if completion_result[:type] == :namespace_prefix
|
57
|
+
# namespace_prefix completions are always valid
|
58
|
+
completion_result[:validation] = {
|
59
|
+
expression: completion_result[:value],
|
60
|
+
valid_syntax: true,
|
61
|
+
valid_semantics: true,
|
62
|
+
message: 'Valid semantics',
|
63
|
+
warnings: [],
|
64
|
+
term_signatures: []
|
65
|
+
}
|
66
|
+
completion_result
|
68
67
|
else
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
message = ''
|
69
|
+
terms = completion_ast.traverse.select { |node| node.type == :term }.to_a
|
70
|
+
semantics_functions =
|
71
|
+
BELParser::Language::Semantics.semantics_functions.reject { |fun|
|
72
|
+
fun == BELParser::Language::Semantics::SignatureMapping
|
73
73
|
}
|
74
|
-
message << "\n"
|
75
|
-
end
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
semantic_warnings =
|
76
|
+
completion_ast
|
77
|
+
.traverse
|
78
|
+
.flat_map { |node|
|
79
|
+
semantics_functions.flat_map { |func|
|
80
|
+
func.map(node, spec, namespaces, will_match_partial)
|
81
|
+
}
|
82
|
+
}
|
83
|
+
.compact
|
82
84
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
if semantic_warnings.empty?
|
86
|
+
valid = true
|
87
|
+
else
|
88
|
+
valid = false
|
89
|
+
message =
|
90
|
+
semantic_warnings.reduce('') { |msg, warning|
|
91
|
+
msg << "#{warning}\n"
|
87
92
|
}
|
88
|
-
|
89
|
-
|
93
|
+
message << "\n"
|
94
|
+
end
|
90
95
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
96
|
+
term_semantics =
|
97
|
+
terms.map { |term|
|
98
|
+
term_result = validator.validate(term)
|
99
|
+
valid &= term_result.valid_semantics?
|
100
|
+
bel_term = serialize(term)
|
101
|
+
|
102
|
+
unless valid
|
103
|
+
message << "Term: #{bel_term}\n"
|
104
|
+
term_result.invalid_signature_mappings.map { |m|
|
105
|
+
message << " #{m}\n"
|
106
|
+
}
|
107
|
+
message << "\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
{
|
111
|
+
term: bel_term,
|
112
|
+
valid_signatures: term_result.valid_signature_mappings.map(&:to_s),
|
113
|
+
invalid_signatures: term_result.invalid_signature_mappings.map(&:to_s)
|
114
|
+
}
|
95
115
|
}
|
96
|
-
}
|
97
116
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
117
|
+
completion_result[:validation] = {
|
118
|
+
expression: completion_result[:value],
|
119
|
+
valid_syntax: true,
|
120
|
+
valid_semantics: valid,
|
121
|
+
message: valid ? 'Valid semantics' : message,
|
122
|
+
warnings: semantic_warnings.map(&:to_s),
|
123
|
+
term_signatures: term_semantics
|
124
|
+
}
|
125
|
+
completion_result
|
126
|
+
end
|
107
127
|
}
|
108
128
|
.group_by { |completion_result|
|
109
129
|
completion_result[:validation][:valid_semantics]
|
110
130
|
}
|
111
131
|
|
112
|
-
|
132
|
+
if include_invalid_semantics
|
133
|
+
(validated_completions[true] || []) + (validated_completions[false] || [])
|
134
|
+
else
|
135
|
+
validated_completions[true] || []
|
136
|
+
end
|
113
137
|
end
|
114
138
|
|
115
139
|
def self.complete_function(
|
@@ -9,15 +9,20 @@ module BELParser
|
|
9
9
|
# when supplied a {BELParser::Language::Specification} and Hash of
|
10
10
|
# namespaces.
|
11
11
|
class ExpressionValidator
|
12
|
-
def initialize(spec, namespaces, uri_reader, url_reader)
|
12
|
+
def initialize(spec, namespaces, uri_reader, url_reader, will_match_partial = false)
|
13
13
|
@spec = spec
|
14
14
|
@namespaces = namespaces || {}
|
15
|
+
|
16
|
+
# double negate truthy or falsey value to strict boolean
|
17
|
+
@will_match_partial = !!will_match_partial
|
18
|
+
|
15
19
|
@syntax_functions = Syntax.syntax_functions
|
16
20
|
@semantics_functions = Semantics.semantics_functions
|
17
21
|
@default_namespace_transform =
|
18
22
|
ApplyDefaultNamespace.new(@spec, @namespaces, uri_reader, url_reader)
|
19
23
|
@namespace_encoding_transform =
|
20
24
|
ApplyNamespaceEncoding.new(@spec, @namespaces, uri_reader, url_reader)
|
25
|
+
|
21
26
|
end
|
22
27
|
|
23
28
|
# Validate the syntax and semantics of
|
@@ -85,7 +90,9 @@ module BELParser
|
|
85
90
|
|
86
91
|
def semantics(expression_node)
|
87
92
|
expression_node.traverse.flat_map do |node|
|
88
|
-
@semantics_functions.flat_map { |func|
|
93
|
+
@semantics_functions.flat_map { |func|
|
94
|
+
func.map(node, @spec, @namespaces, @will_match_partial)
|
95
|
+
}
|
89
96
|
end.compact
|
90
97
|
end
|
91
98
|
|
@@ -18,7 +18,7 @@ module BELParser
|
|
18
18
|
|
19
19
|
private_class_method :new
|
20
20
|
|
21
|
-
def self.map(node, spec, _namespaces)
|
21
|
+
def self.map(node, spec, _namespaces, will_match_partial = false)
|
22
22
|
return nil unless node.is_a?(BELParser::Parsers::AST::NestedStatement)
|
23
23
|
|
24
24
|
nested_number = count_nested_statements(node)
|
@@ -12,7 +12,7 @@ module BELParser
|
|
12
12
|
|
13
13
|
private_class_method :new
|
14
14
|
|
15
|
-
def self.map(node, spec, _namespaces)
|
15
|
+
def self.map(node, spec, _namespaces, will_match_partial = false)
|
16
16
|
return nil unless node.is_a?(BELParser::Parsers::AST::Function)
|
17
17
|
return nil unless node.identifier
|
18
18
|
|
@@ -13,7 +13,7 @@ module BELParser
|
|
13
13
|
|
14
14
|
private_class_method :new
|
15
15
|
|
16
|
-
def self.map(node, spec, _namespaces)
|
16
|
+
def self.map(node, spec, _namespaces, will_match_partial = false)
|
17
17
|
return nil unless node.is_a?(BELParser::Parsers::AST::Subject)
|
18
18
|
|
19
19
|
list_func = spec.function(:list)
|
@@ -11,7 +11,7 @@ module BELParser
|
|
11
11
|
|
12
12
|
private_class_method :new
|
13
13
|
|
14
|
-
def self.map(stmt_node, spec, _namespaces)
|
14
|
+
def self.map(stmt_node, spec, _namespaces, will_match_partial = false)
|
15
15
|
return nil unless stmt_node.is_a?(BELParser::Parsers::AST::Statement)
|
16
16
|
return nil unless stmt_node.relationship?
|
17
17
|
return nil if stmt_node.relationship.string_literal.nil?
|
@@ -11,7 +11,7 @@ module BELParser
|
|
11
11
|
|
12
12
|
private_class_method :new
|
13
13
|
|
14
|
-
def self.map(node, spec,
|
14
|
+
def self.map(node, spec, _namespacesi, will_match_partial = false)
|
15
15
|
return nil unless node.is_a?(BELParser::Parsers::AST::Statement)
|
16
16
|
return nil unless node.object? && node.object.statement?
|
17
17
|
|
@@ -11,7 +11,7 @@ module BELParser
|
|
11
11
|
|
12
12
|
private_class_method :new
|
13
13
|
|
14
|
-
def self.map(node, spec, _namespaces)
|
14
|
+
def self.map(node, spec, _namespaces, will_match_partial = false)
|
15
15
|
return nil unless node.is_a?(BELParser::Parsers::AST::Statement)
|
16
16
|
return nil unless node.object? && node.object.statement?
|
17
17
|
|
@@ -11,7 +11,7 @@ module BELParser
|
|
11
11
|
|
12
12
|
private_class_method :new
|
13
13
|
|
14
|
-
def self.map(stmt_node, spec, _namespaces)
|
14
|
+
def self.map(stmt_node, spec, _namespaces, will_match_partial = false)
|
15
15
|
return nil unless stmt_node.is_a?(BELParser::Parsers::AST::Statement)
|
16
16
|
return nil unless stmt_node.relationship?
|
17
17
|
return nil unless stmt_node.object?
|
@@ -12,7 +12,7 @@ module BELParser
|
|
12
12
|
|
13
13
|
private_class_method :new
|
14
14
|
|
15
|
-
def self.map(node, spec, _namespaces)
|
15
|
+
def self.map(node, spec, _namespaces, will_match_partial = false)
|
16
16
|
return nil unless node.is_a?(BELParser::Parsers::AST::Relationship)
|
17
17
|
return nil if node.string_literal.nil?
|
18
18
|
|
@@ -11,7 +11,7 @@ module BELParser
|
|
11
11
|
|
12
12
|
private_class_method :new
|
13
13
|
|
14
|
-
def self.map(node, spec, _namespaces)
|
14
|
+
def self.map(node, spec, _namespaces, will_match_partial = false)
|
15
15
|
return nil unless node.is_a?(BELParser::Parsers::AST::Statement)
|
16
16
|
return nil unless node.relationship?
|
17
17
|
return nil unless node.object?
|
@@ -17,30 +17,48 @@ module BELParser
|
|
17
17
|
# Map {BELParser::Parsers::AST::Term term} to BEL signatures
|
18
18
|
# defined by a {BELParser::Language::Specification}. The mapping
|
19
19
|
# includes both successful and failed signature matches.
|
20
|
-
def self.map(term_node, spec, _namespaces)
|
20
|
+
def self.map(term_node, spec, _namespaces, will_match_partial = false)
|
21
21
|
return nil unless term_node.is_a?(BELParser::Parsers::AST::Term)
|
22
22
|
return nil unless term_node.function
|
23
23
|
return nil unless term_node.function.identifier
|
24
24
|
|
25
|
+
# double negate truthy or falsey value to strict boolean
|
26
|
+
will_match_partial = !!will_match_partial
|
27
|
+
|
25
28
|
function_name = term_node.function.identifier.string_literal
|
26
29
|
function = spec.function(function_name.to_sym)
|
27
30
|
return nil unless function
|
28
31
|
|
29
|
-
|
30
|
-
|
32
|
+
function.signatures.map { |signature|
|
33
|
+
self._map_signature(term_node, spec, signature, will_match_partial)
|
34
|
+
}
|
31
35
|
end
|
32
36
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
def self._map_signature(term_node, spec, signature, will_match_partial)
|
40
|
+
results =
|
41
|
+
BELParser::Language::Semantics.match(
|
42
|
+
term_node,
|
43
|
+
signature.semantic_ast,
|
44
|
+
spec,
|
45
|
+
will_match_partial
|
46
|
+
)
|
47
|
+
|
48
|
+
_remove_partial_warnings!(results) if will_match_partial
|
49
|
+
|
38
50
|
if results.all?(&:success?)
|
39
51
|
SignatureMappingSuccess.new(term_node, spec, signature, results)
|
40
52
|
else
|
41
53
|
SignatureMappingWarning.new(term_node, spec, signature, results)
|
42
54
|
end
|
43
55
|
end
|
56
|
+
|
57
|
+
def self._remove_partial_warnings!(semantic_results)
|
58
|
+
semantic_results.reject! { |res|
|
59
|
+
res.is_a?(SemanticsNilNodeWarning)
|
60
|
+
}
|
61
|
+
end
|
44
62
|
end
|
45
63
|
|
46
64
|
# SignatureMappingSuccess defines a {SemanticsResult} that indicates
|
@@ -10,8 +10,8 @@ module BELParser
|
|
10
10
|
module Semantics
|
11
11
|
# rubocop:disable Metrics/MethodLength
|
12
12
|
# rubocop:disable Metrics/AbcSize
|
13
|
-
def self.match(input_ast, semantic_ast, spec, match_results = [])
|
14
|
-
res = semantic_ast.match(input_ast, spec)
|
13
|
+
def self.match(input_ast, semantic_ast, spec, will_match_partial = false, match_results = [])
|
14
|
+
res = semantic_ast.match(input_ast, spec, will_match_partial)
|
15
15
|
match_results.concat(res)
|
16
16
|
if res.flatten.all?(&:success?) && !semantic_ast.terminal?
|
17
17
|
return match_results if semantic_ast.children.empty?
|
@@ -35,24 +35,26 @@ module BELParser
|
|
35
35
|
input_children[input_children.index(input_child)..-1]
|
36
36
|
argument_pattern = semantic_child.children.first
|
37
37
|
input_arguments.each do |argument_child|
|
38
|
-
res = semantic_child.match(argument_child, spec)
|
38
|
+
res = semantic_child.match(argument_child, spec, will_match_partial)
|
39
39
|
match_results << res
|
40
40
|
if res.all?(&:success?)
|
41
41
|
param_or_term = argument_child.children.first
|
42
|
-
match(param_or_term, argument_pattern, spec, match_results)
|
42
|
+
match(param_or_term, argument_pattern, spec, will_match_partial, match_results)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
else
|
46
|
-
match(input_child, semantic_child, spec, match_results)
|
46
|
+
match(input_child, semantic_child, spec, will_match_partial, match_results)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
else
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
if input_ast
|
51
|
+
semantic_ast
|
52
|
+
.children
|
53
|
+
.zip(input_ast.children)
|
54
|
+
.each do |semantic_child, input_child|
|
55
|
+
match(input_child, semantic_child, spec, will_match_partial, match_results)
|
56
|
+
end
|
57
|
+
end
|
56
58
|
end
|
57
59
|
end
|
58
60
|
match_results.flatten
|
@@ -268,7 +270,7 @@ module BELParser
|
|
268
270
|
children[1..-1]
|
269
271
|
end
|
270
272
|
|
271
|
-
def match(parse_node, spec)
|
273
|
+
def match(parse_node, spec, will_match_partial = false)
|
272
274
|
return nil_node_warning(
|
273
275
|
parse_node,
|
274
276
|
spec,
|
@@ -279,12 +281,16 @@ module BELParser
|
|
279
281
|
BELParser::Parsers::AST::Term,
|
280
282
|
parse_node) if parse_node.type != type
|
281
283
|
|
282
|
-
#
|
284
|
+
# Allowed empty.
|
283
285
|
if arguments.empty? || variadic_arguments?
|
284
286
|
success(parse_node, spec)
|
285
|
-
#
|
287
|
+
# Partial match on arity.
|
288
|
+
elsif will_match_partial && parse_node.arguments.length < arguments.length
|
289
|
+
success(parse_node, spec)
|
290
|
+
# Or, check full arity
|
286
291
|
elsif arguments.length == parse_node.arguments.length
|
287
292
|
success(parse_node, spec)
|
293
|
+
# Mismatch, warning
|
288
294
|
else
|
289
295
|
argument_length_warning(
|
290
296
|
parse_node,
|
@@ -301,7 +307,7 @@ module BELParser
|
|
301
307
|
super(:statement, children, properties)
|
302
308
|
end
|
303
309
|
|
304
|
-
def match(parse_node, spec)
|
310
|
+
def match(parse_node, spec, will_match_partial = false)
|
305
311
|
return nil_node_warning(
|
306
312
|
parse_node,
|
307
313
|
spec,
|
@@ -325,7 +331,7 @@ module BELParser
|
|
325
331
|
super(:parameter, children, properties)
|
326
332
|
end
|
327
333
|
|
328
|
-
def match(parse_node, spec)
|
334
|
+
def match(parse_node, spec, will_match_partial = false)
|
329
335
|
return nil_node_warning(
|
330
336
|
parse_node,
|
331
337
|
spec,
|
@@ -349,7 +355,7 @@ module BELParser
|
|
349
355
|
super(:function, children, properties)
|
350
356
|
end
|
351
357
|
|
352
|
-
def match(parse_node, spec)
|
358
|
+
def match(parse_node, spec, will_match_partial = false)
|
353
359
|
return nil_node_warning(
|
354
360
|
parse_node,
|
355
361
|
spec,
|
@@ -373,7 +379,7 @@ module BELParser
|
|
373
379
|
super(:argument, children, properties)
|
374
380
|
end
|
375
381
|
|
376
|
-
def match(parse_node, spec)
|
382
|
+
def match(parse_node, spec, will_match_partial = false)
|
377
383
|
return nil_node_warning(
|
378
384
|
parse_node,
|
379
385
|
spec,
|
@@ -397,7 +403,7 @@ module BELParser
|
|
397
403
|
super(:variadic_arguments, children, properties)
|
398
404
|
end
|
399
405
|
|
400
|
-
def match(parse_node, spec)
|
406
|
+
def match(parse_node, spec, will_match_partial = false)
|
401
407
|
return nil_node_warning(
|
402
408
|
parse_node,
|
403
409
|
spec,
|
@@ -429,7 +435,7 @@ module BELParser
|
|
429
435
|
children
|
430
436
|
end
|
431
437
|
|
432
|
-
def match(parse_node, spec)
|
438
|
+
def match(parse_node, spec, will_match_partial = false)
|
433
439
|
return nil_node_warning(
|
434
440
|
parse_node,
|
435
441
|
spec,
|
@@ -463,7 +469,7 @@ module BELParser
|
|
463
469
|
children
|
464
470
|
end
|
465
471
|
|
466
|
-
def match(parse_node, spec)
|
472
|
+
def match(parse_node, spec, will_match_partial = false)
|
467
473
|
return nil_node_warning(
|
468
474
|
parse_node,
|
469
475
|
spec,
|
@@ -493,7 +499,7 @@ module BELParser
|
|
493
499
|
true
|
494
500
|
end
|
495
501
|
|
496
|
-
def match(parse_node, spec)
|
502
|
+
def match(parse_node, spec, will_match_partial = false)
|
497
503
|
if parse_node.nil?
|
498
504
|
success(parse_node, spec)
|
499
505
|
else
|
@@ -516,7 +522,7 @@ module BELParser
|
|
516
522
|
children
|
517
523
|
end
|
518
524
|
|
519
|
-
def match(identifier, spec)
|
525
|
+
def match(identifier, spec, will_match_partial = false)
|
520
526
|
return nil_node_warning(
|
521
527
|
identifier,
|
522
528
|
spec,
|
@@ -540,7 +546,7 @@ module BELParser
|
|
540
546
|
super(:any, [], properties)
|
541
547
|
end
|
542
548
|
|
543
|
-
def match(parse_node, spec)
|
549
|
+
def match(parse_node, spec, will_match_partial = false)
|
544
550
|
success(parse_node, spec)
|
545
551
|
end
|
546
552
|
end
|
@@ -551,7 +557,7 @@ module BELParser
|
|
551
557
|
super(:has_namespace, [], properties)
|
552
558
|
end
|
553
559
|
|
554
|
-
def match(prefix, spec)
|
560
|
+
def match(prefix, spec, will_match_partial = false)
|
555
561
|
if prefix.respond_to?(:namespace) && prefix.namespace
|
556
562
|
success(prefix, spec)
|
557
563
|
else
|
@@ -570,7 +576,7 @@ module BELParser
|
|
570
576
|
children
|
571
577
|
end
|
572
578
|
|
573
|
-
def match(prefix_node, spec)
|
579
|
+
def match(prefix_node, spec, will_match_partial = false)
|
574
580
|
unless prefix_node.respond_to?(:namespace) && prefix_node.namespace
|
575
581
|
return invalid_namespace(prefix_node, spec, namespaces)
|
576
582
|
end
|
@@ -589,7 +595,7 @@ module BELParser
|
|
589
595
|
super(:has_encoding, [], properties)
|
590
596
|
end
|
591
597
|
|
592
|
-
def match(value_node, spec)
|
598
|
+
def match(value_node, spec, will_match_partial = false)
|
593
599
|
if value_node.respond_to?(:encoding) && value_node.encoding
|
594
600
|
success(value_node, spec)
|
595
601
|
else
|
@@ -608,7 +614,7 @@ module BELParser
|
|
608
614
|
children
|
609
615
|
end
|
610
616
|
|
611
|
-
def match(value_node, spec)
|
617
|
+
def match(value_node, spec, will_match_partial = false)
|
612
618
|
unless value_node.respond_to?(:encoding) && value_node.encoding
|
613
619
|
return invalid_encoding_warning(value_node, spec, match_encoding)
|
614
620
|
end
|
@@ -637,7 +643,7 @@ module BELParser
|
|
637
643
|
children
|
638
644
|
end
|
639
645
|
|
640
|
-
def match(identifier, spec)
|
646
|
+
def match(identifier, spec, will_match_partial = false)
|
641
647
|
return success(identifier, spec) if functions.include?(:*)
|
642
648
|
|
643
649
|
function = spec.function(identifier.string_literal.to_sym)
|
@@ -659,7 +665,7 @@ module BELParser
|
|
659
665
|
children
|
660
666
|
end
|
661
667
|
|
662
|
-
def match(identifier, spec)
|
668
|
+
def match(identifier, spec, will_match_partial = false)
|
663
669
|
return success(identifier, spec) if return_types.include?(:*)
|
664
670
|
|
665
671
|
function = spec.function(identifier.string_literal.to_sym)
|
@@ -687,7 +693,7 @@ module BELParser
|
|
687
693
|
children
|
688
694
|
end
|
689
695
|
|
690
|
-
def match(value_node, spec)
|
696
|
+
def match(value_node, spec, will_match_partial = false)
|
691
697
|
string_literal_sym = value_node.children[0].string_literal.to_sym
|
692
698
|
return success(value_node, spec) if @hashed[:*]
|
693
699
|
|
@@ -713,7 +719,7 @@ module BELParser
|
|
713
719
|
children
|
714
720
|
end
|
715
721
|
|
716
|
-
def match(value_node, spec)
|
722
|
+
def match(value_node, spec, will_match_partial = false)
|
717
723
|
string_literal_sym = value_node.children[0].string_literal.to_sym
|
718
724
|
return success(value_node, spec) if @hashed[:*]
|
719
725
|
|
@@ -735,7 +741,7 @@ module BELParser
|
|
735
741
|
super(:is_amino_acid_range, [], properties)
|
736
742
|
end
|
737
743
|
|
738
|
-
def match(value_node, spec)
|
744
|
+
def match(value_node, spec, will_match_partial = false)
|
739
745
|
ident_or_string = value_node.children[0]
|
740
746
|
value =
|
741
747
|
case ident_or_string
|
@@ -760,7 +766,7 @@ module BELParser
|
|
760
766
|
super(:is_sequence_position, [], properties)
|
761
767
|
end
|
762
768
|
|
763
|
-
def match(value_node, spec)
|
769
|
+
def match(value_node, spec, will_match_partial = false)
|
764
770
|
string_literal = value_node.children[0].string_literal
|
765
771
|
integer_position =
|
766
772
|
begin
|
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.1.
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Bargnesi
|
@@ -43,6 +43,7 @@ description: Implements language versions 1.0 and 2.0.
|
|
43
43
|
email: abargnesi@selventa.com
|
44
44
|
executables:
|
45
45
|
- bel2_compatibility
|
46
|
+
- bel2_completion
|
46
47
|
- bel2_debug_ast
|
47
48
|
- bel2_upgrade
|
48
49
|
- bel2_validator
|
@@ -56,6 +57,7 @@ files:
|
|
56
57
|
- README.md
|
57
58
|
- VERSION
|
58
59
|
- bin/bel2_compatibility
|
60
|
+
- bin/bel2_completion
|
59
61
|
- bin/bel2_debug_ast
|
60
62
|
- bin/bel2_upgrade
|
61
63
|
- bin/bel2_validator
|