slow_blink 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }