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,63 @@
1
+ module Kauri
2
+ grammar StatementIf
3
+
4
+ rule statement_if
5
+ 'if' ws1:whitespaces condition:statement_if_condition ws2:_ body:code_block ws3:_ else_block:statement_if_else? {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push(T_IF)
10
+ tokens.concat(ws1.tokens)
11
+ tokens.concat(condition.tokens)
12
+ tokens.concat(ws2.tokens) unless ws2.text_value.empty?
13
+ tokens.concat(body.tokens)
14
+ tokens.concat(ws3.tokens) unless ws3.text_value.empty?
15
+ tokens.concat(else_block.tokens) unless else_block.text_value.empty?
16
+
17
+ tokens
18
+ end
19
+
20
+ def ast
21
+
22
+ ast = {
23
+ block_type: 'if-statement',
24
+ condition: condition.ast.first,
25
+ body: body.ast
26
+ }
27
+
28
+ unless else_block.text_value.empty?
29
+ ast[:else] = else_block.ast
30
+ end
31
+
32
+ [ast]
33
+ end
34
+ }
35
+ end
36
+
37
+ rule statement_if_condition
38
+ expression
39
+ end
40
+
41
+ rule statement_if_else
42
+ (
43
+ ('else' ws:whitespaces block:statement_if)
44
+ /
45
+ ('else' ws:_ block:code_block)
46
+ ) {
47
+ def tokens
48
+ tokens = []
49
+
50
+ tokens.push(T_ELSE)
51
+ tokens.concat(ws.tokens) unless ws.text_value.empty?
52
+ tokens.concat(block.tokens)
53
+
54
+ tokens
55
+ end
56
+
57
+ def ast
58
+ block.ast
59
+ end
60
+ }
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,32 @@
1
+ module Kauri
2
+ grammar StatementDoWhile
3
+
4
+ rule statement_do_while
5
+ 'do' ws1:_ body:code_block ws2:_ 'while' ws3:whitespaces test:expression {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push(T_DO)
10
+ tokens.concat(ws1.tokens) unless ws1.text_value.empty?
11
+ tokens.concat(body.tokens)
12
+ tokens.concat(ws2.tokens) unless ws2.text_value.empty?
13
+ tokens.push(T_WHILE)
14
+ tokens.concat(ws3.tokens)
15
+ tokens.concat(test.tokens)
16
+
17
+ tokens
18
+ end
19
+
20
+ def ast
21
+ [
22
+ {
23
+ block_type: 'do-while-statement',
24
+ body: body.ast,
25
+ test: test.ast.first
26
+ }
27
+ ]
28
+ end
29
+ }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,127 @@
1
+ module Kauri
2
+ grammar StatementFor
3
+
4
+ rule statement_for
5
+ 'for' ws1:_ for_block:(for_block_without_parentheses / for_block_with_parentheses) ws2:_ for_body {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push(T_FOR)
10
+ tokens.concat(ws1.tokens) unless ws1.text_value.empty?
11
+ tokens.concat(for_block.tokens)
12
+ tokens.concat(ws2.tokens) unless ws2.text_value.empty?
13
+ tokens.concat(for_body.tokens)
14
+
15
+ tokens
16
+ end
17
+
18
+ def ast
19
+
20
+ ast_for_block = for_block.ast
21
+
22
+ init = ast_for_block[:init]
23
+ test = ast_for_block[:test]
24
+ update = ast_for_block[:update]
25
+ body = for_body.ast
26
+
27
+ ast = {
28
+ block_type: 'for-statement',
29
+ init: init
30
+ }
31
+
32
+ if test
33
+ ast[:test] = test
34
+ end
35
+
36
+ if update
37
+ ast[:update] = update
38
+ end
39
+
40
+ ast[:body] = body
41
+
42
+ [ast]
43
+ end
44
+ }
45
+ end
46
+
47
+ rule for_block_without_parentheses
48
+ for_block
49
+ end
50
+
51
+ rule for_block_with_parentheses
52
+ '(' ws1:_ for_block:for_block ws2:_ ')' {
53
+ def tokens
54
+ tokens = []
55
+
56
+ tokens.push(T_OPEN_ROUND_BRACKET)
57
+ tokens.concat(ws1.tokens) unless ws1.text_value.empty?
58
+ tokens.concat(for_block.tokens)
59
+ tokens.concat(ws2.tokens) unless ws2.text_value.empty?
60
+ tokens.push(T_CLOSE_ROUND_BRACKET)
61
+
62
+ tokens
63
+ end
64
+
65
+ def ast
66
+ for_block.ast
67
+ end
68
+ }
69
+ end
70
+
71
+ rule for_block
72
+ for_init:for_init? ws1:_ ';' ws2:_ for_test:for_test? ws3:_ ';' ws4:_ for_update:for_update? {
73
+ def tokens
74
+ tokens = []
75
+
76
+ tokens.concat(for_init.tokens) unless for_init.text_value.empty?
77
+ tokens.concat(ws1.tokens) unless ws1.text_value.empty?
78
+ tokens.push(T_SEMICOLON)
79
+ tokens.concat(ws2.tokens) unless ws2.text_value.empty?
80
+ tokens.concat(for_test.tokens) unless for_test.text_value.empty?
81
+ tokens.concat(ws3.tokens) unless ws3.text_value.empty?
82
+ tokens.push(T_SEMICOLON)
83
+ tokens.concat(ws4.tokens) unless ws4.text_value.empty?
84
+ tokens.concat(for_update.tokens) unless for_update.text_value.empty?
85
+
86
+ tokens
87
+ end
88
+
89
+ def ast
90
+ ast = {}
91
+
92
+ unless for_init.text_value.empty?
93
+ ast[:init] = for_init.ast
94
+ else
95
+ ast[:init] = []
96
+ end
97
+
98
+ unless for_test.text_value.empty?
99
+ ast[:test] = for_test.ast.first
100
+ end
101
+
102
+ unless for_update.text_value.empty?
103
+ ast[:update] = for_update.ast
104
+ end
105
+
106
+ ast
107
+ end
108
+ }
109
+ end
110
+
111
+ rule for_init
112
+ variable_declaration / expression_list
113
+ end
114
+
115
+ rule for_test
116
+ expression
117
+ end
118
+
119
+ rule for_update
120
+ expression_list
121
+ end
122
+
123
+ rule for_body
124
+ code_block
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,35 @@
1
+ module Kauri
2
+ grammar StatementForIn
3
+
4
+ rule statement_for_in
5
+ 'for' ws1:whitespaces iterator:pattern ws2:whitespaces 'in' ws3:whitespaces collection:expression ws4:_ body:code_block {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push(T_FOR)
10
+ tokens.concat(ws1.tokens)
11
+ tokens.concat(iterator.tokens)
12
+ tokens.concat(ws2.tokens)
13
+ tokens.push(T_IN)
14
+ tokens.concat(ws3.tokens)
15
+ tokens.concat(collection.tokens)
16
+ tokens.concat(ws4.tokens) unless ws4.text_value.empty?
17
+ tokens.concat(body.tokens)
18
+
19
+ tokens
20
+ end
21
+
22
+ def ast
23
+ [
24
+ {
25
+ block_type: 'for-in-statement',
26
+ iterator: iterator.ast.first,
27
+ collection: collection.ast.first,
28
+ body: body.ast
29
+ }
30
+ ]
31
+ end
32
+ }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ require 'parser/grammar/statement/loop/for'
2
+ require 'parser/grammar/statement/loop/for_in'
3
+ require 'parser/grammar/statement/loop/while'
4
+ require 'parser/grammar/statement/loop/do_while'
5
+
6
+ module Kauri
7
+ module Grammar
8
+ module Statement
9
+ grammar Loop
10
+
11
+ include Kauri::StatementFor
12
+ include Kauri::StatementForIn
13
+ include Kauri::StatementWhile
14
+ include Kauri::StatementDoWhile
15
+
16
+ rule statement_loop
17
+ statement_for_in / statement_for / statement_while / statement_do_while
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ module Kauri
2
+ grammar StatementWhile
3
+
4
+ rule statement_while
5
+ 'while' ws1:whitespaces condition:statement_while_condition ws2:_ body:code_block {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push(T_WHILE)
10
+ tokens.concat(ws1.tokens)
11
+ tokens.concat(condition.tokens)
12
+ tokens.concat(ws2.tokens) unless ws2.text_value.empty?
13
+ tokens.concat(body.tokens)
14
+
15
+ tokens
16
+ end
17
+
18
+ def ast
19
+ [
20
+ {
21
+ block_type: 'while-statement',
22
+ condition: condition.ast.first,
23
+ body: body.ast
24
+ }
25
+ ]
26
+ end
27
+ }
28
+ end
29
+
30
+ rule statement_while_condition
31
+ expression
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,97 @@
1
+ require 'parser/grammar/statement/loop/loop'
2
+ require 'parser/grammar/statement/branch/branch'
3
+
4
+ module Kauri
5
+ grammar Statement
6
+
7
+ include Kauri::Grammar::Statement::Loop
8
+ include Kauri::Grammar::Statement::Branch
9
+
10
+ rule statement
11
+ statement_loop / statement_branch / expression_statement / declaration_statement
12
+ end
13
+
14
+ rule statement_list
15
+ statement+ {
16
+ def tokens
17
+ tokens = []
18
+
19
+ elements.each { |e|
20
+ tokens.concat(e.tokens)
21
+ }
22
+
23
+ tokens
24
+ end
25
+
26
+ def ast
27
+ ast = []
28
+
29
+ elements.each { |e|
30
+ ast.concat(e.ast)
31
+ }
32
+
33
+ ast
34
+ end
35
+ }
36
+ end
37
+
38
+ rule expression_statement
39
+ expression:expression ws:_ semicolon:semicolon? {
40
+ def tokens
41
+ tokens = []
42
+
43
+ tokens.concat(expression.tokens)
44
+
45
+ unless ws.text_value.empty?
46
+ tokens.concat(ws.tokens)
47
+ end
48
+
49
+ unless semicolon.text_value.empty?
50
+ tokens.concat(semicolon.tokens)
51
+ end
52
+
53
+ tokens
54
+ end
55
+
56
+ def ast
57
+ expression.ast
58
+ end
59
+ }
60
+ end
61
+
62
+ rule declaration_statement
63
+ declaration:declaration ws:_ semicolon:semicolon? {
64
+ def tokens
65
+ tokens = []
66
+
67
+ tokens.concat(declaration.tokens)
68
+
69
+ unless ws.text_value.empty?
70
+ tokens.concat(ws.tokens)
71
+ end
72
+
73
+ unless semicolon.text_value.empty?
74
+ tokens.concat(semicolon.tokens)
75
+ end
76
+
77
+ tokens
78
+ end
79
+
80
+ def ast
81
+ declaration.ast
82
+ end
83
+ }
84
+ end
85
+
86
+ rule semicolon
87
+ ';' {
88
+ def tokens
89
+ [{
90
+ type: 'T_SEMICOLON',
91
+ value: ';'
92
+ }]
93
+ end
94
+ }
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,18 @@
1
+ require 'parser/grammar/type/type_identifier'
2
+ require 'parser/grammar/type/type_array'
3
+ require 'parser/grammar/type/type_dictionary'
4
+ require 'parser/grammar/type/type_annotation'
5
+
6
+ module Kauri
7
+ grammar Type
8
+
9
+ include Kauri::TypeIdentifier
10
+ include Kauri::TypeArray
11
+ include Kauri::TypeDictionary
12
+ include Kauri::TypeAnnotation
13
+
14
+ rule type
15
+ type_identifier / type_dictionary / type_array
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ module Kauri
2
+ grammar TypeAnnotation
3
+
4
+ rule type_annotation
5
+ ':' ws:_ type {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push({
10
+ type: 'T_COLON',
11
+ value: ':',
12
+ })
13
+
14
+ unless ws.text_value.empty?
15
+ tokens.concat(ws.tokens)
16
+ end
17
+
18
+ tokens.concat(type.tokens)
19
+
20
+ tokens
21
+ end
22
+
23
+ def ast
24
+ type.ast
25
+ end
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,43 @@
1
+ module Kauri
2
+ grammar TypeArray
3
+
4
+ rule type_array
5
+ '[' ws1:_ type:type ws2:_ ']' {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push({
10
+ type: 'T_OPEN_SQUARE_BRACKET',
11
+ value: '[',
12
+ })
13
+
14
+ unless ws1.text_value.empty?
15
+ tokens.concat(ws1.tokens)
16
+ end
17
+
18
+ tokens.concat(type.tokens)
19
+
20
+ unless ws2.text_value.empty?
21
+ tokens.concat(ws2.tokens)
22
+ end
23
+
24
+ tokens.push({
25
+ type: 'T_CLOSE_SQUARE_BRACKET',
26
+ value: ']',
27
+ })
28
+
29
+ tokens
30
+ end
31
+
32
+ def ast
33
+ [
34
+ {
35
+ block_type: 'array',
36
+ type: type.ast.first
37
+ }
38
+ ]
39
+ end
40
+ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,59 @@
1
+ module Kauri
2
+ grammar TypeDictionary
3
+
4
+ rule type_dictionary
5
+ '[' ws1:_ key_type:type ws2:_ ':' ws3:_ value_type:type ws4:_ ']' {
6
+ def tokens
7
+ tokens = []
8
+
9
+ tokens.push({
10
+ type: 'T_OPEN_SQUARE_BRACKET',
11
+ value: '[',
12
+ })
13
+
14
+ unless ws1.text_value.empty?
15
+ tokens.concat(ws1.tokens)
16
+ end
17
+
18
+ tokens.concat(key_type.tokens)
19
+
20
+ unless ws2.text_value.empty?
21
+ tokens.concat(ws2.tokens)
22
+ end
23
+
24
+ tokens.push({
25
+ type: 'T_COLON',
26
+ value: ':',
27
+ })
28
+
29
+ unless ws3.text_value.empty?
30
+ tokens.concat(ws3.tokens)
31
+ end
32
+
33
+ tokens.concat(value_type.tokens)
34
+
35
+ unless ws4.text_value.empty?
36
+ tokens.concat(ws4.tokens)
37
+ end
38
+
39
+ tokens.push({
40
+ type: 'T_CLOSE_SQUARE_BRACKET',
41
+ value: ']',
42
+ })
43
+
44
+ tokens
45
+ end
46
+
47
+ def ast
48
+ [
49
+ {
50
+ block_type: 'dictionary',
51
+ key_type: key_type.ast.first,
52
+ value_type: value_type.ast.first
53
+ }
54
+ ]
55
+ end
56
+ }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+ module Kauri
2
+ grammar TypeIdentifier
3
+
4
+ rule type_identifier
5
+ type_name:type_name ws:_ generic_argument_clause:generic_argument_clause? {
6
+ def tokens
7
+
8
+ tokens = []
9
+
10
+ tokens.concat(type_name.tokens)
11
+
12
+ unless ws.text_value.empty?
13
+ tokens.concat(ws.tokens)
14
+ end
15
+
16
+ unless generic_argument_clause.text_value.empty?
17
+ tokens.concat(generic_argument_clause.tokens)
18
+ end
19
+
20
+ tokens
21
+ end
22
+ def ast
23
+
24
+ ast = type_name.ast
25
+
26
+ unless generic_argument_clause.text_value.empty?
27
+ ast.first[:parameters] = generic_argument_clause.ast
28
+ end
29
+
30
+ ast
31
+ end
32
+ }
33
+ end
34
+
35
+ rule type_name
36
+ identifier
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ module Kauri
2
+ grammar Whitespace
3
+
4
+ rule _
5
+ whitespaces?
6
+ end
7
+
8
+ rule whitespaces
9
+ whitespace+ {
10
+ def tokens
11
+ [
12
+ {
13
+ type: 'T_WHITESPACES',
14
+ value: text_value
15
+ }
16
+ ]
17
+ end
18
+ def ast
19
+ []
20
+ end
21
+ }
22
+ end
23
+
24
+ rule whitespace
25
+ space / tab / line_break
26
+ end
27
+
28
+ rule space
29
+ [ ]
30
+ end
31
+
32
+ rule tab
33
+ [\t]
34
+ end
35
+
36
+ rule line_break
37
+ [\n]
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ module Kauri
2
+ grammar Wildcard
3
+
4
+ rule wildcard
5
+ '_' {
6
+ def tokens
7
+ [
8
+ {
9
+ type: 'T_WILDCARD',
10
+ value: '_'
11
+ }
12
+ ]
13
+ end
14
+
15
+ def ast
16
+ [
17
+ {
18
+ block_type: 'wildcard'
19
+ }
20
+ ]
21
+ end
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ module Jievro
2
+ class ParseResult
3
+
4
+ def initialize(tokens, ast)
5
+ @tokens = tokens
6
+ @ast = ast
7
+ end
8
+
9
+ def tokens
10
+ @tokens
11
+ end
12
+
13
+ def ast
14
+ @ast
15
+ end
16
+ end
17
+ end