jievro-parser 0.4.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/.gitignore +1 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +30 -0
  6. data/README.md +1 -0
  7. data/Rakefile +7 -0
  8. data/lib/parser/binary_operator.rb +64 -0
  9. data/lib/parser/grammar/code_block.treetop +46 -0
  10. data/lib/parser/grammar/declaration/constant_declaration.treetop +38 -0
  11. data/lib/parser/grammar/declaration/declaration.treetop +16 -0
  12. data/lib/parser/grammar/declaration/function_declaration.treetop +302 -0
  13. data/lib/parser/grammar/declaration/variable_declaration.treetop +38 -0
  14. data/lib/parser/grammar/expression/binary_expression.treetop +75 -0
  15. data/lib/parser/grammar/expression/closure_expression.treetop +188 -0
  16. data/lib/parser/grammar/expression/expression.treetop +83 -0
  17. data/lib/parser/grammar/expression/function_call_expression.treetop +32 -0
  18. data/lib/parser/grammar/expression/literal_expression.treetop +8 -0
  19. data/lib/parser/grammar/expression/parenthesized_expression.treetop +146 -0
  20. data/lib/parser/grammar/expression/postfix_expression.treetop +8 -0
  21. data/lib/parser/grammar/expression/prefix_expression.treetop +29 -0
  22. data/lib/parser/grammar/expression/primary_expression.treetop +8 -0
  23. data/lib/parser/grammar/expression/range_expression.treetop +53 -0
  24. data/lib/parser/grammar/expression/self_expression.treetop +25 -0
  25. data/lib/parser/grammar/expression/super_expression.treetop +25 -0
  26. data/lib/parser/grammar/expression/wildcard_expression.treetop +8 -0
  27. data/lib/parser/grammar/generics/generic_argument_clause.treetop +89 -0
  28. data/lib/parser/grammar/generics/generics.treetop +9 -0
  29. data/lib/parser/grammar/grammar.treetop +76 -0
  30. data/lib/parser/grammar/identifier.treetop +56 -0
  31. data/lib/parser/grammar/implicit_parameter_name.treetop +26 -0
  32. data/lib/parser/grammar/literal/literal.treetop +45 -0
  33. data/lib/parser/grammar/literal/literal_array.treetop +98 -0
  34. data/lib/parser/grammar/literal/literal_boolean.treetop +50 -0
  35. data/lib/parser/grammar/literal/literal_decimal_floating_point.treetop +49 -0
  36. data/lib/parser/grammar/literal/literal_dictionary.treetop +157 -0
  37. data/lib/parser/grammar/literal/literal_hexadecimal_floating_point.treetop +47 -0
  38. data/lib/parser/grammar/literal/literal_integer_binary.treetop +47 -0
  39. data/lib/parser/grammar/literal/literal_integer_decimal.treetop +47 -0
  40. data/lib/parser/grammar/literal/literal_integer_hexadecimal.treetop +47 -0
  41. data/lib/parser/grammar/literal/literal_integer_octal.treetop +47 -0
  42. data/lib/parser/grammar/literal/literal_nil.treetop +25 -0
  43. data/lib/parser/grammar/literal/literal_numeric.treetop +69 -0
  44. data/lib/parser/grammar/literal/literal_string.treetop +207 -0
  45. data/lib/parser/grammar/operator.treetop +35 -0
  46. data/lib/parser/grammar/pattern/pattern.treetop +16 -0
  47. data/lib/parser/grammar/pattern/pattern_identifier.treetop +8 -0
  48. data/lib/parser/grammar/pattern/pattern_initializer.treetop +189 -0
  49. data/lib/parser/grammar/pattern/pattern_wildcard.treetop +8 -0
  50. data/lib/parser/grammar/statement/branch/branch.treetop +16 -0
  51. data/lib/parser/grammar/statement/branch/if.treetop +63 -0
  52. data/lib/parser/grammar/statement/loop/do_while.treetop +32 -0
  53. data/lib/parser/grammar/statement/loop/for.treetop +127 -0
  54. data/lib/parser/grammar/statement/loop/for_in.treetop +35 -0
  55. data/lib/parser/grammar/statement/loop/loop.treetop +22 -0
  56. data/lib/parser/grammar/statement/loop/while.treetop +34 -0
  57. data/lib/parser/grammar/statement/statement.treetop +97 -0
  58. data/lib/parser/grammar/type/type.treetop +18 -0
  59. data/lib/parser/grammar/type/type_annotation.treetop +29 -0
  60. data/lib/parser/grammar/type/type_array.treetop +43 -0
  61. data/lib/parser/grammar/type/type_dictionary.treetop +59 -0
  62. data/lib/parser/grammar/type/type_identifier.treetop +39 -0
  63. data/lib/parser/grammar/whitespace.treetop +40 -0
  64. data/lib/parser/grammar/wildcard.treetop +25 -0
  65. data/lib/parser/parse_result.rb +17 -0
  66. data/lib/parser/parser.rb +34 -0
  67. data/lib/parser/tools/converter/binary_string_to_int_converter.rb +20 -0
  68. data/lib/parser/tools/converter/converter.rb +12 -0
  69. data/lib/parser/tools/converter/decimal_float_string_to_float_converter.rb +22 -0
  70. data/lib/parser/tools/converter/decimal_string_to_int_converter.rb +20 -0
  71. data/lib/parser/tools/converter/hexadecimal_float_string_to_float_converter.rb +42 -0
  72. data/lib/parser/tools/converter/hexadecimal_string_to_int_converter.rb +20 -0
  73. data/lib/parser/tools/converter/octal_string_to_int_converter.rb +20 -0
  74. data/lib/parser/tools/quote_stripper.rb +18 -0
  75. data/lib/parser/tools/shunting_yard.rb +80 -0
  76. data/lib/parser/tools/tokens.rb +112 -0
  77. data/lib/parser/version.rb +5 -0
  78. data/lib/parser.rb +2 -0
  79. data/parser.gemspec +25 -0
  80. metadata +163 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 14e2978148043c35f1cc7228b7586fe4383bceda
4
+ data.tar.gz: 64604bffdc949996288c78a90a8a04507011c03c
5
+ SHA512:
6
+ metadata.gz: 01489d03f902d929fe888fc49ab402fb156d9ea916197b6239527262bed880e29119774003030e0557c0331b67de375a80e3fcfcc5bc4cb783a52c2749f4f942
7
+ data.tar.gz: f3a20355d13406bf740a7604f469639d747ec38d093ce25ac277eefc36047a38663e3c13dcf5898e15584da7e1a78510aa6e270fa8fd551418f8d6b6014f3d5f
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /vendor/
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+
3
+ script: bundle exec rake test
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'treetop'
5
+ gem 'polyglot'
6
+ gem 'rspec', :require => 'spec'
data/Gemfile.lock ADDED
@@ -0,0 +1,30 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.2.5)
5
+ polyglot (0.3.5)
6
+ rake (10.3.2)
7
+ rspec (3.2.0)
8
+ rspec-core (~> 3.2.0)
9
+ rspec-expectations (~> 3.2.0)
10
+ rspec-mocks (~> 3.2.0)
11
+ rspec-core (3.2.2)
12
+ rspec-support (~> 3.2.0)
13
+ rspec-expectations (3.2.0)
14
+ diff-lcs (>= 1.2.0, < 2.0)
15
+ rspec-support (~> 3.2.0)
16
+ rspec-mocks (3.2.1)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.2.0)
19
+ rspec-support (3.2.2)
20
+ treetop (1.5.3)
21
+ polyglot (~> 0.3)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ polyglot
28
+ rake
29
+ rspec
30
+ treetop
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # jievro ~ parser [![Build Status](https://travis-ci.org/jievro/parser.svg?branch=develop)](https://travis-ci.org/jievro/parser)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rspec'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:test) do |t|
5
+ t.ruby_opts = %w(-I lib -I spec)
6
+ t.rspec_opts = '--color --format progress'
7
+ end
@@ -0,0 +1,64 @@
1
+ module Kauri
2
+ class BinaryOperator
3
+
4
+ def initialize(sign, associativity, precedence)
5
+ @sign = sign
6
+ @associativity = associativity
7
+ @precedence = precedence
8
+ end
9
+
10
+ def sign
11
+ @sign
12
+ end
13
+
14
+ def associativity
15
+ @associativity
16
+ end
17
+
18
+ def precedence
19
+ @precedence
20
+ end
21
+
22
+ def self.get(sign)
23
+ case sign
24
+ when '<<', '>>'
25
+ operator = BinaryOperator.new(sign, :none, 160)
26
+ when '*', '/', '%', '&*', '&/', '&%', '&'
27
+ operator = BinaryOperator.new(sign, :left, 150)
28
+ when '+', '-', '&+', '&-', '|', '^'
29
+ operator = BinaryOperator.new(sign, :left, 140)
30
+ when '..<', '...'
31
+ operator = BinaryOperator.new(sign, :none, 135)
32
+ when 'is', 'as'
33
+ operator = BinaryOperator.new(sign, :none, 132)
34
+ when '<', '<=', '>', '>=', '==', '!=', '===', '!==', '~='
35
+ operator = BinaryOperator.new(sign, :left, 130)
36
+ when '&&'
37
+ operator = BinaryOperator.new(sign, :left, 120)
38
+ when '||'
39
+ operator = BinaryOperator.new(sign, :left, 110)
40
+ when '??'
41
+ operator = BinaryOperator.new(sign, :right, 110)
42
+ when '?:'
43
+ operator = BinaryOperator.new(sign, :right, 100)
44
+ when '=', '*=', '/=', '%=', '+=', '-=', '<<=', '>>=', '&=', '^=', '|=', '&&=', '||='
45
+ operator = BinaryOperator.new(sign, :right, 90)
46
+ else
47
+ raise Exception, 'sign not managed'
48
+ end
49
+
50
+ operator
51
+ end
52
+
53
+ def self.is_operator(sign)
54
+ begin
55
+ self.get(sign)
56
+ is_operator = true
57
+ rescue Exception
58
+ is_operator = false
59
+ end
60
+
61
+ is_operator
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,46 @@
1
+ module Kauri
2
+ grammar CodeBlock
3
+
4
+ rule code_block
5
+ '{' ws1:_ statement_list:statement_list? ws2:_ '}' {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push({
10
+ type: 'T_OPEN_CURLY_BRACKET',
11
+ value: '{'
12
+ })
13
+
14
+ unless ws1.text_value.empty?
15
+ tokens.concat(ws1.tokens)
16
+ end
17
+
18
+ unless statement_list.text_value.empty?
19
+ tokens.concat(statement_list.tokens)
20
+ end
21
+
22
+ unless ws2.text_value.empty?
23
+ tokens.concat(ws2.tokens)
24
+ end
25
+
26
+ tokens.push({
27
+ type: 'T_CLOSE_CURLY_BRACKET',
28
+ value: '}'
29
+ })
30
+
31
+ tokens
32
+ end
33
+
34
+ def ast
35
+ ast = []
36
+
37
+ unless statement_list.text_value.empty?
38
+ ast = statement_list.ast
39
+ end
40
+
41
+ ast
42
+ end
43
+ }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,38 @@
1
+ module Kauri
2
+ grammar ConstantDeclaration
3
+
4
+ rule constant_declaration
5
+ 'let' whitespaces:whitespaces pattern_initializer_list:pattern_initializer_list {
6
+ def tokens
7
+
8
+ tokens = []
9
+
10
+ tokens.push({
11
+ type: 'T_LET',
12
+ value: 'let'
13
+ })
14
+
15
+ tokens.concat(whitespaces.tokens)
16
+ tokens.concat(pattern_initializer_list.tokens)
17
+
18
+ tokens
19
+ end
20
+
21
+ def ast
22
+
23
+ ast = []
24
+
25
+ pattern_initializer_list.ast.each { |e|
26
+ ast.push({
27
+ block_type: 'constant-declaration',
28
+ pattern: e[:pattern],
29
+ initializer: e[:initializer]
30
+ })
31
+ }
32
+
33
+ ast
34
+ end
35
+ }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ require 'parser/grammar/declaration/constant_declaration'
2
+ require 'parser/grammar/declaration/variable_declaration'
3
+ require 'parser/grammar/declaration/function_declaration'
4
+
5
+ module Kauri
6
+ grammar Declaration
7
+
8
+ include Kauri::ConstantDeclaration
9
+ include Kauri::VariableDeclaration
10
+ include Kauri::FunctionDeclaration
11
+
12
+ rule declaration
13
+ constant_declaration / variable_declaration / function_declaration
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,302 @@
1
+ module Kauri
2
+ grammar FunctionDeclaration
3
+
4
+ rule function_declaration
5
+ function_head ws1:_ function_name ws2:_ function_signature ws3:_ function_body {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.concat(function_head.tokens)
10
+
11
+ unless ws1.text_value.empty?
12
+ tokens.concat(ws1.tokens)
13
+ end
14
+
15
+ tokens.concat(function_name.tokens)
16
+
17
+ unless ws2.text_value.empty?
18
+ tokens.concat(ws2.tokens)
19
+ end
20
+
21
+ tokens.concat(function_signature.tokens)
22
+
23
+ unless ws3.text_value.empty?
24
+ tokens.concat(ws3.tokens)
25
+ end
26
+
27
+ tokens.concat(function_body.tokens)
28
+
29
+ tokens
30
+ end
31
+
32
+ def ast
33
+
34
+ signature = function_signature.ast
35
+
36
+ name = function_name.ast.first
37
+ parameters = signature[:parameters]
38
+ return_type = signature[:return_type]
39
+ body = function_body.ast
40
+
41
+ [
42
+ {
43
+ block_type: 'function-declaration',
44
+ name: name,
45
+ parameters: parameters,
46
+ return_type: return_type,
47
+ body: body
48
+ }
49
+ ]
50
+ end
51
+ }
52
+ end
53
+
54
+ rule function_head
55
+ 'func' {
56
+ def tokens
57
+ [
58
+ {
59
+ type: 'T_FUNCTION',
60
+ value: 'func'
61
+ }
62
+ ]
63
+ end
64
+ }
65
+ end
66
+
67
+ rule function_name
68
+ identifier
69
+ end
70
+
71
+ rule function_signature
72
+ parameter_clause:parameter_clause ws:_ return_type:return_type? {
73
+ def tokens
74
+ tokens = []
75
+
76
+ tokens.concat(parameter_clause.tokens)
77
+
78
+ unless ws.text_value.empty?
79
+ tokens.concat(ws.tokens)
80
+ end
81
+
82
+ unless return_type.text_value.empty?
83
+ tokens.concat(return_type.tokens)
84
+ end
85
+
86
+ tokens
87
+ end
88
+
89
+ def ast
90
+
91
+ parameters = parameter_clause.ast
92
+
93
+ unless return_type.text_value.empty?
94
+ type = return_type.ast
95
+ end
96
+
97
+ {
98
+ parameters: parameters,
99
+ return_type: type
100
+ }
101
+ end
102
+ }
103
+ end
104
+
105
+ rule parameter_clause
106
+ empty_parameter_clause / parameter_clause_with_arguments
107
+ end
108
+
109
+ rule empty_parameter_clause
110
+ '(' ws:_ ')' {
111
+ def tokens
112
+ tokens = []
113
+
114
+ tokens.push({
115
+ type: 'T_OPEN_ROUND_BRACKET',
116
+ value: '('
117
+ })
118
+
119
+ unless ws.text_value.empty?
120
+ tokens.concat(ws.tokens)
121
+ end
122
+
123
+ tokens.push({
124
+ type: 'T_CLOSE_ROUND_BRACKET',
125
+ value: ')'
126
+ })
127
+
128
+ tokens
129
+ end
130
+
131
+ def ast
132
+ []
133
+ end
134
+ }
135
+ end
136
+
137
+ rule parameter_clause_with_arguments
138
+ '(' ws1:_ parameter_list ws2:_ ')' {
139
+ def tokens
140
+ tokens = []
141
+
142
+ tokens.push({
143
+ type: 'T_OPEN_ROUND_BRACKET',
144
+ value: '('
145
+ })
146
+
147
+ unless ws1.text_value.empty?
148
+ tokens.concat(ws1.tokens)
149
+ end
150
+
151
+ tokens.concat(parameter_list.tokens)
152
+
153
+ unless ws2.text_value.empty?
154
+ tokens.concat(ws2.tokens)
155
+ end
156
+
157
+ tokens.push({
158
+ type: 'T_CLOSE_ROUND_BRACKET',
159
+ value: ')'
160
+ })
161
+
162
+ tokens
163
+ end
164
+
165
+ def ast
166
+ parameter_list.ast
167
+ end
168
+ }
169
+ end
170
+
171
+ rule parameter_list
172
+ head:(parameter ws1:_ ',' ws2:_)* tail:parameter {
173
+ def tokens
174
+ tokens = []
175
+
176
+ unless head.text_value.empty?
177
+ head.elements.each { |e|
178
+ tokens.concat(e.parameter.tokens)
179
+
180
+ unless e.ws1.text_value.empty?
181
+ tokens.concat(e.ws1.tokens)
182
+ end
183
+
184
+ tokens.push({
185
+ type: 'T_COMMA',
186
+ value: ','
187
+ })
188
+
189
+ unless e.ws2.text_value.empty?
190
+ tokens.concat(e.ws2.tokens)
191
+ end
192
+ }
193
+ end
194
+
195
+ tokens.concat(tail.tokens)
196
+
197
+ tokens
198
+ end
199
+
200
+ def ast
201
+ ast = []
202
+
203
+ unless head.text_value.empty?
204
+ head.elements.each { |e|
205
+ ast.push(e.parameter.ast)
206
+ }
207
+ end
208
+
209
+ ast.push(tail.ast)
210
+
211
+ ast
212
+ end
213
+ }
214
+ end
215
+
216
+ rule parameter
217
+ (
218
+ (external_parameter_name ws1:_ local_parameter_name ws2:_ type_annotation)
219
+ /
220
+ (local_parameter_name ws2:_ type_annotation)
221
+ ) {
222
+ def tokens
223
+ tokens = []
224
+
225
+ if defined? external_parameter_name
226
+ tokens.concat(external_parameter_name.tokens)
227
+ end
228
+
229
+ if defined? ws1
230
+ unless ws1.text_value.empty?
231
+ tokens.concat(ws1.tokens)
232
+ end
233
+ end
234
+
235
+ tokens.concat(local_parameter_name.tokens)
236
+
237
+ unless ws2.text_value.empty?
238
+ tokens.concat(ws2.tokens)
239
+ end
240
+
241
+ tokens.concat(type_annotation.tokens)
242
+
243
+ tokens
244
+ end
245
+
246
+ def ast
247
+
248
+ type = type_annotation.ast.first
249
+ local = local_parameter_name.ast.first
250
+
251
+ if defined? external_parameter_name
252
+ external = external_parameter_name.ast.first
253
+ end
254
+
255
+ {
256
+ type: type,
257
+ local: local,
258
+ external: external,
259
+ default: nil
260
+ }
261
+ end
262
+ }
263
+ end
264
+
265
+ rule local_parameter_name
266
+ identifier / wildcard
267
+ end
268
+
269
+ rule external_parameter_name
270
+ identifier / wildcard
271
+ end
272
+
273
+ rule return_type
274
+ '->' ws:_ type:type {
275
+ def tokens
276
+ tokens = []
277
+
278
+ tokens.push({
279
+ type: 'T_RETURN_TYPE_ARROW',
280
+ value: '->'
281
+ })
282
+
283
+ unless ws.text_value.empty?
284
+ tokens.concat(ws.tokens)
285
+ end
286
+
287
+ tokens.concat(type.tokens)
288
+
289
+ tokens
290
+ end
291
+
292
+ def ast
293
+ type.ast.first
294
+ end
295
+ }
296
+ end
297
+
298
+ rule function_body
299
+ code_block
300
+ end
301
+ end
302
+ end
@@ -0,0 +1,38 @@
1
+ module Kauri
2
+ grammar VariableDeclaration
3
+
4
+ rule variable_declaration
5
+ 'var' whitespaces:whitespaces pattern_initializer_list:pattern_initializer_list {
6
+ def tokens
7
+
8
+ tokens = []
9
+
10
+ tokens.push({
11
+ type: 'T_VAR',
12
+ value: 'var'
13
+ })
14
+
15
+ tokens.concat(whitespaces.tokens)
16
+ tokens.concat(pattern_initializer_list.tokens)
17
+
18
+ tokens
19
+ end
20
+
21
+ def ast
22
+
23
+ ast = []
24
+
25
+ pattern_initializer_list.ast.each { |e|
26
+ ast.push({
27
+ block_type: 'variable-declaration',
28
+ pattern: e[:pattern],
29
+ initializer: e[:initializer]
30
+ })
31
+ }
32
+
33
+ ast
34
+ end
35
+ }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,75 @@
1
+ require 'parser/tools/shunting_yard'
2
+
3
+ module Kauri
4
+ grammar BinaryExpression
5
+
6
+ rule binary_expression
7
+ left:infix_operation_chain ws:_ right:primary_expression {
8
+ def tokens
9
+
10
+ tokens = []
11
+
12
+ tokens.concat(left.tokens)
13
+
14
+ unless ws.text_value.empty?
15
+ tokens.concat(ws.tokens)
16
+ end
17
+
18
+ tokens.concat(right.tokens)
19
+
20
+ tokens
21
+ end
22
+
23
+ def ast
24
+
25
+ sy = Kauri::Tools::ShuntingYard.new
26
+
27
+ flatten_ast = []
28
+
29
+ flatten_ast.concat(left.flatten_ast)
30
+ flatten_ast.push(right.ast.first)
31
+
32
+ ast = sy.generate_ast(flatten_ast)
33
+
34
+ ast
35
+ end
36
+ }
37
+ end
38
+
39
+ rule infix_operation_chain
40
+ (primary:primary_expression ws1:_ operator:operator ws2:_)+ {
41
+ def tokens
42
+ tokens = []
43
+
44
+ elements.each { |e|
45
+
46
+ tokens.concat(e.primary.tokens)
47
+
48
+ unless e.ws1.text_value.empty?
49
+ tokens.concat(e.ws1.tokens)
50
+ end
51
+
52
+ tokens.concat(e.operator.tokens)
53
+
54
+ unless e.ws2.text_value.empty?
55
+ tokens.concat(e.ws2.tokens)
56
+ end
57
+ }
58
+
59
+ tokens
60
+ end
61
+
62
+ def flatten_ast
63
+ nodes = []
64
+
65
+ elements.each { |e|
66
+ nodes.push(e.primary.ast.first)
67
+ nodes.push(e.operator.text_value)
68
+ }
69
+
70
+ nodes
71
+ end
72
+ }
73
+ end
74
+ end
75
+ end