bel_parser 1.0.0.alpha.2 → 1.0.0.alpha.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|