myl-parser 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ *.gemspec
3
+ *.swp
4
+ /.idea
5
+ /pkg
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'treetop'
4
+ gem 'rspec', require: 'spec'
5
+ gem 'awesome_print'
6
+ gem 'guard'
7
+ gem 'guard-rspec', require: false
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
@@ -0,0 +1,8 @@
1
+ myl
2
+ ===
3
+
4
+ a simple language
5
+
6
+ Based on the koi language
7
+
8
+ see code_example.md for tested code and have example of what you can do
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,8 @@
1
+ require 'rubygems'
2
+
3
+ require_files = []
4
+ require_files.concat Dir[File.join(File.dirname(__FILE__), 'parser', '**', '*.rb')]
5
+
6
+ require_files.each do |file|
7
+ require File.expand_path(file)
8
+ end
@@ -0,0 +1,2 @@
1
+ class ParseError < Exception
2
+ end
@@ -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
@@ -0,0 +1,6 @@
1
+ RSpec::Matchers.define :be_a_statement do
2
+ match do |tree|
3
+ tree.should be_a Block
4
+ tree.get_element(0).should be_a Statement
5
+ end
6
+ end
@@ -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: