jievro-parser 0.4.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/.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