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
@@ -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