slow_blink 0.0.1 → 0.0.2
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/ext/slow_blink/ext_schema_parser/common.h +27 -0
- data/ext/slow_blink/ext_schema_parser/extconf.rb +3 -0
- data/ext/slow_blink/ext_schema_parser/lexer.c +2701 -0
- data/ext/slow_blink/ext_schema_parser/lexer.h +486 -0
- data/ext/slow_blink/ext_schema_parser/parser.c +3848 -0
- data/ext/slow_blink/ext_schema_parser/parser.h +110 -0
- data/ext/slow_blink/ext_schema_parser/parser.l +139 -0
- data/ext/slow_blink/ext_schema_parser/parser.y +932 -0
- data/lib/slow_blink/annotatable.rb +46 -0
- data/lib/slow_blink/annotation.rb +38 -0
- data/lib/slow_blink/compact_encoder.rb +97 -0
- data/lib/slow_blink/component_reference.rb +50 -0
- data/lib/slow_blink/definition.rb +57 -0
- data/lib/slow_blink/enumeration.rb +105 -0
- data/lib/slow_blink/error.rb +4 -0
- data/lib/slow_blink/field.rb +82 -0
- data/lib/slow_blink/group.rb +129 -0
- data/lib/slow_blink/incremental_annotation.rb +91 -0
- data/lib/slow_blink/message.rb +43 -0
- data/lib/slow_blink/name_with_id.rb +49 -0
- data/lib/slow_blink/schema.rb +135 -0
- data/lib/slow_blink/sym.rb +54 -0
- data/lib/slow_blink/type.rb +448 -0
- data/lib/slow_blink/version.rb +22 -0
- data/lib/slow_blink.rb +20 -0
- data/rakefile +29 -0
- data/test/integration/capture_stderr.rb +20 -0
- data/test/integration/tc_inputs.rb +57 -0
- metadata +36 -5
@@ -0,0 +1,932 @@
|
|
1
|
+
/* Blink Protocol Bison Configuration
|
2
|
+
*
|
3
|
+
* Cameron Harper 2016
|
4
|
+
*
|
5
|
+
* */
|
6
|
+
%{
|
7
|
+
|
8
|
+
/* includes ***********************************************************/
|
9
|
+
|
10
|
+
#include <stdio.h>
|
11
|
+
#include <stdlib.h>
|
12
|
+
#include <stdbool.h>
|
13
|
+
#include <ruby.h>
|
14
|
+
#include <assert.h>
|
15
|
+
|
16
|
+
#include "lexer.h"
|
17
|
+
|
18
|
+
/* function prototypes ************************************************/
|
19
|
+
|
20
|
+
void yyerror(YYLTYPE *locp, yyscan_t scanner, VALUE filename, VALUE *tree, char const *msg, ... );
|
21
|
+
|
22
|
+
/* static function prototypes *****************************************/
|
23
|
+
|
24
|
+
static VALUE parseFileBuffer(int argc, VALUE* argv, VALUE self);
|
25
|
+
static VALUE newLocation(VALUE filename, const YYLTYPE *location);
|
26
|
+
|
27
|
+
/* static variables ***************************************************/
|
28
|
+
|
29
|
+
static VALUE cSlowBlink;
|
30
|
+
|
31
|
+
static VALUE cNameWithID;
|
32
|
+
|
33
|
+
static VALUE cSchema;
|
34
|
+
static VALUE cGroup;
|
35
|
+
static VALUE cField;
|
36
|
+
static VALUE cAnnotation;
|
37
|
+
static VALUE cIncrementalAnnotation;
|
38
|
+
|
39
|
+
static VALUE cDefinition;
|
40
|
+
static VALUE cEnumeration;
|
41
|
+
static VALUE cSym;
|
42
|
+
|
43
|
+
static VALUE cI8;
|
44
|
+
static VALUE cI16;
|
45
|
+
static VALUE cI32;
|
46
|
+
static VALUE cI64;
|
47
|
+
static VALUE cU8;
|
48
|
+
static VALUE cU16;
|
49
|
+
static VALUE cU32;
|
50
|
+
static VALUE cU64;
|
51
|
+
static VALUE cF64;
|
52
|
+
static VALUE cDECIMAL;
|
53
|
+
static VALUE cFIXED;
|
54
|
+
static VALUE cSEQUENCE;
|
55
|
+
static VALUE cSTRING;
|
56
|
+
static VALUE cBOOLEAN;
|
57
|
+
static VALUE cOBJECT;
|
58
|
+
static VALUE cBINARY;
|
59
|
+
static VALUE cREF;
|
60
|
+
|
61
|
+
static VALUE cDATE;
|
62
|
+
static VALUE cTIME_OF_DAY_MILLI;
|
63
|
+
static VALUE cTIME_OF_DAY_NANO;
|
64
|
+
static VALUE cMILLI_TIME;
|
65
|
+
static VALUE cNANO_TIME;
|
66
|
+
|
67
|
+
static VALUE cSchemaRef;
|
68
|
+
static VALUE cDefinitionRef;
|
69
|
+
static VALUE cDefinitionTypeRef;
|
70
|
+
static VALUE cFieldRef;
|
71
|
+
static VALUE cFieldTypeRef;
|
72
|
+
|
73
|
+
/* generated **********************************************************/
|
74
|
+
|
75
|
+
%}
|
76
|
+
|
77
|
+
%define api.value.type {VALUE}
|
78
|
+
%define api.pure
|
79
|
+
%locations
|
80
|
+
%lex-param {yyscan_t scanner}
|
81
|
+
%parse-param {yyscan_t scanner}{VALUE filename}{VALUE *tree}
|
82
|
+
%define parse.error verbose
|
83
|
+
%define api.token.prefix {TOK_}
|
84
|
+
%glr-parser
|
85
|
+
|
86
|
+
%token
|
87
|
+
I8 "i8"
|
88
|
+
I16 "i16"
|
89
|
+
I32 "i32"
|
90
|
+
I64 "i64"
|
91
|
+
U8 "u8"
|
92
|
+
U16 "u16"
|
93
|
+
U32 "u32"
|
94
|
+
U64 "u64"
|
95
|
+
F64 "f64"
|
96
|
+
DECIMAL "decimal"
|
97
|
+
DATE "date"
|
98
|
+
TIME_OF_DAY_MILLI "timeOfDayMilli"
|
99
|
+
TIME_OF_DAY_NANO "timeOfDayNano"
|
100
|
+
NANO_TIME "nanotime"
|
101
|
+
MILLI_TIME "millitime"
|
102
|
+
BOOLEAN "boolean"
|
103
|
+
STRING "string"
|
104
|
+
OBJECT "object"
|
105
|
+
NAMESPACE "namespace"
|
106
|
+
TYPE "type"
|
107
|
+
SCHEMA "schema"
|
108
|
+
BINARY "binary"
|
109
|
+
NUMBER "number"
|
110
|
+
FIXED "fixed"
|
111
|
+
LEFT_ARROW "<-"
|
112
|
+
RIGHT_ARROW "->"
|
113
|
+
HEX "hexnum"
|
114
|
+
UINT "uint"
|
115
|
+
INT "int"
|
116
|
+
NAME "name"
|
117
|
+
NC_NAME "ncName"
|
118
|
+
ESCAPED_NC_NAME "\\ncName"
|
119
|
+
C_NAME "cName"
|
120
|
+
LITERAL "\"<annotation>\" or '<annotation>'"
|
121
|
+
|
122
|
+
|
123
|
+
%%
|
124
|
+
|
125
|
+
top:
|
126
|
+
schema
|
127
|
+
{
|
128
|
+
*tree = $schema;
|
129
|
+
}
|
130
|
+
;
|
131
|
+
|
132
|
+
schema:
|
133
|
+
defs
|
134
|
+
{
|
135
|
+
VALUE args[] = {Qnil, $defs};
|
136
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cSchema);
|
137
|
+
}
|
138
|
+
|
|
139
|
+
nsDecl defs
|
140
|
+
{
|
141
|
+
VALUE args[] = {$nsDecl, $defs};
|
142
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cSchema);
|
143
|
+
}
|
144
|
+
;
|
145
|
+
|
146
|
+
defs:
|
147
|
+
e
|
148
|
+
{
|
149
|
+
$$ = rb_ary_new();
|
150
|
+
}
|
151
|
+
|
|
152
|
+
defList
|
153
|
+
;
|
154
|
+
|
155
|
+
defList:
|
156
|
+
def
|
157
|
+
{
|
158
|
+
$$ = rb_ary_new_from_args(1, $def);
|
159
|
+
}
|
160
|
+
|
|
161
|
+
defList def
|
162
|
+
{
|
163
|
+
rb_ary_push($$, $def);
|
164
|
+
}
|
165
|
+
;
|
166
|
+
|
167
|
+
def:
|
168
|
+
annots define
|
169
|
+
{
|
170
|
+
$$ = $define;
|
171
|
+
rb_funcall($$, rb_intern("annote"), 1, $annots);
|
172
|
+
}
|
173
|
+
|
|
174
|
+
annots groupDef
|
175
|
+
{
|
176
|
+
$$ = $groupDef;
|
177
|
+
rb_funcall($$, rb_intern("annote"), 1, $annots);
|
178
|
+
}
|
179
|
+
|
|
180
|
+
incrAnnot
|
181
|
+
;
|
182
|
+
|
183
|
+
define:
|
184
|
+
nameWithId '=' enum
|
185
|
+
{
|
186
|
+
VALUE enumArgs[] = {$enum};
|
187
|
+
VALUE args[] = {$nameWithId, rb_class_new_instance(sizeof(enumArgs)/sizeof(*enumArgs),enumArgs, cEnumeration), newLocation(filename, &@$)};
|
188
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cDefinition);
|
189
|
+
}
|
190
|
+
|
|
191
|
+
nameWithId '=' type
|
192
|
+
{
|
193
|
+
VALUE args[] = {$nameWithId, $type, newLocation(filename, &@$)};
|
194
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cDefinition);
|
195
|
+
}
|
196
|
+
;
|
197
|
+
|
198
|
+
groupDef:
|
199
|
+
nameWithId
|
200
|
+
{
|
201
|
+
VALUE args[] = {$nameWithId, Qnil, rb_ary_new(), newLocation(filename, &@$)};
|
202
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cGroup);
|
203
|
+
}
|
204
|
+
|
|
205
|
+
nameWithId ':' qName
|
206
|
+
{
|
207
|
+
VALUE refArgs[] = {$qName, Qfalse, newLocation(filename, &@qName)};
|
208
|
+
VALUE args[] = {$nameWithId, rb_class_new_instance(sizeof(refArgs)/sizeof(*refArgs),refArgs, cREF), rb_ary_new(), newLocation(filename, &@$)};
|
209
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cGroup);
|
210
|
+
}
|
211
|
+
|
|
212
|
+
nameWithId ':' qName RIGHT_ARROW fields
|
213
|
+
{
|
214
|
+
VALUE refArgs[] = {$qName, Qfalse, newLocation(filename, &@qName)};
|
215
|
+
VALUE args[] = {$nameWithId, rb_class_new_instance(sizeof(refArgs)/sizeof(*refArgs),refArgs, cREF), $fields, newLocation(filename, &@$)};
|
216
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cGroup);
|
217
|
+
}
|
218
|
+
|
|
219
|
+
nameWithId RIGHT_ARROW fields
|
220
|
+
{
|
221
|
+
VALUE args[] = {$nameWithId, Qnil, $fields, newLocation(filename, &@$)};
|
222
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cGroup);
|
223
|
+
}
|
224
|
+
;
|
225
|
+
|
226
|
+
fields:
|
227
|
+
field
|
228
|
+
{
|
229
|
+
$$ = rb_ary_new_from_args(1, $field);
|
230
|
+
}
|
231
|
+
|
|
232
|
+
fields ',' field
|
233
|
+
{
|
234
|
+
rb_ary_push($$, $field);
|
235
|
+
}
|
236
|
+
;
|
237
|
+
|
238
|
+
field:
|
239
|
+
annots[typeAnnot] type annots[nameAnnot] nameWithId opt
|
240
|
+
{
|
241
|
+
VALUE args[] = {$nameWithId, $type, $opt, rb_funcall($type, rb_intern("location"), 0)};
|
242
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args),args, cField);
|
243
|
+
|
244
|
+
rb_funcall($$, rb_intern("annote"), 1, $typeAnnot);
|
245
|
+
rb_funcall($nameWithId, rb_intern("annote"), 1, $nameAnnot);
|
246
|
+
}
|
247
|
+
;
|
248
|
+
|
249
|
+
opt:
|
250
|
+
e
|
251
|
+
{
|
252
|
+
$$ = Qfalse;
|
253
|
+
}
|
254
|
+
|
|
255
|
+
'?'
|
256
|
+
{
|
257
|
+
$$ = Qtrue;
|
258
|
+
}
|
259
|
+
;
|
260
|
+
|
261
|
+
type:
|
262
|
+
single
|
263
|
+
|
|
264
|
+
sequence
|
265
|
+
;
|
266
|
+
|
267
|
+
single:
|
268
|
+
ref
|
269
|
+
|
|
270
|
+
time
|
271
|
+
|
|
272
|
+
number
|
273
|
+
|
|
274
|
+
string
|
275
|
+
|
|
276
|
+
binary
|
277
|
+
|
|
278
|
+
fixed
|
279
|
+
|
|
280
|
+
BOOLEAN
|
281
|
+
{
|
282
|
+
VALUE args[] = {Qnil, newLocation(filename, &@$)};
|
283
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cBOOLEAN);
|
284
|
+
}
|
285
|
+
|
|
286
|
+
OBJECT
|
287
|
+
{
|
288
|
+
VALUE args[] = {Qnil, newLocation(filename, &@$)};
|
289
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cOBJECT);
|
290
|
+
}
|
291
|
+
;
|
292
|
+
|
293
|
+
sequence:
|
294
|
+
single '[' ']'
|
295
|
+
{
|
296
|
+
VALUE args[] = {$single, rb_funcall($single, rb_intern("location"), 0)};
|
297
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cSEQUENCE);
|
298
|
+
}
|
299
|
+
;
|
300
|
+
|
301
|
+
string:
|
302
|
+
STRING
|
303
|
+
{
|
304
|
+
VALUE args[] = {Qnil, newLocation(filename, &@$)};
|
305
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cSTRING);
|
306
|
+
}
|
307
|
+
|
|
308
|
+
STRING size
|
309
|
+
{
|
310
|
+
VALUE args[] = {$size, newLocation(filename, &@$)};
|
311
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cSTRING);
|
312
|
+
}
|
313
|
+
;
|
314
|
+
|
315
|
+
binary:
|
316
|
+
BINARY
|
317
|
+
{
|
318
|
+
VALUE args[] = {Qnil, newLocation(filename, &@$)};
|
319
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cBINARY);
|
320
|
+
}
|
321
|
+
|
|
322
|
+
BINARY size
|
323
|
+
{
|
324
|
+
VALUE args[] = {$size, newLocation(filename, &@$)};
|
325
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cBINARY);
|
326
|
+
}
|
327
|
+
;
|
328
|
+
|
329
|
+
fixed:
|
330
|
+
FIXED size
|
331
|
+
{
|
332
|
+
VALUE args[] = {$size, newLocation(filename, &@$)};
|
333
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cFIXED);
|
334
|
+
}
|
335
|
+
;
|
336
|
+
|
337
|
+
size:
|
338
|
+
'(' uInt ')'
|
339
|
+
{
|
340
|
+
$$ = $uInt;
|
341
|
+
}
|
342
|
+
|
|
343
|
+
'(' hexNum ')'
|
344
|
+
{
|
345
|
+
$$ = $hexNum;
|
346
|
+
}
|
347
|
+
;
|
348
|
+
|
349
|
+
ref:
|
350
|
+
qName
|
351
|
+
{
|
352
|
+
VALUE args[] = {$qName, Qfalse};
|
353
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cREF);
|
354
|
+
}
|
355
|
+
|
|
356
|
+
qName '*'
|
357
|
+
{
|
358
|
+
VALUE args[] = {$qName, Qtrue};
|
359
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cREF);
|
360
|
+
}
|
361
|
+
;
|
362
|
+
|
363
|
+
number:
|
364
|
+
I8
|
365
|
+
{
|
366
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
367
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cI8);
|
368
|
+
}
|
369
|
+
|
|
370
|
+
I16
|
371
|
+
{
|
372
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
373
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cI16);
|
374
|
+
}
|
375
|
+
|
|
376
|
+
I32
|
377
|
+
{
|
378
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
379
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cI32);
|
380
|
+
}
|
381
|
+
|
|
382
|
+
I64
|
383
|
+
{
|
384
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
385
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cI64);
|
386
|
+
}
|
387
|
+
|
|
388
|
+
U8
|
389
|
+
{
|
390
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
391
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cU8);
|
392
|
+
}
|
393
|
+
|
|
394
|
+
U16
|
395
|
+
{
|
396
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
397
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cU16);
|
398
|
+
}
|
399
|
+
|
|
400
|
+
U32
|
401
|
+
{
|
402
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
403
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cU32);
|
404
|
+
}
|
405
|
+
|
|
406
|
+
U64
|
407
|
+
{
|
408
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
409
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cU64);
|
410
|
+
}
|
411
|
+
|
|
412
|
+
F64
|
413
|
+
{
|
414
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
415
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cF64);
|
416
|
+
}
|
417
|
+
|
|
418
|
+
DECIMAL
|
419
|
+
{
|
420
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
421
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cDECIMAL);
|
422
|
+
}
|
423
|
+
;
|
424
|
+
|
425
|
+
time:
|
426
|
+
DATE
|
427
|
+
{
|
428
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
429
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cDATE);
|
430
|
+
}
|
431
|
+
|
|
432
|
+
TIME_OF_DAY_MILLI
|
433
|
+
{
|
434
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
435
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cTIME_OF_DAY_MILLI);
|
436
|
+
}
|
437
|
+
|
|
438
|
+
TIME_OF_DAY_NANO
|
439
|
+
{
|
440
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
441
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cTIME_OF_DAY_NANO);
|
442
|
+
}
|
443
|
+
|
|
444
|
+
NANO_TIME
|
445
|
+
{
|
446
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
447
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cNANO_TIME);
|
448
|
+
}
|
449
|
+
|
|
450
|
+
MILLI_TIME
|
451
|
+
{
|
452
|
+
VALUE args[] = {newLocation(filename, &@$)};
|
453
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cMILLI_TIME);
|
454
|
+
}
|
455
|
+
;
|
456
|
+
|
457
|
+
/* note: a single entry enum does in fact lead with a '|' */
|
458
|
+
enum:
|
459
|
+
'|' sym
|
460
|
+
{
|
461
|
+
$$ = rb_ary_new_from_args(1, $sym);
|
462
|
+
}
|
463
|
+
|
|
464
|
+
symList
|
465
|
+
;
|
466
|
+
|
467
|
+
symList:
|
468
|
+
sym
|
469
|
+
{
|
470
|
+
$$ = rb_ary_new_from_args(1, $sym);
|
471
|
+
}
|
472
|
+
|
|
473
|
+
symList '|' sym
|
474
|
+
{
|
475
|
+
rb_ary_push($$, $sym);
|
476
|
+
}
|
477
|
+
;
|
478
|
+
|
479
|
+
sym:
|
480
|
+
annots name val
|
481
|
+
{
|
482
|
+
VALUE args[] = {$name, $val, newLocation(filename, &@name)};
|
483
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cSym);
|
484
|
+
rb_funcall($$, rb_intern("annote"), 1, $annots);
|
485
|
+
}
|
486
|
+
;
|
487
|
+
|
488
|
+
val:
|
489
|
+
e
|
490
|
+
|
|
491
|
+
'/' int
|
492
|
+
{
|
493
|
+
$$ = $int;
|
494
|
+
}
|
495
|
+
|
|
496
|
+
'/' hexNum
|
497
|
+
{
|
498
|
+
$$ = $hexNum;
|
499
|
+
}
|
500
|
+
;
|
501
|
+
|
502
|
+
annots:
|
503
|
+
e
|
504
|
+
{
|
505
|
+
$$ = rb_ary_new();
|
506
|
+
}
|
507
|
+
|
|
508
|
+
annotList
|
509
|
+
;
|
510
|
+
|
511
|
+
annotList:
|
512
|
+
annot
|
513
|
+
{
|
514
|
+
$$ = rb_ary_new_from_args(1, $annot);
|
515
|
+
}
|
516
|
+
|
|
517
|
+
annotList annot
|
518
|
+
{
|
519
|
+
rb_ary_push($$, $annot);
|
520
|
+
}
|
521
|
+
|
522
|
+
annot:
|
523
|
+
'@' qNameOrKeyword '=' literal
|
524
|
+
{
|
525
|
+
VALUE args[] = {$qNameOrKeyword, $literal, newLocation(filename, &@$)};
|
526
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cAnnotation);
|
527
|
+
}
|
528
|
+
;
|
529
|
+
|
530
|
+
literal:
|
531
|
+
literalSegment
|
532
|
+
|
|
533
|
+
literal literalSegment
|
534
|
+
{
|
535
|
+
rb_str_append($$, $literalSegment);
|
536
|
+
}
|
537
|
+
;
|
538
|
+
|
539
|
+
nameWithId:
|
540
|
+
name id
|
541
|
+
{
|
542
|
+
VALUE args[] = {$name, $id};
|
543
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cNameWithID);
|
544
|
+
}
|
545
|
+
;
|
546
|
+
|
547
|
+
id:
|
548
|
+
e
|
549
|
+
|
|
550
|
+
'/' uInt
|
551
|
+
{
|
552
|
+
$$ = $uInt;
|
553
|
+
}
|
554
|
+
|
|
555
|
+
'/' hexNum
|
556
|
+
{
|
557
|
+
$$ = $hexNum;
|
558
|
+
}
|
559
|
+
;
|
560
|
+
|
561
|
+
incrAnnot:
|
562
|
+
compRef LEFT_ARROW incrAnnotList
|
563
|
+
{
|
564
|
+
VALUE args[] = {$compRef, $incrAnnotList, newLocation(filename, &@$)};
|
565
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cIncrementalAnnotation);
|
566
|
+
}
|
567
|
+
;
|
568
|
+
|
569
|
+
compRef:
|
570
|
+
SCHEMA
|
571
|
+
{
|
572
|
+
VALUE args[] = {cSchema};
|
573
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cSchemaRef);
|
574
|
+
}
|
575
|
+
|
|
576
|
+
qName
|
577
|
+
{
|
578
|
+
VALUE args[] = {$qName};
|
579
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cDefinitionRef);
|
580
|
+
}
|
581
|
+
|
|
582
|
+
qName '.' TYPE
|
583
|
+
{
|
584
|
+
VALUE args[] = {$qName};
|
585
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cDefinitionTypeRef);
|
586
|
+
}
|
587
|
+
|
|
588
|
+
qName '.' name
|
589
|
+
{
|
590
|
+
VALUE args[] = {$qName, $name};
|
591
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cFieldRef);
|
592
|
+
}
|
593
|
+
|
|
594
|
+
qName '.' name '.' TYPE
|
595
|
+
{
|
596
|
+
VALUE args[] = {$qName, $name};
|
597
|
+
$$ = rb_class_new_instance(sizeof(args)/sizeof(*args), args, cFieldTypeRef);
|
598
|
+
}
|
599
|
+
;
|
600
|
+
|
601
|
+
incrAnnotList:
|
602
|
+
incrAnnotItem
|
603
|
+
{
|
604
|
+
$$ = rb_ary_new_from_args(1, $incrAnnotItem);
|
605
|
+
}
|
606
|
+
|
|
607
|
+
incrAnnotItem LEFT_ARROW incrAnnotList[list]
|
608
|
+
{
|
609
|
+
$$ = $list;
|
610
|
+
rb_ary_unshift($$, $incrAnnotItem);
|
611
|
+
}
|
612
|
+
;
|
613
|
+
|
614
|
+
incrAnnotItem:
|
615
|
+
INT
|
616
|
+
|
|
617
|
+
UINT
|
618
|
+
|
|
619
|
+
HEX
|
620
|
+
|
|
621
|
+
annot
|
622
|
+
;
|
623
|
+
|
624
|
+
qName:
|
625
|
+
name
|
626
|
+
|
|
627
|
+
cName
|
628
|
+
;
|
629
|
+
|
630
|
+
qNameOrKeyword:
|
631
|
+
qName
|
632
|
+
|
|
633
|
+
keyword
|
634
|
+
;
|
635
|
+
|
636
|
+
keyword:
|
637
|
+
I8
|
638
|
+
{
|
639
|
+
$$ = rb_str_new_cstr("i8");
|
640
|
+
}
|
641
|
+
|
|
642
|
+
I16
|
643
|
+
{
|
644
|
+
$$ = rb_str_new_cstr("i16");
|
645
|
+
}
|
646
|
+
|
|
647
|
+
I32
|
648
|
+
{
|
649
|
+
$$ = rb_str_new_cstr("i32");
|
650
|
+
}
|
651
|
+
|
|
652
|
+
I64
|
653
|
+
{
|
654
|
+
$$ = rb_str_new_cstr("i64");
|
655
|
+
}
|
656
|
+
|
|
657
|
+
U8
|
658
|
+
{
|
659
|
+
$$ = rb_str_new_cstr("u8");
|
660
|
+
}
|
661
|
+
|
|
662
|
+
U16
|
663
|
+
{
|
664
|
+
$$ = rb_str_new_cstr("u16");
|
665
|
+
}
|
666
|
+
|
|
667
|
+
U32
|
668
|
+
{
|
669
|
+
$$ = rb_str_new_cstr("u32");
|
670
|
+
}
|
671
|
+
|
|
672
|
+
U64
|
673
|
+
{
|
674
|
+
$$ = rb_str_new_cstr("u64");
|
675
|
+
}
|
676
|
+
|
|
677
|
+
F64
|
678
|
+
{
|
679
|
+
$$ = rb_str_new_cstr("f64");
|
680
|
+
}
|
681
|
+
|
|
682
|
+
DECIMAL
|
683
|
+
{
|
684
|
+
$$ = rb_str_new_cstr("decimal");
|
685
|
+
}
|
686
|
+
|
|
687
|
+
DATE
|
688
|
+
{
|
689
|
+
$$ = rb_str_new_cstr("date");
|
690
|
+
}
|
691
|
+
|
|
692
|
+
TIME_OF_DAY_MILLI
|
693
|
+
{
|
694
|
+
$$ = rb_str_new_cstr("timeOfDayMilli");
|
695
|
+
}
|
696
|
+
|
|
697
|
+
TIME_OF_DAY_NANO
|
698
|
+
{
|
699
|
+
$$ = rb_str_new_cstr("timeOfDayNano");
|
700
|
+
}
|
701
|
+
|
|
702
|
+
NANO_TIME
|
703
|
+
{
|
704
|
+
$$ = rb_str_new_cstr("nanoTime");
|
705
|
+
}
|
706
|
+
|
|
707
|
+
MILLI_TIME
|
708
|
+
{
|
709
|
+
$$ = rb_str_new_cstr("milliTime");
|
710
|
+
}
|
711
|
+
|
|
712
|
+
BOOLEAN
|
713
|
+
{
|
714
|
+
$$ = rb_str_new_cstr("boolean");
|
715
|
+
}
|
716
|
+
|
|
717
|
+
STRING
|
718
|
+
{
|
719
|
+
$$ = rb_str_new_cstr("string");
|
720
|
+
}
|
721
|
+
|
|
722
|
+
BINARY
|
723
|
+
{
|
724
|
+
$$ = rb_str_new_cstr("binary");
|
725
|
+
}
|
726
|
+
|
|
727
|
+
FIXED
|
728
|
+
{
|
729
|
+
$$ = rb_str_new_cstr("fixed");
|
730
|
+
}
|
731
|
+
|
|
732
|
+
OBJECT
|
733
|
+
{
|
734
|
+
$$ = rb_str_new_cstr("object");
|
735
|
+
}
|
736
|
+
|
|
737
|
+
NAMESPACE
|
738
|
+
{
|
739
|
+
$$ = rb_str_new_cstr("namespace");
|
740
|
+
}
|
741
|
+
|
|
742
|
+
TYPE
|
743
|
+
{
|
744
|
+
$$ = rb_str_new_cstr("type");
|
745
|
+
}
|
746
|
+
|
|
747
|
+
SCHEMA
|
748
|
+
{
|
749
|
+
$$ = rb_str_new_cstr("schema");
|
750
|
+
}
|
751
|
+
;
|
752
|
+
|
753
|
+
cName:
|
754
|
+
C_NAME
|
755
|
+
;
|
756
|
+
|
757
|
+
name:
|
758
|
+
NC_NAME
|
759
|
+
|
|
760
|
+
ESCAPED_NC_NAME
|
761
|
+
;
|
762
|
+
|
763
|
+
nsDecl:
|
764
|
+
NAMESPACE name
|
765
|
+
{
|
766
|
+
$$ = $name;
|
767
|
+
}
|
768
|
+
;
|
769
|
+
|
770
|
+
literalSegment:
|
771
|
+
LITERAL
|
772
|
+
;
|
773
|
+
|
774
|
+
int:
|
775
|
+
INT
|
776
|
+
|
|
777
|
+
UINT
|
778
|
+
;
|
779
|
+
|
780
|
+
uInt:
|
781
|
+
UINT
|
782
|
+
;
|
783
|
+
|
784
|
+
hexNum:
|
785
|
+
HEX
|
786
|
+
;
|
787
|
+
|
788
|
+
e:
|
789
|
+
%empty
|
790
|
+
{
|
791
|
+
$$ = Qnil;
|
792
|
+
}
|
793
|
+
;
|
794
|
+
|
795
|
+
%%
|
796
|
+
|
797
|
+
/* functions **********************************************************/
|
798
|
+
|
799
|
+
|
800
|
+
void Init_ext_schema_parser(void)
|
801
|
+
{
|
802
|
+
cSlowBlink = rb_define_module("SlowBlink");
|
803
|
+
|
804
|
+
cNameWithID = rb_const_get(cSlowBlink, rb_intern("NameWithID"));
|
805
|
+
|
806
|
+
cSchema = rb_const_get(cSlowBlink, rb_intern("Schema"));
|
807
|
+
cGroup = rb_const_get(cSlowBlink, rb_intern("Group"));
|
808
|
+
cField = rb_const_get(cSlowBlink, rb_intern("Field"));
|
809
|
+
cDefinition = rb_const_get(cSlowBlink, rb_intern("Field"));
|
810
|
+
|
811
|
+
cAnnotation = rb_const_get(cSlowBlink, rb_intern("Annotation"));
|
812
|
+
cIncrementalAnnotation = rb_const_get(cSlowBlink, rb_intern("IncrementalAnnotation"));
|
813
|
+
|
814
|
+
cDefinition = rb_const_get(cSlowBlink, rb_intern("Definition"));
|
815
|
+
cEnumeration = rb_const_get(cSlowBlink, rb_intern("Enumeration"));
|
816
|
+
cSym = rb_const_get(cSlowBlink, rb_intern("Sym"));
|
817
|
+
|
818
|
+
cU8 = rb_const_get(cSlowBlink, rb_intern("U8"));
|
819
|
+
cU16 = rb_const_get(cSlowBlink, rb_intern("U16"));
|
820
|
+
cU32 = rb_const_get(cSlowBlink, rb_intern("U32"));
|
821
|
+
cU64 = rb_const_get(cSlowBlink, rb_intern("U64"));
|
822
|
+
cI8 = rb_const_get(cSlowBlink, rb_intern("I8"));
|
823
|
+
cI16 = rb_const_get(cSlowBlink, rb_intern("I16"));
|
824
|
+
cI32 = rb_const_get(cSlowBlink, rb_intern("I32"));
|
825
|
+
cI64 = rb_const_get(cSlowBlink, rb_intern("I64"));
|
826
|
+
cF64 = rb_const_get(cSlowBlink, rb_intern("F64"));
|
827
|
+
cDECIMAL = rb_const_get(cSlowBlink, rb_intern("DECIMAL"));
|
828
|
+
cFIXED = rb_const_get(cSlowBlink, rb_intern("FIXED"));
|
829
|
+
cBINARY = rb_const_get(cSlowBlink, rb_intern("BINARY"));
|
830
|
+
cSTRING = rb_const_get(cSlowBlink, rb_intern("STRING"));
|
831
|
+
cBOOLEAN = rb_const_get(cSlowBlink, rb_intern("BOOLEAN"));
|
832
|
+
cDATE = rb_const_get(cSlowBlink, rb_intern("DATE"));
|
833
|
+
cMILLI_TIME = rb_const_get(cSlowBlink, rb_intern("MILLI_TIME"));
|
834
|
+
cNANO_TIME = rb_const_get(cSlowBlink, rb_intern("NANO_TIME"));
|
835
|
+
cTIME_OF_DAY_MILLI = rb_const_get(cSlowBlink, rb_intern("TIME_OF_DAY_MILLI"));
|
836
|
+
cTIME_OF_DAY_NANO = rb_const_get(cSlowBlink, rb_intern("TIME_OF_DAY_NANO"));
|
837
|
+
cSEQUENCE = rb_const_get(cSlowBlink, rb_intern("SEQUENCE"));
|
838
|
+
cREF = rb_const_get(cSlowBlink, rb_intern("REF"));
|
839
|
+
cOBJECT = rb_const_get(cSlowBlink, rb_intern("OBJECT"));
|
840
|
+
|
841
|
+
cSchemaRef = rb_const_get(cSlowBlink, rb_intern("SchemaRef"));
|
842
|
+
cDefinitionRef = rb_const_get(cSlowBlink, rb_intern("DefinitionRef"));
|
843
|
+
cDefinitionTypeRef = rb_const_get(cSlowBlink, rb_intern("DefinitionTypeRef"));
|
844
|
+
cFieldRef = rb_const_get(cSlowBlink, rb_intern("FieldRef"));
|
845
|
+
cFieldTypeRef = rb_const_get(cSlowBlink, rb_intern("FieldTypeRef"));
|
846
|
+
|
847
|
+
rb_define_singleton_method(cSchema, "parse", parseFileBuffer, -1);
|
848
|
+
}
|
849
|
+
|
850
|
+
void yyerror(YYLTYPE *locp, yyscan_t scanner, VALUE filename, VALUE *tree, char const *msg, ... )
|
851
|
+
{
|
852
|
+
int retval;
|
853
|
+
VALUE rbString;
|
854
|
+
char error[500];
|
855
|
+
|
856
|
+
int hdrLen;
|
857
|
+
|
858
|
+
hdrLen = snprintf(error, sizeof(error), "%s:%i:%i: error: ", (const char *)RSTRING_PTR(filename), locp->first_line, locp->first_column);
|
859
|
+
|
860
|
+
if((hdrLen > 0) && (hdrLen <= sizeof(error))){
|
861
|
+
|
862
|
+
va_list argptr;
|
863
|
+
va_start(argptr, msg);
|
864
|
+
retval = vsnprintf(&error[hdrLen], sizeof(error) - hdrLen, msg, argptr);
|
865
|
+
va_end(argptr);
|
866
|
+
|
867
|
+
if((retval > 0) && ((hdrLen + retval) <= sizeof(error))){
|
868
|
+
|
869
|
+
rbString = rb_str_new((const char *)error, (hdrLen + retval));
|
870
|
+
rb_io_puts(1, &rbString, rb_stderr);
|
871
|
+
}
|
872
|
+
else{
|
873
|
+
|
874
|
+
rb_bug("yyerror buffer is too short to contain error message");
|
875
|
+
}
|
876
|
+
}
|
877
|
+
else{
|
878
|
+
|
879
|
+
rb_bug("yyerror buffer is too short to contain error message");
|
880
|
+
}
|
881
|
+
}
|
882
|
+
|
883
|
+
/* static functions ***************************************************/
|
884
|
+
|
885
|
+
static VALUE parseFileBuffer(int argc, VALUE* argv, VALUE self)
|
886
|
+
{
|
887
|
+
yyscan_t scanner;
|
888
|
+
VALUE tree = Qnil;
|
889
|
+
VALUE buffer;
|
890
|
+
VALUE opts;
|
891
|
+
|
892
|
+
rb_scan_args(argc, argv, "10:", &buffer, &opts);
|
893
|
+
|
894
|
+
if(opts == Qnil){
|
895
|
+
opts = rb_hash_new();
|
896
|
+
}
|
897
|
+
|
898
|
+
VALUE filename = rb_hash_aref(opts, ID2SYM(rb_intern("filename")));
|
899
|
+
|
900
|
+
if(yylex_init(&scanner) == 0){
|
901
|
+
|
902
|
+
if(yy_scan_bytes((const char *)RSTRING_PTR(buffer), RSTRING_LEN(buffer), scanner)){
|
903
|
+
|
904
|
+
yyparse(scanner, filename, &tree);
|
905
|
+
}
|
906
|
+
|
907
|
+
yylex_destroy(scanner);
|
908
|
+
}
|
909
|
+
|
910
|
+
return tree;
|
911
|
+
}
|
912
|
+
|
913
|
+
static VALUE newLocation(VALUE filename, const YYLTYPE *location)
|
914
|
+
{
|
915
|
+
char msg[500];
|
916
|
+
int pos = 0;
|
917
|
+
|
918
|
+
if(filename != Qnil){
|
919
|
+
|
920
|
+
if(RSTRING_LEN(filename) < sizeof(msg)){
|
921
|
+
memcpy(msg, RSTRING_PTR(filename), RSTRING_LEN(filename));
|
922
|
+
pos = RSTRING_LEN(filename);
|
923
|
+
}
|
924
|
+
else{
|
925
|
+
return rb_str_new("...", strlen("..."));
|
926
|
+
}
|
927
|
+
}
|
928
|
+
|
929
|
+
int len = snprintf(&msg[pos], sizeof(msg) - pos, ":%i:%i:", location->first_line, location->first_column);
|
930
|
+
|
931
|
+
return rb_str_new(msg, len);
|
932
|
+
}
|