yagg 0.1.0 → 0.1.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 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