rip-parser 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +15 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.md +9 -0
  8. data/README.md +13 -0
  9. data/Rakefile +1 -0
  10. data/bin/console +8 -0
  11. data/bin/setup +8 -0
  12. data/legacy/normalizer.rb +279 -0
  13. data/legacy/parser_spec.rb +999 -0
  14. data/legacy/rules.rb +250 -0
  15. data/legacy/rules_spec.rb +1700 -0
  16. data/rip-parser.gemspec +20 -0
  17. data/source/rip/parser/about.rb +9 -0
  18. data/source/rip/parser/error.rb +36 -0
  19. data/source/rip/parser/grammar.rb +23 -0
  20. data/source/rip/parser/keywords.rb +84 -0
  21. data/source/rip/parser/location.rb +47 -0
  22. data/source/rip/parser/node.rb +115 -0
  23. data/source/rip/parser/rules/assignment.rb +23 -0
  24. data/source/rip/parser/rules/binary_condition.rb +24 -0
  25. data/source/rip/parser/rules/character.rb +40 -0
  26. data/source/rip/parser/rules/class.rb +60 -0
  27. data/source/rip/parser/rules/common.rb +47 -0
  28. data/source/rip/parser/rules/date_time.rb +31 -0
  29. data/source/rip/parser/rules/expression.rb +122 -0
  30. data/source/rip/parser/rules/import.rb +23 -0
  31. data/source/rip/parser/rules/invocation.rb +15 -0
  32. data/source/rip/parser/rules/invocation_index.rb +15 -0
  33. data/source/rip/parser/rules/keyword.rb +12 -0
  34. data/source/rip/parser/rules/lambda.rb +45 -0
  35. data/source/rip/parser/rules/list.rb +18 -0
  36. data/source/rip/parser/rules/map.rb +15 -0
  37. data/source/rip/parser/rules/module.rb +29 -0
  38. data/source/rip/parser/rules/number.rb +21 -0
  39. data/source/rip/parser/rules/pair.rb +13 -0
  40. data/source/rip/parser/rules/property.rb +33 -0
  41. data/source/rip/parser/rules/range.rb +15 -0
  42. data/source/rip/parser/rules/reference.rb +16 -0
  43. data/source/rip/parser/rules/string.rb +41 -0
  44. data/source/rip/parser/rules/unit.rb +17 -0
  45. data/source/rip/parser/rules.rb +7 -0
  46. data/source/rip/parser/utilities/normalizer.rb +638 -0
  47. data/source/rip/parser.rb +24 -0
  48. data/source/rip-parser.rb +1 -0
  49. data/spec/fixtures/syntax_sample.rip +96 -0
  50. data/spec/spec_helper.rb +20 -0
  51. data/spec/support/helpers.rb +57 -0
  52. data/spec/support/parslet.rb +1 -0
  53. data/spec/support/shared_examples.rb +9 -0
  54. data/spec/unit/rip/parser/grammar_spec.rb +8 -0
  55. data/spec/unit/rip/parser/location_spec.rb +89 -0
  56. data/spec/unit/rip/parser/node_spec.rb +157 -0
  57. data/spec/unit/rip/parser/rules/assignment_spec.rb +59 -0
  58. data/spec/unit/rip/parser/rules/binary_condition_spec.rb +41 -0
  59. data/spec/unit/rip/parser/rules/character_spec.rb +29 -0
  60. data/spec/unit/rip/parser/rules/class_spec.rb +181 -0
  61. data/spec/unit/rip/parser/rules/common_spec.rb +88 -0
  62. data/spec/unit/rip/parser/rules/date_time_spec.rb +61 -0
  63. data/spec/unit/rip/parser/rules/expression_spec.rb +95 -0
  64. data/spec/unit/rip/parser/rules/import_spec.rb +64 -0
  65. data/spec/unit/rip/parser/rules/invocation_index_spec.rb +46 -0
  66. data/spec/unit/rip/parser/rules/invocation_spec.rb +46 -0
  67. data/spec/unit/rip/parser/rules/keyword_spec.rb +17 -0
  68. data/spec/unit/rip/parser/rules/lambda_spec.rb +174 -0
  69. data/spec/unit/rip/parser/rules/list_spec.rb +45 -0
  70. data/spec/unit/rip/parser/rules/map_spec.rb +36 -0
  71. data/spec/unit/rip/parser/rules/module_spec.rb +63 -0
  72. data/spec/unit/rip/parser/rules/number_spec.rb +40 -0
  73. data/spec/unit/rip/parser/rules/pair_spec.rb +25 -0
  74. data/spec/unit/rip/parser/rules/property_spec.rb +27 -0
  75. data/spec/unit/rip/parser/rules/range_spec.rb +37 -0
  76. data/spec/unit/rip/parser/rules/reference_spec.rb +43 -0
  77. data/spec/unit/rip/parser/rules/string_spec.rb +166 -0
  78. data/spec/unit/rip/parser/rules/unit_spec.rb +17 -0
  79. data/spec/unit/rip/parser_spec.rb +106 -0
  80. metadata +192 -0
@@ -0,0 +1,23 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './keyword'
5
+ require_relative './string'
6
+
7
+ module Rip::Parser::Rules
8
+ module Import
9
+ include ::Parslet
10
+
11
+ include Rip::Parser::Rules::Common
12
+ include Rip::Parser::Rules::Keyword
13
+ include Rip::Parser::Rules::String
14
+
15
+ rule(:import) { keyword(:import) >> (import_bare | import_parens) }
16
+
17
+ rule(:import_bare) { spaces >> module_name }
18
+
19
+ rule(:import_parens) { parenthesis_open >> module_name >> spaces? >> parenthesis_close }
20
+
21
+ rule(:module_name) { spaces? >> (string_symbol | string_double).as(:module_name) }
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './list'
5
+
6
+ module Rip::Parser::Rules
7
+ module Invocation
8
+ include ::Parslet
9
+
10
+ include Rip::Parser::Rules::Common
11
+ include Rip::Parser::Rules::List
12
+
13
+ rule(:invocation) { parenthesis_open.as(:location) >> csv(expression).as(:arguments) >> parenthesis_close }
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './list'
5
+
6
+ module Rip::Parser::Rules
7
+ module InvocationIndex
8
+ include ::Parslet
9
+
10
+ include Rip::Parser::Rules::Common
11
+ include Rip::Parser::Rules::List
12
+
13
+ rule(:invocation_index) { bracket_open.as(:location) >> csv(expression).as(:index_arguments) >> bracket_close }
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ require 'parslet'
2
+
3
+ module Rip::Parser::Rules
4
+ module Keyword
5
+ include ::Parslet
6
+
7
+ def keyword(word)
8
+ keyword = Rip::Parser::Keyword[word]
9
+ str(keyword.source_text).as(keyword.name)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,45 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './keyword'
5
+ require_relative './list'
6
+ require_relative './reference'
7
+
8
+ module Rip::Parser::Rules
9
+ module Lambda
10
+ include ::Parslet
11
+
12
+ include Rip::Parser::Rules::Common
13
+ include Rip::Parser::Rules::Keyword
14
+ include Rip::Parser::Rules::List
15
+ include Rip::Parser::Rules::Reference
16
+
17
+ rule(:lambda_block) do
18
+ keyword(:fat_rocket) >> whitespaces? >> brace_open >> whitespaces? >>
19
+ (whitespaces? >> overload_block >> whitespaces?).repeat(1).as(:overloads) >>
20
+ whitespaces? >> brace_close
21
+ end
22
+
23
+ rule(:overload_block) do
24
+ parameters.maybe >> whitespaces? >>
25
+ keyword(:dash_rocket) >> whitespaces? >> block_body
26
+ end
27
+
28
+ rule(:parameters) do
29
+ parenthesis_open >> whitespaces? >> parameters_list.as(:parameters) >> whitespaces? >> parenthesis_close
30
+ end
31
+
32
+ rule(:parameters_list) { csv(optional_parameter | required_parameter) }
33
+
34
+ rule(:required_parameter) { word.as(:parameter) >> parameter_type_argument.maybe }
35
+ rule(:optional_parameter) { required_parameter >> spaces >> equals >> whitespaces >> expression.as(:default) }
36
+
37
+ rule(:parameter_type_argument) { angled_open >> spaces? >> reference.as(:type_argument) >> spaces? >> angled_close }
38
+
39
+ def block_body(label = :body)
40
+ brace_open >> whitespaces? >>
41
+ nested_lines.as(label) >>
42
+ whitespaces? >> brace_close
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,18 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+
5
+ module Rip::Parser::Rules
6
+ module List
7
+ include ::Parslet
8
+
9
+ include Rip::Parser::Rules::Common
10
+
11
+ rule(:list) { bracket_open.as(:location) >> whitespaces? >> csv(expression).as(:list) >> whitespaces? >> bracket_close }
12
+
13
+ def csv(value)
14
+ _value = whitespaces? >> value >> whitespaces?
15
+ (_value >> (comma >> _value).repeat).repeat(0, 1)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './list'
5
+
6
+ module Rip::Parser::Rules
7
+ module Map
8
+ include ::Parslet
9
+
10
+ include Rip::Parser::Rules::Common
11
+ include Rip::Parser::Rules::List
12
+
13
+ rule(:map) { brace_open.as(:location) >> whitespaces? >> csv(expression).as(:map) >> whitespaces? >> brace_close }
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './assignment'
5
+ require_relative './expression'
6
+
7
+ module Rip::Parser::Rules
8
+ module Module
9
+ include ::Parslet
10
+
11
+ include Rip::Parser::Rules::Common
12
+ include Rip::Parser::Rules::Assignment
13
+ include Rip::Parser::Rules::Expression
14
+
15
+ rule(:module) { root_lines.as(:module) }
16
+
17
+ rule(:root_lines) do
18
+ whitespaces? >> (reference_assignment | expression) >> spaces? >> (
19
+ (semicolon | line_break) >> whitespaces? >> root_lines
20
+ ).repeat >> whitespaces?
21
+ end
22
+
23
+ rule(:nested_lines) do
24
+ whitespaces? >> (property_assignment | reference_assignment | expression) >> spaces? >> (
25
+ (semicolon | line_break) >> whitespaces? >> nested_lines
26
+ ).repeat >> whitespaces?
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+
5
+ module Rip::Parser::Rules
6
+ module Number
7
+ include ::Parslet
8
+
9
+ include Rip::Parser::Rules::Common
10
+
11
+ rule(:number) { sign.maybe >> (decimal | integer) }
12
+
13
+ rule(:sign) { match['+-'].as(:sign) }
14
+
15
+ rule(:decimal) { integer >> dot >> digits.as(:decimal) }
16
+ rule(:integer) { digits.as(:integer) }
17
+
18
+ rule(:digit) { match['0-9'] }
19
+ rule(:digits) { digit.repeat(1) >> (underscore.maybe >> digit.repeat(1)).repeat }
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+
5
+ module Rip::Parser::Rules
6
+ module Pair
7
+ include ::Parslet
8
+
9
+ include Rip::Parser::Rules::Common
10
+
11
+ rule(:pair_value) { spaces? >> colon.as(:location) >> spaces? >> expression.as(:value) }
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './reference'
5
+
6
+ module Rip::Parser::Rules
7
+ module Property
8
+ SPECIAL_NAMES = [
9
+ '/',
10
+ '/%',
11
+ '<',
12
+ '<<',
13
+ '<=',
14
+ '<=>',
15
+ '>',
16
+ '>>',
17
+ '>=',
18
+ '[]',
19
+ '|>'
20
+ ]
21
+
22
+ include ::Parslet
23
+
24
+ include Rip::Parser::Rules::Common
25
+ include Rip::Parser::Rules::Reference
26
+
27
+ rule(:property) { whitespaces? >> dot.as(:location) >> whitespaces? >> property_name.as(:property_name) }
28
+
29
+ rule(:property_name) { property_name_special | word }
30
+
31
+ rule(:property_name_special) { SPECIAL_NAMES.map(&method(:str)).inject(&:|) }
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './character'
5
+
6
+ module Rip::Parser::Rules
7
+ module Range
8
+ include ::Parslet
9
+
10
+ include Rip::Parser::Rules::Common
11
+ include Rip::Parser::Rules::Reference
12
+
13
+ rule(:range_end) { spaces? >> (dot >> dot).as(:location) >> spaces? >> expression.as(:end) }
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'parslet'
2
+
3
+ require_relative './number'
4
+
5
+ module Rip::Parser::Rules
6
+ module Reference
7
+ include ::Parslet
8
+
9
+ include Rip::Parser::Rules::Number
10
+
11
+ rule(:reference) { word.as(:reference) }
12
+
13
+ rule(:word) { word_legal >> (word_legal | digit).repeat }
14
+ rule(:word_legal) { match['^\d\s\`\'",.:;#\/\\()<>\[\]{}'] }
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './character'
5
+
6
+ module Rip::Parser::Rules
7
+ module String
8
+ include ::Parslet
9
+
10
+ include Rip::Parser::Rules::Common
11
+ include Rip::Parser::Rules::Character
12
+
13
+ rule(:string) { string_symbol | string_double | heredoc }
14
+
15
+ rule(:string_symbol) { colon.as(:location) >> character_legal.as(:character).repeat(1).as(:string) }
16
+
17
+ rule(:string_double) { string_parser(quote_double, escape_sequence, :string) }
18
+ rule(:regular_expression) { string_parser(slash_forward, escape_sequence, :regular_expression) }
19
+
20
+ rule(:quote_single) { str('\'') }
21
+ rule(:quote_double) { str('"') }
22
+
23
+ rule(:heredoc) { heredoc_start >> heredoc_content.as(:string) >> heredoc_end }
24
+
25
+ rule(:heredoc_start) { angled_open.repeat(2, 2).as(:location) >> match['A-Z_'].repeat(1).capture(:heredoc_label).as(:label) >> line_break }
26
+
27
+ rule(:heredoc_content) { (heredoc_end.absent? >> (interpolation | escape_sequence | any.as(:character))).repeat }
28
+
29
+ rule(:heredoc_end) do
30
+ dynamic do |source, context|
31
+ spaces? >> str(context.captures[:heredoc_label]) >> (line_break | eof)
32
+ end
33
+ end
34
+
35
+ rule(:interpolation) { (pound >> brace_open).as(:location) >> whitespaces? >> expression.as(:interpolation) >> whitespaces? >> brace_close }
36
+
37
+ def string_parser(delimiter, inner_special, label)
38
+ delimiter.as(:location) >> (delimiter.absent? >> (interpolation | inner_special | any.as(:character))).repeat.as(label) >> delimiter
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './number'
5
+ require_relative './reference'
6
+
7
+ module Rip::Parser::Rules
8
+ module Unit
9
+ include ::Parslet
10
+
11
+ include Rip::Parser::Rules::Common
12
+ include Rip::Parser::Rules::Number
13
+ include Rip::Parser::Rules::Reference
14
+
15
+ rule(:unit) { number.as(:magnitude) >> word.as(:label) }
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module Rip::Parser
2
+ module Rules
3
+ end
4
+ end
5
+
6
+ pattern = Pathname.new(__dir__).join('rules/*.rb')
7
+ Pathname.glob(pattern).each(&method(:require))