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.
@@ -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
+ }