metal 0.0.2 → 0.0.3

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.
@@ -0,0 +1,4 @@
1
+ #import "metal/runtime.h"
2
+ #import "metal/input.h"
3
+ #import "metal/exception.h"
4
+ // vim: ft=objcpp
@@ -0,0 +1,15 @@
1
+ #import <string>
2
+ #import <stdexcept>
3
+
4
+ namespace Metal {
5
+
6
+
7
+ struct ParseError : public std::runtime_error {
8
+ ParseError(const std::string& msg) :
9
+ std::runtime_error(msg) {}
10
+ };
11
+
12
+
13
+ } // namespace Metal
14
+
15
+ // vim: ft=objcpp
@@ -0,0 +1,42 @@
1
+ #import <vector>
2
+ #import <stack>
3
+
4
+ namespace Metal {
5
+
6
+
7
+ class Input {
8
+ public:
9
+ Input() {}
10
+ virtual ~Input() {}
11
+
12
+ struct at_t {
13
+ at_t() {}
14
+ at_t(const char* pos_, unsigned charlen_) :
15
+ pos(pos_), charlen(charlen_) {}
16
+ const char* pos;
17
+ unsigned charlen;
18
+ };
19
+
20
+ virtual at_t at(size_t pos) = 0;
21
+ };
22
+
23
+
24
+ class BufferedInput : public Input {
25
+ public:
26
+ BufferedInput(const char* src, size_t len);
27
+ ~BufferedInput();
28
+ public:
29
+ at_t at(size_t pos);
30
+ private:
31
+ size_t m_cur;
32
+ const char* m_pos;
33
+ const char* const m_endpos;
34
+ private:
35
+ inline void prev();
36
+ inline unsigned charlen();
37
+ };
38
+
39
+
40
+ } // namespace Metal
41
+
42
+ // vim: ft=objcpp
@@ -0,0 +1,24 @@
1
+ #import "metal/runtime.h"
2
+ #import "metal/exception.h"
3
+ #import "metal/input.h"
4
+
5
+ namespace Metal {
6
+
7
+ template <typename Parser>
8
+ static VALUE parse_method_template(VALUE self, VALUE src)
9
+ {
10
+ StringValue(src);
11
+ Metal::BufferedInput input(RSTRING_PTR(src), RSTRING_LEN(src));
12
+ id parser = [[Parser alloc] init:self];
13
+ try {
14
+ VALUE ret = [parser parse:input];
15
+ [parser free];
16
+ return ret;
17
+ } catch (Metal::ParseError& e) {
18
+ [parser free];
19
+ rb_raise(rb_eException, e.what());
20
+ return Qnil;
21
+ }
22
+ }
23
+
24
+ } // namespace Metal
@@ -0,0 +1,97 @@
1
+ #import "ruby.h"
2
+ #import <objc/Object.h>
3
+
4
+ #define RB_P(val) { \
5
+ rb_define_variable("$RB_P", &val); \
6
+ rb_eval_string("p $RB_P"); \
7
+ }
8
+
9
+ namespace Metal {
10
+
11
+
12
+ typedef const char* param_t;
13
+ param_t param_lookup(const char* name);
14
+
15
+
16
+ class EnvIMPL;
17
+ class Env {
18
+ public:
19
+ Env();
20
+ ~Env();
21
+ public:
22
+ VALUE& operator[](param_t key);
23
+ private:
24
+ EnvIMPL* m_impl;
25
+ VALUE m_gc_marker;
26
+ friend class EnvIMPL;
27
+ private:
28
+ Env(const Env&);
29
+ };
30
+
31
+
32
+ class Context;
33
+
34
+ class Lambda {
35
+ public:
36
+ Lambda(Context* _ctx, Env& _env) : ctx(_ctx), env(_env) {}
37
+ virtual ~Lambda() { }
38
+ virtual VALUE call() = 0;
39
+ protected:
40
+ Context* const ctx;
41
+ Env& env;
42
+ private:
43
+ Lambda();
44
+ Lambda(const Lambda&);
45
+ };
46
+
47
+
48
+ class Input;
49
+
50
+ class ContextIMPL;
51
+ class Context {
52
+ public:
53
+ Context(id instance, VALUE rb_instance, Input& input);
54
+ ~Context();
55
+
56
+ public:
57
+ VALUE apply(SEL method);
58
+
59
+ VALUE act_or(Lambda** blocks);
60
+ VALUE act_many(Lambda* block);
61
+ VALUE act_many1(Lambda* block);
62
+ VALUE act_may(Lambda* block);
63
+ VALUE act_not(Lambda* block);
64
+ VALUE act_lookahead(Lambda* block);
65
+ VALUE act_char(const char* c, unsigned clen);
66
+ VALUE act_token(const char* s, unsigned slen);
67
+ VALUE act_any();
68
+ VALUE act_charclass(const char* s, unsigned slen);
69
+
70
+ VALUE act_run(Env& env, const char* code, unsigned code_len);
71
+ VALUE act_where(Env& env, const char* code, unsigned code_len);
72
+
73
+ VALUE act_end();
74
+
75
+ private:
76
+ ContextIMPL* m_impl;
77
+ friend class ContextIMPL;
78
+ private:
79
+ Context();
80
+ Context(const Context&);
81
+ };
82
+
83
+
84
+ } // namespace Metal
85
+
86
+
87
+ @interface MetalParserBase : Object
88
+ {
89
+ VALUE instance;
90
+ }
91
+ -(id)init:(VALUE)instance;
92
+ -(VALUE)parse:(Metal::Input&)input withRule:(SEL)name;
93
+ -(VALUE)parse:(Metal::Input&)input;
94
+ @end
95
+
96
+
97
+ // vim: ft=objcpp
@@ -1,353 +1 @@
1
- #
2
- # Metal Bootstrap Parser
3
- #
4
- # Copyright (C) 2008 FURUHASHI Sadayuki
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- require 'metal/generator'
19
-
20
- class MetalParser < Metal::ParserBase
21
- include Metal::Generator
22
- def rule_main()
23
- m = apply(:meta)
24
- apply(:end)
25
- m
26
- end
27
- def rule_meta()
28
- xs = act_many(lambda{act_or([lambda{apply(:grammar)
29
- },
30
- lambda{apply(:meta_command)
31
- },
32
- ])
33
- })
34
- apply(:s)
35
- Meta.new(xs)
36
- end
37
- def rule_meta_command()
38
- apply(:s)
39
- apply(:precode)
40
- end
41
- def rule_grammar()
42
- apply(:s)
43
- i = apply(:interface_attr)
44
- n = apply(:grammar_name)
45
- apply(:s)
46
- e = act_may(lambda{apply(:extend_attr)})
47
- apply(:s)
48
- act_token('{')
49
- b = apply(:grammar_body)
50
- act_token('}')
51
- Grammar.new(n, b, e, i)
52
- end
53
- def rule_interface_attr()
54
- act_or([lambda{act_token('module')
55
- apply(:fs)
56
- true
57
- },
58
- lambda{act_token('class')
59
- apply(:fs)
60
- false
61
- },
62
- lambda{ false
63
- },
64
- ])
65
- end
66
- def rule_extend_attr()
67
- act_token('<')
68
- apply(:s)
69
- apply(:grammar_name)
70
- end
71
- def rule_grammar_body()
72
- apply(:s)
73
- act_many(lambda{act_or([lambda{apply(:rule)
74
- },
75
- lambda{apply(:grammar_command)
76
- },
77
- ])
78
- })
79
- end
80
- def rule_grammar_command()
81
- act_or([lambda{apply(:precode)
82
- },
83
- lambda{apply(:mixin)
84
- },
85
- ])
86
- end
87
- def rule_precode()
88
- act_token('@{')
89
- s = act_many1(lambda{act_or([lambda{act_not(lambda{act_token('@')})
90
- act_any
91
- },
92
- lambda{act_token('@')
93
- act_not(lambda{act_token('}')})
94
- '@'
95
- },
96
- ])
97
- })
98
- act_token('@}')
99
- apply(:s)
100
- Precode.new(s.join)
101
- end
102
- def rule_mixin()
103
- act_token('@include')
104
- apply(:fs)
105
- n = apply(:scoped_grammar_name)
106
- apply(:s)
107
- Mixin.new(n)
108
- end
109
- def rule_scoped_grammar_name()
110
- xs = act_many1(lambda{s = act_may(lambda{act_token('::')})
111
- n = apply(:grammar_name)
112
- "#{s}#{n}"
113
- })
114
- xs.join
115
- end
116
- def rule_rule()
117
- act_token('-')
118
- apply(:s)
119
- n = apply(:rule_name)
120
- a = apply(:rule_args)
121
- apply(:fs)
122
- r = apply(:or_set)
123
- apply(:s)
124
- Rule.new(n, r, a)
125
- end
126
- def rule_rule_args()
127
- act_many(lambda{apply(:s)
128
- act_token(':')
129
- apply(:var_name)
130
- })
131
- end
132
- def rule_or_set()
133
- x = apply(:and_set)
134
- apply(:s)
135
- xs = act_many(lambda{apply(:s)
136
- act_token('/')
137
- apply(:and_set)
138
- })
139
- OrSet.new([x] + xs)
140
- end
141
- def rule_and_set()
142
- apply(:s)
143
- xs = act_may(lambda{x = apply(:expr)
144
- xs = act_many(lambda{apply(:fs)
145
- apply(:expr)
146
- })
147
- [x]+xs
148
- })
149
- AndSet.new(xs || [])
150
- end
151
- def rule_expr()
152
- p = apply(:pred)
153
- p = act_may(lambda{apply(:iter,p)})
154
- v = act_may(lambda{apply(:var)})
155
- Expression.new(p, v)
156
- end
157
- def rule_pred()
158
- act_or([lambda{act_token('!')
159
- p = apply(:pred)
160
- PredNot.new(p)
161
- },
162
- lambda{act_token('&')
163
- f = apply(:literal)
164
- PredLookahead.new(f)
165
- },
166
- lambda{apply(:literal)
167
- },
168
- ])
169
- end
170
- def rule_iter(x)
171
- act_or([lambda{act_token('*')
172
- IterMany.new(x)
173
- },
174
- lambda{act_token('+')
175
- IterMany1.new(x)
176
- },
177
- lambda{act_token('?')
178
- IterMay.new(x)
179
- },
180
- lambda{ x
181
- },
182
- ])
183
- end
184
- def rule_literal()
185
- act_or([lambda{apply(:apply_rule)
186
- },
187
- lambda{apply(:action)
188
- },
189
- lambda{apply(:where)
190
- },
191
- lambda{s = apply(:q_string)
192
- LiteralQuotedToken.new(s)
193
- },
194
- lambda{s = apply(:dq_string)
195
- LiteralToken.new(s)
196
- },
197
- lambda{s = apply(:charclass)
198
- LiteralCharset.new(s)
199
- },
200
- lambda{act_token('.')
201
- LiteralAny.new
202
- },
203
- lambda{apply(:other_call)
204
- },
205
- lambda{act_token('(')
206
- apply(:s)
207
- r = apply(:or_set)
208
- apply(:s)
209
- act_token(')')
210
- r
211
- },
212
- ])
213
- end
214
- def rule_var()
215
- act_token(':')
216
- n = apply(:var_name)
217
- n
218
- end
219
- def rule_apply_rule()
220
- r = apply(:rule_name)
221
- a = act_may(lambda{apply(:apply_args)})
222
-
223
- if r == "super"
224
- Super.new(a)
225
- elsif r == "self"
226
- Self.new(a || [])
227
- else
228
- Apply.new(r, a || [])
229
- end
230
- end
231
- def rule_other_call()
232
- g = apply(:grammar_name)
233
- act_token('.')
234
- r = apply(:rule_name)
235
- a = act_may(lambda{apply(:apply_args)})
236
- Other.new(g, r, a || [])
237
- end
238
- def rule_apply_args()
239
- act_token('(')
240
- a = act_may(lambda{apply(:s)
241
- x = apply(:var_name)
242
- xs = act_many(lambda{act_token(',')
243
- apply(:s)
244
- apply(:var_name)
245
- })
246
- [x] + xs
247
- })
248
- act_token(')')
249
- a || []
250
- end
251
- def rule_action()
252
- act_token('{*')
253
- s = act_many1(lambda{act_or([lambda{act_not(lambda{act_token('*')})
254
- act_any
255
- },
256
- lambda{act_token('*')
257
- act_not(lambda{act_token('}')})
258
- '*'
259
- },
260
- ])
261
- })
262
- act_token('*}')
263
- Action.new(s.join)
264
- end
265
- def rule_where()
266
- act_token('?{*')
267
- s = act_many1(lambda{act_or([lambda{act_not(lambda{act_token('*')})
268
- act_any
269
- },
270
- lambda{act_token('*')
271
- act_not(lambda{act_token('}')})
272
- '*'
273
- },
274
- ])
275
- })
276
- act_token('*}')
277
- Where.new(s.join)
278
- end
279
- def rule_rule_name()
280
- x = act_charset(%[a-z_])
281
- xs = act_many(lambda{act_charset(%[a-zA-Z_0-9])})
282
- ([x] + xs).join
283
- end
284
- def rule_var_name()
285
- x = act_charset(%[a-z_])
286
- xs = act_many(lambda{act_charset(%[a-zA-Z_0-9])})
287
- ([x] + xs).join
288
- end
289
- def rule_grammar_name()
290
- x = act_charset(%[A-Z])
291
- xs = act_many(lambda{act_charset(%[a-zA-Z_0-9])})
292
- ([x] + xs).join
293
- end
294
- def rule_dq_string()
295
- act_token('"')
296
- s = act_many1(lambda{act_or([lambda{act_not(lambda{act_token('"')})
297
- act_any
298
- },
299
- lambda{act_token('\"')
300
- },
301
- ])
302
- })
303
- act_token('"')
304
- s.join
305
- end
306
- def rule_q_string()
307
- act_token("'")
308
- s = act_many1(lambda{act_or([lambda{act_not(lambda{act_token("'")})
309
- act_any
310
- },
311
- lambda{act_token("\\'")
312
- },
313
- ])
314
- })
315
- act_token("'")
316
- s.join
317
- end
318
- def rule_charclass()
319
- act_token('[')
320
- s = act_many1(lambda{act_or([lambda{act_not(lambda{act_token(']')})
321
- act_any
322
- },
323
- lambda{act_token('\]')
324
- },
325
- ])
326
- })
327
- act_token(']')
328
- s.join
329
- end
330
- def rule_s()
331
- act_many(lambda{act_or([lambda{apply(:comment)
332
- },
333
- lambda{act_charset(%[ \t\r\n])
334
- },
335
- ])
336
- })
337
- end
338
- def rule_fs()
339
- act_many1(lambda{act_or([lambda{apply(:comment)
340
- },
341
- lambda{act_charset(%[ \t\r\n])
342
- },
343
- ])
344
- })
345
- end
346
- def rule_comment()
347
- act_token('#')
348
- act_many(lambda{act_not(lambda{act_token("\n")})
349
- act_any
350
- })
351
- act_token("\n")
352
- end
353
- end
1
+ require 'metal_boot'