myl-parser 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +61 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +8 -0
- data/Rakefile +1 -0
- data/code_example.md +286 -0
- data/lib/myl_parser.rb +8 -0
- data/lib/parser/exceptions.rb +2 -0
- data/lib/parser/myl_parser.treetop +148 -0
- data/lib/parser/syntax_node_extensions.rb +32 -0
- data/lib/parser/syntax_nodes.rb +80 -0
- data/lib/parser/tree_parser.rb +26 -0
- data/run_gurad.rb +1 -0
- data/spec/assignement/assignement_spec.rb +39 -0
- data/spec/expressions/comparaison_expressions_spec.rb +28 -0
- data/spec/expressions/compund_expressions_spec.rb +26 -0
- data/spec/expressions/simple_expressions_spec.rb +28 -0
- data/spec/flow_control/if_unless_spec.rb +15 -0
- data/spec/functions/functions_call_spec.rb +32 -0
- data/spec/helpers/assignement_helper.rb +13 -0
- data/spec/helpers/expression_helper.rb +15 -0
- data/spec/helpers/flow_control_helper.rb +9 -0
- data/spec/helpers/functions_helper.rb +9 -0
- data/spec/helpers/statement_helper.rb +6 -0
- data/spec/spec_helper.rb +23 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f6eee66c8c966f466c5bcd00f577bff30c12e04d
|
4
|
+
data.tar.gz: 53f9019cac3e714533f580f2961cd9fe79b10901
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5d504bbaf83dca795c5114e0aa6d97ec1ba21909d787eefecdff0d635e6466334ff1cf5036ff56181bb04eccb761037b3b47820372f90af3f57c911ad1a82cda
|
7
|
+
data.tar.gz: 37c90ae046874d0775edb1eb04e1e027c978918d4525f4a57591873947485a2604698979f42af08ae5fe4d924566ddc9cf3c29a5435f420d082f57bded565619
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
awesome_print (1.2.0)
|
5
|
+
celluloid (0.15.2)
|
6
|
+
timers (~> 1.1.0)
|
7
|
+
celluloid-io (0.15.0)
|
8
|
+
celluloid (>= 0.15.0)
|
9
|
+
nio4r (>= 0.5.0)
|
10
|
+
coderay (1.1.0)
|
11
|
+
diff-lcs (1.2.5)
|
12
|
+
ffi (1.9.3)
|
13
|
+
formatador (0.2.4)
|
14
|
+
guard (2.6.0)
|
15
|
+
formatador (>= 0.2.4)
|
16
|
+
listen (~> 2.7)
|
17
|
+
lumberjack (~> 1.0)
|
18
|
+
pry (>= 0.9.12)
|
19
|
+
thor (>= 0.18.1)
|
20
|
+
guard-rspec (4.2.8)
|
21
|
+
guard (~> 2.1)
|
22
|
+
rspec (>= 2.14, < 4.0)
|
23
|
+
listen (2.7.1)
|
24
|
+
celluloid (>= 0.15.2)
|
25
|
+
celluloid-io (>= 0.15.0)
|
26
|
+
rb-fsevent (>= 0.9.3)
|
27
|
+
rb-inotify (>= 0.9)
|
28
|
+
lumberjack (1.0.5)
|
29
|
+
method_source (0.8.2)
|
30
|
+
nio4r (1.0.0)
|
31
|
+
polyglot (0.3.4)
|
32
|
+
pry (0.9.12.6)
|
33
|
+
coderay (~> 1.0)
|
34
|
+
method_source (~> 0.8)
|
35
|
+
slop (~> 3.4)
|
36
|
+
rb-fsevent (0.9.4)
|
37
|
+
rb-inotify (0.9.3)
|
38
|
+
ffi (>= 0.5.0)
|
39
|
+
rspec (2.14.1)
|
40
|
+
rspec-core (~> 2.14.0)
|
41
|
+
rspec-expectations (~> 2.14.0)
|
42
|
+
rspec-mocks (~> 2.14.0)
|
43
|
+
rspec-core (2.14.8)
|
44
|
+
rspec-expectations (2.14.5)
|
45
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
46
|
+
rspec-mocks (2.14.6)
|
47
|
+
slop (3.5.0)
|
48
|
+
thor (0.19.1)
|
49
|
+
timers (1.1.0)
|
50
|
+
treetop (1.5.3)
|
51
|
+
polyglot (~> 0.3)
|
52
|
+
|
53
|
+
PLATFORMS
|
54
|
+
ruby
|
55
|
+
|
56
|
+
DEPENDENCIES
|
57
|
+
awesome_print
|
58
|
+
guard
|
59
|
+
guard-rspec
|
60
|
+
rspec
|
61
|
+
treetop
|
data/Guardfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/parser/myl_parser\.treetop$}) { "spec" }
|
7
|
+
watch(%r{^spec/helpers/.+_helper\.rb$}) {'spec'}
|
8
|
+
watch('spec/spec_helper.rb') { "spec" }
|
9
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 leo
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/code_example.md
ADDED
@@ -0,0 +1,286 @@
|
|
1
|
+
|
2
|
+
```
|
3
|
+
test = 1.0
|
4
|
+
```
|
5
|
+
|
6
|
+
```
|
7
|
+
test = -2234.342
|
8
|
+
```
|
9
|
+
|
10
|
+
```
|
11
|
+
test = 12134
|
12
|
+
```
|
13
|
+
|
14
|
+
```
|
15
|
+
test = -2234
|
16
|
+
```
|
17
|
+
|
18
|
+
```
|
19
|
+
test = 1
|
20
|
+
```
|
21
|
+
|
22
|
+
```
|
23
|
+
test = -2
|
24
|
+
```
|
25
|
+
|
26
|
+
```
|
27
|
+
test = true
|
28
|
+
```
|
29
|
+
|
30
|
+
```
|
31
|
+
test = false
|
32
|
+
```
|
33
|
+
|
34
|
+
```
|
35
|
+
test = nil
|
36
|
+
```
|
37
|
+
|
38
|
+
```
|
39
|
+
test = "salut"
|
40
|
+
```
|
41
|
+
|
42
|
+
```
|
43
|
+
test = "salut \"numa\" ca va"
|
44
|
+
```
|
45
|
+
|
46
|
+
```
|
47
|
+
test = 2+2
|
48
|
+
```
|
49
|
+
|
50
|
+
```
|
51
|
+
test = function(args)
|
52
|
+
```
|
53
|
+
|
54
|
+
```
|
55
|
+
test = function()
|
56
|
+
```
|
57
|
+
|
58
|
+
```
|
59
|
+
test = ident
|
60
|
+
```
|
61
|
+
|
62
|
+
```
|
63
|
+
1 == 1
|
64
|
+
```
|
65
|
+
|
66
|
+
```
|
67
|
+
2.3 == 2.3
|
68
|
+
```
|
69
|
+
|
70
|
+
```
|
71
|
+
"a" == "a"
|
72
|
+
```
|
73
|
+
|
74
|
+
```
|
75
|
+
test == test2
|
76
|
+
```
|
77
|
+
|
78
|
+
```
|
79
|
+
1 != 2
|
80
|
+
```
|
81
|
+
|
82
|
+
```
|
83
|
+
2.0 != 2.3
|
84
|
+
```
|
85
|
+
|
86
|
+
```
|
87
|
+
"b" != "a"
|
88
|
+
```
|
89
|
+
|
90
|
+
```
|
91
|
+
test != test2
|
92
|
+
```
|
93
|
+
|
94
|
+
```
|
95
|
+
2 > 1
|
96
|
+
```
|
97
|
+
|
98
|
+
```
|
99
|
+
2.4 > 2.3
|
100
|
+
```
|
101
|
+
|
102
|
+
```
|
103
|
+
"b" > "a"
|
104
|
+
```
|
105
|
+
|
106
|
+
```
|
107
|
+
test > test2
|
108
|
+
```
|
109
|
+
|
110
|
+
```
|
111
|
+
1 < 2
|
112
|
+
```
|
113
|
+
|
114
|
+
```
|
115
|
+
2.0 < 2.3
|
116
|
+
```
|
117
|
+
|
118
|
+
```
|
119
|
+
"a" < "b"
|
120
|
+
```
|
121
|
+
|
122
|
+
```
|
123
|
+
test < test2
|
124
|
+
```
|
125
|
+
|
126
|
+
```
|
127
|
+
blup(2) + 1
|
128
|
+
```
|
129
|
+
|
130
|
+
```
|
131
|
+
blup(2) + 1
|
132
|
+
```
|
133
|
+
|
134
|
+
```
|
135
|
+
blup(2) + 1
|
136
|
+
```
|
137
|
+
|
138
|
+
```
|
139
|
+
2*4+2/8
|
140
|
+
```
|
141
|
+
|
142
|
+
```
|
143
|
+
2*4+2/8
|
144
|
+
```
|
145
|
+
|
146
|
+
```
|
147
|
+
2*4+2/8
|
148
|
+
```
|
149
|
+
|
150
|
+
```
|
151
|
+
2/(8+1)
|
152
|
+
```
|
153
|
+
|
154
|
+
```
|
155
|
+
2/(8+1)
|
156
|
+
```
|
157
|
+
|
158
|
+
```
|
159
|
+
2/(8+1)
|
160
|
+
```
|
161
|
+
|
162
|
+
```
|
163
|
+
2+2
|
164
|
+
```
|
165
|
+
|
166
|
+
```
|
167
|
+
2.0+ 3.9
|
168
|
+
```
|
169
|
+
|
170
|
+
```
|
171
|
+
"saalut"+ "ça va?"
|
172
|
+
```
|
173
|
+
|
174
|
+
```
|
175
|
+
q+ w
|
176
|
+
```
|
177
|
+
|
178
|
+
```
|
179
|
+
2-2
|
180
|
+
```
|
181
|
+
|
182
|
+
```
|
183
|
+
2.0 - 3.9
|
184
|
+
```
|
185
|
+
|
186
|
+
```
|
187
|
+
"saalut"- "ça va?"
|
188
|
+
```
|
189
|
+
|
190
|
+
```
|
191
|
+
q -w
|
192
|
+
```
|
193
|
+
|
194
|
+
```
|
195
|
+
2*2
|
196
|
+
```
|
197
|
+
|
198
|
+
```
|
199
|
+
2.0* 3.9
|
200
|
+
```
|
201
|
+
|
202
|
+
```
|
203
|
+
"abc"* 3
|
204
|
+
```
|
205
|
+
|
206
|
+
```
|
207
|
+
q* w
|
208
|
+
```
|
209
|
+
|
210
|
+
```
|
211
|
+
2/2
|
212
|
+
```
|
213
|
+
|
214
|
+
```
|
215
|
+
2.0/ 3.9
|
216
|
+
```
|
217
|
+
|
218
|
+
```
|
219
|
+
"saalut"/ "ça va?"
|
220
|
+
```
|
221
|
+
|
222
|
+
```
|
223
|
+
q/ w
|
224
|
+
```
|
225
|
+
|
226
|
+
```
|
227
|
+
if(1 == 1) test = 1; test2 = 2; end
|
228
|
+
```
|
229
|
+
|
230
|
+
```
|
231
|
+
if(1 == 1)
|
232
|
+
test = 1
|
233
|
+
test2 = 2
|
234
|
+
end
|
235
|
+
```
|
236
|
+
|
237
|
+
```
|
238
|
+
unless(1 == 1) test = 1; test2 = 2; end
|
239
|
+
```
|
240
|
+
|
241
|
+
```
|
242
|
+
unless(1 == 1)
|
243
|
+
test = 1
|
244
|
+
test2 = 2
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
248
|
+
```
|
249
|
+
test()
|
250
|
+
```
|
251
|
+
|
252
|
+
```
|
253
|
+
test(1)
|
254
|
+
```
|
255
|
+
|
256
|
+
```
|
257
|
+
test(1)
|
258
|
+
```
|
259
|
+
|
260
|
+
```
|
261
|
+
test(1, "abc")
|
262
|
+
```
|
263
|
+
|
264
|
+
```
|
265
|
+
test(1, "abc")
|
266
|
+
```
|
267
|
+
|
268
|
+
```
|
269
|
+
test(1, "abc")
|
270
|
+
```
|
271
|
+
|
272
|
+
```
|
273
|
+
test(1, test2())
|
274
|
+
```
|
275
|
+
|
276
|
+
```
|
277
|
+
test(1, test2())
|
278
|
+
```
|
279
|
+
|
280
|
+
```
|
281
|
+
test(1, test2())
|
282
|
+
```
|
283
|
+
|
284
|
+
```
|
285
|
+
test(1, test2())
|
286
|
+
```
|
data/lib/myl_parser.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# More info on PEGs: http://en.wikipedia.org/wiki/Parsing_expression_grammar
|
2
|
+
# More info on Treetop: http://treetop.rubyforge.org/
|
3
|
+
|
4
|
+
grammar Myl
|
5
|
+
rule block
|
6
|
+
statement+ <Block>
|
7
|
+
end
|
8
|
+
rule statement
|
9
|
+
space? expression space? <Statement>
|
10
|
+
end
|
11
|
+
|
12
|
+
rule expression
|
13
|
+
space? (flow_control / assignment / comparative / additive) '.'? function_call? <Expression>
|
14
|
+
end
|
15
|
+
|
16
|
+
# LITERALS
|
17
|
+
rule true
|
18
|
+
'true' <TrueLiteral>
|
19
|
+
end
|
20
|
+
|
21
|
+
rule false
|
22
|
+
'false' <FalseLiteral>
|
23
|
+
end
|
24
|
+
|
25
|
+
rule nil
|
26
|
+
'nil' <NilLiteral>
|
27
|
+
end
|
28
|
+
|
29
|
+
rule integer
|
30
|
+
('-')? [0-9]+ <IntegerLiteral>
|
31
|
+
end
|
32
|
+
|
33
|
+
rule float
|
34
|
+
('-')? [0-9]+ '.' [0-9]+ <FloatLiteral>
|
35
|
+
end
|
36
|
+
|
37
|
+
rule string
|
38
|
+
'"' ([^"\\] / "\\" . )* '"' <StringLiteral>
|
39
|
+
end
|
40
|
+
|
41
|
+
rule identifier
|
42
|
+
[a-zA-Z] [a-zA-Z0-9_]* ('?' / '!')? <Identifier>
|
43
|
+
end
|
44
|
+
|
45
|
+
#END LITERALS
|
46
|
+
|
47
|
+
#FUNCTION CALL
|
48
|
+
rule function_call
|
49
|
+
identifier '(' space? expression? space? ','? expression? space? ')' <FunctionCall>
|
50
|
+
end
|
51
|
+
#END FUNCTION CALL
|
52
|
+
|
53
|
+
# FLOW CONTROL
|
54
|
+
rule flow_control
|
55
|
+
unless / if
|
56
|
+
end
|
57
|
+
|
58
|
+
rule if
|
59
|
+
'if' '('? space? expression space? ')'? space? '{'? space? block space? '}'? <If>
|
60
|
+
end
|
61
|
+
|
62
|
+
rule unless
|
63
|
+
'unless' '('? space? expression space? ')'? space? '{'? space? block space? '}'? <Unless>
|
64
|
+
end
|
65
|
+
# END FLOW CONTROL
|
66
|
+
|
67
|
+
# ASSIGNMENT
|
68
|
+
rule assignment
|
69
|
+
identifier space? assignment_operator space? expression <Assignment>
|
70
|
+
end
|
71
|
+
|
72
|
+
rule assignment_operator
|
73
|
+
'=' <AssignmentOperator>
|
74
|
+
end
|
75
|
+
|
76
|
+
#END ASSIGNMENT
|
77
|
+
|
78
|
+
# MATH
|
79
|
+
rule comparative
|
80
|
+
primary space? comparative_operator space? primary <ComparativeExpression>
|
81
|
+
end
|
82
|
+
rule additive
|
83
|
+
multitive space? additive_operator space? additive <AdditiveExpression>
|
84
|
+
/
|
85
|
+
multitive
|
86
|
+
end
|
87
|
+
|
88
|
+
rule multitive
|
89
|
+
primary space? multitive_operator space? multitive <MultitiveExpression>
|
90
|
+
/
|
91
|
+
primary
|
92
|
+
end
|
93
|
+
|
94
|
+
rule primary
|
95
|
+
(function_call / nil / true / false / identifier / float / integer / string)
|
96
|
+
/
|
97
|
+
'(' expression ')' <Expression>
|
98
|
+
end
|
99
|
+
# END MATH
|
100
|
+
|
101
|
+
# OPERATOR
|
102
|
+
rule comparative_operator
|
103
|
+
equality_operator / inequality_operator / greater_than_operator / less_than_operator
|
104
|
+
end
|
105
|
+
rule equality_operator
|
106
|
+
'==' <EqualityOperator>
|
107
|
+
end
|
108
|
+
|
109
|
+
rule inequality_operator
|
110
|
+
'!=' <InEqualityOperator>
|
111
|
+
end
|
112
|
+
|
113
|
+
rule greater_than_operator
|
114
|
+
'>' <GreaterThanOperator>
|
115
|
+
end
|
116
|
+
|
117
|
+
rule less_than_operator
|
118
|
+
'<' <LessThanOperator>
|
119
|
+
end
|
120
|
+
|
121
|
+
rule multitive_operator
|
122
|
+
multiplication_operator / division_operator
|
123
|
+
end
|
124
|
+
|
125
|
+
rule multiplication_operator
|
126
|
+
'*' <MultiplicationOperator>
|
127
|
+
end
|
128
|
+
|
129
|
+
rule division_operator
|
130
|
+
'/' <DivisionOperator>
|
131
|
+
end
|
132
|
+
|
133
|
+
rule additive_operator
|
134
|
+
addition_operator / subtraction_operator
|
135
|
+
end
|
136
|
+
|
137
|
+
rule subtraction_operator
|
138
|
+
'-' <SubtractionOperator>
|
139
|
+
end
|
140
|
+
|
141
|
+
rule addition_operator
|
142
|
+
'+' <AdditionOperator>
|
143
|
+
end
|
144
|
+
# END OPERATOR
|
145
|
+
rule space
|
146
|
+
[\s]
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
module MylReferenceParser
|
3
|
+
class Treetop::Runtime::SyntaxNode
|
4
|
+
|
5
|
+
def to_hash()
|
6
|
+
hash = {}
|
7
|
+
hash[:offset] = self.interval.first
|
8
|
+
hash[:text_value] = self.text_value
|
9
|
+
hash[:name] = self.class.name.split("::").last
|
10
|
+
unless( self.elements.nil? )
|
11
|
+
hash[:elements] = self.elements.map {|element| element.to_hash() }
|
12
|
+
else
|
13
|
+
hash[:elements] = nil
|
14
|
+
end
|
15
|
+
return hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_element(nth, params = {})
|
19
|
+
demand_elem = get_element_rec(nth, 0, self.elements)
|
20
|
+
return demand_elem.elements[params[:child]] if params[:child]
|
21
|
+
return demand_elem
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def get_element_rec(nth, level, rec_elements)
|
27
|
+
return rec_elements.last if level == nth
|
28
|
+
get_element_rec(nth, level+1, rec_elements.last.elements)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module MylReferenceParser
|
2
|
+
|
3
|
+
class Block < Treetop::Runtime::SyntaxNode
|
4
|
+
end
|
5
|
+
|
6
|
+
class Statement < Treetop::Runtime::SyntaxNode
|
7
|
+
end
|
8
|
+
|
9
|
+
class Assignment < Treetop::Runtime::SyntaxNode
|
10
|
+
end
|
11
|
+
|
12
|
+
class If < Treetop::Runtime::SyntaxNode
|
13
|
+
end
|
14
|
+
|
15
|
+
class Unless < Treetop::Runtime::SyntaxNode
|
16
|
+
end
|
17
|
+
|
18
|
+
class FunctionCall < Treetop::Runtime::SyntaxNode
|
19
|
+
end
|
20
|
+
|
21
|
+
class NilLiteral < Treetop::Runtime::SyntaxNode
|
22
|
+
end
|
23
|
+
|
24
|
+
class TrueLiteral < Treetop::Runtime::SyntaxNode
|
25
|
+
end
|
26
|
+
|
27
|
+
class FalseLiteral < Treetop::Runtime::SyntaxNode
|
28
|
+
end
|
29
|
+
|
30
|
+
class IntegerLiteral < Treetop::Runtime::SyntaxNode
|
31
|
+
end
|
32
|
+
|
33
|
+
class FloatLiteral < Treetop::Runtime::SyntaxNode
|
34
|
+
end
|
35
|
+
|
36
|
+
class StringLiteral < Treetop::Runtime::SyntaxNode
|
37
|
+
end
|
38
|
+
|
39
|
+
class Identifier < Treetop::Runtime::SyntaxNode
|
40
|
+
end
|
41
|
+
|
42
|
+
class AssignmentOperator < Treetop::Runtime::SyntaxNode
|
43
|
+
end
|
44
|
+
|
45
|
+
class EqualityOperator < Treetop::Runtime::SyntaxNode
|
46
|
+
end
|
47
|
+
|
48
|
+
class InEqualityOperator < Treetop::Runtime::SyntaxNode
|
49
|
+
end
|
50
|
+
|
51
|
+
class GreaterThanOperator < Treetop::Runtime::SyntaxNode
|
52
|
+
end
|
53
|
+
|
54
|
+
class LessThanOperator < Treetop::Runtime::SyntaxNode
|
55
|
+
end
|
56
|
+
|
57
|
+
class AdditionOperator < Treetop::Runtime::SyntaxNode
|
58
|
+
end
|
59
|
+
|
60
|
+
class SubtractionOperator < Treetop::Runtime::SyntaxNode
|
61
|
+
end
|
62
|
+
|
63
|
+
class MultiplicationOperator < Treetop::Runtime::SyntaxNode
|
64
|
+
end
|
65
|
+
|
66
|
+
class DivisionOperator < Treetop::Runtime::SyntaxNode
|
67
|
+
end
|
68
|
+
|
69
|
+
class Expression < Treetop::Runtime::SyntaxNode
|
70
|
+
end
|
71
|
+
|
72
|
+
class ComparativeExpression < Treetop::Runtime::SyntaxNode
|
73
|
+
end
|
74
|
+
|
75
|
+
class AdditiveExpression < Treetop::Runtime::SyntaxNode
|
76
|
+
end
|
77
|
+
|
78
|
+
class MultitiveExpression < Treetop::Runtime::SyntaxNode
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class TreeParser
|
2
|
+
require 'treetop'
|
3
|
+
Treetop.load(File.expand_path(File.join(File.dirname(__FILE__), 'myl_parser.treetop')))
|
4
|
+
@@parser = MylParser.new
|
5
|
+
|
6
|
+
def self.parse(data)
|
7
|
+
tree = @@parser.parse(data)
|
8
|
+
|
9
|
+
if(tree.nil?)
|
10
|
+
raise ParseError, "Parse error at offset: #{@@parser.index}"
|
11
|
+
end
|
12
|
+
|
13
|
+
# clean up the tree by removing all nodes of default type 'SyntaxNode'
|
14
|
+
self.clean_tree(tree)
|
15
|
+
|
16
|
+
return tree
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def self.clean_tree(root_node)
|
22
|
+
return if(root_node.elements.nil?)
|
23
|
+
root_node.elements.delete_if{|node| node.class.name == "Treetop::Runtime::SyntaxNode" }
|
24
|
+
root_node.elements.each {|node| self.clean_tree(node) }
|
25
|
+
end
|
26
|
+
end
|
data/run_gurad.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
exec 'bundle exec guard'
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'assignement of a' do
|
4
|
+
context 'float' do
|
5
|
+
it { parse('test = 1.0').should be_an_assignement 1.0, FloatLiteral }
|
6
|
+
it { parse('test = -2234.342').should be_an_assignement -2234.342, FloatLiteral }
|
7
|
+
end
|
8
|
+
context 'integer' do
|
9
|
+
it { parse('test = 12134').should be_an_assignement(12134, IntegerLiteral) }
|
10
|
+
it { parse('test = -2234').should be_an_assignement(-2234, IntegerLiteral) }
|
11
|
+
it { parse('test = 1').should be_an_assignement(1, IntegerLiteral) }
|
12
|
+
it { parse('test = -2').should be_an_assignement(-2, IntegerLiteral) }
|
13
|
+
end
|
14
|
+
context 'boolean' do
|
15
|
+
it { parse('test = true').should be_an_assignement true, TrueLiteral }
|
16
|
+
it { parse('test = false').should be_an_assignement false, FalseLiteral }
|
17
|
+
end
|
18
|
+
context 'nil' do
|
19
|
+
it { parse('test = nil').should be_an_assignement 'nil', NilLiteral }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'string' do
|
23
|
+
it { parse('test = "salut"').should be_an_assignement '"salut"', StringLiteral }
|
24
|
+
it 'with escaped quotes' do
|
25
|
+
parse('test = "salut \"numa\" ca va"').
|
26
|
+
should be_an_assignement '"salut \"numa\" ca va"', StringLiteral
|
27
|
+
end
|
28
|
+
end
|
29
|
+
context 'expression' do
|
30
|
+
it { puts parse('test = 2+2').should be_an_assignement '2+2', AdditiveExpression }
|
31
|
+
end
|
32
|
+
context 'function call' do
|
33
|
+
it { parse('test = function(args)').should be_an_assignement 'function(args)', FunctionCall }
|
34
|
+
it { parse('test = function()').should be_an_assignement 'function()', FunctionCall }
|
35
|
+
end
|
36
|
+
context 'identifier' do
|
37
|
+
it { parse('test = ident').should be_an_assignement 'ident', Identifier }
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'comparaison expressions' do
|
4
|
+
context 'equality' do
|
5
|
+
it {parse('1 == 1').should be_a_full_expression ComparativeExpression, EqualityOperator}
|
6
|
+
it {parse('2.3 == 2.3').should be_a_full_expression ComparativeExpression, EqualityOperator}
|
7
|
+
it {parse('"a" == "a"').should be_a_full_expression ComparativeExpression, EqualityOperator}
|
8
|
+
it {parse('test == test2').should be_a_full_expression ComparativeExpression, EqualityOperator}
|
9
|
+
end
|
10
|
+
context 'inequality' do
|
11
|
+
it {parse('1 != 2').should be_a_full_expression ComparativeExpression, InEqualityOperator}
|
12
|
+
it {parse('2.0 != 2.3').should be_a_full_expression ComparativeExpression, InEqualityOperator}
|
13
|
+
it {parse('"b" != "a"').should be_a_full_expression ComparativeExpression, InEqualityOperator}
|
14
|
+
it {parse('test != test2').should be_a_full_expression ComparativeExpression, InEqualityOperator}
|
15
|
+
end
|
16
|
+
context 'greater than' do
|
17
|
+
it {parse('2 > 1').should be_a_full_expression ComparativeExpression, GreaterThanOperator}
|
18
|
+
it {parse('2.4 > 2.3').should be_a_full_expression ComparativeExpression, GreaterThanOperator}
|
19
|
+
it {parse('"b" > "a"').should be_a_full_expression ComparativeExpression, GreaterThanOperator}
|
20
|
+
it {parse('test > test2').should be_a_full_expression ComparativeExpression, GreaterThanOperator}
|
21
|
+
end
|
22
|
+
context 'less than' do
|
23
|
+
it {parse('1 < 2').should be_a_full_expression ComparativeExpression, LessThanOperator}
|
24
|
+
it {parse('2.0 < 2.3').should be_a_full_expression ComparativeExpression, LessThanOperator}
|
25
|
+
it {parse('"a" < "b"').should be_a_full_expression ComparativeExpression, LessThanOperator}
|
26
|
+
it {parse('test < test2').should be_a_full_expression ComparativeExpression, LessThanOperator}
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'compound expressions' do
|
4
|
+
context 'has function call' do
|
5
|
+
subject(:result) { parse('blup(2)+ 1') }
|
6
|
+
it { should be_a_full_expression(AdditiveExpression, AdditionOperator) }
|
7
|
+
it { result.get_element(2, child: 0).should be_a FunctionCall }
|
8
|
+
it { result.get_element(3).should be_a IntegerLiteral }
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'has sub expression' do
|
12
|
+
subject(:result) { parse('2*4+2/8') }
|
13
|
+
let(:expr) { result.get_element(1) }
|
14
|
+
it { should be_a_full_expression AdditiveExpression, AdditionOperator }
|
15
|
+
it { expr.get_element(0, child: 0).should be_an_expression(MultitiveExpression, MultiplicationOperator) }
|
16
|
+
it { expr.get_element(1).should be_an_expression(MultitiveExpression, DivisionOperator) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'has parenthesis' do
|
20
|
+
subject(:result) { parse('2/(8+1)') }
|
21
|
+
let(:expr) { result.get_element(1) }
|
22
|
+
it { should be_a_full_expression MultitiveExpression, DivisionOperator }
|
23
|
+
it { result.get_element(5).should be_an_expression AdditiveExpression, AdditionOperator }
|
24
|
+
it { result.get_element(4).should be_a Expression }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'simple expressions' do
|
4
|
+
context 'addition' do
|
5
|
+
it { parse('2+2').should be_a_full_expression(AdditiveExpression, AdditionOperator) }
|
6
|
+
it { parse('2+ 3.9').should be_a_full_expression(AdditiveExpression, AdditionOperator) }
|
7
|
+
it { parse('"saalut"+ "ça va?"').should be_a_full_expression(AdditiveExpression, AdditionOperator) }
|
8
|
+
it { parse('q+ w').should be_a_full_expression(AdditiveExpression, AdditionOperator) }
|
9
|
+
end
|
10
|
+
context 'subtraction' do
|
11
|
+
it { parse('2-2').should be_a_full_expression(AdditiveExpression, SubtractionOperator) }
|
12
|
+
it { parse('2.0 - 3.9').should be_a_full_expression(AdditiveExpression, SubtractionOperator) }
|
13
|
+
it { parse('"saalut"- "ça va?"').should be_a_full_expression(AdditiveExpression, SubtractionOperator) }
|
14
|
+
it { parse('q -w').should be_a_full_expression(AdditiveExpression, SubtractionOperator) }
|
15
|
+
end
|
16
|
+
context 'multiplication' do
|
17
|
+
it { parse('2*2').should be_a_full_expression(MultitiveExpression, MultiplicationOperator) }
|
18
|
+
it { parse('2.0* 3.9').should be_a_full_expression(MultitiveExpression, MultiplicationOperator) }
|
19
|
+
it { parse('"abc"* 3').should be_a_full_expression(MultitiveExpression, MultiplicationOperator) }
|
20
|
+
it { parse('q* w').should be_a_full_expression(MultitiveExpression, MultiplicationOperator) }
|
21
|
+
end
|
22
|
+
context 'division' do
|
23
|
+
it { parse('2/2').should be_a_full_expression(MultitiveExpression, DivisionOperator) }
|
24
|
+
it { parse('2.0/ 3.9').should be_a_full_expression(MultitiveExpression, DivisionOperator) }
|
25
|
+
it { parse('"saalut"/ "ça va?"').should be_a_full_expression(MultitiveExpression, DivisionOperator) }
|
26
|
+
it { parse('q/ w').should be_a_full_expression(MultitiveExpression, DivisionOperator) }
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'flow control' do
|
4
|
+
context 'if' do
|
5
|
+
subject(:result) { parse('if 1 == 1 test = 1 test2 = 2 } test3=3') }
|
6
|
+
it { should be_a_flow_control If }
|
7
|
+
it { result.get_element(0, child: 0).get_element(0).text_value.should eq('test3=3') }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'unless' do
|
11
|
+
subject(:result) { parse("unless(1 == 1) {\ntest = 1\ntest2 = 2\n}\ntest=3\n") }
|
12
|
+
it { should be_a_flow_control Unless }
|
13
|
+
it { result.get_element(0, child: 0).get_element(0).text_value.should eq('test=3') }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'function call' do
|
4
|
+
context 'without arguments' do
|
5
|
+
subject(:result) { parse('test()') }
|
6
|
+
it{ should be_a_function_call 'test' }
|
7
|
+
end
|
8
|
+
context 'with one argument' do
|
9
|
+
subject(:result) { parse('test(1)') }
|
10
|
+
it{ should be_a_function_call 'test' }
|
11
|
+
it{ result.get_element(4).should be_a IntegerLiteral }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with multiple arguments' do
|
15
|
+
subject(:result) { parse('test(1, "abc")') }
|
16
|
+
it{ should be_a_function_call 'test' }
|
17
|
+
it{ result.get_element(2, child: 1).elements.first.should be_a IntegerLiteral }
|
18
|
+
it{ result.get_element(4).should be_a StringLiteral }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with argument as function call' do
|
22
|
+
subject(:result) { parse('test(1, test2())') }
|
23
|
+
it{ should be_a_function_call 'test' }
|
24
|
+
it{ result.get_element(2, child: 1).elements.first.should be_a IntegerLiteral }
|
25
|
+
it{ result.get_element(4).should be_a FunctionCall }
|
26
|
+
it{ result.get_element(5).text_value.should eq('test2') }
|
27
|
+
end
|
28
|
+
context 'after an expression' do
|
29
|
+
subject(:result) { parse('2.print()') }
|
30
|
+
it { puts result.get_element(2).should be_a FunctionCall }
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
RSpec::Matchers.define :be_an_assignement do |value, type|
|
2
|
+
match do |tree|
|
3
|
+
tree.should be_a Block
|
4
|
+
tree.get_element(0).should be_a Statement
|
5
|
+
tree.get_element(1).should be_a Expression
|
6
|
+
tree.get_element(1, child: 0).should be_a Assignment
|
7
|
+
tree.get_element(2, child: 0).should be_a Identifier
|
8
|
+
tree.get_element(2, child: 1).should be_a AssignmentOperator
|
9
|
+
tree.get_element(2, child: 2).should be_a Expression
|
10
|
+
tree.get_element(3).get_element(0).should be_a type
|
11
|
+
tree.get_element(3).get_element(0).text_value.should eq value.to_s
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
RSpec::Matchers.define :be_an_expression do |expression_type, operator|
|
2
|
+
match do |tree|
|
3
|
+
tree.should be_a expression_type
|
4
|
+
tree.elements.size.should eq 3
|
5
|
+
tree.elements[1].should be_a operator
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec::Matchers.define :be_a_full_expression do |expression_type, operator|
|
10
|
+
match do |tree|
|
11
|
+
tree.should be_a_statement
|
12
|
+
tree.get_element(1).should be_a Expression
|
13
|
+
tree.get_element(2).should be_an_expression expression_type, operator
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
RSpec::Matchers.define :be_a_flow_control do |condition_type|
|
2
|
+
match do |tree|
|
3
|
+
tree.should be_a_statement
|
4
|
+
if_element = tree.elements.first.get_element(0, child: 0)
|
5
|
+
if_element.should be_a condition_type
|
6
|
+
if_element.elements.first.should be_a Expression
|
7
|
+
if_element.elements[1].should be_a Block
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
RSpec::Matchers.define :be_a_function_call do |identifier|
|
2
|
+
match do |tree|
|
3
|
+
tree.should be_a_statement
|
4
|
+
tree.get_element(1).should be_a Expression
|
5
|
+
tree.get_element(2).should be_a FunctionCall
|
6
|
+
tree.get_element(2, child: 0).should be_a Identifier
|
7
|
+
tree.get_element(2, child: 0).text_value.should eq(identifier)
|
8
|
+
end
|
9
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'ap'
|
2
|
+
required_files = []
|
3
|
+
required_files.concat Dir[File.join(File.dirname(__FILE__), 'helpers', '**', '*.rb')]
|
4
|
+
required_files << File.join(File.dirname(__FILE__), '..', 'lib', 'myl_parser.rb')
|
5
|
+
required_files.each do |file|
|
6
|
+
require File.expand_path file
|
7
|
+
end
|
8
|
+
|
9
|
+
include MylReferenceParser
|
10
|
+
|
11
|
+
def parse(data)
|
12
|
+
if ENV['Myl'] == 'print'
|
13
|
+
begin
|
14
|
+
file = File.open(File.join(File.dirname(__FILE__), '..', 'code_example.md'), 'a')
|
15
|
+
file.write("\n```\n#{data}\n```\n")
|
16
|
+
rescue IOError => e
|
17
|
+
puts 'error while writing to file '
|
18
|
+
ensure
|
19
|
+
file.close unless file == nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
TreeParser.parse(data)
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: myl-parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- facenord
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Parser for the myl language inspired by the koi language
|
42
|
+
email:
|
43
|
+
- facenord.sud@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
|
+
- Gemfile
|
51
|
+
- Gemfile.lock
|
52
|
+
- Guardfile
|
53
|
+
- LICENSE.txt
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- code_example.md
|
57
|
+
- lib/myl_parser.rb
|
58
|
+
- lib/parser/exceptions.rb
|
59
|
+
- lib/parser/myl_parser.treetop
|
60
|
+
- lib/parser/syntax_node_extensions.rb
|
61
|
+
- lib/parser/syntax_nodes.rb
|
62
|
+
- lib/parser/tree_parser.rb
|
63
|
+
- run_gurad.rb
|
64
|
+
- spec/assignement/assignement_spec.rb
|
65
|
+
- spec/expressions/comparaison_expressions_spec.rb
|
66
|
+
- spec/expressions/compund_expressions_spec.rb
|
67
|
+
- spec/expressions/simple_expressions_spec.rb
|
68
|
+
- spec/flow_control/if_unless_spec.rb
|
69
|
+
- spec/functions/functions_call_spec.rb
|
70
|
+
- spec/helpers/assignement_helper.rb
|
71
|
+
- spec/helpers/expression_helper.rb
|
72
|
+
- spec/helpers/flow_control_helper.rb
|
73
|
+
- spec/helpers/functions_helper.rb
|
74
|
+
- spec/helpers/statement_helper.rb
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
homepage: https://github.com/facenord-sud/myl
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.2.1
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: The first for implementing the myl language. The parser which is returning
|
100
|
+
an AST. Using Treetop, based on the PEG
|
101
|
+
test_files:
|
102
|
+
- spec/assignement/assignement_spec.rb
|
103
|
+
- spec/expressions/comparaison_expressions_spec.rb
|
104
|
+
- spec/expressions/compund_expressions_spec.rb
|
105
|
+
- spec/expressions/simple_expressions_spec.rb
|
106
|
+
- spec/flow_control/if_unless_spec.rb
|
107
|
+
- spec/functions/functions_call_spec.rb
|
108
|
+
- spec/helpers/assignement_helper.rb
|
109
|
+
- spec/helpers/expression_helper.rb
|
110
|
+
- spec/helpers/flow_control_helper.rb
|
111
|
+
- spec/helpers/functions_helper.rb
|
112
|
+
- spec/helpers/statement_helper.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
has_rdoc:
|