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
@@ -0,0 +1,47 @@
1
+ require 'parser/tools/converter/converter'
2
+
3
+ module Kauri
4
+ grammar LiteralIntegerHexadecimal
5
+
6
+ rule literal_integer_hexadecimal
7
+ '0x' hexadecimal_digit hexadecimal_literal_characters? {
8
+ def tokens
9
+ [
10
+ {
11
+ type: 'T_LITERAL_INTEGER_HEXADECIMAL',
12
+ value: text_value
13
+ }
14
+ ]
15
+ end
16
+
17
+ def ast
18
+
19
+ converter = Kauri::Tools::Converter::HexadecimalStringToIntConverter.new
20
+
21
+ [
22
+ {
23
+ block_type: 'literal-integer',
24
+ value: converter.convert(text_value)
25
+ }
26
+ ]
27
+ end
28
+ }
29
+ end
30
+
31
+ rule hexadecimal_literal_characters
32
+ hexadecimal_literal_character+
33
+ end
34
+
35
+ rule hexadecimal_literal_character
36
+ hexadecimal_digit / '_'
37
+ end
38
+
39
+ rule hexadecimal_digits
40
+ hexadecimal_digit+
41
+ end
42
+
43
+ rule hexadecimal_digit
44
+ [0-9A-Fa-f]
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ require 'parser/tools/converter/converter'
2
+
3
+ module Kauri
4
+ grammar LiteralIntegerOctal
5
+
6
+ rule literal_integer_octal
7
+ '0o' octal_digit octal_literal_characters? {
8
+ def tokens
9
+ [
10
+ {
11
+ type: 'T_LITERAL_INTEGER_OCTAL',
12
+ value: text_value
13
+ }
14
+ ]
15
+ end
16
+
17
+ def ast
18
+
19
+ converter = Kauri::Tools::Converter::OctalStringToIntConverter.new
20
+
21
+ [
22
+ {
23
+ block_type: 'literal-integer',
24
+ value: converter.convert(text_value)
25
+ }
26
+ ]
27
+ end
28
+ }
29
+ end
30
+
31
+ rule octal_literal_characters
32
+ octal_literal_character+
33
+ end
34
+
35
+ rule octal_literal_character
36
+ octal_digit / '_'
37
+ end
38
+
39
+ rule octal_digits
40
+ octal_digit+
41
+ end
42
+
43
+ rule octal_digit
44
+ [0-7]+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+ module Kauri
2
+ grammar LiteralNil
3
+
4
+ rule literal_nil
5
+ 'nil' {
6
+ def tokens
7
+ [
8
+ {
9
+ type: 'T_NIL',
10
+ value: text_value
11
+ }
12
+ ]
13
+ end
14
+
15
+ def ast
16
+ [
17
+ {
18
+ block_type: 'literal-nil'
19
+ }
20
+ ]
21
+ end
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,69 @@
1
+ require 'parser/grammar/literal/literal_integer_binary'
2
+ require 'parser/grammar/literal/literal_integer_octal'
3
+ require 'parser/grammar/literal/literal_integer_decimal'
4
+ require 'parser/grammar/literal/literal_integer_hexadecimal'
5
+ require 'parser/grammar/literal/literal_decimal_floating_point'
6
+ require 'parser/grammar/literal/literal_hexadecimal_floating_point'
7
+
8
+ module Kauri
9
+ grammar LiteralNumeric
10
+
11
+ include Kauri::LiteralIntegerBinary
12
+ include Kauri::LiteralIntegerOctal
13
+ include Kauri::LiteralIntegerDecimal
14
+ include Kauri::LiteralIntegerHexadecimal
15
+ include Kauri::LiteralDecimalFloatingPoint
16
+ include Kauri::LiteralHexadecimalFloatingPoint
17
+
18
+ rule literal_numeric
19
+ minus:minus? numeric:(literal_floating_point / literal_integer) {
20
+ def tokens
21
+ tokens = []
22
+
23
+ unless minus.text_value.empty?
24
+ tokens.push(minus.tokens)
25
+ end
26
+
27
+ tokens.concat(numeric.tokens)
28
+
29
+ tokens
30
+ end
31
+
32
+ def ast
33
+ ast = numeric.ast.first
34
+
35
+ unless minus.text_value.empty?
36
+ ast[:value] = -ast[:value]
37
+ end
38
+
39
+ [ast]
40
+ end
41
+ }
42
+ end
43
+
44
+ rule literal_integer
45
+ literal_integer_hexadecimal
46
+ /
47
+ literal_integer_octal
48
+ /
49
+ literal_integer_binary
50
+ /
51
+ literal_integer_decimal
52
+ end
53
+
54
+ rule literal_floating_point
55
+ literal_hexadecimal_floating_point / literal_decimal_floating_point
56
+ end
57
+
58
+ rule minus
59
+ '-' {
60
+ def tokens
61
+ {
62
+ type: 'T_MINUS',
63
+ value: '-'
64
+ }
65
+ end
66
+ }
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,207 @@
1
+ module Kauri
2
+ grammar LiteralString
3
+
4
+ rule literal_string
5
+ '"' quoted_text:quoted_text? '"' {
6
+ def tokens
7
+
8
+ tokens = [
9
+ {
10
+ type: 'T_DOUBLE_QUOTE',
11
+ value: '"'
12
+ }
13
+ ]
14
+
15
+ unless quoted_text.text_value.empty?
16
+ tokens.concat(quoted_text.tokens)
17
+ end
18
+
19
+ tokens.push({
20
+ type: 'T_DOUBLE_QUOTE',
21
+ value: '"'
22
+ })
23
+
24
+ tokens
25
+ end
26
+
27
+ def ast
28
+
29
+ if quoted_text.text_value.empty?
30
+ ast = [
31
+ {
32
+ block_type: 'literal-string',
33
+ value: ''
34
+ }
35
+ ]
36
+ else
37
+ ast = quoted_text.ast
38
+ end
39
+
40
+ ast
41
+ end
42
+ }
43
+ end
44
+
45
+ rule quoted_text
46
+ quoted_text_item+ {
47
+ def tokens
48
+ tokens = []
49
+ elements.each { |e|
50
+ tokens.concat(e.tokens)
51
+ }
52
+ tokens
53
+ end
54
+
55
+ def ast
56
+ ast = []
57
+ is_interpolated_string = false
58
+ last_node_is_literal_string = false
59
+ stripper = Kauri::Tools::QuoteStripper.new
60
+
61
+ elements.each { |e|
62
+ if e.is_expression
63
+ is_interpolated_string = true
64
+ last_node_is_literal_string = false
65
+ ast.push(e.ast)
66
+ else
67
+
68
+ if e.is_quoted_unicode_char
69
+ value = e.raw_value
70
+ else
71
+ value = stripper.strip(e.text_value)
72
+ end
73
+
74
+ if last_node_is_literal_string
75
+ ast[-1][:value] += value
76
+ else
77
+ ast.push({
78
+ block_type: 'literal-string',
79
+ value: value
80
+ })
81
+ end
82
+ last_node_is_literal_string = true
83
+ end
84
+ }
85
+
86
+ if is_interpolated_string
87
+ ast = [
88
+ {
89
+ block_type: 'interpolated-string',
90
+ value: ast
91
+ }
92
+ ]
93
+ end
94
+
95
+ ast
96
+ end
97
+ }
98
+ end
99
+
100
+ rule quoted_text_item
101
+ quoted_unicode_char / quoted_expression / sequence_of_chars
102
+ end
103
+
104
+ rule sequence_of_chars
105
+ (escaped_character / standard_character)+ {
106
+ def tokens
107
+ stripper = Kauri::Tools::QuoteStripper.new
108
+ [
109
+ {
110
+ type: 'T_LITERAL_STRING',
111
+ value: stripper.strip(text_value)
112
+ }
113
+ ]
114
+ end
115
+
116
+ def is_expression
117
+ false
118
+ end
119
+
120
+ def is_quoted_unicode_char
121
+ false
122
+ end
123
+ }
124
+ end
125
+
126
+ rule quoted_expression
127
+ '\(' expression:literal ')' {
128
+ def tokens
129
+ tokens = []
130
+
131
+ tokens.push({
132
+ type: 'T_QUOTED_EXPRESSION_OPEN',
133
+ value: '\('
134
+ })
135
+
136
+ tokens.concat(expression.tokens)
137
+
138
+ tokens.push({
139
+ type: 'T_QUOTED_EXPRESSION_CLOSE',
140
+ value: ')'
141
+ })
142
+
143
+ tokens
144
+ end
145
+
146
+ def ast
147
+ expression.ast.first
148
+ end
149
+
150
+ def is_expression
151
+ true
152
+ end
153
+
154
+ def is_quoted_unicode_char
155
+ false
156
+ end
157
+ }
158
+ end
159
+
160
+ rule quoted_unicode_char
161
+ '\u{' unicode_scalar_digits:unicode_scalar_digits 1..8 '}' {
162
+ def tokens
163
+ [
164
+ {
165
+ type: 'T_QUOTED_UNICODE_CHAR_OPEN',
166
+ value: '\\u' + 123.chr
167
+ },
168
+ {
169
+ type: 'T_UNICODE_CHAR',
170
+ value: unicode_scalar_digits.text_value
171
+ },
172
+ {
173
+ type: 'T_QUOTED_UNICODE_CHAR_CLOSE',
174
+ value: 125.chr
175
+ }
176
+ ]
177
+ end
178
+
179
+ def is_expression
180
+ false
181
+ end
182
+
183
+ def is_quoted_unicode_char
184
+ true
185
+ end
186
+
187
+ def raw_value
188
+ unicode_string_value = unicode_scalar_digits.text_value
189
+ unicode_value = unicode_string_value.to_i(base=16)
190
+ [unicode_value].pack('U*')
191
+ end
192
+ }
193
+ end
194
+
195
+ rule unicode_scalar_digits
196
+ hexadecimal_digit
197
+ end
198
+
199
+ rule standard_character
200
+ [a-zA-Z0-9: ]
201
+ end
202
+
203
+ rule escaped_character
204
+ '\0' / '\"' / '\\\'' / '\n' / '\\\\' / '\t' / '\n' / '\r'
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,35 @@
1
+ module Kauri
2
+ grammar Operator
3
+
4
+ rule operator
5
+ operator_head operator_characters? {
6
+ def tokens
7
+ [
8
+ {
9
+ type: 'T_OPERATOR',
10
+ value: text_value
11
+ }
12
+ ]
13
+ end
14
+ def ast
15
+ []
16
+ end
17
+ def operator
18
+ text_value
19
+ end
20
+ }
21
+ end
22
+
23
+ rule operator_head
24
+ operator_basic_char
25
+ end
26
+
27
+ rule operator_characters
28
+ operator_basic_char+
29
+ end
30
+
31
+ rule operator_basic_char
32
+ '/' / '=' / '-' / '+' / '!' / '*' / '%' / '<' / '>' / '&' / '|' / '^' / '~' / '?'
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ require 'parser/grammar/pattern/pattern_wildcard'
2
+ require 'parser/grammar/pattern/pattern_identifier'
3
+ require 'parser/grammar/pattern/pattern_initializer'
4
+
5
+ module Kauri
6
+ grammar Pattern
7
+
8
+ include Kauri::PatternWildcard
9
+ include Kauri::PatternIdentifier
10
+ include Kauri::PatternInitializer
11
+
12
+ rule pattern
13
+ pattern_wildcard / pattern_identifier
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ module Kauri
2
+ grammar PatternIdentifier
3
+
4
+ rule pattern_identifier
5
+ identifier
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,189 @@
1
+ module Kauri
2
+ grammar PatternInitializer
3
+
4
+ rule untyped_pattern_initializer
5
+ pattern:pattern ws:_ initializer:initializer? {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.concat(pattern.tokens)
10
+
11
+ unless ws.text_value.empty?
12
+ tokens.concat(ws.tokens)
13
+ end
14
+
15
+ unless initializer.text_value.empty?
16
+ tokens.concat(initializer.tokens)
17
+ end
18
+
19
+ tokens
20
+ end
21
+
22
+ def ast
23
+
24
+ ast = {
25
+ pattern: pattern.ast.first
26
+ }
27
+
28
+ ast[:pattern] = pattern.ast.first
29
+
30
+ unless initializer.text_value.empty?
31
+ ast[:initializer] = initializer.ast.first
32
+ end
33
+
34
+ ast
35
+ end
36
+ }
37
+ end
38
+
39
+ rule typed_pattern_initializer
40
+ pattern:pattern ws1:_ type_annotation:type_annotation ws2:_ initializer:initializer? {
41
+ def tokens
42
+ tokens = []
43
+
44
+ tokens.concat(pattern.tokens)
45
+
46
+ unless ws1.text_value.empty?
47
+ tokens.concat(ws1.tokens)
48
+ end
49
+
50
+ tokens.concat(type_annotation.tokens)
51
+
52
+ unless ws2.text_value.empty?
53
+ tokens.concat(ws2.tokens)
54
+ end
55
+
56
+ unless initializer.text_value.empty?
57
+ tokens.concat(initializer.tokens)
58
+ end
59
+
60
+ tokens
61
+ end
62
+
63
+ def ast
64
+ ast = {}
65
+
66
+ ast[:pattern] = pattern.ast.first
67
+ ast[:pattern][:type] = type_annotation.ast.first
68
+
69
+ unless initializer.text_value.empty?
70
+ ast[:initializer] = initializer.ast.first
71
+ end
72
+
73
+ ast
74
+ end
75
+ }
76
+ end
77
+
78
+ rule pattern_initializer
79
+ (pattern:typed_pattern_initializer / pattern:untyped_pattern_initializer) {
80
+ def tokens
81
+ pattern.tokens
82
+ end
83
+
84
+ def ast
85
+ pattern.ast
86
+ end
87
+ }
88
+ end
89
+
90
+ rule pattern_initializer_list
91
+ head:pattern_initializer_list_head? ws:_ tail:pattern_initializer {
92
+ def tokens
93
+
94
+ tokens = []
95
+
96
+ unless head.text_value.empty?
97
+ tokens.concat(head.tokens)
98
+ end
99
+
100
+ unless ws.text_value.empty?
101
+ tokens.concat(ws.tokens)
102
+ end
103
+
104
+ tokens.concat(tail.tokens)
105
+
106
+ tokens
107
+ end
108
+
109
+ def ast
110
+
111
+ ast = []
112
+
113
+ unless head.text_value.empty?
114
+ ast.concat(head.ast)
115
+ end
116
+
117
+ ast.push(tail.ast)
118
+
119
+ ast
120
+ end
121
+ }
122
+ end
123
+
124
+ rule pattern_initializer_list_head
125
+ (pattern_initializer:pattern_initializer ws1:_ ',' ws2:_)+ {
126
+ def tokens
127
+
128
+ tokens = []
129
+
130
+ elements.each { |e|
131
+
132
+ tokens.concat(e.pattern_initializer.tokens)
133
+
134
+ unless e.ws1.text_value.empty?
135
+ tokens.concat(e.ws1.tokens)
136
+ end
137
+
138
+ tokens.push({
139
+ type: 'T_COMMA',
140
+ value: ','
141
+ })
142
+
143
+ unless e.ws2.text_value.empty?
144
+ tokens.concat(e.ws2.tokens)
145
+ end
146
+ }
147
+
148
+ tokens
149
+ end
150
+
151
+ def ast
152
+
153
+ ast = []
154
+
155
+ elements.each { |e|
156
+ ast.push(e.pattern_initializer.ast)
157
+ }
158
+
159
+ ast
160
+ end
161
+ }
162
+ end
163
+
164
+ rule initializer
165
+ '=' ws:_ expression:expression {
166
+ def tokens
167
+ tokens = []
168
+
169
+ tokens.push({
170
+ type: 'T_OPERATOR',
171
+ value: '='
172
+ })
173
+
174
+ unless ws.text_value.empty?
175
+ tokens.concat(ws.tokens)
176
+ end
177
+
178
+ tokens.concat(expression.tokens)
179
+
180
+ tokens
181
+ end
182
+
183
+ def ast
184
+ expression.ast
185
+ end
186
+ }
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,8 @@
1
+ module Kauri
2
+ grammar PatternWildcard
3
+
4
+ rule pattern_wildcard
5
+ wildcard
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'parser/grammar/statement/branch/if'
2
+
3
+ module Kauri
4
+ module Grammar
5
+ module Statement
6
+ grammar Branch
7
+
8
+ include Kauri::StatementIf
9
+
10
+ rule statement_branch
11
+ statement_if
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end