rip-parser 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,181 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::Class do
4
+ class ClassParser
5
+ include Rip::Parser::Rules::Class
6
+ include Rip::Parser::Rules::Module
7
+ end
8
+
9
+ let(:parser) { ClassParser.new }
10
+
11
+ describe '#class_block' do
12
+ subject { parser.class_block }
13
+
14
+ it do
15
+ should parse('class {}').as(
16
+ class: 'class',
17
+ body: nil
18
+ )
19
+ end
20
+
21
+ it do
22
+ should parse('class (Collection) { self.foo = 42 }').as(
23
+ class: 'class',
24
+ ancestors: [
25
+ { reference: 'Collection' }
26
+ ],
27
+ body: {
28
+ property: {
29
+ class_self: 'self',
30
+ location: '.',
31
+ property_name: 'foo'
32
+ },
33
+ location: '=',
34
+ property_value: { expression_chain: { integer: '42' } }
35
+ }
36
+ )
37
+ end
38
+
39
+ it do
40
+ should parse('class () { foo = 42; @.initialize = ~> { @.bar = `F } }').as(
41
+ class: 'class',
42
+ ancestors: [],
43
+ body: [
44
+ {
45
+ property: {
46
+ property_name: 'foo'
47
+ },
48
+ location: '=',
49
+ property_value: { expression_chain: { integer: '42' } }
50
+ },
51
+ {
52
+ property: {
53
+ class_prototype: '@',
54
+ location: '.',
55
+ property_name: 'initialize'
56
+ },
57
+ location: '=',
58
+ property_value: {
59
+ swerve_rocket: '~>',
60
+ body: {
61
+ lhs: {
62
+ object: { reference: '@' },
63
+ location: '.',
64
+ property_name: 'bar'
65
+ },
66
+ location: '=',
67
+ rhs: { expression_chain: { location: '`', character: 'F' } }
68
+ }
69
+ }
70
+ }
71
+ ]
72
+ )
73
+ end
74
+ end
75
+
76
+ describe '#class_ancestors' do
77
+ subject { parser.class_ancestors }
78
+
79
+ it { should parse('()').as(ancestors: []) }
80
+
81
+ it do
82
+ should parse('(Queryable)').as(
83
+ ancestors: [
84
+ { reference: 'Queryable' }
85
+ ]
86
+ )
87
+ end
88
+
89
+ it do
90
+ should parse('(Collection, Queryable)').as(
91
+ ancestors: [
92
+ { reference: 'Collection' },
93
+ { reference: 'Queryable' }
94
+ ]
95
+ )
96
+ end
97
+ end
98
+
99
+ describe '#class_property_assignment' do
100
+ subject { parser.class_property_assignment }
101
+
102
+ it do
103
+ should parse('foo = 42').as(
104
+ {
105
+ property: {
106
+ property_name: 'foo'
107
+ },
108
+ location: '=',
109
+ property_value: { expression_chain: { integer: '42' } }
110
+ }
111
+ )
112
+ end
113
+
114
+ it do
115
+ should parse('foo = ~> { 42 }').as(
116
+ {
117
+ property: {
118
+ property_name: 'foo'
119
+ },
120
+ location: '=',
121
+ property_value: {
122
+ swerve_rocket: '~>',
123
+ body: { expression_chain: { integer: '42' } }
124
+ }
125
+ }
126
+ )
127
+ end
128
+
129
+ it do
130
+ should parse('self.[] = -> { 42 }').as(
131
+ {
132
+ property: {
133
+ class_self: 'self',
134
+ location: '.',
135
+ property_name: '[]'
136
+ },
137
+ location: '=',
138
+ property_value: {
139
+ dash_rocket: '->',
140
+ body: { expression_chain: { integer: '42' } }
141
+ }
142
+ }
143
+ )
144
+ end
145
+
146
+ it do
147
+ should parse('@.[] = => { -> { 42 } }').as(
148
+ {
149
+ property: {
150
+ class_prototype: '@',
151
+ location: '.',
152
+ property_name: '[]'
153
+ },
154
+ location: '=',
155
+ property_value: {
156
+ fat_rocket: '=>',
157
+ overloads: [
158
+ {
159
+ dash_rocket: '->',
160
+ body: { expression_chain: { integer: '42' } }
161
+ }
162
+ ]
163
+ }
164
+ }
165
+ )
166
+ end
167
+ end
168
+
169
+ describe '#property_block' do
170
+ subject { parser.property_block }
171
+
172
+ it do
173
+ should parse('~> { 42 }').as(
174
+ swerve_rocket: '~>',
175
+ body: { expression_chain: { integer: '42' } }
176
+ )
177
+ end
178
+
179
+ it { should_not parse('~> {}') }
180
+ end
181
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::Common do
4
+ class CommonParser
5
+ include Rip::Parser::Rules::Common
6
+ end
7
+
8
+ let(:parser) { CommonParser.new }
9
+
10
+ describe '#comment' do
11
+ subject { parser.comment }
12
+
13
+ it { should parse('#') }
14
+ it { should parse('# comment') }
15
+ end
16
+
17
+ describe '#space' do
18
+ subject { parser.space }
19
+
20
+ it { should parse(' ') }
21
+ it { should parse("\t") }
22
+ end
23
+
24
+ describe '#spaces' do
25
+ subject { parser.spaces }
26
+
27
+ it { should parse(' ') }
28
+ it { should parse("\t\t") }
29
+ it { should parse(" \t \t ") }
30
+ end
31
+
32
+ describe '#spaces?' do
33
+ subject { parser.spaces? }
34
+
35
+ it { should parse('') }
36
+ it { should parse(' ') }
37
+ it { should parse(" \t \t ") }
38
+ end
39
+
40
+ describe '#line_break' do
41
+ subject { parser.line_break }
42
+
43
+ it { should parse("\n") }
44
+ it { should parse("\r") }
45
+ it { should parse("\r\n") }
46
+ end
47
+
48
+ describe '#line_breaks' do
49
+ subject { parser.line_breaks }
50
+
51
+ it { should parse("\r\n\r\n") }
52
+ it { should parse("\n\n") }
53
+ it { should parse("\r\r") }
54
+ end
55
+
56
+ describe '#line_breaks?' do
57
+ subject { parser.line_breaks? }
58
+
59
+ it { should parse('') }
60
+ it { should parse("\r\n\r\n") }
61
+ it { should parse("\n\n") }
62
+ end
63
+
64
+ describe '#whitespace' do
65
+ subject { parser.whitespace }
66
+
67
+ it { should parse(' ') }
68
+ it { should parse("\t") }
69
+ it { should parse("\n") }
70
+ it { should parse("\r") }
71
+ it { should parse("\r\n") }
72
+ end
73
+
74
+ describe '#whitespaces' do
75
+ subject { parser.whitespaces }
76
+
77
+ it { should parse(' ') }
78
+ it { should parse("\t\t") }
79
+ end
80
+
81
+ describe '#whitespaces?' do
82
+ subject { parser.whitespaces? }
83
+
84
+ it { should parse('') }
85
+ it { should parse("\n") }
86
+ it { should parse("\t\r") }
87
+ end
88
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::DateTime do
4
+ class DateTimeParser
5
+ include Rip::Parser::Rules::DateTime
6
+ end
7
+
8
+ let(:parser) { DateTimeParser.new }
9
+
10
+ describe '#date_time' do
11
+ subject { parser.date_time }
12
+
13
+ it do
14
+ should parse('2012-02-12T21:51:50').as(
15
+ date: { year: '2012', month: '02', day: '12' },
16
+ time: { hour: '21', minute: '51', second: '50' }
17
+ )
18
+ end
19
+ end
20
+
21
+ describe '#date' do
22
+ subject { parser.date }
23
+
24
+ it { should parse('2012-02-12').as(year: '2012', month: '02', day: '12') }
25
+ end
26
+
27
+ describe '#time' do
28
+ subject { parser.time }
29
+
30
+ it { should parse('21:51:50').as(hour: '21', minute: '51', second: '50') }
31
+
32
+ it { should parse('12:34:45.678').as(hour: '12', minute: '34', second: '45', sub_second: '678') }
33
+
34
+ it do
35
+ should parse('12:34:45-0500').as(
36
+ hour: '12',
37
+ minute: '34',
38
+ second: '45',
39
+ offset: {
40
+ sign: '-',
41
+ hour: '05',
42
+ minute: '00'
43
+ }
44
+ )
45
+ end
46
+
47
+ it do
48
+ should parse('12:34:45.678+1230').as(
49
+ hour: '12',
50
+ minute: '34',
51
+ second: '45',
52
+ sub_second: '678',
53
+ offset: {
54
+ sign: '+',
55
+ hour: '12',
56
+ minute: '30'
57
+ }
58
+ )
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::Expression do
4
+ class ExpressionParser
5
+ include Rip::Parser::Rules::Expression
6
+ include Rip::Parser::Rules::Module
7
+ end
8
+
9
+ let(:parser) { ExpressionParser.new }
10
+
11
+ describe '#expression' do
12
+ subject { parser.expression }
13
+
14
+ it { should parse('42') }
15
+ it { should parse('-39.7') }
16
+
17
+ it { should parse('`r') }
18
+
19
+ it { should parse(':rip') }
20
+
21
+ it { should parse('[ "nested", [] ]') }
22
+
23
+ it { should parse('foo') }
24
+
25
+ it { should parse('import :bar') }
26
+
27
+ context 'with nested parenthesis' do
28
+ it { should parse('(( ((`z))) )') }
29
+ it { should parse('(import :bar)') }
30
+ end
31
+
32
+ context 'map literals' do
33
+ it do
34
+ should parse('{ nested: {} }').as(
35
+ expression_chain: {
36
+ location: '{',
37
+ map: [
38
+ {
39
+ expression_chain: [
40
+ { reference: 'nested' },
41
+ {
42
+ location: ':',
43
+ value: {
44
+ expression_chain: { location: '{', map: [] }
45
+ }
46
+ }
47
+ ]
48
+ }
49
+ ]
50
+ }
51
+ )
52
+ end
53
+ end
54
+
55
+ context 'chaining' do
56
+ it do
57
+ should parse('foo.bar').as(expression_chain: [
58
+ { reference: 'foo' },
59
+ { location: '.', property_name: 'bar' }
60
+ ])
61
+ end
62
+
63
+ it do
64
+ should parse('a.b.c').as(expression_chain: [
65
+ { reference: 'a' },
66
+ { location: '.', property_name: 'b' },
67
+ { location: '.', property_name: 'c' }
68
+ ])
69
+ end
70
+
71
+ it do
72
+ should parse('(((((foo).bar()).baz)))').as(
73
+ expression_chain: {
74
+ expression_chain: {
75
+ expression_chain: {
76
+ expression_chain: [
77
+ {
78
+ expression_chain: [
79
+ {
80
+ expression_chain: { reference: 'foo' }
81
+ },
82
+ { location: '.', property_name: 'bar' },
83
+ { location: '(', arguments: [] }
84
+ ]
85
+ },
86
+ { location: '.', property_name: 'baz' }
87
+ ]
88
+ }
89
+ }
90
+ }
91
+ )
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::Import do
4
+ class ImportParser
5
+ include ::Parslet
6
+
7
+ include Rip::Parser::Rules::Import
8
+ include Rip::Parser::Rules::Reference
9
+
10
+ rule(:expression) { reference }
11
+ end
12
+
13
+ let(:parser) { ImportParser.new }
14
+
15
+ describe '#import' do
16
+ subject { parser.import }
17
+
18
+ it do
19
+ should parse('import :foo').as(import: 'import', module_name: {
20
+ location: ':',
21
+ string: [
22
+ { character: 'f' },
23
+ { character: 'o' },
24
+ { character: 'o' }
25
+ ]
26
+ })
27
+ end
28
+
29
+ it do
30
+ should parse('import(:bar)').as(import: 'import', module_name: {
31
+ location: ':',
32
+ string: [
33
+ { character: 'b' },
34
+ { character: 'a' },
35
+ { character: 'r' }
36
+ ]
37
+ })
38
+ end
39
+
40
+ it do
41
+ should parse('import "bar"').as(import: 'import', module_name: {
42
+ location: '"',
43
+ string: [
44
+ { character: 'b' },
45
+ { character: 'a' },
46
+ { character: 'r' }
47
+ ]
48
+ })
49
+ end
50
+
51
+ it do
52
+ should parse('import "./a/b"').as(import: 'import', module_name: {
53
+ location: '"',
54
+ string: [
55
+ { character: '.' },
56
+ { character: '/' },
57
+ { character: 'a' },
58
+ { character: '/' },
59
+ { character: 'b' }
60
+ ]
61
+ })
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::InvocationIndex do
4
+ class InvocationIndexParser
5
+ include ::Parslet
6
+
7
+ include Rip::Parser::Rules::InvocationIndex
8
+ include Rip::Parser::Rules::Module
9
+ end
10
+
11
+ let(:parser) { InvocationIndexParser.new }
12
+
13
+ describe '#invocation_index' do
14
+ subject { parser.invocation_index }
15
+
16
+ it { should parse('[]').as(location: '[', index_arguments: []) }
17
+
18
+ it do
19
+ should parse('[`3]').as(
20
+ location: '[',
21
+ index_arguments: [
22
+ {
23
+ expression_chain: { character: '3', location: '`' }
24
+ }
25
+ ]
26
+ )
27
+ end
28
+
29
+ it do
30
+ should parse('[1, 2, 3]').as(
31
+ location: '[',
32
+ index_arguments: [
33
+ {
34
+ expression_chain: { integer: '1' }
35
+ },
36
+ {
37
+ expression_chain: { integer: '2' }
38
+ },
39
+ {
40
+ expression_chain: { integer: '3' }
41
+ }
42
+ ]
43
+ )
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::Invocation do
4
+ class InvocationParser
5
+ include ::Parslet
6
+
7
+ include Rip::Parser::Rules::Invocation
8
+ include Rip::Parser::Rules::Module
9
+ end
10
+
11
+ let(:parser) { InvocationParser.new }
12
+
13
+ describe '#invocation' do
14
+ subject { parser.invocation }
15
+
16
+ it { should parse('()').as(location: '(', arguments: []) }
17
+
18
+ it do
19
+ should parse('(`3)').as(
20
+ location: '(',
21
+ arguments: [
22
+ {
23
+ expression_chain: { character: '3', location: '`' }
24
+ }
25
+ ]
26
+ )
27
+ end
28
+
29
+ it do
30
+ should parse('(1, 2, 3)').as(
31
+ location: '(',
32
+ arguments: [
33
+ {
34
+ expression_chain: { integer: '1' }
35
+ },
36
+ {
37
+ expression_chain: { integer: '2' }
38
+ },
39
+ {
40
+ expression_chain: { integer: '3' }
41
+ }
42
+ ]
43
+ )
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Rip::Parser::Rules::Keyword do
4
+ class KeywordParser
5
+ include Rip::Parser::Rules::Keyword
6
+ end
7
+
8
+ let(:parser) { KeywordParser.new }
9
+
10
+ describe '#keyword' do
11
+ subject { parser.keyword(:import) }
12
+
13
+ it { should parse('import').as(import: 'import') }
14
+
15
+ it { should_not parse('importer') }
16
+ end
17
+ end