bel_parser 1.0.0.alpha.2 → 1.0.0.alpha.3
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 +4 -4
- data/.gemspec +1 -1
- data/VERSION +1 -1
- data/bin/bel2_validator +19 -0
- data/lib/bel_parser/expression/parser.rb +2 -0
- data/lib/bel_parser/expression/term_validator.rb +50 -0
- data/lib/bel_parser/language/expression_validator.rb +15 -25
- data/lib/bel_parser/language/syntax/invalid_function.rb +44 -0
- data/lib/bel_parser/language/syntax/undefined_namespace.rb +48 -0
- data/lib/bel_parser/language/syntax.rb +33 -0
- data/lib/bel_parser/language/syntax_error.rb +25 -0
- data/lib/bel_parser/language/syntax_function.rb +13 -0
- data/lib/bel_parser/language/syntax_result.rb +23 -0
- data/lib/bel_parser/language/syntax_warning.rb +20 -0
- data/lib/bel_parser/language.rb +1 -0
- metadata +11 -5
- data/bin/bel2_termcheck +0 -39
- data/lib/bel_parser/expression/term_semantics.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc1ced9daf61e6924edb4e15fe137e76fac85049
|
4
|
+
data.tar.gz: 1662c4c080eb06306ddc52a0c730bb226fe89e69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 614db5a804a2ded6d9df1e93fe0a656fc033deccce4a20b649a52ead92eb18efc89900cbb3946f48faa97f29c0657b4c2190e7a987db0fc86b8c8ed9864356ee
|
7
|
+
data.tar.gz: 1d10d5b3a5605cd52ed3adde6998a0f6d0412c4f5008b71f818398e7f80e173348ac849f82b333c89ead3b1015fd75db5aff08fdf395f59198e60aabc43648a0
|
data/.gemspec
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0.alpha.
|
1
|
+
1.0.0.alpha.3
|
data/bin/bel2_validator
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
|
3
|
+
|
4
|
+
unless ARGV.first
|
5
|
+
program = File.basename($PROGRAM_NAME)
|
6
|
+
$stderr.puts <<-USAGE.gsub(/ {6}/, '')
|
7
|
+
usage: #{program} [BEL specification version] [PREFIX=URI]...
|
8
|
+
USAGE
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
namespaces = Hash[ARGV[1..-1].map { |ns| ns.split('=') }]
|
12
|
+
|
13
|
+
require 'bel_parser'
|
14
|
+
require 'bel_parser/expression/term_validator'
|
15
|
+
BELParser::Expression::TermValidator.new(ARGV.first, namespaces).each($stdin) do |res|
|
16
|
+
res.each do |res|
|
17
|
+
puts " #{res}"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative '../ast_filter'
|
2
|
+
require_relative '../ast_generator'
|
3
|
+
require_relative '../parsers/expression'
|
4
|
+
require_relative '../language'
|
5
|
+
require_relative '../language/expression_validator'
|
6
|
+
|
7
|
+
module BELParser
|
8
|
+
module Expression
|
9
|
+
# Parser for BEL Expression.
|
10
|
+
class TermValidator
|
11
|
+
include BELParser::Parsers::Common
|
12
|
+
include BELParser::Parsers::Expression
|
13
|
+
|
14
|
+
FILTER = BELParser::ASTFilter.new(:term)
|
15
|
+
|
16
|
+
def initialize(specification_version, namespaces)
|
17
|
+
@spec = BELParser::Language.specification(specification_version)
|
18
|
+
@validator = BELParser::Language::ExpressionValidator.new(@spec, namespaces)
|
19
|
+
end
|
20
|
+
|
21
|
+
def each(io)
|
22
|
+
if block_given?
|
23
|
+
filtered_ast = FILTER.each(BELParser::ASTGenerator.new.each(io))
|
24
|
+
filtered_ast.each do |results|
|
25
|
+
term = results.last.first
|
26
|
+
yield @validator.validate(term)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
enum_for(:each, io)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if __FILE__ == $PROGRAM_NAME
|
37
|
+
unless ARGV.first
|
38
|
+
program = File.basename($PROGRAM_NAME)
|
39
|
+
$stderr.puts <<-USAGE.gsub(/ {6}/, '')
|
40
|
+
usage: #{program} [BEL specification version] [PREFIX=URI]...
|
41
|
+
USAGE
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
namespaces = Hash[ARGV[1..-1].map { |ns| ns.split('=') }]
|
45
|
+
BELParser::Expression::TermValidator.new(ARGV.first, namespaces).each($stdin) do |res|
|
46
|
+
res.each do |res|
|
47
|
+
puts " #{res}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,41 +1,31 @@
|
|
1
|
+
require_relative 'syntax'
|
2
|
+
require_relative 'semantics'
|
3
|
+
|
1
4
|
module BELParser
|
2
5
|
module Language
|
3
6
|
class ExpressionValidator
|
4
|
-
def initialize(spec)
|
5
|
-
@spec
|
7
|
+
def initialize(spec, namespaces)
|
8
|
+
@spec = spec
|
9
|
+
@namespaces = namespaces
|
10
|
+
@syntax_functions = Syntax.syntax_functions
|
6
11
|
end
|
7
12
|
|
8
13
|
def validate(expression_ast)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
puts "Syntax error (#{node_error.syntax_errors}) with #{node_error.type}."
|
13
|
-
end
|
14
|
-
else
|
15
|
-
check_semantics(expression_ast)
|
16
|
-
end
|
14
|
+
syntax_problems = syntax(expression_ast)
|
15
|
+
return syntax_problems unless syntax_problems.empty?
|
16
|
+
[Syntax::Valid.new(expression_ast, @spec)] + semantics(expression_ast)
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
node.syntax_errors.clear
|
25
|
-
end
|
26
|
-
|
27
|
-
# Run syntax checks, sets syntax_errors on nodes.
|
28
|
-
@spec.syntax.each do |syntax|
|
29
|
-
syntax.match(ast)
|
30
|
-
end
|
31
|
-
|
32
|
-
ast.traverse.select do |node|
|
33
|
-
!node.syntax_errors.empty?
|
21
|
+
def syntax(expression_ast)
|
22
|
+
@syntax_functions.flat_map do |syntax_function|
|
23
|
+
syntax_function.map(expression_ast, @spec, @namespaces)
|
34
24
|
end
|
35
25
|
end
|
36
26
|
|
37
|
-
def
|
38
|
-
BELParser::Language::Semantics.check_term(
|
27
|
+
def semantics(expression_ast)
|
28
|
+
BELParser::Language::Semantics.check_term(expression_ast, @spec)
|
39
29
|
end
|
40
30
|
end
|
41
31
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'bel_parser/parsers/ast/node'
|
2
|
+
|
3
|
+
module BELParser
|
4
|
+
module Language
|
5
|
+
module Syntax
|
6
|
+
# InvalidFunction represents a syntax error with invalid function name
|
7
|
+
# according to a BEL specification.
|
8
|
+
class InvalidFunction
|
9
|
+
include SyntaxFunction
|
10
|
+
|
11
|
+
private_class_method :new
|
12
|
+
|
13
|
+
def self.map(expression_ast, spec, namespaces)
|
14
|
+
errors = []
|
15
|
+
expression_ast.traverse.map do |node|
|
16
|
+
next unless node.is_a?(BELParser::Parsers::AST::Function)
|
17
|
+
function_name = node.identifier.string_literal
|
18
|
+
unless spec.function(function_name.to_sym)
|
19
|
+
errors << InvalidFunctionSyntaxError.new(
|
20
|
+
expression_ast, spec, node, spec.functions)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
errors
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# InvalidFunctionSyntaxError indicates a function name was invalid.
|
28
|
+
class InvalidFunctionSyntaxError < SyntaxError
|
29
|
+
# Gets the functions defined by a BEL specification.
|
30
|
+
attr_reader :bel_functions
|
31
|
+
|
32
|
+
def initialize(expression_node, spec, error_node, bel_functions)
|
33
|
+
super(expression_node, spec, error_node)
|
34
|
+
@bel_functions = bel_functions
|
35
|
+
end
|
36
|
+
|
37
|
+
def msg
|
38
|
+
invalid_function = error_node.identifier.string_literal
|
39
|
+
%Q{Invalid function "#{invalid_function}".}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'bel_parser/parsers/ast/node'
|
2
|
+
|
3
|
+
module BELParser
|
4
|
+
module Language
|
5
|
+
module Syntax
|
6
|
+
# Undefined namespace finds parameter prefixes that reference an
|
7
|
+
# undefined namespace.
|
8
|
+
class UndefinedNamespace
|
9
|
+
include SyntaxFunction
|
10
|
+
|
11
|
+
private_class_method :new
|
12
|
+
|
13
|
+
def self.map(expression_ast, spec, namespaces)
|
14
|
+
errors = []
|
15
|
+
expression_ast.traverse.map do |node|
|
16
|
+
next unless node.is_a?(BELParser::Parsers::AST::Prefix)
|
17
|
+
next if node.identifier.nil?
|
18
|
+
|
19
|
+
namespace_prefix = node.identifier.string_literal
|
20
|
+
unless namespaces[namespace_prefix]
|
21
|
+
errors << UndefinedNamespaceError.new(
|
22
|
+
expression_ast, node, namespaces)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
errors
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# UndefinedNamespaceError indicates a parameter prefix is referencing
|
30
|
+
# an undefined namespace.
|
31
|
+
class UndefinedNamespaceError < SyntaxError
|
32
|
+
# Gets the defined namespaces.
|
33
|
+
attr_reader :defined_namespaces
|
34
|
+
|
35
|
+
def initialize(expression_node, spec, error_node, defined_namespaces)
|
36
|
+
super(expression_node, spec, error_node)
|
37
|
+
@defined_namespaces = defined_namespaces.dup
|
38
|
+
end
|
39
|
+
|
40
|
+
def msg
|
41
|
+
undefined_namespace = error_node.identifier.string_literal
|
42
|
+
%Q{Undefined namespace "#{undefined_namespace}".}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'syntax_function'
|
2
|
+
require_relative 'syntax_error'
|
3
|
+
require_relative 'syntax_warning'
|
4
|
+
|
5
|
+
module BELParser
|
6
|
+
module Language
|
7
|
+
module Syntax
|
8
|
+
def self.syntax_functions
|
9
|
+
self.constants.collect do |symbol|
|
10
|
+
const = self.const_get(symbol)
|
11
|
+
const if
|
12
|
+
const.respond_to?(:include?) &&
|
13
|
+
const.include?(SyntaxFunction)
|
14
|
+
end.compact
|
15
|
+
end
|
16
|
+
|
17
|
+
class Valid < SyntaxResult
|
18
|
+
def msg
|
19
|
+
'Syntax is valid.'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Require all generic syntax functions.
|
27
|
+
Dir[
|
28
|
+
File.join(
|
29
|
+
File.dirname(File.expand_path(__FILE__)),
|
30
|
+
'syntax', '*.rb')
|
31
|
+
].each do |path|
|
32
|
+
require_relative "syntax/#{File.basename(path)}"
|
33
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'syntax_result'
|
2
|
+
|
3
|
+
module BELParser
|
4
|
+
module Language
|
5
|
+
module Syntax
|
6
|
+
class SyntaxError < SyntaxResult
|
7
|
+
attr_reader :expression_node, :target_node
|
8
|
+
|
9
|
+
def initialize(expression_node, specification, target_node)
|
10
|
+
super(expression_node, specification)
|
11
|
+
@target_node = target_node
|
12
|
+
end
|
13
|
+
|
14
|
+
# @abstract Subclass and override {#msg} to provide the message.
|
15
|
+
def msg
|
16
|
+
raise NotImplementedError, "#{__method__} is not implemented."
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"Error: #{msg}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module BELParser
|
2
|
+
module Language
|
3
|
+
module Syntax
|
4
|
+
module SyntaxFunction
|
5
|
+
# @abstract Include {SyntaxFunction} and override {#map} to check
|
6
|
+
# expression syntax.
|
7
|
+
def self.map(expression_ast, spec, namespaces)
|
8
|
+
raise NotImplementedError, "#{__method__} is not implemented."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module BELParser
|
2
|
+
module Language
|
3
|
+
module Syntax
|
4
|
+
class SyntaxResult
|
5
|
+
attr_reader :expression_node, :specification
|
6
|
+
|
7
|
+
def initialize(expression_node, specification)
|
8
|
+
@expression_node = expression_node
|
9
|
+
@specification = specification
|
10
|
+
end
|
11
|
+
|
12
|
+
# @abstract Subclass and override {#msg} to provide the message.
|
13
|
+
def msg
|
14
|
+
raise NotImplementedError, "#{__method__} is not implemented."
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"Info: #{msg}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'syntax_result'
|
2
|
+
|
3
|
+
module BELParser
|
4
|
+
module Language
|
5
|
+
module Syntax
|
6
|
+
class SyntaxWarning < SyntaxResult
|
7
|
+
attr_reader :expression_node, :target_node
|
8
|
+
|
9
|
+
def initialize(expression_node, specification, target_node)
|
10
|
+
super(expression_node, specification)
|
11
|
+
@target_node = target_node
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"Warning: #{msg}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/bel_parser/language.rb
CHANGED
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.
|
4
|
+
version: 1.0.0.alpha.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Bargnesi
|
@@ -9,12 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-04-
|
12
|
+
date: 2016-04-11 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Implements language versions 1.0 and 2.0.
|
15
15
|
email: abargnesi@selventa.com
|
16
16
|
executables:
|
17
|
-
-
|
17
|
+
- bel2_validator
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
@@ -23,13 +23,13 @@ files:
|
|
23
23
|
- LICENSE
|
24
24
|
- README.md
|
25
25
|
- VERSION
|
26
|
-
- bin/
|
26
|
+
- bin/bel2_validator
|
27
27
|
- lib/bel_parser.rb
|
28
28
|
- lib/bel_parser/ast_filter.rb
|
29
29
|
- lib/bel_parser/ast_generator.rb
|
30
30
|
- lib/bel_parser/ast_validator.rb
|
31
31
|
- lib/bel_parser/expression/parser.rb
|
32
|
-
- lib/bel_parser/expression/
|
32
|
+
- lib/bel_parser/expression/term_validator.rb
|
33
33
|
- lib/bel_parser/language.rb
|
34
34
|
- lib/bel_parser/language/expression_validator.rb
|
35
35
|
- lib/bel_parser/language/function.rb
|
@@ -42,6 +42,12 @@ files:
|
|
42
42
|
- lib/bel_parser/language/signature.rb
|
43
43
|
- lib/bel_parser/language/specification.rb
|
44
44
|
- lib/bel_parser/language/syntax.rb
|
45
|
+
- lib/bel_parser/language/syntax/invalid_function.rb
|
46
|
+
- lib/bel_parser/language/syntax/undefined_namespace.rb
|
47
|
+
- lib/bel_parser/language/syntax_error.rb
|
48
|
+
- lib/bel_parser/language/syntax_function.rb
|
49
|
+
- lib/bel_parser/language/syntax_result.rb
|
50
|
+
- lib/bel_parser/language/syntax_warning.rb
|
45
51
|
- lib/bel_parser/language/version1_0.rb
|
46
52
|
- lib/bel_parser/language/version1_0/functions/abundance.rb
|
47
53
|
- lib/bel_parser/language/version1_0/functions/biological_process.rb
|
data/bin/bel2_termcheck
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
$:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
|
3
|
-
|
4
|
-
require 'bel_parser'
|
5
|
-
require 'bel_parser/language/version2_0'
|
6
|
-
require 'bel_parser/language/semantics/analyzer'
|
7
|
-
|
8
|
-
module BELParser
|
9
|
-
module Expression
|
10
|
-
# Parser for BEL Expression.
|
11
|
-
class TermSemanticsParser
|
12
|
-
include BELParser::Parsers::Common
|
13
|
-
include BELParser::Parsers::Expression
|
14
|
-
|
15
|
-
FILTER = BELParser::ASTFilter.new(:term)
|
16
|
-
|
17
|
-
def each(io)
|
18
|
-
if block_given?
|
19
|
-
v2 = BELParser::Language::Version2_0::Specification.new
|
20
|
-
filtered_ast = FILTER.each(BELParser::ASTGenerator.new.each(io))
|
21
|
-
filtered_ast.each do |results|
|
22
|
-
term = results.last.first
|
23
|
-
yield BELParser::Language::Semantics.check_term(term, v2)
|
24
|
-
end
|
25
|
-
else
|
26
|
-
enum_for(:each, io)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
BELParser::Expression::TermSemanticsParser.new.each($stdin) do |signature|
|
34
|
-
valid_signatures = signature.compact
|
35
|
-
puts 'Signatures:'
|
36
|
-
valid_signatures.each do |sig|
|
37
|
-
puts " #{sig}"
|
38
|
-
end
|
39
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require_relative '../ast_filter'
|
2
|
-
require_relative '../ast_generator'
|
3
|
-
require_relative '../parsers/expression'
|
4
|
-
require_relative '../language/version2_0'
|
5
|
-
require_relative '../language/semantics/analyzer'
|
6
|
-
|
7
|
-
module BELParser
|
8
|
-
module Expression
|
9
|
-
# Parser for BEL Expression.
|
10
|
-
class TermSemanticsParser
|
11
|
-
include BELParser::Parsers::Common
|
12
|
-
include BELParser::Parsers::Expression
|
13
|
-
|
14
|
-
FILTER = BELParser::ASTFilter.new(:term)
|
15
|
-
|
16
|
-
def each(io)
|
17
|
-
if block_given?
|
18
|
-
v2 = BELParser::Language::Version2_0::Specification.new
|
19
|
-
filtered_ast = FILTER.each(BELParser::ASTGenerator.new.each(io))
|
20
|
-
filtered_ast.each do |results|
|
21
|
-
term = results.last.first
|
22
|
-
yield BELParser::Language::Semantics.check_term(term, v2)
|
23
|
-
end
|
24
|
-
else
|
25
|
-
enum_for(:each, io)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
if __FILE__ == $PROGRAM_NAME
|
33
|
-
BELParser::Expression::TermSemanticsParser.new.each($stdin) do |semantics|
|
34
|
-
puts semantics.join(", ")
|
35
|
-
end
|
36
|
-
end
|