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