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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90ab686251113e217ed255a26b59b00aa9b6a947
4
- data.tar.gz: 87f55444534d215b579b4aec8d657cf38479ae1b
3
+ metadata.gz: fc1ced9daf61e6924edb4e15fe137e76fac85049
4
+ data.tar.gz: 1662c4c080eb06306ddc52a0c730bb226fe89e69
5
5
  SHA512:
6
- metadata.gz: 959bbb33f76a1888cabec4bc7bef6a00c130a45aeeac7a175e550403e2b14a78c9f75d147208e500a4aa400d5562e08d42a7733a6f53db38b688d0ba0c85a4e4
7
- data.tar.gz: 4c43a80f6ad4263753a5e49d76e6bbb57237a32cb61cb6af3dc8349a417ca2d049df3b18af9f1fddfedc3ff89b5e4bc2f7661b39a751aed790eae0dd596ef4b7
6
+ metadata.gz: 614db5a804a2ded6d9df1e93fe0a656fc033deccce4a20b649a52ead92eb18efc89900cbb3946f48faa97f29c0657b4c2190e7a987db0fc86b8c8ed9864356ee
7
+ data.tar.gz: 1d10d5b3a5605cd52ed3adde6998a0f6d0412c4f5008b71f818398e7f80e173348ac849f82b333c89ead3b1015fd75db5aff08fdf395f59198e60aabc43648a0
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-04-08}
14
+ spec.date = %q{2016-04-11}
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.2
1
+ 1.0.0.alpha.3
@@ -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
@@ -12,6 +12,8 @@ module BELParser
12
12
  include BELParser::Parsers::Expression
13
13
 
14
14
  FILTER = BELParser::ASTFilter.new(
15
+ :parameter,
16
+ :term,
15
17
  :statement_simple,
16
18
  :observed_term,
17
19
  :nested_statement
@@ -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 = 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
- node_errors = check_syntax(expression_ast)
10
- if !node_errors.empty?
11
- node_errors.each do |node_error|
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 check_syntax(ast)
22
- # Clear syntax checks.
23
- ast.traverse.each do |node|
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 check_semantics(ast)
38
- BELParser::Language::Semantics.check_term(ast, @spec)
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
@@ -1,5 +1,6 @@
1
1
  require_relative 'language/function'
2
2
  require_relative 'language/quoting'
3
+ require_relative 'language/syntax'
3
4
  require_relative 'language/semantics'
4
5
  require_relative 'language/signature'
5
6
  require_relative 'language/specification'
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.2
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-08 00:00:00.000000000 Z
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
- - bel2_termcheck
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/bel2_termcheck
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/term_semantics.rb
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