bel_parser 1.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/.gemspec +28 -0
  3. data/CHANGELOG.md +10 -0
  4. data/LICENSE +191 -0
  5. data/README.md +9 -0
  6. data/VERSION +1 -0
  7. data/bin/bel2_termcheck +39 -0
  8. data/lib/bel_parser.rb +17 -0
  9. data/lib/bel_parser/ast_filter.rb +27 -0
  10. data/lib/bel_parser/ast_generator.rb +86 -0
  11. data/lib/bel_parser/ast_validator.rb +40 -0
  12. data/lib/bel_parser/expression/parser.rb +42 -0
  13. data/lib/bel_parser/expression/term_semantics.rb +36 -0
  14. data/lib/bel_parser/language.rb +7 -0
  15. data/lib/bel_parser/language/function.rb +59 -0
  16. data/lib/bel_parser/language/quoting.rb +236 -0
  17. data/lib/bel_parser/language/semantic_ast.rb +604 -0
  18. data/lib/bel_parser/language/semantics/analyzer.rb +59 -0
  19. data/lib/bel_parser/language/signature.rb +39 -0
  20. data/lib/bel_parser/language/specification.rb +49 -0
  21. data/lib/bel_parser/language/syntax/expression/incomplete_node.rb +14 -0
  22. data/lib/bel_parser/language/syntax/expression/invalid_term_function.rb +22 -0
  23. data/lib/bel_parser/language/version1.rb +50 -0
  24. data/lib/bel_parser/language/version1/functions/abundance.rb +85 -0
  25. data/lib/bel_parser/language/version1/functions/biological_process.rb +85 -0
  26. data/lib/bel_parser/language/version1/functions/catalytic_activity.rb +110 -0
  27. data/lib/bel_parser/language/version1/functions/cell_secretion.rb +80 -0
  28. data/lib/bel_parser/language/version1/functions/cell_surface_expression.rb +80 -0
  29. data/lib/bel_parser/language/version1/functions/chaperone_activity.rb +110 -0
  30. data/lib/bel_parser/language/version1/functions/complex_abundance.rb +115 -0
  31. data/lib/bel_parser/language/version1/functions/composite_abundance.rb +80 -0
  32. data/lib/bel_parser/language/version1/functions/degradation.rb +80 -0
  33. data/lib/bel_parser/language/version1/functions/fusion.rb +302 -0
  34. data/lib/bel_parser/language/version1/functions/gene_abundance.rb +125 -0
  35. data/lib/bel_parser/language/version1/functions/gtp_bound_activity.rb +110 -0
  36. data/lib/bel_parser/language/version1/functions/kinase_activity.rb +110 -0
  37. data/lib/bel_parser/language/version1/functions/list.rb +115 -0
  38. data/lib/bel_parser/language/version1/functions/micro_rna_abundance.rb +85 -0
  39. data/lib/bel_parser/language/version1/functions/molecular_activity.rb +80 -0
  40. data/lib/bel_parser/language/version1/functions/pathology.rb +85 -0
  41. data/lib/bel_parser/language/version1/functions/peptidase_activity.rb +110 -0
  42. data/lib/bel_parser/language/version1/functions/phosphatase_activity.rb +110 -0
  43. data/lib/bel_parser/language/version1/functions/products.rb +80 -0
  44. data/lib/bel_parser/language/version1/functions/protein_abundance.rb +245 -0
  45. data/lib/bel_parser/language/version1/functions/protein_modification.rb +167 -0
  46. data/lib/bel_parser/language/version1/functions/reactants.rb +80 -0
  47. data/lib/bel_parser/language/version1/functions/reaction.rb +85 -0
  48. data/lib/bel_parser/language/version1/functions/ribosylation_activity.rb +110 -0
  49. data/lib/bel_parser/language/version1/functions/rna_abundance.rb +125 -0
  50. data/lib/bel_parser/language/version1/functions/substitution.rb +96 -0
  51. data/lib/bel_parser/language/version1/functions/transcriptional_activity.rb +110 -0
  52. data/lib/bel_parser/language/version1/functions/translocation.rb +100 -0
  53. data/lib/bel_parser/language/version1/functions/transport_activity.rb +110 -0
  54. data/lib/bel_parser/language/version1/functions/truncation.rb +82 -0
  55. data/lib/bel_parser/language/version1/return_types/abundance.rb +20 -0
  56. data/lib/bel_parser/language/version1/return_types/any.rb +74 -0
  57. data/lib/bel_parser/language/version1/return_types/biological_process.rb +17 -0
  58. data/lib/bel_parser/language/version1/return_types/catalytic_activity.rb +20 -0
  59. data/lib/bel_parser/language/version1/return_types/chaperone_activity.rb +20 -0
  60. data/lib/bel_parser/language/version1/return_types/complex_abundance.rb +17 -0
  61. data/lib/bel_parser/language/version1/return_types/fusion.rb +17 -0
  62. data/lib/bel_parser/language/version1/return_types/gene_abundance.rb +17 -0
  63. data/lib/bel_parser/language/version1/return_types/gtp_bound_activity.rb +20 -0
  64. data/lib/bel_parser/language/version1/return_types/kinase_activity.rb +20 -0
  65. data/lib/bel_parser/language/version1/return_types/list.rb +17 -0
  66. data/lib/bel_parser/language/version1/return_types/micro_rna_abundance.rb +17 -0
  67. data/lib/bel_parser/language/version1/return_types/molecular_activity.rb +20 -0
  68. data/lib/bel_parser/language/version1/return_types/pathology.rb +17 -0
  69. data/lib/bel_parser/language/version1/return_types/peptidase_activity.rb +20 -0
  70. data/lib/bel_parser/language/version1/return_types/phosphatase_activity.rb +20 -0
  71. data/lib/bel_parser/language/version1/return_types/products.rb +17 -0
  72. data/lib/bel_parser/language/version1/return_types/protein_abundance.rb +17 -0
  73. data/lib/bel_parser/language/version1/return_types/protein_modification.rb +17 -0
  74. data/lib/bel_parser/language/version1/return_types/reactants.rb +17 -0
  75. data/lib/bel_parser/language/version1/return_types/ribosylation_activity.rb +20 -0
  76. data/lib/bel_parser/language/version1/return_types/rna_abundance.rb +17 -0
  77. data/lib/bel_parser/language/version1/return_types/substitution.rb +17 -0
  78. data/lib/bel_parser/language/version1/return_types/transcriptional_activity.rb +20 -0
  79. data/lib/bel_parser/language/version1/return_types/transport_activity.rb +20 -0
  80. data/lib/bel_parser/language/version1/return_types/truncation.rb +17 -0
  81. data/lib/bel_parser/language/version2.rb +50 -0
  82. data/lib/bel_parser/language/version2/functions/abundance.rb +165 -0
  83. data/lib/bel_parser/language/version2/functions/activity.rb +115 -0
  84. data/lib/bel_parser/language/version2/functions/biological_process.rb +85 -0
  85. data/lib/bel_parser/language/version2/functions/cell_secretion.rb +80 -0
  86. data/lib/bel_parser/language/version2/functions/cell_surface_expression.rb +80 -0
  87. data/lib/bel_parser/language/version2/functions/complex_abundance.rb +190 -0
  88. data/lib/bel_parser/language/version2/functions/composite_abundance.rb +80 -0
  89. data/lib/bel_parser/language/version2/functions/degradation.rb +80 -0
  90. data/lib/bel_parser/language/version2/functions/fragment.rb +119 -0
  91. data/lib/bel_parser/language/version2/functions/from_location.rb +85 -0
  92. data/lib/bel_parser/language/version2/functions/fusion.rb +227 -0
  93. data/lib/bel_parser/language/version2/functions/gene_abundance.rb +195 -0
  94. data/lib/bel_parser/language/version2/functions/list.rb +115 -0
  95. data/lib/bel_parser/language/version2/functions/location.rb +85 -0
  96. data/lib/bel_parser/language/version2/functions/micro_rna_abundance.rb +165 -0
  97. data/lib/bel_parser/language/version2/functions/molecular_activity.rb +83 -0
  98. data/lib/bel_parser/language/version2/functions/pathology.rb +85 -0
  99. data/lib/bel_parser/language/version2/functions/products.rb +80 -0
  100. data/lib/bel_parser/language/version2/functions/protein_abundance.rb +285 -0
  101. data/lib/bel_parser/language/version2/functions/protein_modification.rb +167 -0
  102. data/lib/bel_parser/language/version2/functions/reactants.rb +80 -0
  103. data/lib/bel_parser/language/version2/functions/reaction.rb +85 -0
  104. data/lib/bel_parser/language/version2/functions/rna_abundance.rb +195 -0
  105. data/lib/bel_parser/language/version2/functions/to_location.rb +85 -0
  106. data/lib/bel_parser/language/version2/functions/translocation.rb +90 -0
  107. data/lib/bel_parser/language/version2/functions/variant.rb +83 -0
  108. data/lib/bel_parser/language/version2/return_types/abundance.rb +20 -0
  109. data/lib/bel_parser/language/version2/return_types/activity.rb +20 -0
  110. data/lib/bel_parser/language/version2/return_types/any.rb +74 -0
  111. data/lib/bel_parser/language/version2/return_types/biological_process.rb +17 -0
  112. data/lib/bel_parser/language/version2/return_types/complex_abundance.rb +17 -0
  113. data/lib/bel_parser/language/version2/return_types/fragment.rb +20 -0
  114. data/lib/bel_parser/language/version2/return_types/from_location.rb +20 -0
  115. data/lib/bel_parser/language/version2/return_types/fusion.rb +17 -0
  116. data/lib/bel_parser/language/version2/return_types/gene_abundance.rb +17 -0
  117. data/lib/bel_parser/language/version2/return_types/list.rb +17 -0
  118. data/lib/bel_parser/language/version2/return_types/location.rb +20 -0
  119. data/lib/bel_parser/language/version2/return_types/micro_rna_abundance.rb +17 -0
  120. data/lib/bel_parser/language/version2/return_types/molecular_activity.rb +20 -0
  121. data/lib/bel_parser/language/version2/return_types/pathology.rb +17 -0
  122. data/lib/bel_parser/language/version2/return_types/products.rb +17 -0
  123. data/lib/bel_parser/language/version2/return_types/protein_abundance.rb +17 -0
  124. data/lib/bel_parser/language/version2/return_types/protein_modification.rb +17 -0
  125. data/lib/bel_parser/language/version2/return_types/reactants.rb +17 -0
  126. data/lib/bel_parser/language/version2/return_types/rna_abundance.rb +17 -0
  127. data/lib/bel_parser/language/version2/return_types/to_location.rb +20 -0
  128. data/lib/bel_parser/language/version2/return_types/variant.rb +20 -0
  129. data/lib/bel_parser/mixin/line_continuator.rb +15 -0
  130. data/lib/bel_parser/mixin/line_mapping.rb +14 -0
  131. data/lib/bel_parser/parser.rb +54 -0
  132. data/lib/bel_parser/parsers/ast/mapped_traversal.rb +36 -0
  133. data/lib/bel_parser/parsers/ast/node.rb +705 -0
  134. data/lib/bel_parser/parsers/ast/sexp.rb +8 -0
  135. data/lib/bel_parser/parsers/ast/traversal.rb +21 -0
  136. data/lib/bel_parser/parsers/bel_script.rb +4 -0
  137. data/lib/bel_parser/parsers/bel_script/define_annotation.rb +5476 -0
  138. data/lib/bel_parser/parsers/bel_script/define_annotation.rl +141 -0
  139. data/lib/bel_parser/parsers/bel_script/define_namespace.rb +1780 -0
  140. data/lib/bel_parser/parsers/bel_script/define_namespace.rl +121 -0
  141. data/lib/bel_parser/parsers/bel_script/set.rb +4556 -0
  142. data/lib/bel_parser/parsers/bel_script/set.rl +116 -0
  143. data/lib/bel_parser/parsers/bel_script/unset.rb +706 -0
  144. data/lib/bel_parser/parsers/bel_script/unset.rl +95 -0
  145. data/lib/bel_parser/parsers/common.rb +5 -0
  146. data/lib/bel_parser/parsers/common/blank_line.rb +211 -0
  147. data/lib/bel_parser/parsers/common/blank_line.rl +81 -0
  148. data/lib/bel_parser/parsers/common/comment_line.rb +245 -0
  149. data/lib/bel_parser/parsers/common/comment_line.rl +97 -0
  150. data/lib/bel_parser/parsers/common/common.rb +7 -0
  151. data/lib/bel_parser/parsers/common/common.rl +13 -0
  152. data/lib/bel_parser/parsers/common/identifier.rb +289 -0
  153. data/lib/bel_parser/parsers/common/identifier.rl +106 -0
  154. data/lib/bel_parser/parsers/common/list.rb +2142 -0
  155. data/lib/bel_parser/parsers/common/list.rl +144 -0
  156. data/lib/bel_parser/parsers/common/string.rb +271 -0
  157. data/lib/bel_parser/parsers/common/string.rl +107 -0
  158. data/lib/bel_parser/parsers/expression.rb +7 -0
  159. data/lib/bel_parser/parsers/expression/comment.rb +239 -0
  160. data/lib/bel_parser/parsers/expression/comment.rl +97 -0
  161. data/lib/bel_parser/parsers/expression/parameter.rb +1506 -0
  162. data/lib/bel_parser/parsers/expression/parameter.rl +97 -0
  163. data/lib/bel_parser/parsers/expression/relationship.rb +254 -0
  164. data/lib/bel_parser/parsers/expression/relationship.rl +98 -0
  165. data/lib/bel_parser/parsers/expression/statement_nested.rb +17802 -0
  166. data/lib/bel_parser/parsers/expression/statement_nested.rl +141 -0
  167. data/lib/bel_parser/parsers/expression/statement_observed_term.rb +7291 -0
  168. data/lib/bel_parser/parsers/expression/statement_observed_term.rl +92 -0
  169. data/lib/bel_parser/parsers/expression/statement_simple.rb +10475 -0
  170. data/lib/bel_parser/parsers/expression/statement_simple.rl +112 -0
  171. data/lib/bel_parser/parsers/expression/term.rb +3989 -0
  172. data/lib/bel_parser/parsers/expression/term.rl +157 -0
  173. data/lib/bel_parser/parsers/line_parser.rb +92 -0
  174. data/lib/bel_parser/parsers/mixin/buffer.rb +10 -0
  175. data/lib/bel_parser/parsers/nonblocking_io_wrapper.rb +50 -0
  176. data/lib/bel_parser/script/parser.rb +49 -0
  177. data/lib/bel_parser/vendor/ast.rb +17 -0
  178. data/lib/bel_parser/vendor/ast/node.rb +254 -0
  179. data/lib/bel_parser/vendor/ast/processor.rb +12 -0
  180. data/lib/bel_parser/vendor/ast/processor/mixin.rb +282 -0
  181. data/lib/bel_parser/vendor/ast/sexp.rb +30 -0
  182. metadata +226 -0
@@ -0,0 +1,17 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Fusion return type.
8
+ class Fusion < Any
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != Fusion
11
+ :fusion
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'abundance'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Gene abundance return type.
8
+ class GeneAbundance < Abundance
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != GeneAbundance
11
+ :geneAbundance
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # List return type.
8
+ class List < Any
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != List
11
+ :list
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Location return type.
8
+ class Location < Any
9
+ # Return the {Symbol} value.
10
+ #
11
+ # @note This method should be overridden in subclasses.
12
+ def self.to_sym
13
+ raise_not_implemented(__method__) if self != Location
14
+ :location
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'abundance'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Micro RNA abundance return type.
8
+ class MicroRNAAbundance < Abundance
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != MicroRNAAbundance
11
+ :microRNAAbundance
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # MolecularActivity return type.
8
+ class MolecularActivity < Any
9
+ # Return the {Symbol} value.
10
+ #
11
+ # @note This method should be overridden in subclasses.
12
+ def self.to_sym
13
+ raise_not_implemented(__method__) if self != MolecularActivity
14
+ :molecularActivity
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'biological_process'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Pathology return type.
8
+ class Pathology < BiologicalProcess
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != Pathology
11
+ :pathology
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Products return type.
8
+ class Products < Any
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != Products
11
+ :products
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'abundance'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Protein abundance return type.
8
+ class ProteinAbundance < Abundance
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != ProteinAbundance
11
+ :proteinAbundance
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Protein modification return type.
8
+ class ProteinModification < Any
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != ProteinModification
11
+ :proteinModification
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Reactants return type.
8
+ class Reactants < Any
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != Reactants
11
+ :reactants
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'abundance'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # RNA abundance return type.
8
+ class RNAAbundance < Abundance
9
+ def self.to_sym
10
+ raise_not_implemented(__method__) if self != RNAAbundance
11
+ :rnaAbundance
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'location'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # ToLocation return type.
8
+ class ToLocation < Location
9
+ # Return the {Symbol} value.
10
+ #
11
+ # @note This method should be overridden in subclasses.
12
+ def self.to_sym
13
+ raise_not_implemented(__method__) if self != ToLocation
14
+ :toLocation
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'any'
2
+
3
+ module BELParser
4
+ module Language
5
+ module Version2
6
+ module ReturnTypes
7
+ # Variant return type.
8
+ class Variant < Any
9
+ # Return the {Symbol} value.
10
+ #
11
+ # @note This method should be overridden in subclasses.
12
+ def self.to_sym
13
+ raise_not_implemented(__method__) if self != Variant
14
+ :variant
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module BELParser
2
+ # LineContinuator is a mixin for line expansions for BEL Script.
3
+ module LineContinuator
4
+ LINE_CONTINUATOR = "\\\n".freeze
5
+
6
+ def expand_line_continuator(line_enumerator)
7
+ line = line_enumerator.next
8
+ while line.end_with?(LINE_CONTINUATOR)
9
+ line.chomp!(LINE_CONTINUATOR)
10
+ line += line_enumerator.next
11
+ end
12
+ line
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module BELParser
2
+ # LineMapping module.
3
+ module LineMapping
4
+ def normalize_line_terminator(line)
5
+ return nil unless line
6
+ line.sub(/[\r\n]+$/, '') + "\n"
7
+ end
8
+
9
+ def map_lines(line_enumerator)
10
+ line_enumerator
11
+ .map { |line| normalize_line_terminator(line) }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,54 @@
1
+ require_relative 'ast_filter'
2
+ require_relative 'ast_generator'
3
+ require_relative 'parsers/common'
4
+ require_relative 'parsers/expression'
5
+ require_relative 'parsers/bel_script'
6
+
7
+ module BELParser
8
+ # Parser is a line parser that supports recognition using all ragel parsers.
9
+ class Parser
10
+ include BELParser::Parsers::Common
11
+ include BELParser::Parsers::Expression
12
+ include BELParser::Parsers::BELScript
13
+
14
+ FILTER = BELParser::ASTFilter.new(
15
+ :blank_line,
16
+ :comment_line,
17
+ :identifier,
18
+ :string,
19
+ :list,
20
+ :comment,
21
+ :parameter,
22
+ :term,
23
+ :relationship,
24
+ :observed_term,
25
+ :statement_simple,
26
+ :nested_statement,
27
+ :define_annotation,
28
+ :define_namespace,
29
+ :set,
30
+ :unset
31
+ )
32
+
33
+ def each(io)
34
+ if block_given?
35
+ filtered_ast = FILTER.each(BELParser::ASTGenerator.new.each(io))
36
+ filtered_ast.each do |results|
37
+ yield results
38
+ end
39
+ else
40
+ enum_for(:each, io)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ if __FILE__ == $PROGRAM_NAME
47
+ BELParser::Parser.new.each($stdin) do |line_result|
48
+ line_number, line, ast_results = line_result
49
+ puts "#{line_number}: #{line}"
50
+ ast_results.each do |ast|
51
+ puts ast.to_s(1)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,36 @@
1
+ require 'observer'
2
+
3
+ module BELParser
4
+ module Parsers
5
+ module AST
6
+ # Traversal provides an observable walk that maps over the
7
+ # {BELParser::Parsers::AST::Node AST node} and returns the results.
8
+ # Alternatively, see {BELParser::Parsers::AST::Traversal}.
9
+ class MappedTraversal
10
+ include Observable
11
+
12
+ def traverse(ast)
13
+ if block_given?
14
+ ast.traverse do |node|
15
+ changed
16
+ yield(node, notify_observers(node))
17
+ end
18
+ else
19
+ enum_for(:traverse, ast)
20
+ end
21
+ end
22
+
23
+ def notify_observers(*args)
24
+ if defined? @observer_state && @observer_state
25
+ @observer_state = false
26
+ if defined? @observer_peers
27
+ @observer_peers.map do |k, v|
28
+ k.send v, *args
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,705 @@
1
+ require 'bel_parser/vendor/ast'
2
+
3
+ module BELParser
4
+ module Parsers
5
+ # BEL AST module.
6
+ module AST
7
+ # @raise ArgumentError if _argument_ is not _expected_
8
+ def self.assert_is_a(expected, actual, argument)
9
+ msg = ->(x, y, z) { "Expected #{x} of #{y}, but got #{z}" }
10
+ return if actual.is_a? expected
11
+ raise ArgumentError, msg.call(expected, argument, actual.class)
12
+ end
13
+
14
+ # BEL application-specific AST node.
15
+ #
16
+ # All BEL AST nodes have a basic set of properties. Additional properties
17
+ # may be specified by subclasses. Each class in the hierarchy describes
18
+ # its type through the class variable _ast_type_. This is equivalent to
19
+ # its _type_ instance variable but the former is not used by the AST
20
+ # library itself.
21
+ #
22
+ # @see Node.ast_type
23
+ # @see Node.initialize
24
+ #
25
+ class Node < ::AST::Node
26
+ # AST node type
27
+ @ast_type = :node
28
+ # Basic AST node has no meaning
29
+ @has_semantics = false
30
+
31
+ # New BEL AST node.
32
+ #
33
+ # @param [Symbol] type The node type symbol
34
+ # @param [Array] children Optional children of node
35
+ # @param [Hash] properties Optional supported node properties
36
+ #
37
+ # === Supported properties
38
+ # - +line_number+ -> {#line_number}
39
+ # - +character_range+ -> {#character_range}, {#range_start},
40
+ # {#range_end}
41
+ # - +complete+ -> {#complete?}
42
+ #
43
+ # @raise ArgumentError If _children_ is not an Array or _properties_
44
+ # is not a Hash
45
+ def initialize(type, children = [], properties = {})
46
+ AST.assert_is_a(Array, children, 'children')
47
+ AST.assert_is_a(Hash, properties, 'properties')
48
+ super(type, children, properties)
49
+ end
50
+
51
+ # Get the class AST node type.
52
+ # @return [Symbol]
53
+ class << self; attr_reader :ast_type end
54
+
55
+ # Get whether this class AST node has semantics.
56
+ # @return [boolean]
57
+ class << self; attr_reader :has_semantics end
58
+
59
+ # Get the line number where this AST node originates.
60
+ attr_reader :line_number
61
+
62
+ # Get the character range enclosing this AST node.
63
+ # It is defined as the close interval containing all the characters
64
+ # of this AST node.
65
+ attr_reader :character_range
66
+
67
+ # Get the start of the character range enclosing this AST node.
68
+ def range_start
69
+ @character_range[0]
70
+ end
71
+
72
+ # Get _a_ in the character range [a, b].
73
+ alias range_a range_start
74
+
75
+ # Get the end of the character range enclosing this AST node.
76
+ def range_end
77
+ @character_range[1]
78
+ end
79
+
80
+ # Get _b_ in the character range [a, b].
81
+ alias range_b range_end
82
+
83
+ # Get whether the AST node can be considered _complete_.
84
+ def complete?
85
+ @complete
86
+ end
87
+
88
+ # Get whether the AST node should be considered _incomplete_.
89
+ def incomplete?
90
+ !@complete
91
+ end
92
+
93
+ def traverse(&block)
94
+ if block_given?
95
+ children.each do |child_node|
96
+ child_node.traverse(&block) if child_node.respond_to?(:traverse)
97
+ end
98
+ yield self
99
+ else
100
+ enum_for(:traverse)
101
+ end
102
+ end
103
+
104
+ def freeze
105
+ # no freeze...nothing
106
+ # I want to be able to modify properties!
107
+ self
108
+ end
109
+
110
+ def updated(children = nil, properties = nil)
111
+ new_children = children || @children
112
+ new_properties = properties || {}
113
+
114
+ if @children == new_children && properties.nil?
115
+ self
116
+ else
117
+ original_dup.send :initialize, new_children, new_properties
118
+ end
119
+ end
120
+
121
+ # Concatenates `array` with `children` and returns the resulting node.
122
+ #
123
+ # @return [Node]
124
+ def concat(array)
125
+ updated(@children + array.to_a)
126
+ end
127
+
128
+ alias + concat
129
+
130
+ # Appends `element` to `children` and returns the resulting node.
131
+ #
132
+ # @return [Node]
133
+ def append(element)
134
+ updated(@children + [element])
135
+ end
136
+
137
+ alias << append
138
+ end
139
+
140
+ # AST node representing a blank line.
141
+ class BlankLine < Node
142
+ # AST node type
143
+ @ast_type = :blank_line
144
+ # Blank lines have no meaning
145
+ @has_semantics = false
146
+
147
+ # New BlankLine AST node.
148
+ #
149
+ # @see Node#initialize Node class for basic properties
150
+ def initialize(children = [], properties = {})
151
+ super(BlankLine.ast_type, children, properties)
152
+ end
153
+ end
154
+
155
+ # AST node representing a statement comment.
156
+ class Comment < Node
157
+ # AST node type
158
+ @ast_type = :comment
159
+ # Comments have no meaning
160
+ @has_semantics = false
161
+
162
+ # New Comment AST node.
163
+ #
164
+ # @see Node#initialize Node class for basic properties
165
+ def initialize(children = [], properties = {})
166
+ super(Comment.ast_type, children, properties)
167
+ end
168
+ end
169
+
170
+ # AST node representing a line comment.
171
+ class CommentLine < Node
172
+ # AST node type
173
+ @ast_type = :comment_line
174
+ # Comment lines have no meaning
175
+ @has_semantics = false
176
+
177
+ # New CommentLine AST node.
178
+ #
179
+ # @see Node#initialize Node class for basic properties
180
+ def initialize(children = [], properties = {})
181
+ super(CommentLine.ast_type, children, properties)
182
+ end
183
+ end
184
+
185
+ # AST node representing the definition of an annotation.
186
+ class AnnotationDefinition < Node
187
+ # AST node type
188
+ @ast_type = :annotation_definition
189
+ # Content is has semantic meaning
190
+ @has_semantics = true
191
+
192
+ # New AnnotationDefinition AST node.
193
+ #
194
+ # @see Node#initialize Node class for basic properties
195
+ def initialize(children = [], properties = {})
196
+ super(AnnotationDefinition.ast_type, children, properties)
197
+ end
198
+ end
199
+
200
+ # AST node representing the function of a BEL term.
201
+ #
202
+ # === Special node properties
203
+ # - _return_type_: {#return_type}
204
+ #
205
+ class Function < Node
206
+ # AST node type
207
+ @ast_type = :function
208
+ # Functions have semantic meaning
209
+ @has_semantics = true
210
+
211
+ # New Function AST node.
212
+ #
213
+ # @see Node#initialize Node class for basic properties
214
+ def initialize(children = [], properties = {})
215
+ super(Function.ast_type, children, properties)
216
+ end
217
+
218
+ # Get the function's identifier.
219
+ def identifier
220
+ children[0]
221
+ end
222
+
223
+ # Get the return type property.
224
+ attr_reader :return_type
225
+ end
226
+
227
+ # AST node representing the definition of a namespace.
228
+ class NamespaceDefinition < Node
229
+ # AST node type
230
+ @ast_type = :namespace_definition
231
+ # Namespace definitions have semantic meaning
232
+ @has_semantics = true
233
+
234
+ # New NamespaceDefinition AST node.
235
+ #
236
+ # @see Node#initialize Node class for basic properties
237
+ def initialize(children = [], properties = {})
238
+ super(NamespaceDefinition.ast_type, children, properties)
239
+ end
240
+
241
+ # Get the namespace definition's keyword.
242
+ def keyword
243
+ # TODO: access children for content
244
+ end
245
+ end
246
+
247
+ # AST node representing the definition of a namespace.
248
+ class Identifier < Node
249
+ # AST node type
250
+ @ast_type = :identifier
251
+ # Identifier have no semantics
252
+ @has_semantics = false
253
+
254
+ # New Identifier AST node.
255
+ #
256
+ # @see Node#initialize Node class for basic properties
257
+ def initialize(children = [], properties = {})
258
+ super(Identifier.ast_type, children, properties)
259
+ end
260
+
261
+ # Get the string literal.
262
+ def string_literal
263
+ children[0]
264
+ end
265
+ end
266
+
267
+ # AST node representing a list.
268
+ class List < Node
269
+ # AST node type
270
+ @ast_type = :list
271
+ # List have semantics (content is meaningful)
272
+ @has_semantics = true
273
+
274
+ # New List AST node.
275
+ #
276
+ # @see Node#initialize Node class for basic properties
277
+ def initialize(children = [], properties = {})
278
+ super(List.ast_type, children, properties)
279
+ end
280
+ end
281
+
282
+ # AST node representing an argument.
283
+ class Argument < Node
284
+ # AST node type
285
+ @ast_type = :argument
286
+ # Arguments have semantics (position is meaningful)
287
+ @has_semantics = true
288
+
289
+ # New Argument AST node.
290
+ #
291
+ # @see Node#initialize Node class for basic properties
292
+ def initialize(children = [], properties = {})
293
+ super(Argument.ast_type, children, properties)
294
+ end
295
+
296
+ # Does the argument have a {Parameter} child?
297
+ def has_parameter?
298
+ children[0].is_a?(Parameter)
299
+ end
300
+
301
+ # Does the argument have a {Term} child?
302
+ def has_term?
303
+ children[0].is_a?(Term)
304
+ end
305
+
306
+ # Get the {Parameter} or {Term} child.
307
+ def child
308
+ children[0]
309
+ end
310
+ end
311
+
312
+ # AST node representing a parameter.
313
+ class Prefix < Node
314
+ # AST node type
315
+ @ast_type = :prefix
316
+ # Prefix have semantics (indicates namespace)
317
+ @has_semantics = true
318
+
319
+ # New Prefix AST node.
320
+ #
321
+ # @see Node#initialize Node class for basic properties
322
+ def initialize(children = [], properties = {})
323
+ super(Prefix.ast_type, children, properties)
324
+ end
325
+
326
+ # Get the identifier for the prefix.
327
+ def identifier
328
+ children[0]
329
+ end
330
+ end
331
+
332
+ # AST node representing a parameter.
333
+ class Parameter < Node
334
+ # AST node type
335
+ @ast_type = :parameter
336
+ # Parameters have semantics (encodings, namespaces)
337
+ @has_semantics = true
338
+
339
+ # New Parameter AST node.
340
+ #
341
+ # @see Node#initialize Node class for basic properties
342
+ def initialize(children = [], properties = {})
343
+ super(Parameter.ast_type, children, properties)
344
+ end
345
+ end
346
+
347
+ # AST node representing a relationship.
348
+ class Relationship < Node
349
+ # AST node type
350
+ @ast_type = :relationship
351
+ # Relationship have no semantics, statements do
352
+ @has_semantics = false
353
+
354
+ # New Relationship AST node.
355
+ #
356
+ # @see Node#initialize Node class for basic properties
357
+ def initialize(children = [], properties = {})
358
+ super(Relationship.ast_type, children, properties)
359
+ end
360
+ end
361
+
362
+ # AST node representing a set.
363
+ class Set < Node
364
+ # AST node type
365
+ @ast_type = :set
366
+ # Set has semantics (what was set?)
367
+ @has_semantics = true
368
+
369
+ # New Set AST node.
370
+ #
371
+ # @see Node#initialize Node class for basic properties
372
+ def initialize(children = [], properties = {})
373
+ super(Set.ast_type, children, properties)
374
+ end
375
+
376
+ # Get what is being set.
377
+ def name
378
+ # TODO: access children for content
379
+ end
380
+
381
+ # Get the value of what is being set.
382
+ def value
383
+ # TODO: access children for content
384
+ end
385
+ end
386
+
387
+ # AST node representing a statement.
388
+ class Statement < Node
389
+ # AST node type
390
+ @ast_type = :statement
391
+ # Statements have semantics
392
+ @has_semantics = true
393
+
394
+ # New Statement AST node.
395
+ #
396
+ # @see Node#initialize Node class for basic properties
397
+ def initialize(children = [], properties = {})
398
+ super(Statement.ast_type, children, properties)
399
+ end
400
+
401
+ # Get the subject of the statement.
402
+ def subject
403
+ # TODO: access children for content
404
+ end
405
+ end
406
+
407
+ # AST node representing a nested statement.
408
+ class NestedStatement < Node
409
+ # AST node type
410
+ @ast_type = :nested_statement
411
+ # Nested statements have semantics
412
+ @has_semantics = true
413
+
414
+ # New NestedStatement AST node.
415
+ #
416
+ # @see Node#initialize Node class for basic properties
417
+ def initialize(children = [], properties = {})
418
+ super(NestedStatement.ast_type, children, properties)
419
+ end
420
+
421
+ # Get the relationship of the nested statement.
422
+ def relatitonship
423
+ # TODO: access children for content
424
+ end
425
+
426
+ # Get the object of the nested statement.
427
+ def object
428
+ # TODO: access children for content
429
+ end
430
+ end
431
+
432
+ # AST node representing a observed term statement.
433
+ class ObservedTerm < Node
434
+ # AST node type
435
+ @ast_type = :observed_term
436
+ # Observed terms have semantics
437
+ @has_semantics = true
438
+
439
+ # New ObservedTerm AST node.
440
+ #
441
+ # @see Node#initialize Node class for basic properties
442
+ def initialize(children = [], properties = {})
443
+ super(ObservedTerm.ast_type, children, properties)
444
+ end
445
+ end
446
+
447
+ # AST node representing a simple statement.
448
+ class SimpleStatement < Node
449
+ # AST node type
450
+ @ast_type = :simple_statement
451
+ # Simple statements have semantics
452
+ @has_semantics = true
453
+
454
+ # New SimpleStatement AST node.
455
+ #
456
+ # @see Node#initialize Node class for basic properties
457
+ def initialize(children = [], properties = {})
458
+ super(SimpleStatement.ast_type, children, properties)
459
+ end
460
+
461
+ # Get the relationship of the nested statement.
462
+ def relatitonship
463
+ # TODO: access children for content
464
+ end
465
+
466
+ # Get the object of the nested statement.
467
+ def object
468
+ # TODO: access children for content
469
+ end
470
+ end
471
+
472
+ # AST node representing the subject of a statement.
473
+ class Subject < Node
474
+ # AST node type
475
+ @ast_type = :subject
476
+ # Subject have semantics
477
+ @has_semantics = true
478
+
479
+ # New Subject AST node.
480
+ #
481
+ # @see Node#initialize Node class for basic properties
482
+ def initialize(children = [], properties = {})
483
+ super(Subject.ast_type, children, properties)
484
+ end
485
+
486
+ # Get the subject's term.
487
+ def term
488
+ children[0]
489
+ end
490
+ end
491
+
492
+ # AST node representing the object of a statement.
493
+ class Object < Node
494
+ # AST node type
495
+ @ast_type = :object
496
+ # Object have semantics
497
+ @has_semantics = true
498
+
499
+ # New Object AST node.
500
+ #
501
+ # @see Node#initialize Node class for basic properties
502
+ def initialize(children = [], properties = {})
503
+ super(Object.ast_type, children, properties)
504
+ end
505
+
506
+ # Does the object have a {Term} child?
507
+ def has_term?
508
+ children[0].is_a?(Term)
509
+ end
510
+
511
+ # Does the object have a {Statement} child?
512
+ def has_statement?
513
+ children[0].is_a?(Statement)
514
+ end
515
+
516
+ # Get the {Term} or {Statement} child.
517
+ def child
518
+ children[0]
519
+ end
520
+ end
521
+
522
+ # AST node representing a UTF-8 encoded string
523
+ class String < Node
524
+ # AST node type
525
+ @ast_type = :string
526
+ # String have no semantic meaning
527
+ @has_semantics = false
528
+
529
+ # New String AST node.
530
+ #
531
+ # @see Node#initialize Node class for basic properties
532
+ def initialize(children = [], properties = {})
533
+ super(String.ast_type, children, properties)
534
+ end
535
+
536
+ # Get the string literal.
537
+ def string_literal
538
+ children[0]
539
+ end
540
+ end
541
+
542
+ # AST node representing a term.
543
+ class Term < Node
544
+ # AST node type
545
+ @ast_type = :term
546
+ # Terms have semantics
547
+ @has_semantics = true
548
+
549
+ # New Term AST node.
550
+ #
551
+ # @see Node#initialize Node class for basic properties
552
+ def initialize(children = [], properties = {})
553
+ super(Term.ast_type, children, properties)
554
+ end
555
+
556
+ # Get the term's function.
557
+ def function
558
+ children[0]
559
+ end
560
+
561
+ # Get the term's arguments.
562
+ def arguments
563
+ children[1..-1]
564
+ end
565
+
566
+ # Get the term's function semantics.
567
+ def function_semantics
568
+ @function_semantics
569
+ end
570
+
571
+ # Sets the term's function semantics.
572
+ def function_semantics=(function_semantics)
573
+ if function_semantics != nil && !function_semantics.is_a?(BELParser::Language::Signature)
574
+ raise ArgumentError, "function_semantics: expected nil or BELParser::Language::Signature"
575
+ end
576
+ assign_properties({function_semantics: function_semantics})
577
+ end
578
+ end
579
+
580
+ # AST node representing an unset.
581
+ class Unset < Node
582
+ # AST node type
583
+ @ast_type = :unset
584
+ # Unset has semantics; what was unset?
585
+ @has_semantics = true
586
+
587
+ # New Unset AST node.
588
+ #
589
+ # @see Node#initialize Node class for basic properties
590
+ def initialize(children = [], properties = {})
591
+ super(Unset.ast_type, children, properties)
592
+ end
593
+
594
+ # Get what is being unset.
595
+ def name
596
+ # TODO: access children for content
597
+ end
598
+ end
599
+
600
+ # AST node representing a value.
601
+ #
602
+ # === Special node properties
603
+ # - _encoding_: {#encoding}
604
+ #
605
+ class Value < Node
606
+ # AST node type
607
+ @ast_type = :value
608
+ # Values have semantics (encodings)
609
+ @has_semantics = true
610
+
611
+ # New Value AST node.
612
+ #
613
+ # @see Node#initialize Node class for basic properties
614
+ def initialize(children = [], properties = {})
615
+ super(Value.ast_type, children, properties)
616
+ end
617
+
618
+ # Get the value's encoding.
619
+ attr_reader :encoding
620
+ end
621
+
622
+ module Sexp
623
+ def nested_statement(*children)
624
+ NestedStatement.new(children)
625
+ end
626
+
627
+ def simple_statement(*children)
628
+ SimpleStatement.new(children)
629
+ end
630
+
631
+ def observed_term(*children)
632
+ ObservedTerm.new(children)
633
+ end
634
+
635
+ def statement(*children)
636
+ Statement.new(children)
637
+ end
638
+
639
+ def subject(*children)
640
+ Subject.new(children)
641
+ end
642
+
643
+ def object(*children)
644
+ Object.new(children)
645
+ end
646
+
647
+ def relationship(*children)
648
+ Relationship.new(children)
649
+ end
650
+
651
+ def term(*children)
652
+ Term.new(children)
653
+ end
654
+
655
+ def function(*children)
656
+ Function.new(children)
657
+ end
658
+
659
+ def argument(*children)
660
+ Argument.new(children)
661
+ end
662
+
663
+ def parameter(*children)
664
+ Parameter.new(children)
665
+ end
666
+
667
+ def prefix(*children)
668
+ Prefix.new(children)
669
+ end
670
+
671
+ def value(*children)
672
+ Value.new(children)
673
+ end
674
+
675
+ def identifier(*children)
676
+ Identifier.new(children)
677
+ end
678
+
679
+ def string(*children)
680
+ String.new(children)
681
+ end
682
+
683
+ def list(*children)
684
+ List.new(children)
685
+ end
686
+
687
+ def comment(*children)
688
+ Comment.new(children)
689
+ end
690
+
691
+ def comment_line(*children)
692
+ CommentLine.new(children)
693
+ end
694
+
695
+ def annotation_definition(*children)
696
+ AnnotationDefinition.new(children)
697
+ end
698
+
699
+ def namespace_definition(*children)
700
+ NamespaceDefinition.new(children)
701
+ end
702
+ end
703
+ end
704
+ end
705
+ end