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 +4 -4
- data/exe/yagg +20 -0
- data/lib/ansi.y +428 -0
- data/lib/yagg/gen.rb +195 -0
- data/lib/yagg/parsery.rb +63 -0
- data/lib/yagg/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bd9bbd1a91dee06cab9aa7243845b729bed90d2
|
4
|
+
data.tar.gz: 18ec269d8c14cf011f5a69e9eeed0d5373b01073
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d4b65ca03673a77eddd47c6b8683521bca6ffc33db382f2277d9d92106c69ff0a5a69c4f456a88f54955f9d63bd63e70bd37775c269cad678639b511dd9d6b8
|
7
|
+
data.tar.gz: a5c978c72483a551e8091f1a9a0a6d0329916f473b2652977c6f5b1e53e572694934f3219a30f2d176d057f0c6523a0d74b66f7d80090d39e538b1e2044fcb24
|
data/exe/yagg
ADDED
@@ -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
|
+
|
data/lib/ansi.y
ADDED
@@ -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
|
+
}
|
data/lib/yagg/gen.rb
ADDED
@@ -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
|
data/lib/yagg/parsery.rb
ADDED
@@ -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
|
+
|
data/lib/yagg/version.rb
CHANGED
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.
|
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
|