yagg 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eeba14d3c5bdb8c2c0c5c0bcee8ec3b84796b459
4
- data.tar.gz: b0fbf3d3a7513cf53895976482f6de10437a3277
3
+ metadata.gz: 6bd9bbd1a91dee06cab9aa7243845b729bed90d2
4
+ data.tar.gz: 18ec269d8c14cf011f5a69e9eeed0d5373b01073
5
5
  SHA512:
6
- metadata.gz: 28b9f7110049a2a7f525dd5b40e0e07b4b64d85c83b04f3ba53831eb994f09b6cf6b3e43c089507d9c307c9e58ae7aaf2796d2dabaa408e2891420d1103951ed
7
- data.tar.gz: cc70a251dc86e97e2170ff609fe2c2ab8a436f1ff0aa8d3b3293b31a1933d3196e4e3e29a3769cecbbd3b096850ea6957de6d1c6a609ce0ee0ce281ece1fc2b9
6
+ metadata.gz: 8d4b65ca03673a77eddd47c6b8683521bca6ffc33db382f2277d9d92106c69ff0a5a69c4f456a88f54955f9d63bd63e70bd37775c269cad678639b511dd9d6b8
7
+ data.tar.gz: a5c978c72483a551e8091f1a9a0a6d0329916f473b2652977c6f5b1e53e572694934f3219a30f2d176d057f0c6523a0d74b66f7d80090d39e538b1e2044fcb24
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ require 'thor'
3
+ require 'yagg'
4
+ class YaggRunner < Thor
5
+ desc 'generate IN [OUT]', 'generate a ruby file from given .y file'
6
+ def generate(infile, outfile = "-")
7
+ u = Yagg::Parser.new File.read infile
8
+ u.parse
9
+ v = Yagg::Generator.new u.result
10
+ if outfile == "-"
11
+ puts v.generate
12
+ else
13
+ open(outfile, "w") do |f| f.write v.generate end
14
+ end
15
+ end
16
+
17
+ start ARGV
18
+ end
19
+
20
+
@@ -0,0 +1,428 @@
1
+ %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
2
+ %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
3
+ %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
4
+ %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
5
+ %token XOR_ASSIGN OR_ASSIGN TYPE_NAME
6
+
7
+ %token TYPEDEF EXTERN STATIC AUTO REGISTER
8
+ %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
9
+ %token STRUCT UNION ENUM ELLIPSIS
10
+
11
+ %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
12
+
13
+ %start translation_unit
14
+ %%
15
+
16
+ primary_expression
17
+ : IDENTIFIER
18
+ | CONSTANT
19
+ | STRING_LITERAL
20
+ | '(' expression ')'
21
+ ;
22
+
23
+ postfix_expression
24
+ : primary_expression
25
+ | postfix_expression '[' expression ']'
26
+ | postfix_expression '(' ')'
27
+ | postfix_expression '(' argument_expression_list ')'
28
+ | postfix_expression '.' IDENTIFIER
29
+ | postfix_expression PTR_OP IDENTIFIER
30
+ | postfix_expression INC_OP
31
+ | postfix_expression DEC_OP
32
+ ;
33
+
34
+ argument_expression_list
35
+ : assignment_expression
36
+ | argument_expression_list ',' assignment_expression
37
+ ;
38
+
39
+ unary_expression
40
+ : postfix_expression
41
+ | INC_OP unary_expression
42
+ | DEC_OP unary_expression
43
+ | unary_operator cast_expression
44
+ | SIZEOF unary_expression
45
+ | SIZEOF '(' type_name ')'
46
+ ;
47
+
48
+ unary_operator
49
+ : '&'
50
+ | '*'
51
+ | '+'
52
+ | '-'
53
+ | '~'
54
+ | '!'
55
+ ;
56
+
57
+ cast_expression
58
+ : unary_expression
59
+ | '(' type_name ')' cast_expression
60
+ ;
61
+
62
+ multiplicative_expression
63
+ : cast_expression
64
+ | multiplicative_expression '*' cast_expression
65
+ | multiplicative_expression '/' cast_expression
66
+ | multiplicative_expression '%' cast_expression
67
+ ;
68
+
69
+ additive_expression
70
+ : multiplicative_expression
71
+ | additive_expression '+' multiplicative_expression
72
+ | additive_expression '-' multiplicative_expression
73
+ ;
74
+
75
+ shift_expression
76
+ : additive_expression
77
+ | shift_expression LEFT_OP additive_expression
78
+ | shift_expression RIGHT_OP additive_expression
79
+ ;
80
+
81
+ relational_expression
82
+ : shift_expression
83
+ | relational_expression '<' shift_expression
84
+ | relational_expression '>' shift_expression
85
+ | relational_expression LE_OP shift_expression
86
+ | relational_expression GE_OP shift_expression
87
+ ;
88
+
89
+ equality_expression
90
+ : relational_expression
91
+ | equality_expression EQ_OP relational_expression
92
+ | equality_expression NE_OP relational_expression
93
+ ;
94
+
95
+ and_expression
96
+ : equality_expression
97
+ | and_expression '&' equality_expression
98
+ ;
99
+
100
+ exclusive_or_expression
101
+ : and_expression
102
+ | exclusive_or_expression '^' and_expression
103
+ ;
104
+
105
+ inclusive_or_expression
106
+ : exclusive_or_expression
107
+ | inclusive_or_expression '|' exclusive_or_expression
108
+ ;
109
+
110
+ logical_and_expression
111
+ : inclusive_or_expression
112
+ | logical_and_expression AND_OP inclusive_or_expression
113
+ ;
114
+
115
+ logical_or_expression
116
+ : logical_and_expression
117
+ | logical_or_expression OR_OP logical_and_expression
118
+ ;
119
+
120
+ conditional_expression
121
+ : logical_or_expression
122
+ | logical_or_expression '?' expression ':' conditional_expression
123
+ ;
124
+
125
+ assignment_expression
126
+ : conditional_expression
127
+ | unary_expression assignment_operator assignment_expression
128
+ ;
129
+
130
+ assignment_operator
131
+ : '='
132
+ | MUL_ASSIGN
133
+ | DIV_ASSIGN
134
+ | MOD_ASSIGN
135
+ | ADD_ASSIGN
136
+ | SUB_ASSIGN
137
+ | LEFT_ASSIGN
138
+ | RIGHT_ASSIGN
139
+ | AND_ASSIGN
140
+ | XOR_ASSIGN
141
+ | OR_ASSIGN
142
+ ;
143
+
144
+ expression
145
+ : assignment_expression
146
+ | expression ',' assignment_expression
147
+ ;
148
+
149
+ constant_expression
150
+ : conditional_expression
151
+ ;
152
+
153
+ declaration
154
+ : declaration_specifiers ';'
155
+ | declaration_specifiers init_declarator_list ';'
156
+ ;
157
+
158
+ declaration_specifiers
159
+ : storage_class_specifier
160
+ | storage_class_specifier declaration_specifiers
161
+ | type_specifier
162
+ | type_specifier declaration_specifiers
163
+ | type_qualifier
164
+ | type_qualifier declaration_specifiers
165
+ ;
166
+
167
+ init_declarator_list
168
+ : init_declarator
169
+ | init_declarator_list ',' init_declarator
170
+ ;
171
+
172
+ init_declarator
173
+ : declarator
174
+ | declarator '=' initializer
175
+ ;
176
+
177
+ storage_class_specifier
178
+ : TYPEDEF
179
+ | EXTERN
180
+ | STATIC
181
+ | AUTO
182
+ | REGISTER
183
+ ;
184
+
185
+ type_specifier
186
+ : VOID
187
+ | CHAR
188
+ | SHORT
189
+ | INT
190
+ | LONG
191
+ | FLOAT
192
+ | DOUBLE
193
+ | SIGNED
194
+ | UNSIGNED
195
+ | struct_or_union_specifier
196
+ | enum_specifier
197
+ | TYPE_NAME
198
+ ;
199
+
200
+ struct_or_union_specifier
201
+ : struct_or_union IDENTIFIER '{' struct_declaration_list '}'
202
+ | struct_or_union '{' struct_declaration_list '}'
203
+ | struct_or_union IDENTIFIER
204
+ ;
205
+
206
+ struct_or_union
207
+ : STRUCT
208
+ | UNION
209
+ ;
210
+
211
+ struct_declaration_list
212
+ : struct_declaration
213
+ | struct_declaration_list struct_declaration
214
+ ;
215
+
216
+ struct_declaration
217
+ : specifier_qualifier_list struct_declarator_list ';'
218
+ ;
219
+
220
+ specifier_qualifier_list
221
+ : type_specifier specifier_qualifier_list
222
+ | type_specifier
223
+ | type_qualifier specifier_qualifier_list
224
+ | type_qualifier
225
+ ;
226
+
227
+ struct_declarator_list
228
+ : struct_declarator
229
+ | struct_declarator_list ',' struct_declarator
230
+ ;
231
+
232
+ struct_declarator
233
+ : declarator
234
+ | ':' constant_expression
235
+ | declarator ':' constant_expression
236
+ ;
237
+
238
+ enum_specifier
239
+ : ENUM '{' enumerator_list '}'
240
+ | ENUM IDENTIFIER '{' enumerator_list '}'
241
+ | ENUM IDENTIFIER
242
+ ;
243
+
244
+ enumerator_list
245
+ : enumerator
246
+ | enumerator_list ',' enumerator
247
+ ;
248
+
249
+ enumerator
250
+ : IDENTIFIER
251
+ | IDENTIFIER '=' constant_expression
252
+ ;
253
+
254
+ type_qualifier
255
+ : CONST
256
+ | VOLATILE
257
+ ;
258
+
259
+ declarator
260
+ : pointer direct_declarator
261
+ | direct_declarator
262
+ ;
263
+
264
+ direct_declarator
265
+ : IDENTIFIER
266
+ | '(' declarator ')'
267
+ | direct_declarator '[' constant_expression ']'
268
+ | direct_declarator '[' ']'
269
+ | direct_declarator '(' parameter_type_list ')'
270
+ | direct_declarator '(' identifier_list ')'
271
+ | direct_declarator '(' ')'
272
+ ;
273
+
274
+ pointer
275
+ : '*'
276
+ | '*' type_qualifier_list
277
+ | '*' pointer
278
+ | '*' type_qualifier_list pointer
279
+ ;
280
+
281
+ type_qualifier_list
282
+ : type_qualifier
283
+ | type_qualifier_list type_qualifier
284
+ ;
285
+
286
+
287
+ parameter_type_list
288
+ : parameter_list
289
+ | parameter_list ',' ELLIPSIS
290
+ ;
291
+
292
+ parameter_list
293
+ : parameter_declaration
294
+ | parameter_list ',' parameter_declaration
295
+ ;
296
+
297
+ parameter_declaration
298
+ : declaration_specifiers declarator
299
+ | declaration_specifiers abstract_declarator
300
+ | declaration_specifiers
301
+ ;
302
+
303
+ identifier_list
304
+ : IDENTIFIER
305
+ | identifier_list ',' IDENTIFIER
306
+ ;
307
+
308
+ type_name
309
+ : specifier_qualifier_list
310
+ | specifier_qualifier_list abstract_declarator
311
+ ;
312
+
313
+ abstract_declarator
314
+ : pointer
315
+ | direct_abstract_declarator
316
+ | pointer direct_abstract_declarator
317
+ ;
318
+
319
+ direct_abstract_declarator
320
+ : '(' abstract_declarator ')'
321
+ | '[' ']'
322
+ | '[' constant_expression ']'
323
+ | direct_abstract_declarator '[' ']'
324
+ | direct_abstract_declarator '[' constant_expression ']'
325
+ | '(' ')'
326
+ | '(' parameter_type_list ')'
327
+ | direct_abstract_declarator '(' ')'
328
+ | direct_abstract_declarator '(' parameter_type_list ')'
329
+ ;
330
+
331
+ initializer
332
+ : assignment_expression
333
+ | '{' initializer_list '}'
334
+ | '{' initializer_list ',' '}'
335
+ ;
336
+
337
+ initializer_list
338
+ : initializer
339
+ | initializer_list ',' initializer
340
+ ;
341
+
342
+ statement
343
+ : labeled_statement
344
+ | compound_statement
345
+ | expression_statement
346
+ | selection_statement
347
+ | iteration_statement
348
+ | jump_statement
349
+ ;
350
+
351
+ labeled_statement
352
+ : IDENTIFIER ':' statement
353
+ | CASE constant_expression ':' statement
354
+ | DEFAULT ':' statement
355
+ ;
356
+
357
+ compound_statement
358
+ : '{' '}'
359
+ | '{' statement_list '}'
360
+ | '{' declaration_list '}'
361
+ | '{' declaration_list statement_list '}'
362
+ ;
363
+
364
+ declaration_list
365
+ : declaration
366
+ | declaration_list declaration
367
+ ;
368
+
369
+ statement_list
370
+ : statement
371
+ | statement_list statement
372
+ ;
373
+
374
+ expression_statement
375
+ : ';'
376
+ | expression ';'
377
+ ;
378
+
379
+ selection_statement
380
+ : IF '(' expression ')' statement
381
+ | IF '(' expression ')' statement ELSE statement
382
+ | SWITCH '(' expression ')' statement
383
+ ;
384
+
385
+ iteration_statement
386
+ : WHILE '(' expression ')' statement
387
+ | DO statement WHILE '(' expression ')' ';'
388
+ | FOR '(' expression_statement expression_statement ')' statement
389
+ | FOR '(' expression_statement expression_statement expression ')' statement
390
+ ;
391
+
392
+ jump_statement
393
+ : GOTO IDENTIFIER ';'
394
+ | CONTINUE ';'
395
+ | BREAK ';'
396
+ | RETURN ';'
397
+ | RETURN expression ';'
398
+ ;
399
+
400
+ translation_unit
401
+ : external_declaration
402
+ | translation_unit external_declaration
403
+ ;
404
+
405
+ external_declaration
406
+ : function_definition
407
+ | declaration
408
+ ;
409
+
410
+ function_definition
411
+ : declaration_specifiers declarator declaration_list compound_statement
412
+ | declaration_specifiers declarator compound_statement
413
+ | declarator declaration_list compound_statement
414
+ | declarator compound_statement
415
+ ;
416
+
417
+ %%
418
+ #include <stdio.h>
419
+
420
+ extern char yytext[];
421
+ extern int column;
422
+
423
+ yyerror(s)
424
+ char *s;
425
+ {
426
+ fflush(stdout);
427
+ printf("\n%*s\n%*s\n", column, "^", column, s);
428
+ }
@@ -0,0 +1,195 @@
1
+ module Yagg
2
+ class ::String
3
+ alias to_text to_s
4
+ end
5
+ class Generator
6
+ attr_accessor :result
7
+ def initialize(input)
8
+ @input = input
9
+ @indent = 0
10
+ self.result = ""
11
+ end
12
+
13
+ def generate_lexels
14
+ @input.tokens.each{|x|
15
+ `#{x.upcase} = Class.new(Lexel)\n`
16
+ }
17
+ end
18
+
19
+ private
20
+ def rule_name_case(str)
21
+ str.capitalize.gsub(/_([a-z])/){ $1.upcase }
22
+ end
23
+
24
+ public
25
+
26
+ def generate_rules
27
+ @input.rules.each{|k, v|
28
+ `class #{rule_name_case(k)} < Rule\n`
29
+ ` Rules = #{v.select{|x| x.size != 1}.inspect}\n`
30
+ ` Includes = #{v.select{|x| x.size == 1}.flatten}\n`
31
+ `end\n`
32
+ }
33
+ end
34
+
35
+ def `(text)
36
+ @result << make_indent(@indent, text)
37
+ end
38
+
39
+ def make_indent(num, text)
40
+ text.split(/(\n)/).map{|x| " "*num << x}.join
41
+ end
42
+
43
+ def indent(a = 0)
44
+ @indent += a
45
+ end
46
+
47
+ def generate_header
48
+ <<~`EOF`
49
+ class Lexel
50
+ attr_accessor :value
51
+ def values
52
+ [value]
53
+ end
54
+ def typeid
55
+ -1
56
+ end
57
+ def initialize(value)
58
+ raise TypeError unless self.class.check(value)
59
+ if self.class === value
60
+ self.value = value.value
61
+ elsif Lexel === value || Rule === value
62
+ raise TypeError
63
+ else
64
+ self.value = value
65
+ end
66
+ end
67
+ def self.check(value)
68
+ if Lexel === value || Rule === value
69
+ return self === value
70
+ end
71
+ true
72
+ end
73
+ def to_text
74
+ value.to_s
75
+ end
76
+ end
77
+
78
+ Unchecked = Struct.new(:values, :typeid)
79
+
80
+ class Rule
81
+ attr_accessor :typeid, :values
82
+ def to_text
83
+ values.map{|x| x.to_text}.join
84
+ end
85
+ def initialize(*values)
86
+ if values.length == 1 && Unchecked === values[0]
87
+ self.values = values[0].values
88
+ self.typeid = values[0].typeid
89
+ else
90
+ old = values
91
+ typeid, values = self.class.check(values)
92
+ raise TypeError, "\#{self.class.to_s}:can't find rule for \#{old}" unless typeid
93
+ if typeid == -1
94
+ self.values = values[0].values
95
+ self.typeid = values[0].typeid
96
+ else
97
+ self.values = values
98
+ self.typeid = typeid
99
+ end
100
+ end
101
+ end
102
+
103
+ def self.grammel(a)
104
+ case a
105
+ when /^[A-Z]/ then Scope.const_get(a.upcase)
106
+ when /^[a-z]/ then Scope.const_get(a.capitalize.gsub(/_([a-z])/){ $1.upcase })
107
+ when /^'(.)'/ then $1
108
+ else
109
+ raise TypeError, "unknown grammar token \#{a}"
110
+ end
111
+ end
112
+
113
+ def self.check_single(pattern, values)
114
+ i = 0
115
+ j = 0
116
+ output = []
117
+ while i < values.length && j < pattern.length
118
+ u = grammel(pattern[j])
119
+ if Class === u
120
+ output << u.new(values[i])
121
+ else
122
+ return nil if u != values[i]
123
+ output << values[i]
124
+ end
125
+ i += 1
126
+ j += 1
127
+ end
128
+ output
129
+ rescue TypeError
130
+ end
131
+
132
+ def to_text
133
+ self.values.map{|x| x.to_text}.join
134
+ end
135
+
136
+ def self.check_one(value, memo = {})
137
+ self::Includes.each{|x|
138
+ next if memo[x]
139
+ u = grammel(x)
140
+ case u
141
+ when String
142
+ return value if u == value
143
+ when lambda{|x| x < Lexel}
144
+ return u.new(value) if u.check(value)
145
+ else
146
+ if u === value
147
+ return u.new(Unchecked.new([value], -1))
148
+ else
149
+ r = u.check_one(value, memo.update({u: 1}))
150
+ return self.new(Unchecked.new([r], -1)) if r
151
+ end
152
+ end
153
+ }
154
+ nil
155
+ end
156
+
157
+ def self.check(values)
158
+ if values.length == 1
159
+ if self === values[0]
160
+ return -1, values
161
+ elsif (r = check_one(values[0], {}))
162
+ if self === r
163
+ return -1, r.values
164
+ else
165
+ return -1, [r]
166
+ end
167
+ else
168
+ return nil
169
+ end
170
+ return nil
171
+ end
172
+
173
+ self::Rules.each_with_index{|k, i|
174
+ next if k.size != values.size
175
+ r = check_single(k, values)
176
+ return i, r if r
177
+ }
178
+
179
+ nil
180
+ end
181
+ end
182
+ EOF
183
+ end
184
+
185
+ def generate(under = "GG")
186
+ `module #{under}\n Scope = self\n`
187
+ indent 2
188
+ generate_header
189
+ generate_lexels
190
+ generate_rules
191
+ indent -2
192
+ `end\n`
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,63 @@
1
+ module Yagg
2
+ Error = Class.new(Exception)
3
+ class Parser
4
+ attr_accessor :header, :body, :tokens, :rules, :token_groups
5
+ ParseError = Class.new(Exception)
6
+ def initialize(text)
7
+ @source = text
8
+ end
9
+
10
+ def result
11
+ self
12
+ end
13
+
14
+ def setup_sections
15
+ if @source =~ /([\w\W]*?)^%%\s*([\w\W]*?)^%%\s*/
16
+ self.header, self.body, * = $1, $2
17
+ else
18
+ raise ParseError, "can't recognize format"
19
+ end
20
+ end
21
+
22
+ def parse_tokens
23
+ self.tokens = self.header.scan(/^%token(.*)/).flat_map{|x| x.flat_map{|y| y.split(" ")}}
24
+ end
25
+
26
+ def parse_rule(arr)
27
+ arr = arr[0..-1]
28
+ name = arr.shift
29
+ arr.shift
30
+ groups = [[]]
31
+ arr.each do |t|
32
+ if t == '|'
33
+ groups.push []
34
+ else
35
+ groups.last.push t
36
+ end
37
+ end
38
+ {name => groups}
39
+ end
40
+
41
+ def parse_rules
42
+ tokens = self.body.scan(/[^'\s]+|'.'/).to_a
43
+ self.token_groups = [[]]
44
+ tokens.each do |t|
45
+ if t != ';'
46
+ self.token_groups.last << t
47
+ else
48
+ self.token_groups << []
49
+ end
50
+ end
51
+ self.token_groups.pop if self.token_groups.last.empty?
52
+ self.rules = self.token_groups.inject({}){|a, b| a.update(parse_rule(b))}
53
+ end
54
+
55
+ def parse
56
+ setup_sections
57
+ parse_tokens
58
+ parse_rules
59
+ end
60
+ end
61
+ end
62
+
63
+
@@ -1,3 +1,3 @@
1
1
  module Yagg
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yagg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - RGSS3
@@ -69,7 +69,8 @@ dependencies:
69
69
  description: Yet another generator for generation
70
70
  email:
71
71
  - RGSS3
72
- executables: []
72
+ executables:
73
+ - yagg
73
74
  extensions: []
74
75
  extra_rdoc_files: []
75
76
  files:
@@ -83,7 +84,11 @@ files:
83
84
  - Rakefile
84
85
  - bin/console
85
86
  - bin/setup
87
+ - exe/yagg
88
+ - lib/ansi.y
86
89
  - lib/yagg.rb
90
+ - lib/yagg/gen.rb
91
+ - lib/yagg/parsery.rb
87
92
  - lib/yagg/version.rb
88
93
  - yagg.gemspec
89
94
  homepage: http://github.com/RGSS3/yagg