bel_parser 1.0.0.alpha.27-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (332) hide show
  1. checksums.yaml +7 -0
  2. data/.gemspec-java +32 -0
  3. data/CHANGELOG.md +10 -0
  4. data/LICENSE +191 -0
  5. data/README.md +20 -0
  6. data/VERSION +1 -0
  7. data/bin/bel2_validator +62 -0
  8. data/bin/bel_script_reader +132 -0
  9. data/lib/bel/translator/plugins/bel_script.rb +38 -0
  10. data/lib/bel/translator/plugins/bel_script/bel_citation_serialization.rb +125 -0
  11. data/lib/bel/translator/plugins/bel_script/bel_discrete_serialization.rb +109 -0
  12. data/lib/bel/translator/plugins/bel_script/bel_top_down_serialization.rb +100 -0
  13. data/lib/bel/translator/plugins/bel_script/nanopub_serialization.rb +79 -0
  14. data/lib/bel/translator/plugins/bel_script/reader.rb +39 -0
  15. data/lib/bel/translator/plugins/bel_script/translator.rb +37 -0
  16. data/lib/bel/translator/plugins/bel_script/writer.rb +180 -0
  17. data/lib/bel_parser.rb +23 -0
  18. data/lib/bel_parser/ast_filter.rb +44 -0
  19. data/lib/bel_parser/ast_generator.rb +83 -0
  20. data/lib/bel_parser/expression.rb +3 -0
  21. data/lib/bel_parser/expression/filter.rb +31 -0
  22. data/lib/bel_parser/expression/parser.rb +72 -0
  23. data/lib/bel_parser/expression/validator.rb +79 -0
  24. data/lib/bel_parser/language.rb +114 -0
  25. data/lib/bel_parser/language/amino_acid.rb +68 -0
  26. data/lib/bel_parser/language/apply_namespace_encoding.rb +98 -0
  27. data/lib/bel_parser/language/base_specification.rb +82 -0
  28. data/lib/bel_parser/language/covalent_protein_modification.rb +56 -0
  29. data/lib/bel_parser/language/expression_validator.rb +68 -0
  30. data/lib/bel_parser/language/function.rb +67 -0
  31. data/lib/bel_parser/language/relationship.rb +102 -0
  32. data/lib/bel_parser/language/semantics.rb +40 -0
  33. data/lib/bel_parser/language/semantics/deeply_nested_statement.rb +65 -0
  34. data/lib/bel_parser/language/semantics/function_deprecation.rb +43 -0
  35. data/lib/bel_parser/language/semantics/list_function_subject.rb +45 -0
  36. data/lib/bel_parser/language/semantics/multiple_subject_object.rb +55 -0
  37. data/lib/bel_parser/language/semantics/non_causal_nested_statement.rb +50 -0
  38. data/lib/bel_parser/language/semantics/non_object_list.rb +56 -0
  39. data/lib/bel_parser/language/semantics/relationship_deprecation.rb +44 -0
  40. data/lib/bel_parser/language/semantics/relationship_not_listable.rb +60 -0
  41. data/lib/bel_parser/language/semantics/signature_mapping.rb +83 -0
  42. data/lib/bel_parser/language/semantics_ast.rb +784 -0
  43. data/lib/bel_parser/language/semantics_ast_warnings.rb +180 -0
  44. data/lib/bel_parser/language/semantics_function.rb +16 -0
  45. data/lib/bel_parser/language/semantics_match.rb +28 -0
  46. data/lib/bel_parser/language/semantics_result.rb +33 -0
  47. data/lib/bel_parser/language/semantics_type_warning.rb +22 -0
  48. data/lib/bel_parser/language/semantics_warning.rb +27 -0
  49. data/lib/bel_parser/language/signature.rb +39 -0
  50. data/lib/bel_parser/language/specification.rb +118 -0
  51. data/lib/bel_parser/language/syntax.rb +38 -0
  52. data/lib/bel_parser/language/syntax/invalid_function.rb +39 -0
  53. data/lib/bel_parser/language/syntax/invalid_relationship.rb +42 -0
  54. data/lib/bel_parser/language/syntax/undefined_namespace.rb +49 -0
  55. data/lib/bel_parser/language/syntax/undefined_namespace_value.rb +44 -0
  56. data/lib/bel_parser/language/syntax_error.rb +32 -0
  57. data/lib/bel_parser/language/syntax_function.rb +16 -0
  58. data/lib/bel_parser/language/syntax_result.rb +32 -0
  59. data/lib/bel_parser/language/syntax_warning.rb +27 -0
  60. data/lib/bel_parser/language/version1_0.rb +20 -0
  61. data/lib/bel_parser/language/version1_0/functions/abundance.rb +83 -0
  62. data/lib/bel_parser/language/version1_0/functions/biological_process.rb +83 -0
  63. data/lib/bel_parser/language/version1_0/functions/catalytic_activity.rb +114 -0
  64. data/lib/bel_parser/language/version1_0/functions/cell_secretion.rb +83 -0
  65. data/lib/bel_parser/language/version1_0/functions/cell_surface_expression.rb +83 -0
  66. data/lib/bel_parser/language/version1_0/functions/chaperone_activity.rb +114 -0
  67. data/lib/bel_parser/language/version1_0/functions/complex_abundance.rb +115 -0
  68. data/lib/bel_parser/language/version1_0/functions/composite_abundance.rb +81 -0
  69. data/lib/bel_parser/language/version1_0/functions/degradation.rb +83 -0
  70. data/lib/bel_parser/language/version1_0/functions/fusion.rb +287 -0
  71. data/lib/bel_parser/language/version1_0/functions/gene_abundance.rb +122 -0
  72. data/lib/bel_parser/language/version1_0/functions/gtp_bound_activity.rb +113 -0
  73. data/lib/bel_parser/language/version1_0/functions/kinase_activity.rb +114 -0
  74. data/lib/bel_parser/language/version1_0/functions/list.rb +114 -0
  75. data/lib/bel_parser/language/version1_0/functions/micro_rna_abundance.rb +85 -0
  76. data/lib/bel_parser/language/version1_0/functions/molecular_activity.rb +82 -0
  77. data/lib/bel_parser/language/version1_0/functions/pathology.rb +83 -0
  78. data/lib/bel_parser/language/version1_0/functions/peptidase_activity.rb +112 -0
  79. data/lib/bel_parser/language/version1_0/functions/phosphatase_activity.rb +112 -0
  80. data/lib/bel_parser/language/version1_0/functions/products.rb +79 -0
  81. data/lib/bel_parser/language/version1_0/functions/protein_abundance.rb +234 -0
  82. data/lib/bel_parser/language/version1_0/functions/protein_modification.rb +179 -0
  83. data/lib/bel_parser/language/version1_0/functions/reactants.rb +79 -0
  84. data/lib/bel_parser/language/version1_0/functions/reaction.rb +86 -0
  85. data/lib/bel_parser/language/version1_0/functions/ribosylation_activity.rb +114 -0
  86. data/lib/bel_parser/language/version1_0/functions/rna_abundance.rb +122 -0
  87. data/lib/bel_parser/language/version1_0/functions/substitution.rb +93 -0
  88. data/lib/bel_parser/language/version1_0/functions/transcriptional_activity.rb +114 -0
  89. data/lib/bel_parser/language/version1_0/functions/translocation.rb +98 -0
  90. data/lib/bel_parser/language/version1_0/functions/transport_activity.rb +115 -0
  91. data/lib/bel_parser/language/version1_0/functions/truncation.rb +81 -0
  92. data/lib/bel_parser/language/version1_0/relationships/acts_in.rb +61 -0
  93. data/lib/bel_parser/language/version1_0/relationships/analogous.rb +41 -0
  94. data/lib/bel_parser/language/version1_0/relationships/association.rb +42 -0
  95. data/lib/bel_parser/language/version1_0/relationships/biomarker_for.rb +42 -0
  96. data/lib/bel_parser/language/version1_0/relationships/causes_no_change.rb +50 -0
  97. data/lib/bel_parser/language/version1_0/relationships/decreases.rb +63 -0
  98. data/lib/bel_parser/language/version1_0/relationships/directly_decreases.rb +56 -0
  99. data/lib/bel_parser/language/version1_0/relationships/directly_increases.rb +56 -0
  100. data/lib/bel_parser/language/version1_0/relationships/has_component.rb +62 -0
  101. data/lib/bel_parser/language/version1_0/relationships/has_components.rb +61 -0
  102. data/lib/bel_parser/language/version1_0/relationships/has_member.rb +48 -0
  103. data/lib/bel_parser/language/version1_0/relationships/has_members.rb +57 -0
  104. data/lib/bel_parser/language/version1_0/relationships/has_modification.rb +54 -0
  105. data/lib/bel_parser/language/version1_0/relationships/has_product.rb +60 -0
  106. data/lib/bel_parser/language/version1_0/relationships/has_variant.rb +54 -0
  107. data/lib/bel_parser/language/version1_0/relationships/includes.rb +59 -0
  108. data/lib/bel_parser/language/version1_0/relationships/increases.rb +63 -0
  109. data/lib/bel_parser/language/version1_0/relationships/is_a.rb +48 -0
  110. data/lib/bel_parser/language/version1_0/relationships/negative_correlation.rb +50 -0
  111. data/lib/bel_parser/language/version1_0/relationships/orthologous.rb +48 -0
  112. data/lib/bel_parser/language/version1_0/relationships/positive_correlation.rb +46 -0
  113. data/lib/bel_parser/language/version1_0/relationships/prognostic_biomarker_for.rb +44 -0
  114. data/lib/bel_parser/language/version1_0/relationships/rate_limiting_step_of.rb +53 -0
  115. data/lib/bel_parser/language/version1_0/relationships/reactant_in.rb +60 -0
  116. data/lib/bel_parser/language/version1_0/relationships/sub_process_of.rb +55 -0
  117. data/lib/bel_parser/language/version1_0/relationships/transcribed_to.rb +53 -0
  118. data/lib/bel_parser/language/version1_0/relationships/translated_to.rb +54 -0
  119. data/lib/bel_parser/language/version1_0/relationships/translocates.rb +57 -0
  120. data/lib/bel_parser/language/version1_0/return_types/abundance.rb +20 -0
  121. data/lib/bel_parser/language/version1_0/return_types/any.rb +74 -0
  122. data/lib/bel_parser/language/version1_0/return_types/biological_process.rb +17 -0
  123. data/lib/bel_parser/language/version1_0/return_types/catalytic_activity.rb +20 -0
  124. data/lib/bel_parser/language/version1_0/return_types/chaperone_activity.rb +20 -0
  125. data/lib/bel_parser/language/version1_0/return_types/complex_abundance.rb +17 -0
  126. data/lib/bel_parser/language/version1_0/return_types/fusion.rb +17 -0
  127. data/lib/bel_parser/language/version1_0/return_types/gene_abundance.rb +17 -0
  128. data/lib/bel_parser/language/version1_0/return_types/gtp_bound_activity.rb +20 -0
  129. data/lib/bel_parser/language/version1_0/return_types/kinase_activity.rb +20 -0
  130. data/lib/bel_parser/language/version1_0/return_types/list.rb +17 -0
  131. data/lib/bel_parser/language/version1_0/return_types/micro_rna_abundance.rb +17 -0
  132. data/lib/bel_parser/language/version1_0/return_types/molecular_activity.rb +20 -0
  133. data/lib/bel_parser/language/version1_0/return_types/pathology.rb +17 -0
  134. data/lib/bel_parser/language/version1_0/return_types/peptidase_activity.rb +20 -0
  135. data/lib/bel_parser/language/version1_0/return_types/phosphatase_activity.rb +20 -0
  136. data/lib/bel_parser/language/version1_0/return_types/products.rb +17 -0
  137. data/lib/bel_parser/language/version1_0/return_types/protein_abundance.rb +17 -0
  138. data/lib/bel_parser/language/version1_0/return_types/protein_modification.rb +17 -0
  139. data/lib/bel_parser/language/version1_0/return_types/reactants.rb +17 -0
  140. data/lib/bel_parser/language/version1_0/return_types/ribosylation_activity.rb +20 -0
  141. data/lib/bel_parser/language/version1_0/return_types/rna_abundance.rb +17 -0
  142. data/lib/bel_parser/language/version1_0/return_types/substitution.rb +17 -0
  143. data/lib/bel_parser/language/version1_0/return_types/transcriptional_activity.rb +20 -0
  144. data/lib/bel_parser/language/version1_0/return_types/transport_activity.rb +20 -0
  145. data/lib/bel_parser/language/version1_0/return_types/truncation.rb +17 -0
  146. data/lib/bel_parser/language/version1_0/value_encodings/abundance.rb +21 -0
  147. data/lib/bel_parser/language/version1_0/value_encodings/any.rb +74 -0
  148. data/lib/bel_parser/language/version1_0/value_encodings/biological_process.rb +21 -0
  149. data/lib/bel_parser/language/version1_0/value_encodings/complex_abundance.rb +21 -0
  150. data/lib/bel_parser/language/version1_0/value_encodings/gene_abundance.rb +21 -0
  151. data/lib/bel_parser/language/version1_0/value_encodings/micro_rna_abundance.rb +21 -0
  152. data/lib/bel_parser/language/version1_0/value_encodings/pathology.rb +21 -0
  153. data/lib/bel_parser/language/version1_0/value_encodings/protein_abundance.rb +21 -0
  154. data/lib/bel_parser/language/version1_0/value_encodings/rna_abundance.rb +21 -0
  155. data/lib/bel_parser/language/version2_0.rb +20 -0
  156. data/lib/bel_parser/language/version2_0/functions/abundance.rb +161 -0
  157. data/lib/bel_parser/language/version2_0/functions/activity.rb +118 -0
  158. data/lib/bel_parser/language/version2_0/functions/biological_process.rb +84 -0
  159. data/lib/bel_parser/language/version2_0/functions/cell_secretion.rb +83 -0
  160. data/lib/bel_parser/language/version2_0/functions/cell_surface_expression.rb +83 -0
  161. data/lib/bel_parser/language/version2_0/functions/complex_abundance.rb +190 -0
  162. data/lib/bel_parser/language/version2_0/functions/composite_abundance.rb +81 -0
  163. data/lib/bel_parser/language/version2_0/functions/degradation.rb +83 -0
  164. data/lib/bel_parser/language/version2_0/functions/fragment.rb +116 -0
  165. data/lib/bel_parser/language/version2_0/functions/from_location.rb +85 -0
  166. data/lib/bel_parser/language/version2_0/functions/fusion.rb +203 -0
  167. data/lib/bel_parser/language/version2_0/functions/gene_abundance.rb +192 -0
  168. data/lib/bel_parser/language/version2_0/functions/list.rb +114 -0
  169. data/lib/bel_parser/language/version2_0/functions/location.rb +83 -0
  170. data/lib/bel_parser/language/version2_0/functions/micro_rna_abundance.rb +163 -0
  171. data/lib/bel_parser/language/version2_0/functions/molecular_activity.rb +86 -0
  172. data/lib/bel_parser/language/version2_0/functions/pathology.rb +83 -0
  173. data/lib/bel_parser/language/version2_0/functions/products.rb +79 -0
  174. data/lib/bel_parser/language/version2_0/functions/protein_abundance.rb +270 -0
  175. data/lib/bel_parser/language/version2_0/functions/protein_modification.rb +172 -0
  176. data/lib/bel_parser/language/version2_0/functions/reactants.rb +79 -0
  177. data/lib/bel_parser/language/version2_0/functions/reaction.rb +86 -0
  178. data/lib/bel_parser/language/version2_0/functions/rna_abundance.rb +192 -0
  179. data/lib/bel_parser/language/version2_0/functions/to_location.rb +84 -0
  180. data/lib/bel_parser/language/version2_0/functions/translocation.rb +91 -0
  181. data/lib/bel_parser/language/version2_0/functions/variant.rb +80 -0
  182. data/lib/bel_parser/language/version2_0/relationships/acts_in.rb +61 -0
  183. data/lib/bel_parser/language/version2_0/relationships/analogous.rb +45 -0
  184. data/lib/bel_parser/language/version2_0/relationships/association.rb +42 -0
  185. data/lib/bel_parser/language/version2_0/relationships/biomarker_for.rb +46 -0
  186. data/lib/bel_parser/language/version2_0/relationships/causes_no_change.rb +50 -0
  187. data/lib/bel_parser/language/version2_0/relationships/decreases.rb +63 -0
  188. data/lib/bel_parser/language/version2_0/relationships/directly_decreases.rb +56 -0
  189. data/lib/bel_parser/language/version2_0/relationships/directly_increases.rb +56 -0
  190. data/lib/bel_parser/language/version2_0/relationships/has_component.rb +62 -0
  191. data/lib/bel_parser/language/version2_0/relationships/has_components.rb +61 -0
  192. data/lib/bel_parser/language/version2_0/relationships/has_member.rb +48 -0
  193. data/lib/bel_parser/language/version2_0/relationships/has_members.rb +57 -0
  194. data/lib/bel_parser/language/version2_0/relationships/has_modification.rb +54 -0
  195. data/lib/bel_parser/language/version2_0/relationships/has_product.rb +60 -0
  196. data/lib/bel_parser/language/version2_0/relationships/has_variant.rb +54 -0
  197. data/lib/bel_parser/language/version2_0/relationships/includes.rb +59 -0
  198. data/lib/bel_parser/language/version2_0/relationships/increases.rb +63 -0
  199. data/lib/bel_parser/language/version2_0/relationships/is_a.rb +48 -0
  200. data/lib/bel_parser/language/version2_0/relationships/negative_correlation.rb +50 -0
  201. data/lib/bel_parser/language/version2_0/relationships/orthologous.rb +48 -0
  202. data/lib/bel_parser/language/version2_0/relationships/positive_correlation.rb +46 -0
  203. data/lib/bel_parser/language/version2_0/relationships/prognostic_biomarker_for.rb +48 -0
  204. data/lib/bel_parser/language/version2_0/relationships/rate_limiting_step_of.rb +53 -0
  205. data/lib/bel_parser/language/version2_0/relationships/reactant_in.rb +60 -0
  206. data/lib/bel_parser/language/version2_0/relationships/regulates.rb +51 -0
  207. data/lib/bel_parser/language/version2_0/relationships/sub_process_of.rb +55 -0
  208. data/lib/bel_parser/language/version2_0/relationships/transcribed_to.rb +53 -0
  209. data/lib/bel_parser/language/version2_0/relationships/translated_to.rb +54 -0
  210. data/lib/bel_parser/language/version2_0/relationships/translocates.rb +57 -0
  211. data/lib/bel_parser/language/version2_0/return_types/abundance.rb +20 -0
  212. data/lib/bel_parser/language/version2_0/return_types/activity.rb +20 -0
  213. data/lib/bel_parser/language/version2_0/return_types/any.rb +74 -0
  214. data/lib/bel_parser/language/version2_0/return_types/biological_process.rb +17 -0
  215. data/lib/bel_parser/language/version2_0/return_types/complex_abundance.rb +17 -0
  216. data/lib/bel_parser/language/version2_0/return_types/fragment.rb +20 -0
  217. data/lib/bel_parser/language/version2_0/return_types/from_location.rb +20 -0
  218. data/lib/bel_parser/language/version2_0/return_types/fusion.rb +17 -0
  219. data/lib/bel_parser/language/version2_0/return_types/gene_abundance.rb +17 -0
  220. data/lib/bel_parser/language/version2_0/return_types/list.rb +17 -0
  221. data/lib/bel_parser/language/version2_0/return_types/location.rb +20 -0
  222. data/lib/bel_parser/language/version2_0/return_types/micro_rna_abundance.rb +17 -0
  223. data/lib/bel_parser/language/version2_0/return_types/molecular_activity.rb +20 -0
  224. data/lib/bel_parser/language/version2_0/return_types/pathology.rb +17 -0
  225. data/lib/bel_parser/language/version2_0/return_types/products.rb +17 -0
  226. data/lib/bel_parser/language/version2_0/return_types/protein_abundance.rb +17 -0
  227. data/lib/bel_parser/language/version2_0/return_types/protein_modification.rb +17 -0
  228. data/lib/bel_parser/language/version2_0/return_types/reactants.rb +17 -0
  229. data/lib/bel_parser/language/version2_0/return_types/rna_abundance.rb +17 -0
  230. data/lib/bel_parser/language/version2_0/return_types/to_location.rb +20 -0
  231. data/lib/bel_parser/language/version2_0/return_types/variant.rb +20 -0
  232. data/lib/bel_parser/language/version2_0/value_encodings/abundance.rb +21 -0
  233. data/lib/bel_parser/language/version2_0/value_encodings/activity.rb +21 -0
  234. data/lib/bel_parser/language/version2_0/value_encodings/any.rb +74 -0
  235. data/lib/bel_parser/language/version2_0/value_encodings/biological_process.rb +21 -0
  236. data/lib/bel_parser/language/version2_0/value_encodings/complex_abundance.rb +21 -0
  237. data/lib/bel_parser/language/version2_0/value_encodings/gene_abundance.rb +21 -0
  238. data/lib/bel_parser/language/version2_0/value_encodings/location.rb +21 -0
  239. data/lib/bel_parser/language/version2_0/value_encodings/micro_rna_abundance.rb +21 -0
  240. data/lib/bel_parser/language/version2_0/value_encodings/pathology.rb +21 -0
  241. data/lib/bel_parser/language/version2_0/value_encodings/protein_abundance.rb +21 -0
  242. data/lib/bel_parser/language/version2_0/value_encodings/protein_modification.rb +21 -0
  243. data/lib/bel_parser/language/version2_0/value_encodings/rna_abundance.rb +21 -0
  244. data/lib/bel_parser/mixin/line_continuator.rb +15 -0
  245. data/lib/bel_parser/mixin/line_mapping.rb +14 -0
  246. data/lib/bel_parser/parsers/ast/node.rb +987 -0
  247. data/lib/bel_parser/parsers/ast/sexp.rb +8 -0
  248. data/lib/bel_parser/parsers/bel_script.rb +5 -0
  249. data/lib/bel_parser/parsers/bel_script/define_annotation.rb +5920 -0
  250. data/lib/bel_parser/parsers/bel_script/define_annotation.rl +141 -0
  251. data/lib/bel_parser/parsers/bel_script/define_namespace.rb +1780 -0
  252. data/lib/bel_parser/parsers/bel_script/define_namespace.rl +121 -0
  253. data/lib/bel_parser/parsers/bel_script/set.rb +5008 -0
  254. data/lib/bel_parser/parsers/bel_script/set.rl +116 -0
  255. data/lib/bel_parser/parsers/bel_script/set_document.rb +7722 -0
  256. data/lib/bel_parser/parsers/bel_script/set_document.rl +97 -0
  257. data/lib/bel_parser/parsers/bel_script/unset.rb +706 -0
  258. data/lib/bel_parser/parsers/bel_script/unset.rl +95 -0
  259. data/lib/bel_parser/parsers/common.rb +5 -0
  260. data/lib/bel_parser/parsers/common/blank_line.rb +211 -0
  261. data/lib/bel_parser/parsers/common/blank_line.rl +81 -0
  262. data/lib/bel_parser/parsers/common/comment_line.rb +245 -0
  263. data/lib/bel_parser/parsers/common/comment_line.rl +97 -0
  264. data/lib/bel_parser/parsers/common/common.rb +7 -0
  265. data/lib/bel_parser/parsers/common/common.rl +13 -0
  266. data/lib/bel_parser/parsers/common/identifier.rb +289 -0
  267. data/lib/bel_parser/parsers/common/identifier.rl +106 -0
  268. data/lib/bel_parser/parsers/common/list.rb +2388 -0
  269. data/lib/bel_parser/parsers/common/list.rl +146 -0
  270. data/lib/bel_parser/parsers/common/string.rb +271 -0
  271. data/lib/bel_parser/parsers/common/string.rl +107 -0
  272. data/lib/bel_parser/parsers/expression.rb +7 -0
  273. data/lib/bel_parser/parsers/expression/comment.rb +239 -0
  274. data/lib/bel_parser/parsers/expression/comment.rl +97 -0
  275. data/lib/bel_parser/parsers/expression/nested_statement.rb +17802 -0
  276. data/lib/bel_parser/parsers/expression/nested_statement.rl +141 -0
  277. data/lib/bel_parser/parsers/expression/observed_term.rb +7291 -0
  278. data/lib/bel_parser/parsers/expression/observed_term.rl +92 -0
  279. data/lib/bel_parser/parsers/expression/parameter.rb +1506 -0
  280. data/lib/bel_parser/parsers/expression/parameter.rl +97 -0
  281. data/lib/bel_parser/parsers/expression/relationship.rb +254 -0
  282. data/lib/bel_parser/parsers/expression/relationship.rl +98 -0
  283. data/lib/bel_parser/parsers/expression/simple_statement.rb +10475 -0
  284. data/lib/bel_parser/parsers/expression/simple_statement.rl +112 -0
  285. data/lib/bel_parser/parsers/expression/term.rb +3989 -0
  286. data/lib/bel_parser/parsers/expression/term.rl +157 -0
  287. data/lib/bel_parser/parsers/line_parser.rb +92 -0
  288. data/lib/bel_parser/parsers/mixin/buffer.rb +10 -0
  289. data/lib/bel_parser/parsers/nonblocking_io_wrapper.rb +50 -0
  290. data/lib/bel_parser/parsers/serializer.rb +205 -0
  291. data/lib/bel_parser/quoting.rb +177 -0
  292. data/lib/bel_parser/resource/concept.rb +56 -0
  293. data/lib/bel_parser/resource/concept_scheme.rb +35 -0
  294. data/lib/bel_parser/resource/dataset.rb +34 -0
  295. data/lib/bel_parser/resource/eager_reader.rb +89 -0
  296. data/lib/bel_parser/resource/eager_sparql_reader.rb +51 -0
  297. data/lib/bel_parser/resource/file_resource.rb +21 -0
  298. data/lib/bel_parser/resource/file_resource_value.rb +24 -0
  299. data/lib/bel_parser/resource/jena_tdb_reader.rb +246 -0
  300. data/lib/bel_parser/resource/lru_cache.rb +111 -0
  301. data/lib/bel_parser/resource/lru_reader.rb +34 -0
  302. data/lib/bel_parser/resource/reader.rb +18 -0
  303. data/lib/bel_parser/resource/resource_url_reader.rb +181 -0
  304. data/lib/bel_parser/resource/sparql_reader.rb +179 -0
  305. data/lib/bel_parser/resource/value.rb +31 -0
  306. data/lib/bel_parser/script.rb +8 -0
  307. data/lib/bel_parser/script/filter.rb +35 -0
  308. data/lib/bel_parser/script/first_node.rb +21 -0
  309. data/lib/bel_parser/script/keywords.rb +32 -0
  310. data/lib/bel_parser/script/nanopub_mapper.rb +182 -0
  311. data/lib/bel_parser/script/parser.rb +51 -0
  312. data/lib/bel_parser/script/state/annotation_definition.rb +62 -0
  313. data/lib/bel_parser/script/state/bel_version.rb +36 -0
  314. data/lib/bel_parser/script/state/document_property.rb +29 -0
  315. data/lib/bel_parser/script/state/namespace_definition.rb +32 -0
  316. data/lib/bel_parser/script/state/set.rb +82 -0
  317. data/lib/bel_parser/script/state/unset.rb +46 -0
  318. data/lib/bel_parser/script/state_aggregator.rb +49 -0
  319. data/lib/bel_parser/script/state_function.rb +10 -0
  320. data/lib/bel_parser/script/syntax/expression_validation.rb +46 -0
  321. data/lib/bel_parser/script/syntax/invalid_regex_pattern.rb +49 -0
  322. data/lib/bel_parser/script/syntax/undefined_annotation.rb +61 -0
  323. data/lib/bel_parser/script/syntax/undefined_annotation_value.rb +84 -0
  324. data/lib/bel_parser/script/syntax/unresolvable_namespace.rb +54 -0
  325. data/lib/bel_parser/script/syntax/unsupported_bel_version.rb +59 -0
  326. data/lib/bel_parser/script/validator.rb +65 -0
  327. data/lib/bel_parser/vendor/ast.rb +17 -0
  328. data/lib/bel_parser/vendor/ast/node.rb +254 -0
  329. data/lib/bel_parser/vendor/ast/processor.rb +12 -0
  330. data/lib/bel_parser/vendor/ast/processor/mixin.rb +282 -0
  331. data/lib/bel_parser/vendor/ast/sexp.rb +30 -0
  332. metadata +390 -0
@@ -0,0 +1,65 @@
1
+ require 'concurrent/hash'
2
+
3
+ require_relative '../parsers/common'
4
+ require_relative '../parsers/expression'
5
+ require_relative '../parsers/bel_script'
6
+
7
+ require_relative '../ast_filter'
8
+ require_relative '../ast_generator'
9
+
10
+ require_relative 'state_function'
11
+ require_relative '../language/syntax_function'
12
+
13
+ module BELParser
14
+ module Script
15
+ # Validator defines a BEL Script syntax validator. This validator
16
+ # expects to receive the BEL Script state for each node. This is
17
+ # accomplished by initializing with a {StateAggregator} that this
18
+ # will enumerate.
19
+ class Validator
20
+
21
+ def initialize(state_aggregator)
22
+ @state_aggregator = state_aggregator
23
+
24
+ Validator.require_script_path
25
+ @syntax_functions = Validator.syntax_constants(Syntax)
26
+ end
27
+
28
+ def each
29
+ if block_given?
30
+ @state_aggregator.each do |(line_number, line, ast_node, state)|
31
+ ast_node.traverse.flat_map do |node|
32
+ @syntax_functions.flat_map do |func|
33
+ func.map(node, state)
34
+ end
35
+ end.compact.each do |syntax_result|
36
+ ast_node.add_syntax_error(syntax_result)
37
+ end
38
+
39
+ yield [line_number, line, ast_node, state]
40
+ end
41
+ else
42
+ enum_for(:each)
43
+ end
44
+ end
45
+
46
+ def self.require_script_path
47
+ base_path = File.expand_path(File.dirname(__FILE__)) + File::SEPARATOR
48
+ ['state', 'syntax'].each do |set|
49
+ Dir[File.join(base_path, set, '*.rb')]
50
+ .each do |ruby_file|
51
+ ruby_file.sub!(/^#{Regexp.escape(base_path)}/, '')
52
+ require_relative ruby_file
53
+ end
54
+ end
55
+ end
56
+
57
+ def self.syntax_constants(mod)
58
+ mod.constants.collect do |symbol|
59
+ const = mod.const_get(symbol)
60
+ const if const.respond_to?(:map)
61
+ end.compact
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,17 @@
1
+ # {AST} is a library for manipulating abstract syntax trees.
2
+ #
3
+ # It embraces immutability; each AST node is inherently frozen at
4
+ # creation, and updating a child node requires recreating that node
5
+ # and its every parent, recursively.
6
+ # This is a design choice. It does create some pressure on
7
+ # garbage collector, but completely eliminates all concurrency
8
+ # and aliasing problems.
9
+ #
10
+ # See also {AST::Node}, {AST::Processor::Mixin} and {AST::Sexp} for
11
+ # additional recommendations and design patterns.
12
+ #
13
+ module AST
14
+ require_relative 'ast/node'
15
+ require_relative 'ast/processor'
16
+ require_relative 'ast/sexp'
17
+ end
@@ -0,0 +1,254 @@
1
+ module AST
2
+ # Node is an immutable class, instances of which represent abstract
3
+ # syntax tree nodes. It combines semantic information (i.e. anything
4
+ # that affects the algorithmic properties of a program) with
5
+ # meta-information (line numbers or compiler intermediates).
6
+ #
7
+ # Notes on inheritance
8
+ # ====================
9
+ #
10
+ # The distinction between semantics and metadata is important. Complete
11
+ # semantic information should be contained within just the {#type} and
12
+ # {#children} of a Node instance; in other words, if an AST was to be
13
+ # stripped of all meta-information, it should remain a valid AST which
14
+ # could be successfully processed to yield a result with the same
15
+ # algorithmic properties.
16
+ #
17
+ # Thus, Node should never be inherited in order to define methods which
18
+ # affect or return semantic information, such as getters for `class_name`,
19
+ # `superclass` and `body` in the case of a hypothetical `ClassNode`. The
20
+ # correct solution is to use a generic Node with a {#type} of `:class`
21
+ # and three children. See also {Processor} for tips on working with such
22
+ # ASTs.
23
+ #
24
+ # On the other hand, Node can and should be inherited to define
25
+ # application-specific metadata (see also {#initialize}) or customize the
26
+ # printing format. It is expected that an application would have one or two
27
+ # such classes and use them across the entire codebase.
28
+ #
29
+ # The rationale for this pattern is extensibility and maintainability.
30
+ # Unlike static ones, dynamic languages do not require the presence of a
31
+ # predefined, rigid structure, nor does it improve dispatch efficiency,
32
+ # and while such a structure can certainly be defined, it does not add
33
+ # any value but incurs a maintaining cost.
34
+ # For example, extending the AST even with a transformation-local
35
+ # temporary node type requires making globally visible changes to
36
+ # the codebase.
37
+ #
38
+ class Node
39
+ # Returns the type of this node.
40
+ # @return [Symbol]
41
+ attr_reader :type
42
+
43
+ # Returns the children of this node.
44
+ # The returned value is frozen.
45
+ # @return [Array]
46
+ attr_reader :children
47
+
48
+ # Returns the precomputed hash value for this node
49
+ # @return [Fixnum]
50
+ attr_reader :hash
51
+
52
+ # Constructs a new instance of Node.
53
+ #
54
+ # The arguments `type` and `children` are converted with `to_sym` and
55
+ # `to_a` respectively. Additionally, the result of converting `children`
56
+ # is frozen. While mutating the arguments is generally considered harmful,
57
+ # the most common case is to pass an array literal to the constructor. If
58
+ # your code does not expect the argument to be frozen, use `#dup`.
59
+ #
60
+ # The `properties` hash is passed to {#assign_properties}.
61
+ def initialize(type, children=[], properties={})
62
+ @type, @children = type.to_sym, children.to_a.freeze
63
+
64
+ assign_properties(properties)
65
+
66
+ @hash = [@type, @children, self.class].hash
67
+
68
+ freeze
69
+ end
70
+
71
+ # Test if other object is equal to
72
+ # @param [Object] other
73
+ # @return [Boolean]
74
+ def eql?(other)
75
+ self.class.eql?(other.class) &&
76
+ @type.eql?(other.type) &&
77
+ @children.eql?(other.children)
78
+ end
79
+
80
+ # By default, each entry in the `properties` hash is assigned to
81
+ # an instance variable in this instance of Node. A subclass should define
82
+ # attribute readers for such variables. The values passed in the hash
83
+ # are not frozen or whitelisted; such behavior can also be implemented
84
+ # by subclassing Node and overriding this method.
85
+ #
86
+ # @return [nil]
87
+ def assign_properties(properties)
88
+ properties.each do |name, value|
89
+ instance_variable_set :"@#{name}", value
90
+ end
91
+
92
+ nil
93
+ end
94
+ protected :assign_properties
95
+
96
+ alias :original_dup :dup
97
+ private :original_dup
98
+
99
+ # Nodes are already frozen, so there is no harm in returning the
100
+ # current node as opposed to initializing from scratch and freezing
101
+ # another one.
102
+ #
103
+ # @return self
104
+ def dup
105
+ self
106
+ end
107
+ alias :clone :dup
108
+
109
+ # Returns a new instance of Node where non-nil arguments replace the
110
+ # corresponding fields of `self`.
111
+ #
112
+ # For example, `Node.new(:foo, [ 1, 2 ]).updated(:bar)` would yield
113
+ # `(bar 1 2)`, and `Node.new(:foo, [ 1, 2 ]).updated(nil, [])` would
114
+ # yield `(foo)`.
115
+ #
116
+ # If the resulting node would be identical to `self`, does nothing.
117
+ #
118
+ # @param [Symbol, nil] type
119
+ # @param [Array, nil] children
120
+ # @param [Hash, nil] properties
121
+ # @return [AST::Node]
122
+ def updated(type=nil, children=nil, properties=nil)
123
+ new_type = type || @type
124
+ new_children = children || @children
125
+ new_properties = properties || {}
126
+
127
+ if @type == new_type &&
128
+ @children == new_children &&
129
+ properties.nil?
130
+ self
131
+ else
132
+ # Maybe change call?
133
+ original_dup.send :initialize, new_type, new_children, new_properties
134
+ end
135
+ end
136
+
137
+ # Compares `self` to `other`, possibly converting with `to_ast`. Only
138
+ # `type` and `children` are compared; metadata is deliberately ignored.
139
+ #
140
+ # @return [Boolean]
141
+ def ==(other)
142
+ if equal?(other)
143
+ true
144
+ elsif other.respond_to? :to_ast
145
+ other = other.to_ast
146
+ other.type == self.type &&
147
+ other.children == self.children
148
+ else
149
+ false
150
+ end
151
+ end
152
+
153
+ # Concatenates `array` with `children` and returns the resulting node.
154
+ #
155
+ # @return [AST::Node]
156
+ def concat(array)
157
+ updated(nil, @children + array.to_a)
158
+ end
159
+
160
+ alias + concat
161
+
162
+ # Appends `element` to `children` and returns the resulting node.
163
+ #
164
+ # @return [AST::Node]
165
+ def append(element)
166
+ updated(nil, @children + [element])
167
+ end
168
+
169
+ alias << append
170
+
171
+ # Returns {#children}. This is very useful in order to decompose nodes
172
+ # concisely. For example:
173
+ #
174
+ # node = s(:gasgn, :$foo, s(:integer, 1))
175
+ # s
176
+ # var_name, value = *node
177
+ # p var_name # => :$foo
178
+ # p value # => (integer 1)
179
+ #
180
+ # @return [Array]
181
+ def to_a
182
+ children
183
+ end
184
+
185
+ # Converts `self` to a pretty-printed s-expression.
186
+ #
187
+ # @param [Integer] indent Base indentation level.
188
+ # @return [String]
189
+ def to_sexp(indent=0)
190
+ indented = " " * indent
191
+ sexp = "#{indented}(#{fancy_type}"
192
+
193
+ first_node_child = children.index do |child|
194
+ child.is_a?(Node) || child.is_a?(Array)
195
+ end || children.count
196
+
197
+ children.each_with_index do |child, idx|
198
+ if child.is_a?(Node) && idx >= first_node_child
199
+ sexp << "\n#{child.to_sexp(indent + 1)}"
200
+ else
201
+ sexp << " #{child.inspect}"
202
+ end
203
+ end
204
+
205
+ sexp << ")"
206
+
207
+ sexp
208
+ end
209
+
210
+ alias to_s to_sexp
211
+
212
+ # Converts `self` to a s-expression ruby string.
213
+ # The code return will recreate the node, using the sexp module s()
214
+ #
215
+ # @param [Integer] indent Base indentation level.
216
+ # @return [String]
217
+ def inspect(indent=0)
218
+ indented = " " * indent
219
+ sexp = "#{indented}s(:#{@type}"
220
+
221
+ first_node_child = children.index do |child|
222
+ child.is_a?(Node) || child.is_a?(Array)
223
+ end || children.count
224
+
225
+ children.each_with_index do |child, idx|
226
+ if child.is_a?(Node) && idx >= first_node_child
227
+ sexp << ",\n#{child.inspect(indent + 1)}"
228
+ else
229
+ sexp << ", #{child.inspect}"
230
+ end
231
+ end
232
+
233
+ sexp << ")"
234
+
235
+ sexp
236
+ end
237
+
238
+ # @return [AST::Node] self
239
+ def to_ast
240
+ self
241
+ end
242
+
243
+ protected
244
+
245
+ # Returns `@type` with all underscores replaced by dashes. This allows
246
+ # to write symbol literals without quotes in Ruby sources and yet have
247
+ # nicely looking s-expressions.
248
+ #
249
+ # @return [String]
250
+ def fancy_type
251
+ @type.to_s.gsub('_', '-')
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,12 @@
1
+ module AST
2
+ # This class includes {AST::Processor::Mixin}; however, it is
3
+ # deprecated, since the module defines all of the behaviors that
4
+ # the processor includes. Any new libraries should use
5
+ # {AST::Processor::Mixin} instead of subclassing this.
6
+ #
7
+ # @deprecated Use {AST::Processor::Mixin} instead.
8
+ class Processor
9
+ require_relative 'processor/mixin'
10
+ include Mixin
11
+ end
12
+ end
@@ -0,0 +1,282 @@
1
+ module AST
2
+ class Processor
3
+ # The processor module is a module which helps transforming one
4
+ # AST into another. In a nutshell, the {#process} method accepts
5
+ # a {Node} and dispatches it to a handler corresponding to its
6
+ # type, and returns a (possibly) updated variant of the node.
7
+ #
8
+ # The processor module has a set of associated design patterns.
9
+ # They are best explained with a concrete example. Let's define a
10
+ # simple arithmetic language and an AST format for it:
11
+ #
12
+ # Terminals (AST nodes which do not have other AST nodes inside):
13
+ #
14
+ # * `(integer <int-literal>)`,
15
+ #
16
+ # Nonterminals (AST nodes with other nodes as children):
17
+ #
18
+ # * `(add <node> <node>)`,
19
+ # * `(multiply <node> <node>)`,
20
+ # * `(divide <node> <node>)`,
21
+ # * `(negate <node>)`,
22
+ # * `(store <node> <string-literal>)`: stores value of `<node>`
23
+ # into a variable named `<string-literal>`,
24
+ # * `(load <string-literal>)`: loads value of a variable named
25
+ # `<string-literal>`,
26
+ # * `(each <node> ...): computes each of the `<node>`s and
27
+ # prints the result.
28
+ #
29
+ # All AST nodes have the same Ruby class, and therefore they don't
30
+ # know how to traverse themselves. (A solution which dynamically
31
+ # checks the type of children is possible, but is slow and
32
+ # error-prone.) So, a class including the module which knows how
33
+ # to traverse the entire tree should be defined. Such classes
34
+ # have a handler for each nonterminal node which recursively
35
+ # processes children nodes:
36
+ #
37
+ # require 'ast'
38
+ #
39
+ # class ArithmeticsProcessor
40
+ # include AST::Processor::Module
41
+ # # This method traverses any binary operators such as (add)
42
+ # # or (multiply).
43
+ # def process_binary_op(node)
44
+ # # Children aren't decomposed automatically; it is
45
+ # # suggested to use Ruby multiple assignment expansion,
46
+ # # as it is very convenient here.
47
+ # left_expr, right_expr = *node
48
+ #
49
+ # # AST::Node#updated won't change node type if nil is
50
+ # # passed as a first argument, which allows to reuse the
51
+ # # same handler for multiple node types using `alias'
52
+ # # (below).
53
+ # node.updated(nil, [
54
+ # process(left_expr),
55
+ # process(right_expr)
56
+ # ])
57
+ # end
58
+ # alias_method :on_add, :process_binary_op
59
+ # alias_method :on_multiply, :process_binary_op
60
+ # alias_method :on_divide, :process_binary_op
61
+ #
62
+ # def on_negate(node)
63
+ # # It is also possible to use #process_all for more
64
+ # # compact code if every child is a Node.
65
+ # node.updated(nil, process_all(node))
66
+ # end
67
+ #
68
+ # def on_store(node)
69
+ # expr, variable_name = *node
70
+ #
71
+ # # Note that variable_name is not a Node and thus isn't
72
+ # # passed to #process.
73
+ # node.updated(nil, [
74
+ # process(expr),
75
+ # variable_name
76
+ # ])
77
+ # end
78
+ #
79
+ # # (load) is effectively a terminal node, and so it does
80
+ # # not need an explicit handler, as the following is the
81
+ # # default behavior. Essentially, for any nodes that don't
82
+ # # have a defined handler, the node remains unchanged.
83
+ # def on_load(node)
84
+ # nil
85
+ # end
86
+ #
87
+ # def on_each(node)
88
+ # node.updated(nil, process_all(node))
89
+ # end
90
+ # end
91
+ #
92
+ # Let's test our ArithmeticsProcessor:
93
+ #
94
+ # include AST::Sexp
95
+ # expr = s(:add, s(:integer, 2), s(:integer, 2))
96
+ #
97
+ # p ArithmeticsProcessor.new.process(expr) == expr # => true
98
+ #
99
+ # As expected, it does not change anything at all. This isn't
100
+ # actually very useful, so let's now define a Calculator, which
101
+ # will compute the expression values:
102
+ #
103
+ # # This Processor folds nonterminal nodes and returns an
104
+ # # (integer) terminal node.
105
+ # class ArithmeticsCalculator < ArithmeticsProcessor
106
+ # def compute_op(node)
107
+ # # First, node children are processed and then unpacked
108
+ # # to local variables.
109
+ # nodes = process_all(node)
110
+ #
111
+ # if nodes.all? { |node| node.type == :integer }
112
+ # # If each of those nodes represents a literal, we can
113
+ # # fold this node!
114
+ # values = nodes.map { |node| node.children.first }
115
+ # AST::Node.new(:integer, [
116
+ # yield(values)
117
+ # ])
118
+ # else
119
+ # # Otherwise, we can just leave the current node in the
120
+ # # tree and only update it with processed children
121
+ # # nodes, which can be partially folded.
122
+ # node.updated(nil, nodes)
123
+ # end
124
+ # end
125
+ #
126
+ # def on_add(node)
127
+ # compute_op(node) { |left, right| left + right }
128
+ # end
129
+ #
130
+ # def on_multiply(node)
131
+ # compute_op(node) { |left, right| left * right }
132
+ # end
133
+ # end
134
+ #
135
+ # Let's check:
136
+ #
137
+ # p ArithmeticsCalculator.new.process(expr) # => (integer 4)
138
+ #
139
+ # Excellent, the calculator works! Now, a careful reader could
140
+ # notice that the ArithmeticsCalculator does not know how to
141
+ # divide numbers. What if we pass an expression with division to
142
+ # it?
143
+ #
144
+ # expr_with_division = \
145
+ # s(:add,
146
+ # s(:integer, 1),
147
+ # s(:divide,
148
+ # s(:add, s(:integer, 8), s(:integer, 4)),
149
+ # s(:integer, 3))) # 1 + (8 + 4) / 3
150
+ #
151
+ # folded_expr_with_division = ArithmeticsCalculator.new.process(expr_with_division)
152
+ # p folded_expr_with_division
153
+ # # => (add
154
+ # # (integer 1)
155
+ # # (divide
156
+ # # (integer 12)
157
+ # # (integer 3)))
158
+ #
159
+ # As you can see, the expression was folded _partially_: the inner
160
+ # `(add)` node which could be computed was folded to
161
+ # `(integer 12)`, the `(divide)` node is left as-is because there
162
+ # is no computing handler for it, and the root `(add)` node was
163
+ # also left as it is because some of its children were not
164
+ # literals.
165
+ #
166
+ # Note that this partial folding is only possible because the
167
+ # _data_ format, i.e. the format in which the computed values of
168
+ # the nodes are represented, is the same as the AST itself. # # Let's extend our ArithmeticsCalculator class further. # # class ArithmeticsCalculator # def on_divide(node) # compute_op(node) { |left, right| left / right }
169
+ # end
170
+ #
171
+ # def on_negate(node)
172
+ # # Note how #compute_op works regardless of the operator
173
+ # # arity.
174
+ # compute_op(node) { |value| -value }
175
+ # end
176
+ # end
177
+ #
178
+ # Now, let's apply our renewed ArithmeticsCalculator to a partial
179
+ # result of previous evaluation:
180
+ #
181
+ # p ArithmeticsCalculator.new.process(expr_with_division) # => (integer 5)
182
+ #
183
+ # Five! Excellent. This is also pretty much how CRuby 1.8 executed
184
+ # its programs.
185
+ #
186
+ # Now, let's do some automated bug searching. Division by zero is
187
+ # an error, right? So if we could detect that someone has divided
188
+ # by zero before the program is even run, that could save some
189
+ # debugging time.
190
+ #
191
+ # class DivisionByZeroVerifier < ArithmeticsProcessor
192
+ # class VerificationFailure < Exception; end
193
+ #
194
+ # def on_divide(node)
195
+ # # You need to process the children to handle nested divisions
196
+ # # such as:
197
+ # # (divide
198
+ # # (integer 1)
199
+ # # (divide (integer 1) (integer 0))
200
+ # left, right = process_all(node)
201
+ #
202
+ # if right.type == :integer &&
203
+ # right.children.first == 0
204
+ # raise VerificationFailure, "Ouch! This code divides by zero."
205
+ # end
206
+ # end
207
+ #
208
+ # def divides_by_zero?(ast)
209
+ # process(ast)
210
+ # false
211
+ # rescue VerificationFailure
212
+ # true
213
+ # end
214
+ # end
215
+ #
216
+ # nice_expr = \
217
+ # s(:divide,
218
+ # s(:add, s(:integer, 10), s(:integer, 2)),
219
+ # s(:integer, 4))
220
+ #
221
+ # p DivisionByZeroVerifier.new.divides_by_zero?(nice_expr)
222
+ # # => false. Good.
223
+ #
224
+ # bad_expr = \
225
+ # s(:add, s(:integer, 10),
226
+ # s(:divide, s(:integer, 1), s(:integer, 0)))
227
+ #
228
+ # p DivisionByZeroVerifier.new.divides_by_zero?(bad_expr)
229
+ # # => true. WHOOPS. DO NOT RUN THIS.
230
+ #
231
+ # Of course, this won't detect more complex cases... unless you
232
+ # use some partial evaluation before! The possibilites are
233
+ # endless. Have fun.
234
+ module Mixin
235
+ # Dispatches `node`. If a node has type `:foo`, then a handler
236
+ # named `on_foo` is invoked with one argument, the `node`; if
237
+ # there isn't such a handler, {#handler_missing} is invoked
238
+ # with the same argument.
239
+ #
240
+ # If the handler returns `nil`, `node` is returned; otherwise,
241
+ # the return value of the handler is passed along.
242
+ #
243
+ # @param [AST::Node, nil] node
244
+ # @return [AST::Node, nil]
245
+ def process(node)
246
+ return if node.nil?
247
+
248
+ node = node.to_ast
249
+
250
+ # Invoke a specific handler
251
+ on_handler = :"on_#{node.type}"
252
+ if respond_to? on_handler
253
+ new_node = send on_handler, node
254
+ else
255
+ new_node = handler_missing(node)
256
+ end
257
+
258
+ node = new_node if new_node
259
+
260
+ node
261
+ end
262
+
263
+ # {#process}es each node from `nodes` and returns an array of
264
+ # results.
265
+ #
266
+ # @param [Array<AST::Node>] nodes
267
+ # @return [Array<AST::Node>]
268
+ def process_all(nodes)
269
+ nodes.to_a.map do |node|
270
+ process node
271
+ end
272
+ end
273
+
274
+ # Default handler. Does nothing.
275
+ #
276
+ # @param [AST::Node] node
277
+ # @return [AST::Node, nil]
278
+ def handler_missing(node)
279
+ end
280
+ end
281
+ end
282
+ end