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 +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
|