File Coverage

lib/Marpa/R2.xs
Criterion Covered Total %
statement 1742 2468 70.5
branch 824 1716 48.0
condition n/a
subroutine n/a
pod n/a
total 2566 4184 61.3


line stmt bran cond sub pod time code
1             /*
2             * Copyright 2022 Jeffrey Kegler
3             * This file is part of Marpa::R2. Marpa::R2 is free software: you can
4             * redistribute it and/or modify it under the terms of the GNU Lesser
5             * General Public License as published by the Free Software Foundation,
6             * either version 3 of the License, or (at your option) any later version.
7             *
8             * Marpa::R2 is distributed in the hope that it will be useful,
9             * but WITHOUT ANY WARRANTY; without even the implied warranty of
10             * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11             * Lesser General Public License for more details.
12             *
13             * You should have received a copy of the GNU Lesser
14             * General Public License along with Marpa::R2. If not, see
15             * http://www.gnu.org/licenses/.
16             */
17              
18             #include "config.h"
19             #include "marpa.h"
20             #include "marpa_codes.h"
21              
22             #define PERL_NO_GET_CONTEXT
23             #include
24             #include
25             #include
26             #include "ppport.h"
27              
28             /* This kind of pointer comparison is not portable per C89,
29             * but the Perl source depends on it throughout,
30             * and there seems to be no other way to do it.
31             */
32             #undef IS_PERL_UNDEF
33             #define IS_PERL_UNDEF(x) ((x) == &PL_sv_undef)
34              
35             #undef STRINGIFY_ARG
36             #undef STRINGIFY
37             #undef STRLOC
38             #define STRINGIFY_ARG(contents) #contents
39             #define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string)
40             #define STRLOC __FILE__ ":" STRINGIFY (__LINE__)
41              
42             #undef MAX
43             #define MAX(a, b) ((a) > (b) ? (a) : (b))
44              
45             /* utf8_to_uvchr is deprecated in 5.16, but
46             * utf8_to_uvchr_buf is not available before 5.16
47             * If I need to get fancier, I should look at Dumper.xs
48             * in Data::Dumper
49             */
50             #if PERL_VERSION <= 15 && ! defined(utf8_to_uvchr_buf)
51             #define utf8_to_uvchr_buf(s, send, p_length) (utf8_to_uvchr(s, p_length))
52             #endif
53              
54             typedef SV* SVREF;
55              
56             #undef Dim
57             #define Dim(x) (sizeof(x)/sizeof(*x))
58              
59             typedef unsigned int Marpa_Codepoint;
60              
61             extern const struct marpa_error_description_s marpa_error_description[];
62             extern const struct marpa_event_description_s marpa_event_description[];
63             extern const struct marpa_step_type_description_s
64             marpa_step_type_description[];
65              
66             struct marpa_slr_s;
67             typedef struct marpa_slr_s* Marpa_SLR;
68             struct marpa_slr_s {
69              
70             union marpa_slr_event_s* t_events;
71             int t_event_capacity;
72             int t_event_count;
73              
74             union marpa_slr_event_s* t_lexemes;
75             int t_lexeme_capacity;
76             int t_lexeme_count;
77              
78             int t_ref_count;
79             int t_count_of_deleted_events;
80             };
81             typedef Marpa_SLR SLR;
82              
83             union marpa_slr_event_s;
84              
85             #define MARPA_SLREV_AFTER_LEXEME 1
86             #define MARPA_SLREV_BEFORE_LEXEME 2
87             #define MARPA_SLREV_LEXEME_DISCARDED 3
88             #define MARPA_SLREV_LEXER_RESTARTED_RECCE 4
89             #define MARPA_SLREV_MARPA_R_UNKNOWN 5
90             #define MARPA_SLREV_NO_ACCEPTABLE_INPUT 6
91             #define MARPA_SLREV_SYMBOL_COMPLETED 7
92             #define MARPA_SLREV_SYMBOL_NULLED 8
93             #define MARPA_SLREV_SYMBOL_PREDICTED 9
94             #define MARPA_SLRTR_AFTER_LEXEME 10
95             #define MARPA_SLRTR_BEFORE_LEXEME 11
96             /* #define MARPA_SLRTR_CHANGE_LEXERS 12 */
97             #define MARPA_SLRTR_CODEPOINT_ACCEPTED 13
98             #define MARPA_SLRTR_CODEPOINT_READ 14
99             #define MARPA_SLRTR_CODEPOINT_REJECTED 15
100             #define MARPA_SLRTR_LEXEME_DISCARDED 16
101             #define MARPA_SLRTR_G1_ACCEPTED_LEXEME 17
102             #define MARPA_SLRTR_G1_ATTEMPTING_LEXEME 18
103             #define MARPA_SLRTR_G1_DUPLICATE_LEXEME 19
104             #define MARPA_SLRTR_LEXEME_REJECTED 20
105             #define MARPA_SLRTR_LEXEME_IGNORED 21
106             #define MARPA_SLREV_DELETED 22
107             #define MARPA_SLRTR_LEXEME_ACCEPTABLE 23
108             #define MARPA_SLRTR_LEXEME_OUTPRIORITIZED 24
109             #define MARPA_SLRTR_LEXEME_EXPECTED 26
110              
111             #define MARPA_SLREV_TYPE(event) ((event)->t_header.t_event_type)
112              
113             union marpa_slr_event_s
114             {
115             struct
116             {
117             int t_event_type;
118             } t_header;
119              
120             struct
121             {
122             int event_type;
123             int t_codepoint;
124             int t_perl_pos;
125             } t_trace_codepoint_read;
126              
127             struct
128             {
129             int event_type;
130             int t_codepoint;
131             int t_perl_pos;
132             int t_symbol_id;
133             } t_trace_codepoint_rejected;
134              
135             struct
136             {
137             int event_type;
138             int t_codepoint;
139             int t_perl_pos;
140             int t_symbol_id;
141             } t_trace_codepoint_accepted;
142              
143             struct
144             {
145             int event_type;
146             int t_event_type;
147             int t_lexeme;
148             int t_start_of_lexeme;
149             int t_end_of_lexeme;
150             } t_trace_lexeme_ignored;
151              
152             struct
153             {
154             int event_type;
155             int t_rule_id;
156             int t_start_of_lexeme;
157             int t_end_of_lexeme;
158             } t_trace_lexeme_discarded;
159              
160             struct
161             {
162             int event_type;
163             int t_rule_id;
164             int t_start_of_lexeme;
165             int t_end_of_lexeme;
166             int t_last_g1_location;
167             } t_lexeme_discarded;
168              
169             struct
170             {
171             int event_type;
172             int t_symbol;
173             } t_symbol_completed;
174              
175             struct
176             {
177             int event_type;
178             int t_symbol;
179             } t_symbol_nulled;
180              
181             struct
182             {
183             int event_type;
184             int t_symbol;
185             } t_symbol_predicted;
186              
187             struct
188             {
189             int event_type;
190             int t_event;
191             } t_marpa_r_unknown;
192              
193             struct
194             {
195             int event_type;
196             int t_start_of_lexeme;
197             int t_end_of_lexeme;
198             int t_lexeme;
199             }
200             t_trace_lexeme_rejected;
201              
202             struct
203             {
204             int event_type;
205             int t_start_of_lexeme;
206             int t_end_of_lexeme;
207             int t_lexeme;
208             int t_priority;
209             int t_required_priority;
210             } t_trace_lexeme_acceptable;
211              
212             struct
213             {
214             int event_type;
215             int t_start_of_pause_lexeme;
216             int t_end_of_pause_lexeme;
217             int t_pause_lexeme;
218             } t_trace_before_lexeme;
219              
220             struct
221             {
222             int event_type;
223             int t_pause_lexeme;
224             } t_before_lexeme;
225              
226             struct
227             {
228             int event_type;
229             int t_start_of_lexeme;
230             int t_end_of_lexeme;
231             int t_lexeme;
232             } t_trace_after_lexeme;
233              
234             struct
235             {
236             int event_type;
237             int t_lexeme;
238             } t_after_lexeme;
239              
240             struct
241             {
242             int event_type;
243             int t_start_of_lexeme;
244             int t_end_of_lexeme;
245             int t_lexeme;
246             }
247             t_trace_attempting_lexeme;
248              
249             struct
250             {
251             int event_type;
252             int t_start_of_lexeme;
253             int t_end_of_lexeme;
254             int t_lexeme;
255             }
256             t_trace_duplicate_lexeme;
257              
258             struct
259             {
260             int event_type;
261             int t_start_of_lexeme;
262             int t_end_of_lexeme;
263             int t_lexeme;
264             }
265             t_trace_accepted_lexeme;
266              
267             struct
268             {
269             int event_type;
270             int t_start_of_lexeme;
271             int t_end_of_lexeme;
272             int t_lexeme;
273             int t_priority;
274             int t_required_priority;
275             } t_lexeme_acceptable;
276             struct
277             {
278             int event_type;
279             } t_no_acceptable_input;
280             struct
281             {
282             int event_type;
283             int t_perl_pos;
284             } t_lexer_restarted_recce;
285             struct
286             {
287             int event_type;
288             int t_perl_pos;
289             Marpa_Symbol_ID t_lexeme;
290             Marpa_Assertion_ID t_assertion;
291             } t_trace_lexeme_expected;
292              
293             };
294              
295 975           static Marpa_SLR marpa__slr_new(void)
296             {
297             SLR slr;
298 975           Newx (slr, 1, struct marpa_slr_s);
299 975           slr->t_ref_count = 1;
300              
301 975           slr->t_count_of_deleted_events = 0;
302 975           slr->t_event_count = 0;
303 975           slr->t_event_capacity = MAX (1024 / sizeof (union marpa_slr_event_s), 16);
304 975           Newx (slr->t_events, slr->t_event_capacity, union marpa_slr_event_s);
305              
306 975           slr->t_lexeme_count = 0;
307 975           slr->t_lexeme_capacity = MAX (1024 / sizeof (union marpa_slr_event_s), 16);
308 975           Newx (slr->t_lexemes, slr->t_lexeme_capacity, union marpa_slr_event_s);
309              
310 975           return slr;
311             }
312              
313 975           static void slr_free(SLR slr)
314             {
315 975           Safefree(slr->t_events);
316 975           Safefree(slr->t_lexemes);
317 975           Safefree( slr);
318 975           }
319              
320             static void
321             slr_unref (Marpa_SLR slr)
322             {
323             /* MARPA_ASSERT (slr->t_ref_count > 0) */
324 975           slr->t_ref_count--;
325 975 50         if (slr->t_ref_count <= 0)
326             {
327 975           slr_free(slr);
328             }
329             }
330              
331             static void
332             marpa__slr_unref (Marpa_SLR slr)
333             {
334             slr_unref(slr);
335             }
336              
337             typedef int Marpa_Op;
338              
339             struct op_data_s { const char *name; Marpa_Op op; };
340              
341             #include "marpa_slifop.h"
342              
343             static const char*
344             marpa__slif_op_name (Marpa_Op op_id)
345             {
346 0 0         if (op_id >= (int)Dim(op_name_by_id_object)) return "unknown";
347 0           return op_name_by_id_object[op_id];
348             }
349              
350             static Marpa_Op
351 2538           marpa__slif_op_id (const char *name)
352             {
353             int lo = 0;
354             int hi = Dim (op_by_name_object) - 1;
355 9857 50         while (hi >= lo)
356             {
357 9857           const int trial = lo + (hi - lo) / 2;
358 9857           const char *trial_name = op_by_name_object[trial].name;
359 9857           int cmp = strcmp (name, trial_name);
360 9857 100         if (!cmp)
361 2538           return op_by_name_object[trial].op;
362 7319 100         if (cmp < 0)
363             {
364 3298           hi = trial - 1;
365             }
366             else
367             {
368 7319           lo = trial + 1;
369             }
370             }
371             return -1;
372             }
373              
374             static void marpa__slr_event_clear( Marpa_SLR slr )
375             {
376 6666           slr->t_event_count = 0;
377 6666           slr->t_count_of_deleted_events = 0;
378             }
379              
380             static int marpa__slr_event_count( Marpa_SLR slr )
381             {
382             const int event_count = slr->t_event_count;
383 28685           return event_count - slr->t_count_of_deleted_events;
384             }
385              
386 1249           static union marpa_slr_event_s * marpa__slr_event_push( Marpa_SLR slr )
387             {
388 1249 50         if (slr->t_event_count >= slr->t_event_capacity)
389             {
390 0           slr->t_event_capacity *= 2;
391 0 0         Renew (slr->t_events, slr->t_event_capacity, union marpa_slr_event_s);
392             }
393 1249           return slr->t_events + (slr->t_event_count++);
394             }
395              
396             static void marpa__slr_lexeme_clear( Marpa_SLR slr )
397             {
398 28047           slr->t_lexeme_count = 0;
399             }
400              
401 31371           static union marpa_slr_event_s * marpa__slr_lexeme_push( Marpa_SLR slr )
402             {
403 31371 50         if (slr->t_lexeme_count >= slr->t_lexeme_capacity)
404             {
405 0           slr->t_lexeme_capacity *= 2;
406 0 0         Renew (slr->t_lexemes, slr->t_lexeme_capacity, union marpa_slr_event_s);
407             }
408 31371           return slr->t_lexemes + (slr->t_lexeme_count++);
409             }
410              
411              
412             typedef struct marpa_g Grammar;
413             /* The error_code member should usually be ignored in favor of
414             * getting a fresh error code from Libmarpa. Essentially it
415             * acts as an optional return value for marpa_g_error()
416             */
417             typedef struct {
418             Marpa_Grammar g;
419             char *message_buffer;
420             int libmarpa_error_code;
421             const char *libmarpa_error_string;
422             unsigned int throw:1;
423             unsigned int message_is_marpa_thin_error:1;
424             } G_Wrapper;
425              
426             typedef struct marpa_r Recce;
427             typedef struct {
428             Marpa_Recce r;
429             Marpa_Symbol_ID* terminals_buffer;
430             SV* base_sv;
431             AV* event_queue;
432             G_Wrapper* base;
433             unsigned int ruby_slippers:1;
434             } R_Wrapper;
435              
436             typedef struct {
437             int next_offset; /* Offset of *NEXT* codepoint */
438             int linecol;
439             /* Lines are 1-based, columns are zero-based and negated.
440             * In the first column (column 0), linecol is the 1-based line number.
441             * In subsequent columns, linecol is -n, where n is the 0-based column
442             * number.
443             */
444             } Pos_Entry;
445              
446             #undef POS_TO_OFFSET
447             #define POS_TO_OFFSET(slr, pos) \
448             ((pos) > 0 ? (slr)->pos_db[(pos) - 1].next_offset : 0)
449             #undef OFFSET_IN_INPUT
450             #define OFFSET_IN_INPUT(slr) POS_TO_OFFSET((slr), (slr)->perl_pos)
451              
452             struct symbol_g_properties {
453             int priority;
454             unsigned int latm:1;
455             unsigned int is_lexeme:1;
456             unsigned int t_pause_before:1;
457             unsigned int t_pause_before_active:1;
458             unsigned int t_pause_after:1;
459             unsigned int t_pause_after_active:1;
460             };
461              
462             struct l0_rule_g_properties {
463             Marpa_Symbol_ID g1_lexeme;
464             unsigned int t_event_on_discard:1;
465             unsigned int t_event_on_discard_active:1;
466             };
467              
468             struct symbol_r_properties {
469             int lexeme_priority;
470             unsigned int t_pause_before_active:1;
471             unsigned int t_pause_after_active:1;
472             };
473              
474             struct l0_rule_r_properties {
475             unsigned int t_event_on_discard_active:1;
476             };
477              
478             typedef struct
479             {
480             Marpa_Grammar g1;
481             SV *g1_sv;
482             G_Wrapper *g1_wrapper;
483              
484             SV *l0_sv;
485             G_Wrapper *l0_wrapper;
486             Marpa_Assertion_ID *g1_lexeme_to_assertion;
487             HV *per_codepoint_hash;
488             IV *per_codepoint_array[128];
489             int precomputed;
490             struct symbol_g_properties *symbol_g_properties;
491             struct l0_rule_g_properties *l0_rule_g_properties;
492             } Scanless_G;
493              
494             typedef struct
495             {
496             SV *slg_sv;
497             SV *r1_sv;
498              
499             Scanless_G *slg;
500             R_Wrapper *r1_wrapper;
501             Marpa_Recce r1;
502             G_Wrapper *g1_wrapper;
503             AV *token_values;
504             IV trace_lexers;
505             int trace_terminals;
506             STRLEN start_of_lexeme;
507             STRLEN end_of_lexeme;
508              
509             /* Input position at which to start the lexer.
510             -1 means no restart.
511             */
512             int lexer_start_pos;
513             int lexer_read_result;
514             int r1_earleme_complete_result;
515              
516             /* A boolean to prevent the inappropriate mixing
517             * of internal and external scanning
518             */
519             int is_external_scanning;
520              
521             int last_perl_pos;
522             int perl_pos;
523              
524             Marpa_Recce r0;
525             /* character position, taking into account Unicode
526             Equivalent to Perl pos()
527             One past last actual position indicates past-end-of-string
528             */
529             /* Position of problem -- unspecifed if not returning a problem */
530             int problem_pos;
531             int throw;
532             int start_of_pause_lexeme;
533             int end_of_pause_lexeme;
534             Marpa_Symbol_ID pause_lexeme;
535             struct symbol_r_properties *symbol_r_properties;
536             struct l0_rule_r_properties *l0_rule_r_properties;
537             Pos_Entry *pos_db;
538             int pos_db_logical_size;
539             int pos_db_physical_size;
540              
541             Marpa_Symbol_ID input_symbol_id;
542             UV codepoint; /* For error returns */
543             int end_pos;
544             SV* input;
545             int too_many_earley_items;
546              
547             /* A "Gift" because it is something that is "wrapped". */
548             Marpa_SLR gift;
549              
550             } Scanless_R;
551             #define TOKEN_VALUE_IS_UNDEF (1)
552             #define TOKEN_VALUE_IS_LITERAL (2)
553              
554             typedef struct marpa_b Bocage;
555             typedef struct {
556             Marpa_Bocage b;
557             SV* base_sv;
558             G_Wrapper* base;
559             } B_Wrapper;
560              
561             typedef struct marpa_o Order;
562             typedef struct {
563             Marpa_Order o;
564             SV* base_sv;
565             G_Wrapper* base;
566             } O_Wrapper;
567              
568             typedef struct marpa_t Tree;
569             typedef struct {
570             Marpa_Tree t;
571             SV* base_sv;
572             G_Wrapper* base;
573             } T_Wrapper;
574              
575             typedef struct marpa_v Value;
576             typedef struct
577             {
578             Marpa_Value v;
579             SV *base_sv;
580             G_Wrapper *base;
581             AV *event_queue;
582             AV *token_values;
583             AV *stack;
584             IV trace_values;
585             int mode; /* 'raw' or 'stack' */
586             int result; /* stack location to which to write result */
587             AV *constants;
588             AV *rule_semantics;
589             AV *token_semantics;
590             AV *nulling_semantics;
591             Scanless_R* slr;
592             } V_Wrapper;
593              
594             #define MARPA_XS_V_MODE_IS_INITIAL 0
595             #define MARPA_XS_V_MODE_IS_RAW 1
596             #define MARPA_XS_V_MODE_IS_STACK 2
597              
598             static const char grammar_c_class_name[] = "Marpa::R2::Thin::G";
599             static const char recce_c_class_name[] = "Marpa::R2::Thin::R";
600             static const char bocage_c_class_name[] = "Marpa::R2::Thin::B";
601             static const char order_c_class_name[] = "Marpa::R2::Thin::O";
602             static const char tree_c_class_name[] = "Marpa::R2::Thin::T";
603             static const char value_c_class_name[] = "Marpa::R2::Thin::V";
604             static const char scanless_g_class_name[] = "Marpa::R2::Thin::SLG";
605             static const char scanless_r_class_name[] = "Marpa::R2::Thin::SLR";
606              
607             static const char *
608             event_type_to_string (Marpa_Event_Type event_code)
609             {
610             const char *event_name = NULL;
611 135 50         if (event_code >= 0 && event_code < MARPA_ERROR_COUNT) {
    50          
612 135           event_name = marpa_event_description[event_code].name;
613             }
614             return event_name;
615             }
616              
617             static const char *
618             step_type_to_string (const Marpa_Step_Type step_type)
619             {
620             const char *step_type_name = NULL;
621 136644 50         if (step_type >= 0 && step_type < MARPA_STEP_COUNT) {
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
622 136644           step_type_name = marpa_step_type_description[step_type].name;
623             }
624             return step_type_name;
625             }
626              
627             /* This routine is for the handling exceptions
628             from libmarpa. It is used when in the general
629             cases, for those exception which are not singled
630             out for special handling by the XS logic.
631             It returns a buffer which must be Safefree()'d.
632             */
633             static char *
634 25           error_description_generate (G_Wrapper *g_wrapper)
635             {
636             dTHX;
637 25           const int error_code = g_wrapper->libmarpa_error_code;
638 25           const char *error_string = g_wrapper->libmarpa_error_string;
639             const char *suggested_description = NULL;
640             /*
641             * error_name should always be set when suggested_description is,
642             * so this initialization should never be used.
643             */
644             const char *error_name = "not libmarpa error";
645             const char *output_string;
646 25           switch (error_code)
647             {
648             case MARPA_ERR_DEVELOPMENT:
649 0 0         output_string = form ("(development) %s",
650             (error_string ? error_string : "(null)"));
651 0           goto COPY_STRING;
652             case MARPA_ERR_INTERNAL:
653 0 0         output_string = form ("Internal error (%s)",
654             (error_string ? error_string : "(null)"));
655 0           goto COPY_STRING;
656             }
657 25 50         if (error_code >= 0 && error_code < MARPA_ERROR_COUNT) {
658 25           suggested_description = marpa_error_description[error_code].suggested;
659 25           error_name = marpa_error_description[error_code].name;
660             }
661 25 50         if (!suggested_description)
662             {
663 0 0         if (error_string)
664             {
665 0           output_string = form ("libmarpa error %d %s: %s",
666             error_code, error_name, error_string);
667 0           goto COPY_STRING;
668             }
669 0           output_string = form ("libmarpa error %d %s", error_code, error_name);
670 0           goto COPY_STRING;
671             }
672 25 50         if (error_string)
673             {
674 0           output_string = form ("%s%s%s", suggested_description, "; ", error_string);
675 0           goto COPY_STRING;
676             }
677             output_string = suggested_description;
678             COPY_STRING:
679             {
680 25           char* buffer = g_wrapper->message_buffer;
681 25 100         if (buffer) Safefree(buffer);
682 25           return g_wrapper->message_buffer = savepv(output_string);
683             }
684             }
685              
686             /* Argument must be something that can be Safefree()'d */
687             static const char *
688 0           set_error_from_string (G_Wrapper * g_wrapper, char *string)
689             {
690             dTHX;
691 0           Marpa_Grammar g = g_wrapper->g;
692 0           char *buffer = g_wrapper->message_buffer;
693 0 0         if (buffer) Safefree(buffer);
694 0           g_wrapper->message_buffer = string;
695 0           g_wrapper->message_is_marpa_thin_error = 1;
696 0           marpa_g_error_clear(g);
697 0           g_wrapper->libmarpa_error_code = MARPA_ERR_NONE;
698 0           g_wrapper->libmarpa_error_string = NULL;
699 0           return buffer;
700             }
701              
702             /* Return value must be Safefree()'d */
703             static const char *
704 0           xs_g_error (G_Wrapper * g_wrapper)
705             {
706 0           Marpa_Grammar g = g_wrapper->g;
707 0           g_wrapper->libmarpa_error_code =
708 0           marpa_g_error (g, &g_wrapper->libmarpa_error_string);
709 0           g_wrapper->message_is_marpa_thin_error = 0;
710 0           return error_description_generate (g_wrapper);
711             }
712              
713             /* Wrapper to use vwarn with libmarpa */
714 0           static int marpa_r2_warn(const char* format, ...)
715             {
716             dTHX;
717             va_list args;
718 0           va_start (args, format);
719 0           vwarn (format, &args);
720 0           va_end (args);
721 0           return 1;
722             }
723              
724             /* Static grammar methods */
725              
726             #define SET_G_WRAPPER_FROM_G_SV(g_wrapper, g_sv) { \
727             IV tmp = SvIV ((SV *) SvRV (g_sv)); \
728             (g_wrapper) = INT2PTR (G_Wrapper *, tmp); \
729             }
730              
731             /* Static recognizer methods */
732              
733             #define SET_R_WRAPPER_FROM_R_SV(r_wrapper, r_sv) { \
734             IV tmp = SvIV ((SV *) SvRV (r_sv)); \
735             (r_wrapper) = INT2PTR (R_Wrapper *, tmp); \
736             }
737              
738             /* Maybe inline some of these */
739              
740             /* Assumes caller has checked that g_sv is blessed into right type.
741             Assumes caller holds a ref to the recce.
742             */
743             static R_Wrapper*
744 1316           r_wrap( Marpa_Recce r, SV* g_sv)
745             {
746             dTHX;
747             int highest_symbol_id;
748             R_Wrapper *r_wrapper;
749             G_Wrapper *g_wrapper;
750             Marpa_Grammar g;
751              
752 1316 50         SET_G_WRAPPER_FROM_G_SV(g_wrapper, g_sv);
753 1316           g = g_wrapper->g;
754              
755 1316           highest_symbol_id = marpa_g_highest_symbol_id (g);
756 1316 50         if (highest_symbol_id < 0)
757             {
758 0 0         if (!g_wrapper->throw)
759             {
760             return 0;
761             }
762 0           croak ("failure in marpa_g_highest_symbol_id: %s",
763             xs_g_error (g_wrapper));
764             };
765 1316           Newx (r_wrapper, 1, R_Wrapper);
766 1316           r_wrapper->r = r;
767 1316 50         Newx (r_wrapper->terminals_buffer, highest_symbol_id + 1, Marpa_Symbol_ID);
768 1316           r_wrapper->ruby_slippers = 0;
769             SvREFCNT_inc (g_sv);
770 1316           r_wrapper->base_sv = g_sv;
771 1316           r_wrapper->base = g_wrapper;
772 1316           r_wrapper->event_queue = newAV();
773 1316           return r_wrapper;
774             }
775              
776             /* It is up to the caller to deal with the Libmarpa recce's
777             * reference count
778             */
779             static Marpa_Recce
780 1316           r_unwrap (R_Wrapper * r_wrapper)
781             {
782             dTHX;
783 1316           Marpa_Recce r = r_wrapper->r;
784             /* The wrapper should always have had a ref to its base grammar's SV */
785 1316           SvREFCNT_dec (r_wrapper->base_sv);
786 1316           SvREFCNT_dec ((SV *) r_wrapper->event_queue);
787 1316           Safefree (r_wrapper->terminals_buffer);
788 1316           Safefree (r_wrapper);
789             /* The wrapper should always have had a ref to the Libmarpa recce */
790 1316           return r;
791             }
792              
793             static void
794             u_r0_clear (Scanless_R * slr)
795             {
796             dTHX;
797 28724           Marpa_Recce r0 = slr->r0;
798 28724 100         if (!r0)
799             return;
800 27772           marpa_r_unref (r0);
801 27772           slr->r0 = NULL;
802             }
803              
804             static Marpa_Recce
805 28724           u_r0_new (Scanless_R * slr)
806             {
807             dTHX;
808 28724           Marpa_Recce r0 = slr->r0;
809 28724           const IV trace_lexers = slr->trace_lexers;
810 28724           const IV trace_terminals = slr->trace_terminals;
811 28724           G_Wrapper *lexer_wrapper = slr->slg->l0_wrapper;
812 28724           const int too_many_earley_items = slr->too_many_earley_items;
813              
814 28724 50         if (r0)
815             {
816 0           marpa_r_unref (r0);
817             }
818 28724           slr->r0 = r0 = marpa_r_new (lexer_wrapper->g);
819 28724 50         if (!r0)
820             {
821 0 0         if (!lexer_wrapper->throw)
822             return 0;
823 0           croak ("failure in marpa_r_new(): %s", xs_g_error (lexer_wrapper));
824             };
825 28724 100         if (too_many_earley_items >= 0)
826             {
827 19           marpa_r_earley_item_warning_threshold_set (r0, too_many_earley_items);
828             }
829             {
830             int i;
831 28724           Marpa_Symbol_ID *terminals_buffer = slr->r1_wrapper->terminals_buffer;
832 28724           const int count = marpa_r_terminals_expected (slr->r1, terminals_buffer);
833 28724 50         if (count < 0)
834             {
835 0           croak ("Problem in u_r0_new() with terminals_expected: %s",
836             xs_g_error (slr->g1_wrapper));
837             }
838 596912 100         for (i = 0; i < count; i++)
839             {
840 568188           const Marpa_Symbol_ID terminal = terminals_buffer[i];
841 568188           const Marpa_Assertion_ID assertion =
842 568188           slr->slg->g1_lexeme_to_assertion[terminal];
843 568188 100         if (assertion >= 0 && marpa_r_zwa_default_set (r0, assertion, 1) < 0)
    50          
844             {
845 0           croak
846             ("Problem in u_r0_new() with assertion ID %ld and lexeme ID %ld: %s",
847             (long) assertion, (long) terminal,
848             xs_g_error (lexer_wrapper));
849             }
850 568188 50         if (trace_lexers >= 1 || trace_terminals > 2)
851             {
852 0           union marpa_slr_event_s *event =
853 0           marpa__slr_event_push (slr->gift);
854 0           MARPA_SLREV_TYPE (event) = MARPA_SLRTR_LEXEME_EXPECTED;
855 0           event->t_trace_lexeme_expected.t_perl_pos = slr->perl_pos;
856 0           event->t_trace_lexeme_expected.t_lexeme = terminal;
857 0           event->t_trace_lexeme_expected.t_assertion = assertion;
858             }
859              
860             }
861             }
862             {
863 28724           int gp_result = marpa_r_start_input (r0);
864 28724 50         if (gp_result == -1)
865             return 0;
866 28724 50         if (gp_result < 0)
867             {
868 0 0         if (lexer_wrapper->throw)
869             {
870 0           croak ("Problem in r->start_input(): %s",
871             xs_g_error (lexer_wrapper));
872             }
873             return 0;
874             }
875             }
876             return r0;
877             }
878              
879             /* Assumes it is called
880             after a successful marpa_r_earleme_complete()
881             */
882             static void
883 17802           u_convert_events (Scanless_R * slr)
884             {
885             dTHX;
886             int event_ix;
887 8901           Marpa_Grammar g = slr->slg->l0_wrapper->g;
888 8901           const int event_count = marpa_g_event_count (g);
889 17802 100         for (event_ix = 0; event_ix < event_count; event_ix++)
890             {
891             Marpa_Event marpa_event;
892 8901           Marpa_Event_Type event_type =
893             marpa_g_event (g, &marpa_event, event_ix);
894 8901           switch (event_type)
895             {
896             {
897             case MARPA_EVENT_EXHAUSTED:
898             /* Do nothing about exhaustion on success */
899             break;
900             case MARPA_EVENT_EARLEY_ITEM_THRESHOLD:
901             /* All events are ignored on failure
902             * On success, all except MARPA_EVENT_EARLEY_ITEM_THRESHOLD
903             * are ignored.
904             *
905             * The warning raised for MARPA_EVENT_EARLEY_ITEM_THRESHOLD
906             * can be turned off by raising
907             * the Earley item warning threshold.
908             */
909             {
910 0           warn
911             ("Marpa: lexer Earley item count (%ld) exceeds warning threshold",
912 0           (long) marpa_g_event_value (&marpa_event));
913             }
914             break;
915             default:
916             {
917             const char *result_string = event_type_to_string (event_type);
918 0 0         if (result_string)
919             {
920 0           croak ("unexpected lexer grammar event: %s",
921             result_string);
922             }
923 0           croak ("lexer grammar event with unknown event code, %d",
924             event_type);
925             }
926             break;
927             }
928             }
929             }
930 8901           }
931              
932             #define U_READ_OK 0
933             #define U_READ_REJECTED_CHAR -1
934             #define U_READ_UNREGISTERED_CHAR -2
935             #define U_READ_EXHAUSTED_ON_FAILURE -3
936             #define U_READ_TRACING -4
937             #define U_READ_EXHAUSTED_ON_SUCCESS -5
938             #define U_READ_INVALID_CHAR -6
939              
940             /* Return values:
941             * 1 or greater: reserved for an event count, to deal with multiple events
942             * when and if necessary
943             * 0: success: a full reading of the input, with nothing to report.
944             * -1: a character was rejected
945             * -2: an unregistered character was found
946             * -3: earleme_complete() reported an exhausted parse on failure
947             * -4: we are tracing, character by character
948             * -5: earleme_complete() reported an exhausted parse on success
949             */
950             static int
951 33254           u_read (Scanless_R * slr)
952             {
953             dTHX;
954             U8 *input;
955             STRLEN len;
956             int input_is_utf8;
957              
958 33254           const IV trace_lexers = slr->trace_lexers;
959 33254           Marpa_Recognizer r = slr->r0;
960              
961 33254 100         if (!r)
962             {
963 28724           r = u_r0_new (slr);
964 28724 50         if (!r)
965 0           croak ("Problem in u_read(): %s",
966 0           xs_g_error (slr->slg->l0_wrapper));
967             }
968 33254           input_is_utf8 = SvUTF8 (slr->input);
969 33254 50         input = (U8 *) SvPV (slr->input, len);
970             for (;;)
971             {
972             UV codepoint;
973 113811           STRLEN codepoint_length = 1;
974             STRLEN op_ix;
975             STRLEN op_count;
976             IV *ops;
977             int tokens_accepted = 0;
978 113811 100         if (slr->perl_pos >= slr->end_pos)
979             break;
980              
981 113472 100         if (input_is_utf8)
982             {
983              
984 9402           codepoint =
985 9402 50         utf8_to_uvchr_buf (input + OFFSET_IN_INPUT (slr),
    100          
    100          
986             input + len, &codepoint_length);
987              
988             /* Perl API documents that return value is 0 and length is -1 on error,
989             * "if possible". length can be, and is, in fact unsigned.
990             * I deal with this by noting that 0 is a valid UTF8 char but should
991             * have a length of 1, when valid.
992             */
993 9402 50         if (codepoint == 0 && codepoint_length != 1)
    0          
994             {
995 0           croak ("Problem in r->read_string(): invalid UTF8 character");
996             }
997             }
998             else
999             {
1000 104070 100         codepoint = (UV) input[OFFSET_IN_INPUT (slr)];
1001             codepoint_length = 1;
1002             }
1003              
1004 113472 100         if (codepoint < Dim (slr->slg->per_codepoint_array))
1005             {
1006 113145           ops = slr->slg->per_codepoint_array[codepoint];
1007 113145 100         if (!ops)
1008             {
1009 4442           slr->codepoint = codepoint;
1010 32915           return U_READ_UNREGISTERED_CHAR;
1011             }
1012             }
1013             else
1014             {
1015             STRLEN dummy;
1016 327           SV **p_ops_sv =
1017 327           hv_fetch (slr->slg->per_codepoint_hash, (char *) &codepoint,
1018             (I32) sizeof (codepoint), 0);
1019 327 100         if (!p_ops_sv)
1020             {
1021 88           slr->codepoint = codepoint;
1022 88           return U_READ_UNREGISTERED_CHAR;
1023             }
1024 239 50         ops = (IV *) SvPV (*p_ops_sv, dummy);
1025             }
1026              
1027 108942 50         if (trace_lexers >= 1)
1028             {
1029 0           union marpa_slr_event_s *event = marpa__slr_event_push(slr->gift);
1030 0           MARPA_SLREV_TYPE(event) = MARPA_SLRTR_CODEPOINT_READ;
1031 0           event->t_trace_codepoint_read.t_codepoint = codepoint;
1032 0           event->t_trace_codepoint_read.t_perl_pos = slr->perl_pos;
1033             }
1034              
1035             /* ops[0] is codepoint */
1036 108942           op_count = ops[1];
1037 806943 100         for (op_ix = 2; op_ix < op_count; op_ix++)
1038             {
1039 726386           IV op_code = ops[op_ix];
1040 726386           switch (op_code)
1041             {
1042             case MARPA_OP_ALTERNATIVE:
1043             {
1044             int result;
1045             int symbol_id;
1046             int length;
1047             int value;
1048              
1049 617444           op_ix++;
1050 617444 50         if (op_ix >= op_count)
1051             {
1052 0           croak
1053             ("Missing operand for op code (0x%lx); codepoint=0x%lx, op_ix=0x%lx",
1054             (unsigned long) op_code, (unsigned long) codepoint,
1055             (unsigned long) op_ix);
1056             }
1057 617444           symbol_id = (int) ops[op_ix];
1058 617444 50         if (op_ix + 2 >= op_count)
1059             {
1060 0           croak
1061             ("Missing operand for op code (0x%lx); codepoint=0x%lx, op_ix=0x%lx",
1062             (unsigned long) op_code, (unsigned long) codepoint,
1063             (unsigned long) op_ix);
1064             }
1065 617444           value = (int) ops[++op_ix];
1066 617444           length = (int) ops[++op_ix];
1067 617444           result = marpa_r_alternative (r, symbol_id, value, length);
1068 617444           switch (result)
1069             {
1070             case MARPA_ERR_UNEXPECTED_TOKEN_ID:
1071             /* This guarantees that later, if we fall below
1072             * the minimum number of tokens accepted,
1073             * we have one of them as an example
1074             */
1075 519213           slr->input_symbol_id = symbol_id;
1076 519213 50         if (trace_lexers >= 1)
1077             {
1078 0           union marpa_slr_event_s *slr_event = marpa__slr_event_push(slr->gift);
1079 0           MARPA_SLREV_TYPE(slr_event) = MARPA_SLRTR_CODEPOINT_REJECTED;
1080 0           slr_event->t_trace_codepoint_rejected.t_codepoint = codepoint;
1081 0           slr_event->t_trace_codepoint_rejected.t_perl_pos = slr->perl_pos;
1082 0           slr_event->t_trace_codepoint_rejected.t_symbol_id = symbol_id;
1083             }
1084             break;
1085             case MARPA_ERR_NONE:
1086 98231 50         if (trace_lexers >= 1)
1087             {
1088 0           union marpa_slr_event_s *slr_event = marpa__slr_event_push(slr->gift);
1089 0           MARPA_SLREV_TYPE(slr_event) = MARPA_SLRTR_CODEPOINT_ACCEPTED;
1090 0           slr_event->t_trace_codepoint_accepted.t_codepoint = codepoint;
1091 0           slr_event->t_trace_codepoint_accepted.t_perl_pos = slr->perl_pos;
1092 0           slr_event->t_trace_codepoint_accepted.t_symbol_id = symbol_id;
1093             }
1094 98231           tokens_accepted++;
1095 98231           break;
1096             default:
1097 0           slr->codepoint = codepoint;
1098 0           slr->input_symbol_id = symbol_id;
1099 0           croak
1100             ("Problem alternative() failed at char ix %ld; symbol id %ld; codepoint 0x%lx value %ld\n"
1101             "Problem in u_read(), alternative() failed: %s",
1102 0           (long) slr->perl_pos, (long) symbol_id,
1103             (unsigned long) codepoint,
1104             (long) value,
1105 0           xs_g_error (slr->slg->l0_wrapper));
1106             }
1107             }
1108             break;
1109              
1110             case MARPA_OP_INVALID_CHAR:
1111 2           slr->codepoint = codepoint;
1112 2           return U_READ_INVALID_CHAR;
1113              
1114             case MARPA_OP_EARLEME_COMPLETE:
1115             {
1116             int result;
1117 108940 100         if (tokens_accepted < 1)
1118             {
1119 19482           slr->codepoint = codepoint;
1120 19482           return U_READ_REJECTED_CHAR;
1121             }
1122 89458           result = marpa_r_earleme_complete (r);
1123 89458 100         if (result > 0)
1124             {
1125 8901           u_convert_events (slr);
1126             /* Advance one character before returning */
1127 8901 50         if (marpa_r_is_exhausted (r))
1128             {
1129             return U_READ_EXHAUSTED_ON_SUCCESS;
1130             }
1131             goto ADVANCE_ONE_CHAR;
1132             }
1133 80557 50         if (result == -2)
1134             {
1135 0           const int error =
1136 0           marpa_g_error (slr->slg->l0_wrapper->g, NULL);
1137 0 0         if (error == MARPA_ERR_PARSE_EXHAUSTED)
1138             {
1139             return U_READ_EXHAUSTED_ON_FAILURE;
1140             }
1141             }
1142 80557 50         if (result < 0)
1143             {
1144 0           croak
1145             ("Problem in r->u_read(), earleme_complete() failed: %s",
1146 0           xs_g_error (slr->slg->l0_wrapper));
1147             }
1148             }
1149             break;
1150             default:
1151 0           croak ("Unknown op code (0x%lx); codepoint=0x%lx, op_ix=0x%lx",
1152             (unsigned long) op_code, (unsigned long) codepoint,
1153             (unsigned long) op_ix);
1154             }
1155             }
1156             ADVANCE_ONE_CHAR:;
1157 80557           slr->perl_pos++;
1158 80557 50         if (trace_lexers)
1159             {
1160             return U_READ_TRACING;
1161             }
1162 80557           }
1163 339           return U_READ_OK;
1164             }
1165              
1166             /* It is OK to set pos to last codepoint + 1 */
1167             static STRLEN
1168 1911           u_pos_set (Scanless_R * slr, const char* name, int start_pos_arg, int length_arg)
1169             {
1170             dTHX;
1171 1911           const STRLEN old_perl_pos = slr->perl_pos;
1172 1911           const STRLEN input_length = slr->pos_db_logical_size;
1173             int new_perl_pos;
1174             int new_end_pos;
1175              
1176 1911 50         if (start_pos_arg < 0) {
1177 0           new_perl_pos = input_length + start_pos_arg;
1178             } else {
1179             new_perl_pos = start_pos_arg;
1180             }
1181 1911 50         if (new_perl_pos < 0 || new_perl_pos > slr->pos_db_logical_size)
    50          
1182             {
1183 0           croak ("Bad start position in %s(): %ld", name, (long)start_pos_arg);
1184             }
1185              
1186 1911 100         if (length_arg < 0) {
1187 1716           new_end_pos = input_length + length_arg + 1;
1188             } else {
1189 195           new_end_pos = new_perl_pos + length_arg;
1190             }
1191 1911 50         if (new_end_pos < 0 || new_end_pos > slr->pos_db_logical_size)
    50          
1192             {
1193 0           croak ("Bad length in %s(): %ld", name, (long)length_arg);
1194             }
1195              
1196             /* Application level intervention resets |perl_pos| */
1197 1911           slr->last_perl_pos = -1;
1198 1911           slr->perl_pos = new_perl_pos;
1199 1911           slr->end_pos = new_end_pos;
1200 1911           return old_perl_pos;
1201             }
1202              
1203             static SV *
1204 118858           u_pos_span_to_literal_sv (Scanless_R * slr,
1205             int start_pos, int length_in_positions)
1206             {
1207             dTHX;
1208             STRLEN dummy;
1209 59429 50         char *input = SvPV (slr->input, dummy);
1210             SV* new_sv;
1211 59429 100         int start_offset = POS_TO_OFFSET (slr, start_pos);
1212 59429           int length_in_bytes =
1213 59429 50         POS_TO_OFFSET (slr,
1214             start_pos + length_in_positions) - start_offset;
1215 59429           new_sv = newSVpvn (input + start_offset, length_in_bytes);
1216 59429 100         if (SvUTF8(slr->input)) {
1217 1525           SvUTF8_on(new_sv);
1218             }
1219 59429           return new_sv;
1220             }
1221              
1222             static SV*
1223 216           u_substring (Scanless_R * slr, const char *name, int start_pos_arg,
1224             int length_arg)
1225             {
1226             dTHX;
1227             int start_pos;
1228             int end_pos;
1229 216           const int input_length = slr->pos_db_logical_size;
1230             int substring_length;
1231              
1232             start_pos =
1233 216 50         start_pos_arg < 0 ? input_length + start_pos_arg : start_pos_arg;
1234 216 50         if (start_pos < 0 || start_pos > input_length)
1235             {
1236 0           croak ("Bad start position in %s: %ld", name, (long) start_pos_arg);
1237             }
1238              
1239             end_pos =
1240 216 50         length_arg < 0 ? input_length + length_arg + 1 : start_pos + length_arg;
1241 216 50         if (end_pos < 0 || end_pos > input_length)
1242             {
1243 0           croak ("Bad length in %s: %ld", name, (long) length_arg);
1244             }
1245 216           substring_length = end_pos - start_pos;
1246 216           return u_pos_span_to_literal_sv (slr, start_pos, substring_length);
1247             }
1248              
1249             /* Static valuator methods */
1250              
1251             /* Return -1 on failure due to wrong mode */
1252             static IV
1253 15944           v_create_stack(V_Wrapper* v_wrapper)
1254             {
1255             dTHX;
1256 7972 50         if (v_wrapper->mode == MARPA_XS_V_MODE_IS_RAW)
1257             {
1258             return -1;
1259             }
1260 7972           v_wrapper->stack = newAV ();
1261 7972           av_extend (v_wrapper->stack, 1023);
1262 7972           v_wrapper->mode = MARPA_XS_V_MODE_IS_STACK;
1263             return 0;
1264             }
1265              
1266             static void slr_es_to_span (Scanless_R * slr, Marpa_Earley_Set_ID earley_set,
1267             int *p_start, int *p_length);
1268             static void
1269             slr_es_to_literal_span (Scanless_R * slr,
1270             Marpa_Earley_Set_ID start_earley_set, int length,
1271             int *p_start, int *p_length);
1272             static SV*
1273             slr_es_span_to_literal_sv (Scanless_R * slr,
1274             Marpa_Earley_Set_ID start_earley_set, int length);
1275              
1276             static int
1277 267435           v_do_stack_ops (V_Wrapper * v_wrapper, SV ** stack_results)
1278             {
1279             dTHX;
1280 267435           AV *stack = v_wrapper->stack;
1281 267435           const Marpa_Value v = v_wrapper->v;
1282 267435           const Marpa_Step_Type step_type = marpa_v_step_type (v);
1283 267435           IV result_ix = marpa_v_result (v);
1284             IV *ops;
1285             int op_ix;
1286             UV blessing = 0;
1287              
1288             /* values_av is created when needed.
1289             * It is created mortal, so it automatically goes
1290             * away unless it is de-mortalized.
1291             */
1292             AV *values_av = NULL;
1293              
1294 267435           v_wrapper->result = result_ix;
1295              
1296 267435           switch (step_type)
1297             {
1298             STRLEN dummy;
1299             case MARPA_STEP_RULE:
1300             {
1301 176408           SV **p_ops_sv =
1302 176408           av_fetch (v_wrapper->rule_semantics, marpa_v_rule (v), 0);
1303 176408 50         if (!p_ops_sv)
1304             {
1305 0           croak ("Problem in v->stack_step: rule %d is not registered",
1306             marpa_v_rule (v));
1307             }
1308 176408 50         ops = (IV *) SvPV (*p_ops_sv, dummy);
1309             }
1310 267435           break;
1311             case MARPA_STEP_TOKEN:
1312             {
1313 82152           SV **p_ops_sv =
1314 82152           av_fetch (v_wrapper->token_semantics, marpa_v_token (v), 0);
1315 82152 50         if (!p_ops_sv)
1316             {
1317 0           croak ("Problem in v->stack_step: token %d is not registered",
1318             marpa_v_token (v));
1319             }
1320 82152 50         ops = (IV *) SvPV (*p_ops_sv, dummy);
1321             }
1322             break;
1323             case MARPA_STEP_NULLING_SYMBOL:
1324             {
1325 8875           SV **p_ops_sv =
1326 8875           av_fetch (v_wrapper->nulling_semantics, marpa_v_token (v), 0);
1327 8875 50         if (!p_ops_sv)
1328             {
1329 0           croak
1330             ("Problem in v->stack_step: nulling symbol %d is not registered",
1331             marpa_v_token (v));
1332             }
1333 8875 50         ops = (IV *) SvPV (*p_ops_sv, dummy);
1334             }
1335             break;
1336             default:
1337             /* Never reached -- turns off warning about uninitialized ops */
1338             ops = NULL;
1339             }
1340              
1341             op_ix = 0;
1342             while (1)
1343             {
1344 578982           IV op_code = ops[op_ix++];
1345              
1346 578982 50         if (v_wrapper->trace_values >= 3)
1347             {
1348             AV *event;
1349             SV *event_data[3];
1350             const char *result_string = step_type_to_string (step_type);
1351 0 0         if (!result_string)
1352             result_string = "valuator unknown step";
1353 0           event_data[0] = newSVpvs ("starting op");
1354 0           event_data[1] = newSVpv (result_string, 0);
1355 0           event_data[2] = newSVpv (marpa__slif_op_name (op_code), 0);
1356 0           event = av_make (Dim (event_data), event_data);
1357 0           av_push (v_wrapper->event_queue, newRV_noinc ((SV *) event));
1358             }
1359              
1360 578982           switch (op_code)
1361             {
1362              
1363             case 0:
1364             return -1;
1365              
1366             case MARPA_OP_RESULT_IS_UNDEF:
1367             {
1368 17423           av_fill (stack, -1 + result_ix);
1369             }
1370 17423           return -1;
1371              
1372             case MARPA_OP_RESULT_IS_CONSTANT:
1373             {
1374 33           IV constant_ix = ops[op_ix++];
1375             SV **p_constant_sv;
1376              
1377 33           p_constant_sv = av_fetch (v_wrapper->constants, constant_ix, 0);
1378 33 50         if (p_constant_sv)
1379             {
1380 33           SV *constant_sv = newSVsv (*p_constant_sv);
1381 33           SV **stored_sv = av_store (stack, result_ix, constant_sv);
1382 33 50         if (!stored_sv)
1383             {
1384             SvREFCNT_dec (constant_sv);
1385             }
1386             }
1387             else
1388             {
1389 0           av_store (stack, result_ix, &PL_sv_undef);
1390             }
1391              
1392 33 50         if (v_wrapper->trace_values && step_type == MARPA_STEP_TOKEN)
    0          
1393             {
1394             AV *event;
1395             SV *event_data[3];
1396             const char *result_string = step_type_to_string (step_type);
1397 0 0         if (!result_string)
1398             result_string = "valuator unknown step";
1399 0           event_data[0] = newSVpvn (result_string, 0);
1400 0           event_data[1] = newSViv (marpa_v_token (v));
1401 0 0         if (p_constant_sv) {
1402 0           event_data[2] = newSVsv (*p_constant_sv);
1403             } else {
1404 0           event_data[2] = &PL_sv_undef;
1405             }
1406 0           event = av_make (Dim (event_data), event_data);
1407 0           av_push (v_wrapper->event_queue, newRV_noinc ((SV *) event));
1408             }
1409             }
1410             return -1;
1411              
1412             case MARPA_OP_RESULT_IS_RHS_N:
1413             case MARPA_OP_RESULT_IS_N_OF_SEQUENCE:
1414             {
1415             SV **stored_av;
1416             SV **p_sv;
1417 6533           IV stack_offset = ops[op_ix++];
1418             IV fetch_ix;
1419              
1420 6533 50         if (step_type != MARPA_STEP_RULE)
1421             {
1422 0           av_fill (stack, result_ix - 1);
1423 0           return -1;
1424             }
1425 6533 100         if (stack_offset == 0)
1426             {
1427             /* Special-cased for 4 reasons --
1428             * it's common, it's reference count handling is
1429             * a special case and it can be easily and highly optimized.
1430             */
1431 6525           av_fill (stack, result_ix);
1432 6525           return -1;
1433             }
1434              
1435             /* Determine index of SV to fetch */
1436 8 50         if (op_code == MARPA_OP_RESULT_IS_RHS_N)
1437             {
1438 8 50         if (stack_offset > 0)
1439             {
1440 8           fetch_ix = result_ix + stack_offset;
1441             }
1442             else
1443             {
1444 0           fetch_ix = marpa_v_arg_n (v) + 1 - stack_offset;
1445             }
1446             }
1447             else
1448             { /* sequence */
1449             int item_ix;
1450 0 0         if (stack_offset >= 0)
1451             {
1452 0           item_ix = stack_offset;
1453             }
1454             else
1455             {
1456 0           int item_count =
1457 0           (marpa_v_arg_n (v) - marpa_v_arg_0 (v)) / 2 + 1;
1458 0           item_ix = (item_count + stack_offset);
1459             }
1460 0           fetch_ix = result_ix + item_ix * 2;
1461             }
1462              
1463             /* Bounds check fetch ix */
1464 8 50         if (fetch_ix > marpa_v_arg_n (v) || fetch_ix < result_ix)
    50          
1465             {
1466             /* return an undef */
1467 0           av_fill (stack, result_ix - 1);
1468 0           return -1;
1469             }
1470 8           p_sv = av_fetch (stack, fetch_ix, 0);
1471 8 50         if (!p_sv)
1472             {
1473 0           av_fill (stack, result_ix - 1);
1474 0           return -1;
1475             }
1476 8           stored_av = av_store (stack, result_ix, SvREFCNT_inc_NN (*p_sv));
1477 8 50         if (!stored_av)
1478             {
1479 0           SvREFCNT_dec (*p_sv);
1480 0           av_fill (stack, result_ix - 1);
1481 0           return -1;
1482             }
1483 8           av_fill (stack, result_ix);
1484             }
1485 8           return -1;
1486              
1487             case MARPA_OP_RESULT_IS_ARRAY:
1488             {
1489             SV **stored_av;
1490             /* Increment ref count of values_av to de-mortalize it */
1491             SV *ref_to_values_av;
1492              
1493 41525 100         if (!values_av)
1494             {
1495 8           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1496             }
1497 41525           ref_to_values_av = newRV_inc ((SV *) values_av);
1498 41525 100         if (blessing)
1499             {
1500 40100           SV **p_blessing_sv =
1501 40100           av_fetch (v_wrapper->constants, blessing, 0);
1502 40100 50         if (p_blessing_sv && SvPOK (*p_blessing_sv))
    50          
1503             {
1504             STRLEN blessing_length;
1505 40100 50         char *classname = SvPV (*p_blessing_sv, blessing_length);
1506 40100           sv_bless (ref_to_values_av, gv_stashpv (classname, 1));
1507             }
1508             }
1509 41525           stored_av = av_store (stack, result_ix, ref_to_values_av);
1510              
1511             /* If the new RV did not get stored properly,
1512             * decrement its ref count
1513             */
1514 41525 50         if (!stored_av)
1515             {
1516             SvREFCNT_dec (ref_to_values_av);
1517 0           av_fill (stack, result_ix - 1);
1518 0           return -1;
1519             }
1520 41525           av_fill (stack, result_ix);
1521             }
1522 41525           return -1;
1523              
1524             case MARPA_OP_PUSH_VALUES:
1525             case MARPA_OP_PUSH_SEQUENCE:
1526             {
1527              
1528 14451 100         if (!values_av)
1529             {
1530 749           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1531             }
1532              
1533 14451           switch (step_type)
1534             {
1535             case MARPA_STEP_TOKEN:
1536             {
1537             SV **p_token_value_sv;
1538 8694           int token_ix = marpa_v_token_value (v);
1539 8694           Scanless_R *slr = v_wrapper->slr;
1540 8694 50         if (slr && token_ix == TOKEN_VALUE_IS_LITERAL)
1541             {
1542             SV *sv;
1543 8694           Marpa_Earley_Set_ID start_earley_set =
1544             marpa_v_token_start_es_id (v);
1545 8694           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1546 8694           sv =
1547 8694           slr_es_span_to_literal_sv (slr, start_earley_set,
1548             end_earley_set -
1549             start_earley_set);
1550 8694           av_push (values_av, sv);
1551 311547           break;
1552             }
1553             /* If token value is NOT literal */
1554 0           p_token_value_sv = av_fetch (v_wrapper->token_values, (I32) token_ix, 0);
1555 0 0         if (p_token_value_sv)
1556             {
1557 0           av_push (values_av,
1558             SvREFCNT_inc_NN (*p_token_value_sv));
1559             }
1560             else
1561             {
1562 0           av_push (values_av, &PL_sv_undef);
1563             }
1564             }
1565             break;
1566              
1567             case MARPA_STEP_RULE:
1568             {
1569             int stack_ix;
1570 5738           const int arg_n = marpa_v_arg_n (v);
1571 5738 100         int increment = op_code == MARPA_OP_PUSH_SEQUENCE ? 2 : 1;
1572              
1573 18026 100         for (stack_ix = result_ix; stack_ix <= arg_n;
1574 12288           stack_ix += increment)
1575             {
1576 12288           SV **p_sv = av_fetch (stack, stack_ix, 0);
1577 12288 100         if (!p_sv)
1578             {
1579 121           av_push (values_av, &PL_sv_undef);
1580             }
1581             else
1582             {
1583 12167           av_push (values_av, SvREFCNT_inc_simple_NN (*p_sv));
1584             }
1585             }
1586             }
1587             break;
1588              
1589             default:
1590             case MARPA_STEP_NULLING_SYMBOL:
1591             /* A no-op : push nothing */
1592             break;
1593             }
1594             }
1595             break;
1596              
1597             case MARPA_OP_PUSH_UNDEF:
1598             {
1599 2 50         if (!values_av)
1600             {
1601 0           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1602             }
1603 2           av_push (values_av, &PL_sv_undef);
1604             }
1605 2           goto NEXT_OP_CODE;
1606              
1607             case MARPA_OP_PUSH_CONSTANT:
1608             {
1609 894           IV constant_ix = ops[op_ix++];
1610             SV **p_constant_sv;
1611              
1612 894 100         if (!values_av)
1613             {
1614 521           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1615             }
1616 894           p_constant_sv = av_fetch (v_wrapper->constants, constant_ix, 0);
1617 894 50         if (p_constant_sv)
1618             {
1619 894           av_push (values_av, SvREFCNT_inc_simple_NN (*p_constant_sv));
1620             }
1621             else
1622             {
1623 0           av_push (values_av, &PL_sv_undef);
1624             }
1625              
1626             }
1627             goto NEXT_OP_CODE;
1628              
1629             case MARPA_OP_PUSH_ONE:
1630             {
1631             int offset;
1632             SV **p_sv;
1633              
1634 174970           offset = ops[op_ix++];
1635 174970 100         if (!values_av)
1636             {
1637 89965           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1638             }
1639 174970 100         if (step_type != MARPA_STEP_RULE)
1640             {
1641 1715           av_push (values_av, &PL_sv_undef);
1642 1715           goto NEXT_OP_CODE;
1643             }
1644 173255           p_sv = av_fetch (stack, result_ix + offset, 0);
1645 173255 100         if (!p_sv)
1646             {
1647 706           av_push (values_av, &PL_sv_undef);
1648             }
1649             else
1650             {
1651 172549           av_push (values_av, SvREFCNT_inc_simple_NN (*p_sv));
1652             }
1653             }
1654             goto NEXT_OP_CODE;
1655              
1656             case MARPA_OP_PUSH_START_LOCATION:
1657             {
1658             int start_location;
1659 39991           Scanless_R *slr = v_wrapper->slr;
1660             Marpa_Earley_Set_ID start_earley_set;
1661             int dummy;
1662              
1663 39991 100         if (!values_av)
1664             {
1665 39799           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1666             }
1667 39991 50         if (!slr)
1668             {
1669 0           croak
1670             ("Problem in v->stack_step: 'push_start_location' op attempted when no slr is set");
1671             }
1672 39991           switch (step_type)
1673             {
1674             case MARPA_STEP_RULE:
1675 29675           start_earley_set = marpa_v_rule_start_es_id (v);
1676 29675           break;
1677             case MARPA_STEP_NULLING_SYMBOL:
1678             case MARPA_STEP_TOKEN:
1679 10316           start_earley_set = marpa_v_token_start_es_id (v);
1680 10316           break;
1681             default:
1682 0           croak
1683             ("Problem in v->stack_step: Range requested for improper step type: %s",
1684             step_type_to_string (step_type));
1685             }
1686 39991           slr_es_to_literal_span (slr, start_earley_set, 0, &start_location,
1687             &dummy);
1688 39991           av_push (values_av, newSViv ((IV) start_location));
1689             }
1690 39991           goto NEXT_OP_CODE;
1691              
1692             case MARPA_OP_PUSH_LENGTH:
1693             {
1694             int length;
1695 39991           Scanless_R *slr = v_wrapper->slr;
1696              
1697 39991 50         if (!values_av)
1698             {
1699 0           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1700             }
1701 39991 50         if (!slr)
1702             {
1703 0           croak
1704             ("Problem in v->stack_step: 'push_length' op attempted when no slr is set");
1705             }
1706 39991           switch (step_type)
1707             {
1708             case MARPA_STEP_NULLING_SYMBOL:
1709 1815           length = 0;
1710 1815           break;
1711             case MARPA_STEP_RULE:
1712             {
1713             int dummy;
1714 29675           Marpa_Earley_Set_ID start_earley_set =
1715             marpa_v_rule_start_es_id (v);
1716 29675           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1717 29675           slr_es_to_literal_span (slr, start_earley_set,
1718             end_earley_set - start_earley_set,
1719             &dummy, &length);
1720             }
1721 29675           break;
1722             case MARPA_STEP_TOKEN:
1723             {
1724             int dummy;
1725 8501           Marpa_Earley_Set_ID start_earley_set =
1726             marpa_v_token_start_es_id (v);
1727 8501           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1728 8501           slr_es_to_literal_span (slr, start_earley_set,
1729             end_earley_set - start_earley_set,
1730             &dummy, &length);
1731             }
1732 8501           break;
1733             default:
1734 0           croak
1735             ("Problem in v->stack_step: Range requested for improper step type: %s",
1736             step_type_to_string (step_type));
1737             }
1738 39991           av_push (values_av, newSViv ((IV) length));
1739             }
1740 39991           goto NEXT_OP_CODE;
1741              
1742             case MARPA_OP_PUSH_G1_START:
1743             {
1744 572           Scanless_R *slr = v_wrapper->slr;
1745             Marpa_Earley_Set_ID start_earley_set;
1746              
1747 572 100         if (!values_av)
1748             {
1749 568           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1750             }
1751 572 50         if (!slr)
1752             {
1753 0           croak
1754             ("Problem in v->stack_step: 'push_g1_start' op attempted when no slr is set");
1755             }
1756 572           switch (step_type)
1757             {
1758             case MARPA_STEP_RULE:
1759 103           start_earley_set = marpa_v_rule_start_es_id (v);
1760 103           break;
1761             case MARPA_STEP_NULLING_SYMBOL:
1762             case MARPA_STEP_TOKEN:
1763 469           start_earley_set = marpa_v_token_start_es_id (v);
1764 469           break;
1765             default:
1766 0           croak
1767             ("Problem in v->stack_step: Range requested for improper step type: %s",
1768             step_type_to_string (step_type));
1769             }
1770 572           av_push (values_av, newSViv ((IV) start_earley_set));
1771             }
1772 572           goto NEXT_OP_CODE;
1773              
1774             case MARPA_OP_PUSH_G1_LENGTH:
1775             case MARPA_OP_PUSH_G1_LEN:
1776             {
1777             int length;
1778 576           Scanless_R *slr = v_wrapper->slr;
1779              
1780 576 50         if (!values_av)
1781             {
1782 0           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1783             }
1784 576 50         if (!slr)
1785             {
1786 0           croak
1787             ("Problem in v->stack_step: 'push_length' op attempted when no slr is set");
1788             }
1789 576           switch (step_type)
1790             {
1791             case MARPA_STEP_NULLING_SYMBOL:
1792             length = 0;
1793             break;
1794             case MARPA_STEP_RULE:
1795             {
1796 107           Marpa_Earley_Set_ID start_earley_set =
1797             marpa_v_rule_start_es_id (v);
1798 107           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1799             /* MARPA_OP_PUSH_G1_LENGTH sets the length variable to the length
1800             plus one. This is a mistake, which we have grandfathered in,
1801             and which we deprecate in the upper layers.
1802             */
1803 214           length = end_earley_set - start_earley_set +
1804 107           (op_code == MARPA_OP_PUSH_G1_LENGTH ? 1 : 0);
1805             }
1806 107           break;
1807             case MARPA_STEP_TOKEN:
1808             {
1809 192           Marpa_Earley_Set_ID start_earley_set =
1810             marpa_v_token_start_es_id (v);
1811 192           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1812             /* MARPA_OP_PUSH_G1_LENGTH sets the length variable to the length
1813             plus one. This is a mistake, which we have grandfathered in,
1814             and which we deprecate in the upper layers.
1815             */
1816 384           length = end_earley_set - start_earley_set +
1817 192           (op_code == MARPA_OP_PUSH_G1_LENGTH ? 1 : 0);
1818             }
1819 192           break;
1820             default:
1821 0           croak
1822             ("Problem in v->stack_step: Range requested for improper step type: %s",
1823             step_type_to_string (step_type));
1824             }
1825 576           av_push (values_av, newSViv ((IV) length));
1826             }
1827 576           goto NEXT_OP_CODE;
1828              
1829             case MARPA_OP_BLESS:
1830             {
1831 40100           blessing = ops[op_ix++];
1832             }
1833 40100           goto NEXT_OP_CODE;
1834              
1835             case MARPA_OP_CALLBACK:
1836             {
1837             const char *result_string = step_type_to_string (step_type);
1838             SV **p_stack_results = stack_results;
1839              
1840 128463           switch (step_type)
1841             {
1842             case MARPA_STEP_RULE:
1843             /* For rules, create an array if we don't have one.
1844             * It is expected to be mortal.
1845             */
1846 127129 100         if (!values_av)
1847             {
1848 37120           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1849             }
1850             break;
1851             case MARPA_STEP_NULLING_SYMBOL:
1852             break;
1853             default:
1854             goto BAD_OP;
1855             }
1856              
1857 128463           *p_stack_results++ = sv_2mortal (newSVpv (result_string, 0));
1858 256926           *p_stack_results++ =
1859 128463 100         sv_2mortal (newSViv
1860             (step_type ==
1861             MARPA_STEP_RULE ? marpa_v_rule (v) :
1862             marpa_v_token (v)));
1863              
1864 128463 100         if (values_av)
1865             {
1866             /* De-mortalize av_values */
1867 127205           SV *ref_to_values_av =
1868 127205           sv_2mortal (newRV_inc ((SV *) values_av));
1869 127205 50         if (blessing)
1870             {
1871 0           SV **p_blessing_sv =
1872 0           av_fetch (v_wrapper->constants, blessing, 0);
1873 0 0         if (p_blessing_sv && SvPOK (*p_blessing_sv))
    0          
1874             {
1875             STRLEN blessing_length;
1876             char *classname =
1877 0 0         SvPV (*p_blessing_sv, blessing_length);
1878 0           sv_bless (ref_to_values_av,
1879             gv_stashpv (classname, 1));
1880             }
1881             }
1882 127205           *p_stack_results++ = ref_to_values_av;
1883             }
1884 128463           return p_stack_results - stack_results;
1885             }
1886             /* NOT REACHED */
1887              
1888             case MARPA_OP_RESULT_IS_TOKEN_VALUE:
1889             {
1890             SV **p_token_value_sv;
1891 73458           Scanless_R *slr = v_wrapper->slr;
1892 73458           int token_ix = marpa_v_token_value (v);
1893              
1894 73458 50         if (step_type != MARPA_STEP_TOKEN)
1895             {
1896 0           av_fill (stack, result_ix - 1);
1897 0           return -1;
1898             }
1899 73458 100         if (slr && token_ix == TOKEN_VALUE_IS_LITERAL)
1900             {
1901             SV **stored_sv;
1902             SV *token_literal_sv;
1903 50519           Marpa_Earley_Set_ID start_earley_set =
1904             marpa_v_token_start_es_id (v);
1905 50519           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1906 50519           token_literal_sv =
1907 50519           slr_es_span_to_literal_sv (slr, start_earley_set,
1908             end_earley_set -
1909             start_earley_set);
1910 50519           stored_sv = av_store (stack, result_ix, token_literal_sv);
1911 50519 50         if (!stored_sv)
1912             {
1913             SvREFCNT_dec (token_literal_sv);
1914             }
1915             return -1;
1916             }
1917              
1918              
1919 22939           p_token_value_sv = av_fetch (v_wrapper->token_values, (I32) token_ix, 0);
1920 22939 100         if (p_token_value_sv)
1921             {
1922 12824           SV *token_value_sv = newSVsv (*p_token_value_sv);
1923 12824           SV **stored_sv = av_store (stack, result_ix, token_value_sv);
1924 12824 50         if (!stored_sv)
1925             {
1926             SvREFCNT_dec (token_value_sv);
1927             }
1928             }
1929             else
1930             {
1931 10115           av_fill (stack, result_ix - 1);
1932 10115           return -1;
1933             }
1934              
1935 12824 100         if (v_wrapper->trace_values)
1936             {
1937             AV *event;
1938             SV *event_data[4];
1939             const char *step_type_string =
1940             step_type_to_string (step_type);
1941 14 50         if (!step_type_string)
1942             step_type_string = "token value written to tos";
1943 14           event_data[0] = newSVpv (step_type_string, 0);
1944 14           event_data[1] = newSViv (marpa_v_token (v));
1945 14           event_data[2] = newSViv (marpa_v_token_value (v));
1946 14 50         event_data[3] = *p_token_value_sv ? newSVsv (*p_token_value_sv) : &PL_sv_undef;
1947 14           event = av_make (Dim (event_data), event_data);
1948 14           av_push (v_wrapper->event_queue, newRV_noinc ((SV *) event));
1949             }
1950              
1951             }
1952             return -1;
1953              
1954             default:
1955             BAD_OP:
1956             {
1957             const char *step_type_string = step_type_to_string (step_type);
1958 0 0         if (!step_type_string)
1959             step_type_string = "Unknown";
1960 0           croak
1961             ("Bad op code (%lu, '%s') in v->stack_step, step_type '%s'",
1962             (unsigned long) op_code, marpa__slif_op_name (op_code),
1963             step_type_string);
1964             }
1965             }
1966              
1967             NEXT_OP_CODE:; /* continue while(1) loop */
1968              
1969             }
1970              
1971             /* Never reached */
1972             return -1;
1973             }
1974              
1975             /* Static SLG methods */
1976              
1977             #define SET_SLG_FROM_SLG_SV(slg, slg_sv) { \
1978             IV tmp = SvIV ((SV *) SvRV (slg_sv)); \
1979             (slg) = INT2PTR (Scanless_G *, tmp); \
1980             }
1981              
1982             /* Static SLR methods */
1983              
1984              
1985             /*
1986             * Try to discard lexemes.
1987             * It is assumed this is because R1 is exhausted and we
1988             * are checking for unconsumed text.
1989             * Return values:
1990             * 0 OK.
1991             * -4: Exhausted, but lexemes remain.
1992             */
1993             static IV
1994 677           slr_discard (Scanless_R * slr)
1995             {
1996             dTHX;
1997             int lexemes_discarded = 0;
1998             int lexemes_found = 0;
1999             Marpa_Recce r0;
2000             Marpa_Earley_Set_ID earley_set;
2001 677           const Scanless_G *slg = slr->slg;
2002              
2003 677           r0 = slr->r0;
2004 677 50         if (!r0)
2005             {
2006 0           croak ("Problem in slr->read(): No R0 at %s %d", __FILE__, __LINE__);
2007             }
2008 677           earley_set = marpa_r_latest_earley_set (r0);
2009             /* Zero length lexemes are not of interest, so we do *not*
2010             * search the 0'th Earley set.
2011             */
2012 677 100         while (earley_set > 0)
2013             {
2014             int return_value;
2015 669           const int working_pos = slr->start_of_lexeme + earley_set;
2016 669           return_value = marpa_r_progress_report_start (r0, earley_set);
2017 669 50         if (return_value < 0)
2018             {
2019 0           croak ("Problem in marpa_r_progress_report_start(%p, %ld): %s",
2020             (void *) r0, (unsigned long) earley_set,
2021             xs_g_error (slg->l0_wrapper));
2022             }
2023             while (1)
2024             {
2025             Marpa_Symbol_ID g1_lexeme;
2026             int dot_position;
2027             Marpa_Earley_Set_ID origin;
2028 686           Marpa_Rule_ID rule_id =
2029             marpa_r_progress_item (r0, &dot_position, &origin);
2030 686 50         if (rule_id <= -2)
2031             {
2032 0           croak ("Problem in marpa_r_progress_item(): %s",
2033             xs_g_error (slg->l0_wrapper));
2034             }
2035 686 100         if (rule_id == -1)
2036             goto NO_MORE_REPORT_ITEMS;
2037 684 100         if (origin != 0)
2038             goto NEXT_REPORT_ITEM;
2039 681 50         if (dot_position != -1)
2040             goto NEXT_REPORT_ITEM;
2041 681           g1_lexeme = slg->l0_rule_g_properties[rule_id].g1_lexeme;
2042 681 100         if (g1_lexeme == -1)
2043             goto NEXT_REPORT_ITEM;
2044 669           lexemes_found++;
2045 669           slr->end_of_lexeme = working_pos;
2046              
2047             /* -2 means a discarded item */
2048 669 100         if (g1_lexeme <= -2)
2049             {
2050             lexemes_discarded++;
2051 667 50         if (slr->trace_terminals)
2052             {
2053 0           union marpa_slr_event_s *slr_event =
2054 0           marpa__slr_event_push (slr->gift);
2055 0           MARPA_SLREV_TYPE (slr_event) = MARPA_SLRTR_LEXEME_DISCARDED;
2056              
2057             /* We do not have the lexeme, but we have the
2058             * lexer rule.
2059             * The upper level will have to figure things out.
2060             */
2061 0           slr_event->t_trace_lexeme_discarded.t_rule_id = rule_id;
2062 0           slr_event->t_trace_lexeme_discarded.t_start_of_lexeme =
2063 0           slr->start_of_lexeme;
2064 0           slr_event->t_trace_lexeme_discarded.t_end_of_lexeme =
2065 0           slr->end_of_lexeme;
2066              
2067             }
2068 667 100         if (slr->l0_rule_r_properties[rule_id].
2069             t_event_on_discard_active)
2070             {
2071             union marpa_slr_event_s *new_event;
2072 371           new_event = marpa__slr_event_push (slr->gift);
2073 371           MARPA_SLREV_TYPE (new_event) = MARPA_SLREV_LEXEME_DISCARDED;
2074 371           new_event->t_lexeme_discarded.t_rule_id = rule_id;
2075 371           new_event->t_lexeme_discarded.t_start_of_lexeme =
2076 371           slr->start_of_lexeme;
2077 371           new_event->t_lexeme_discarded.t_end_of_lexeme =
2078 371           slr->end_of_lexeme;
2079 371           new_event->t_lexeme_discarded.t_last_g1_location =
2080 371           marpa_r_latest_earley_set (slr->r1);
2081             }
2082             /* If there is discarded item, we are fine,
2083             * and can return success.
2084             */
2085 667           slr->lexer_start_pos = slr->perl_pos = working_pos;
2086 667           return 0;
2087             }
2088              
2089             /*
2090             * Ignore everything else.
2091             * We don't try to read lexemes into an exhausted
2092             * R1 -- we only are looking for discardable tokens.
2093             */
2094 2 50         if (slr->trace_terminals)
2095             {
2096 0           union marpa_slr_event_s *slr_event =
2097 0           marpa__slr_event_push (slr->gift);
2098 0           MARPA_SLREV_TYPE (slr_event) = MARPA_SLRTR_LEXEME_IGNORED;
2099              
2100 0           slr_event->t_trace_lexeme_ignored.t_lexeme = g1_lexeme;
2101 0           slr_event->t_trace_lexeme_ignored.t_start_of_lexeme =
2102 0           slr->start_of_lexeme;
2103 0           slr_event->t_trace_lexeme_ignored.t_end_of_lexeme =
2104 0           slr->end_of_lexeme;
2105             }
2106             NEXT_REPORT_ITEM:;
2107 17           }
2108             NO_MORE_REPORT_ITEMS:;
2109 2 50         if (lexemes_found)
2110             {
2111             /* We found a lexeme at this location and we are not allowed
2112             * to discard this input.
2113             * Return failure.
2114             */
2115 2           slr->perl_pos = slr->problem_pos = slr->lexer_start_pos =
2116 2           slr->start_of_lexeme;
2117 2           return -4;
2118             }
2119 0           earley_set--;
2120             }
2121              
2122             /* If we are here we found no lexemes anywhere in the input,
2123             * and therefore none which can be discarded.
2124             * Return failure.
2125             */
2126 8           slr->perl_pos = slr->problem_pos = slr->lexer_start_pos =
2127 8           slr->start_of_lexeme;
2128 8           return -4;
2129             }
2130              
2131             /* Assumes it is called
2132             after a successful marpa_r_earleme_complete().
2133             At some point it may need optional SLR information,
2134             at which point I will add a parameter
2135             */
2136             static void
2137 778           slr_convert_events (Scanless_R * slr)
2138             {
2139             dTHX;
2140             int event_ix;
2141 389           Marpa_Grammar g = slr->r1_wrapper->base->g;
2142 389           const int event_count = marpa_g_event_count (g);
2143 981 100         for (event_ix = 0; event_ix < event_count; event_ix++)
2144             {
2145             Marpa_Event marpa_event;
2146 592           Marpa_Event_Type event_type = marpa_g_event (g, &marpa_event, event_ix);
2147 592           switch (event_type)
2148             {
2149             {
2150             case MARPA_EVENT_EXHAUSTED:
2151             /* Do nothing about exhaustion on success */
2152             break;
2153             case MARPA_EVENT_SYMBOL_COMPLETED:
2154             {
2155 240           union marpa_slr_event_s *slr_event = marpa__slr_event_push(slr->gift);
2156 240           MARPA_SLREV_TYPE(slr_event) = MARPA_SLREV_SYMBOL_COMPLETED;
2157 240           slr_event->t_symbol_completed.t_symbol = marpa_g_event_value (&marpa_event);
2158             }
2159             break;
2160             case MARPA_EVENT_SYMBOL_NULLED:
2161             {
2162 41           union marpa_slr_event_s *slr_event = marpa__slr_event_push(slr->gift);
2163 41           MARPA_SLREV_TYPE(slr_event) =MARPA_SLREV_SYMBOL_NULLED;
2164 41           slr_event->t_symbol_nulled.t_symbol = marpa_g_event_value (&marpa_event);
2165             }
2166             break;
2167             case MARPA_EVENT_SYMBOL_PREDICTED:
2168             {
2169 59           union marpa_slr_event_s *slr_event = marpa__slr_event_push(slr->gift);
2170 59           MARPA_SLREV_TYPE(slr_event) = MARPA_SLREV_SYMBOL_PREDICTED;
2171 59           slr_event->t_symbol_predicted.t_symbol = marpa_g_event_value (&marpa_event);
2172             }
2173             break;
2174             case MARPA_EVENT_EARLEY_ITEM_THRESHOLD:
2175             /* All events are ignored on faiulre
2176             * On success, all except MARPA_EVENT_EARLEY_ITEM_THRESHOLD
2177             * are ignored.
2178             *
2179             * The warning raised for MARPA_EVENT_EARLEY_ITEM_THRESHOLD
2180             * can be turned off by raising
2181             * the Earley item warning threshold.
2182             */
2183             {
2184 0           warn
2185             ("Marpa: Scanless G1 Earley item count (%ld) exceeds warning threshold",
2186 0           (long) marpa_g_event_value (&marpa_event));
2187             }
2188             break;
2189             default:
2190             {
2191 0           union marpa_slr_event_s *slr_event = marpa__slr_event_push(slr->gift);
2192 0           MARPA_SLREV_TYPE(slr_event) = MARPA_SLREV_MARPA_R_UNKNOWN;
2193 0           slr_event->t_marpa_r_unknown.t_event = event_type;
2194             }
2195             break;
2196             }
2197             }
2198             }
2199 389           }
2200              
2201             /* Called after marpa_r_start_input() and
2202             * marpa_r_earleme_complete().
2203             */
2204             static void
2205 3020           r_convert_events (R_Wrapper * r_wrapper)
2206             {
2207             dTHX;
2208             int event_ix;
2209 1510           Marpa_Grammar g = r_wrapper->base->g;
2210 1510           const int event_count = marpa_g_event_count (g);
2211 1865 100         for (event_ix = 0; event_ix < event_count; event_ix++)
2212             {
2213             Marpa_Event marpa_event;
2214 355           Marpa_Event_Type event_type =
2215             marpa_g_event (g, &marpa_event, event_ix);
2216 355           switch (event_type)
2217             {
2218             {
2219             case MARPA_EVENT_EXHAUSTED:
2220             /* Do nothing about exhaustion on success */
2221             break;
2222             case MARPA_EVENT_SYMBOL_COMPLETED:
2223             {
2224             AV *event;
2225             SV *event_data[2];
2226 3           Marpa_Symbol_ID completed_symbol =
2227             marpa_g_event_value (&marpa_event);
2228 3           event_data[0] = newSVpvs ("symbol completed");
2229 3           event_data[1] = newSViv (completed_symbol);
2230 3           event = av_make (Dim (event_data), event_data);
2231 3           av_push (r_wrapper->event_queue, newRV_noinc ((SV *) event));
2232             }
2233             break;
2234             case MARPA_EVENT_SYMBOL_NULLED:
2235             {
2236             AV *event;
2237             SV *event_data[2];
2238 18           Marpa_Symbol_ID nulled_symbol =
2239             marpa_g_event_value (&marpa_event);
2240 18           event_data[0] = newSVpvs ("symbol nulled");
2241 18           event_data[1] = newSViv (nulled_symbol);
2242 18           event = av_make (Dim (event_data), event_data);
2243 18           av_push (r_wrapper->event_queue, newRV_noinc ((SV *) event));
2244             }
2245             break;
2246             case MARPA_EVENT_SYMBOL_PREDICTED:
2247             {
2248             AV *event;
2249             SV *event_data[2];
2250 45           Marpa_Symbol_ID predicted_symbol =
2251             marpa_g_event_value (&marpa_event);
2252 45           event_data[0] = newSVpvs ("symbol predicted");
2253 45           event_data[1] = newSViv (predicted_symbol);
2254 45           event = av_make (Dim (event_data), event_data);
2255 45           av_push (r_wrapper->event_queue, newRV_noinc ((SV *) event));
2256             }
2257             break;
2258             case MARPA_EVENT_EARLEY_ITEM_THRESHOLD:
2259             /* All events are ignored on faiulre
2260             * On success, all except MARPA_EVENT_EARLEY_ITEM_THRESHOLD
2261             * are ignored.
2262             *
2263             * The warning raised for MARPA_EVENT_EARLEY_ITEM_THRESHOLD
2264             * can be turned off by raising
2265             * the Earley item warning threshold.
2266             */
2267             {
2268 0           warn
2269             ("Marpa: Scanless G1 Earley item count (%ld) exceeds warning threshold",
2270 0           (long) marpa_g_event_value (&marpa_event));
2271             }
2272             break;
2273             default:
2274             {
2275             AV *event;
2276             const char *result_string = event_type_to_string (event_type);
2277             SV *event_data[2];
2278 8           event_data[0] = newSVpvs ("unknown event");
2279 8 50         if (!result_string)
2280             {
2281 0           result_string =
2282             form ("event(%d): unknown event code, %d", event_ix,
2283             event_type);
2284             }
2285 8           event_data[1] = newSVpv (result_string, 0);
2286 8           event = av_make (Dim (event_data), event_data);
2287 8           av_push (r_wrapper->event_queue, newRV_noinc ((SV *) event));
2288             }
2289             break;
2290             }
2291             }
2292             }
2293 1510           }
2294              
2295             /*
2296             * Return values:
2297             * NULL OK.
2298             * Otherwise, a string containing the error.
2299             * The string must be a constant in static space.
2300             */
2301             static const char *
2302 28047           slr_alternatives (Scanless_R * slr)
2303             {
2304             dTHX;
2305             Marpa_Recce r0;
2306 28047           Marpa_Recce r1 = slr->r1;
2307             Marpa_Earley_Set_ID earley_set;
2308 28047           const Scanless_G *slg = slr->slg;
2309              
2310             /* |high_lexeme_priority| is not valid unless |is_priority_set| is set. */
2311             int is_priority_set = 0;
2312             int high_lexeme_priority = 0;
2313              
2314             int discarded = 0;
2315             int rejected = 0;
2316 28047           int working_pos = slr->start_of_lexeme;
2317             enum pass1_result_type { none, discard, no_lexeme, accept };
2318             enum pass1_result_type pass1_result = none;
2319              
2320 28047           r0 = slr->r0;
2321 28047 50         if (!r0)
2322             {
2323 0           croak ("Problem in slr->read(): No R0 at %s %d", __FILE__, __LINE__);
2324             }
2325              
2326 28047           marpa__slr_lexeme_clear (slr->gift);
2327              
2328             /* Zero length lexemes are not of interest, so we do NOT
2329             * search the 0'th Earley set.
2330             */
2331 28053 100         for (earley_set = marpa_r_latest_earley_set (r0); earley_set > 0;
2332 6           earley_set--)
2333             {
2334             int return_value;
2335             int end_of_earley_items = 0;
2336 28026           working_pos = slr->start_of_lexeme + earley_set;
2337              
2338 28026           return_value = marpa_r_progress_report_start (r0, earley_set);
2339 28026 50         if (return_value < 0)
2340             {
2341 0           croak ("Problem in marpa_r_progress_report_start(%p, %ld): %s",
2342             (void *) r0, (unsigned long) earley_set,
2343 0           xs_g_error (slr->slg->l0_wrapper));
2344             }
2345              
2346 138574 100         while (!end_of_earley_items)
2347             {
2348             struct symbol_g_properties *symbol_g_properties;
2349             struct l0_rule_g_properties *l0_rule_g_properties;
2350             struct symbol_r_properties *symbol_r_properties;
2351             Marpa_Symbol_ID g1_lexeme;
2352             int this_lexeme_priority;
2353             int is_expected;
2354             int dot_position;
2355             Marpa_Earley_Set_ID origin;
2356 110548           Marpa_Rule_ID rule_id =
2357             marpa_r_progress_item (r0, &dot_position, &origin);
2358 110548 50         if (rule_id <= -2)
2359             {
2360 0           croak ("Problem in marpa_r_progress_item(): %s",
2361 0           xs_g_error (slr->slg->l0_wrapper));
2362             }
2363 110548 100         if (rule_id == -1)
2364             {
2365             end_of_earley_items = 1;
2366             goto NEXT_PASS1_REPORT_ITEM;
2367             }
2368 82522 100         if (origin != 0)
2369             goto NEXT_PASS1_REPORT_ITEM;
2370 78237 100         if (dot_position != -1)
2371             goto NEXT_PASS1_REPORT_ITEM;
2372 76038           l0_rule_g_properties = slg->l0_rule_g_properties + rule_id;
2373 76038           g1_lexeme = l0_rule_g_properties->g1_lexeme;
2374 76038 100         if (g1_lexeme == -1)
2375             goto NEXT_PASS1_REPORT_ITEM;
2376 31371           slr->end_of_lexeme = working_pos;
2377             /* -2 means a discarded item */
2378 31371 100         if (g1_lexeme <= -2)
2379             {
2380 12725           union marpa_slr_event_s *lexeme_entry =
2381 12725           marpa__slr_lexeme_push (slr->gift);
2382 12725           MARPA_SLREV_TYPE (lexeme_entry) = MARPA_SLRTR_LEXEME_DISCARDED;
2383 12725           lexeme_entry->t_trace_lexeme_discarded.t_rule_id = rule_id;
2384 12725           lexeme_entry->t_trace_lexeme_discarded.t_start_of_lexeme =
2385 12725           slr->start_of_lexeme;
2386 12725           lexeme_entry->t_trace_lexeme_discarded.t_end_of_lexeme =
2387 12725           slr->end_of_lexeme;
2388 12725           discarded++;
2389              
2390 12725           goto NEXT_PASS1_REPORT_ITEM;
2391             }
2392 18646           symbol_g_properties = slg->symbol_g_properties + g1_lexeme;
2393             l0_rule_g_properties = slg->l0_rule_g_properties + rule_id;
2394 18646           symbol_r_properties = slr->symbol_r_properties + g1_lexeme;
2395 18646           is_expected = marpa_r_terminal_is_expected (r1, g1_lexeme);
2396 18646 100         if (!is_expected)
2397             {
2398 373           union marpa_slr_event_s *lexeme_entry =
2399 373           marpa__slr_lexeme_push (slr->gift);
2400 373 50         if (symbol_g_properties->latm)
2401             {
2402 0           croak
2403             ("Internal error: Marpa recognized unexpected token @%ld-%ld: lexeme=%ld",
2404 0           (long) slr->start_of_lexeme, (long) slr->end_of_lexeme,
2405             (long) g1_lexeme);
2406             }
2407             else
2408             {
2409 373           MARPA_SLREV_TYPE (lexeme_entry) =
2410             MARPA_SLRTR_LEXEME_REJECTED;
2411 373           lexeme_entry->t_trace_lexeme_rejected.t_start_of_lexeme =
2412 373           slr->start_of_lexeme;
2413 373           lexeme_entry->t_trace_lexeme_rejected.t_end_of_lexeme =
2414 373           slr->end_of_lexeme;
2415 373           lexeme_entry->t_trace_lexeme_rejected.t_lexeme = g1_lexeme;
2416 373           rejected++;
2417             }
2418 373           goto NEXT_PASS1_REPORT_ITEM;
2419             }
2420              
2421             /* If we are here, the lexeme will be accepted by the grammar,
2422             * but we do not yet know about priority
2423             */
2424              
2425 18273           this_lexeme_priority = symbol_r_properties->lexeme_priority;
2426 18273 100         if (!is_priority_set || this_lexeme_priority > high_lexeme_priority)
2427             {
2428             high_lexeme_priority = this_lexeme_priority;
2429             is_priority_set = 1;
2430             }
2431              
2432             {
2433 18273           union marpa_slr_event_s *lexeme_entry =
2434 18273           marpa__slr_lexeme_push (slr->gift);
2435 18273           MARPA_SLREV_TYPE (lexeme_entry) = MARPA_SLRTR_LEXEME_ACCEPTABLE;
2436 18273           lexeme_entry->t_lexeme_acceptable.t_start_of_lexeme =
2437 18273           slr->start_of_lexeme;
2438 18273           lexeme_entry->t_lexeme_acceptable.t_end_of_lexeme =
2439 18273           slr->end_of_lexeme;
2440 18273           lexeme_entry->t_lexeme_acceptable.t_lexeme = g1_lexeme;
2441 18273           lexeme_entry->t_lexeme_acceptable.t_priority =
2442             this_lexeme_priority;
2443             /* Default to this symbol's priority, since we don't
2444             yet know what the required priority will be */
2445 110548           lexeme_entry->t_lexeme_acceptable.t_required_priority =
2446             this_lexeme_priority;
2447             }
2448              
2449             NEXT_PASS1_REPORT_ITEM: /* Clearer, I think, using this label than long distance
2450             break and continue */ ;
2451             }
2452              
2453 28026 100         if (discarded || rejected || is_priority_set)
2454             break;
2455              
2456             }
2457              
2458             /* Figure out what the result of pass 1 was */
2459 28047 100         if (is_priority_set)
2460             {
2461             pass1_result = accept;
2462 12751 100         } else if (discarded) {
2463             pass1_result = discard;
2464             } else {
2465             pass1_result = no_lexeme;
2466             }
2467              
2468             {
2469             /* In pass 1, we used a stack of tentative
2470             * trace events to record which lexemes
2471             * are acceptable, to be discarded, etc.
2472             * At this point, if we are tracing,
2473             * we convert the tentative trace
2474             * events into real trace events.
2475             */
2476             int i;
2477 59418 100         for (i = 0; i < slr->gift->t_lexeme_count; i++)
2478             {
2479 31371           union marpa_slr_event_s *const lexeme_stack_event = slr->gift->t_lexemes + i;
2480 31371           const int event_type = MARPA_SLREV_TYPE (lexeme_stack_event);
2481 31371           switch (event_type)
2482             {
2483             case MARPA_SLRTR_LEXEME_ACCEPTABLE:
2484 18273 100         if (lexeme_stack_event->t_lexeme_acceptable.t_priority <
2485             high_lexeme_priority)
2486             {
2487 14           MARPA_SLREV_TYPE (lexeme_stack_event) =
2488             MARPA_SLRTR_LEXEME_OUTPRIORITIZED;
2489 14           lexeme_stack_event->t_lexeme_acceptable.t_required_priority =
2490             high_lexeme_priority;
2491 14 50         if (slr->trace_terminals)
2492             {
2493 0           *(marpa__slr_event_push (slr->gift)) =
2494             *lexeme_stack_event;
2495             }
2496             }
2497             goto NEXT_LEXEME_EVENT;
2498             case MARPA_SLRTR_LEXEME_REJECTED:
2499 373 100         if (slr->trace_terminals || !is_priority_set)
    100          
2500             {
2501 7           *(marpa__slr_event_push (slr->gift)) = *lexeme_stack_event;
2502             }
2503             goto NEXT_LEXEME_EVENT;
2504             case MARPA_SLRTR_LEXEME_DISCARDED:
2505 12725 100         if (slr->trace_terminals)
2506             {
2507 13           *(marpa__slr_event_push (slr->gift)) = *lexeme_stack_event;
2508             }
2509 12725 100         if (pass1_result == discard)
2510             {
2511             union marpa_slr_event_s *new_event;
2512 12722           const Marpa_Rule_ID l0_rule_id =
2513             lexeme_stack_event->t_trace_lexeme_discarded.t_rule_id;
2514 12722           struct l0_rule_r_properties *l0_rule_r_properties
2515 12722           = slr->l0_rule_r_properties + l0_rule_id;
2516 12722 100         if (!l0_rule_r_properties->t_event_on_discard_active)
2517             {
2518             goto NEXT_LEXEME_EVENT;
2519             }
2520 114           new_event = marpa__slr_event_push (slr->gift);
2521 114           MARPA_SLREV_TYPE (new_event) =
2522             MARPA_SLREV_LEXEME_DISCARDED;
2523 114           new_event->t_lexeme_discarded.t_rule_id = l0_rule_id;
2524 114           new_event->t_lexeme_discarded.t_start_of_lexeme =
2525 114           lexeme_stack_event->t_trace_lexeme_discarded.t_start_of_lexeme;
2526 114           new_event->t_lexeme_discarded.t_end_of_lexeme =
2527 114           lexeme_stack_event->t_trace_lexeme_discarded.t_end_of_lexeme;
2528 114           new_event->t_lexeme_discarded.t_last_g1_location =
2529 114           marpa_r_latest_earley_set (slr->r1);
2530             }
2531             goto NEXT_LEXEME_EVENT;
2532             }
2533             NEXT_LEXEME_EVENT: ;
2534             }
2535             }
2536              
2537 28047 100         if (pass1_result == discard) {
2538 12722           slr->perl_pos = slr->lexer_start_pos = working_pos;
2539 12722           return 0;
2540             }
2541              
2542 15325 100         if (pass1_result != accept) {
2543 29           slr->perl_pos = slr->problem_pos = slr->lexer_start_pos =
2544 29           slr->start_of_lexeme;
2545 29           return "no lexeme";
2546             }
2547              
2548             /* If here, a lexeme has been accepted and priority is set
2549             */
2550              
2551             { /* Check for a "pause before" lexeme */
2552             /* A legacy implement allowed only one pause-before lexeme, and used elements of
2553             the SLR structure to hold the data. The new mechanism uses events and allows
2554             multiple pause-before lexemes, but the legacy mechanism must be supported. */
2555             Marpa_Symbol_ID g1_lexeme = -1;
2556             int i;
2557 33941 100         for (i = 0; i < slr->gift->t_lexeme_count; i++)
2558             {
2559 18645           union marpa_slr_event_s *const lexeme_entry = slr->gift->t_lexemes + i;
2560 18645           const int event_type = MARPA_SLREV_TYPE (lexeme_entry);
2561 18645 100         if (event_type == MARPA_SLRTR_LEXEME_ACCEPTABLE)
2562             {
2563 18259           const Marpa_Symbol_ID lexeme_id =
2564             lexeme_entry->t_lexeme_acceptable.t_lexeme;
2565 18259           const struct symbol_r_properties *symbol_r_properties =
2566 18259           slr->symbol_r_properties + lexeme_id;
2567 18259 100         if (symbol_r_properties->t_pause_before_active)
2568             {
2569             g1_lexeme = lexeme_id;
2570 192           slr->start_of_pause_lexeme =
2571 192           lexeme_entry->t_lexeme_acceptable.t_start_of_lexeme;
2572 192           slr->end_of_pause_lexeme =
2573 192           lexeme_entry->t_lexeme_acceptable.t_end_of_lexeme;
2574 192           slr->pause_lexeme = g1_lexeme;
2575 192 50         if (slr->trace_terminals > 2)
2576             {
2577 0           union marpa_slr_event_s *slr_event =
2578             marpa__slr_event_push (slr->gift);
2579 0           MARPA_SLREV_TYPE (slr_event) = MARPA_SLRTR_BEFORE_LEXEME;
2580 0           slr_event->t_trace_before_lexeme.t_start_of_pause_lexeme =
2581 0           slr->start_of_pause_lexeme;
2582 0           slr_event->t_trace_before_lexeme.t_end_of_pause_lexeme = slr->end_of_pause_lexeme; /* end */
2583 0           slr_event->t_trace_before_lexeme.t_pause_lexeme = slr->pause_lexeme; /* lexeme */
2584             }
2585             {
2586 192           union marpa_slr_event_s *slr_event =
2587 192           marpa__slr_event_push (slr->gift);
2588 192           MARPA_SLREV_TYPE (slr_event) = MARPA_SLREV_BEFORE_LEXEME;
2589 192           slr_event->t_before_lexeme.t_pause_lexeme =
2590 192           slr->pause_lexeme;
2591             }
2592             }
2593             }
2594             }
2595              
2596 15296 100         if (g1_lexeme >= 0)
2597             {
2598 192           slr->lexer_start_pos = slr->perl_pos = slr->start_of_lexeme;
2599 192           return 0;
2600             }
2601             }
2602              
2603             {
2604             int return_value;
2605             int i;
2606 33557 100         for (i = 0; i < slr->gift->t_lexeme_count; i++)
2607             {
2608 18453           union marpa_slr_event_s *const event = slr->gift->t_lexemes + i;
2609 18453           const int event_type = MARPA_SLREV_TYPE (event);
2610 18453 100         if (event_type == MARPA_SLRTR_LEXEME_ACCEPTABLE)
2611             {
2612 18067           const Marpa_Symbol_ID g1_lexeme =
2613             event->t_lexeme_acceptable.t_lexeme;
2614 18067           const struct symbol_r_properties *symbol_r_properties =
2615 18067           slr->symbol_r_properties + g1_lexeme;
2616              
2617 18067 50         if (slr->trace_terminals > 2)
2618             {
2619 0           union marpa_slr_event_s *event =
2620             marpa__slr_event_push (slr->gift);
2621 0           MARPA_SLREV_TYPE (event) = MARPA_SLRTR_G1_ATTEMPTING_LEXEME;
2622 0           event->t_trace_attempting_lexeme.t_start_of_lexeme = slr->start_of_lexeme; /* start */
2623 0           event->t_trace_attempting_lexeme.t_end_of_lexeme = slr->end_of_lexeme; /* end */
2624 0           event->t_trace_attempting_lexeme.t_lexeme = g1_lexeme;
2625             }
2626 18067           return_value =
2627             marpa_r_alternative (r1, g1_lexeme, TOKEN_VALUE_IS_LITERAL, 1);
2628 18067           switch (return_value)
2629             {
2630              
2631             case MARPA_ERR_UNEXPECTED_TOKEN_ID:
2632 0           croak ("Internal error: Marpa rejected expected token");
2633             break;
2634              
2635             case MARPA_ERR_DUPLICATE_TOKEN:
2636 0 0         if (slr->trace_terminals)
2637             {
2638 0           union marpa_slr_event_s *event =
2639 0           marpa__slr_event_push (slr->gift);
2640 0           MARPA_SLREV_TYPE (event) =
2641             MARPA_SLRTR_G1_DUPLICATE_LEXEME;
2642 0           event->t_trace_duplicate_lexeme.t_start_of_lexeme = slr->start_of_lexeme; /* start */
2643 0           event->t_trace_duplicate_lexeme.t_end_of_lexeme = slr->end_of_lexeme; /* end */
2644 0           event->t_trace_duplicate_lexeme.t_lexeme = g1_lexeme; /* lexeme */
2645             }
2646             break;
2647              
2648             case MARPA_ERR_NONE:
2649 18067 100         if (slr->trace_terminals)
2650             {
2651 16           union marpa_slr_event_s *event =
2652 16           marpa__slr_event_push (slr->gift);
2653 16           MARPA_SLREV_TYPE (event) = MARPA_SLRTR_G1_ACCEPTED_LEXEME;
2654 16           event->t_trace_accepted_lexeme.t_start_of_lexeme = slr->start_of_lexeme; /* start */
2655 16           event->t_trace_accepted_lexeme.t_end_of_lexeme = slr->end_of_lexeme; /* end */
2656 16           event->t_trace_accepted_lexeme.t_lexeme = g1_lexeme; /* lexeme */
2657             }
2658 18067 100         if (symbol_r_properties->t_pause_after_active)
2659             {
2660 196           slr->start_of_pause_lexeme =
2661 196           event->t_lexeme_acceptable.t_start_of_lexeme;
2662 196           slr->end_of_pause_lexeme =
2663 196           event->t_lexeme_acceptable.t_end_of_lexeme;
2664 196           slr->pause_lexeme = g1_lexeme;
2665 196 50         if (slr->trace_terminals > 2)
2666             {
2667 0           union marpa_slr_event_s *event =
2668 0           marpa__slr_event_push (slr->gift);
2669 0           MARPA_SLREV_TYPE (event) = MARPA_SLRTR_AFTER_LEXEME;
2670 0           event->t_trace_after_lexeme.t_start_of_lexeme =
2671 0           slr->start_of_pause_lexeme;
2672 0           event->t_trace_after_lexeme.t_end_of_lexeme =
2673 0           slr->end_of_pause_lexeme;
2674 0           event->t_trace_after_lexeme.t_lexeme = g1_lexeme;
2675             }
2676             {
2677 196           union marpa_slr_event_s *event =
2678 196           marpa__slr_event_push (slr->gift);
2679 196           MARPA_SLREV_TYPE (event) = MARPA_SLREV_AFTER_LEXEME;
2680 196           event->t_after_lexeme.t_lexeme = slr->pause_lexeme;
2681             }
2682             }
2683             break;
2684              
2685             default:
2686 0           croak
2687             ("Problem SLR->read() failed on symbol id %d at position %d: %s",
2688             g1_lexeme, (int) slr->perl_pos,
2689             xs_g_error (slr->g1_wrapper));
2690             /* NOTREACHED */
2691              
2692             }
2693              
2694             }
2695             }
2696              
2697              
2698 15104           return_value = slr->r1_earleme_complete_result =
2699 15104           marpa_r_earleme_complete (r1);
2700 15104 50         if (return_value < 0)
2701             {
2702 0           croak ("Problem in marpa_r_earleme_complete(): %s",
2703             xs_g_error (slr->g1_wrapper));
2704             }
2705 15104           slr->lexer_start_pos = slr->perl_pos = slr->end_of_lexeme;
2706 15104 100         if (return_value > 0)
2707             {
2708 389           slr_convert_events (slr);
2709             }
2710              
2711 15104           marpa_r_latest_earley_set_values_set (r1, slr->start_of_lexeme,
2712 15104           INT2PTR (void *,
2713             (slr->end_of_lexeme -
2714             slr->start_of_lexeme)));
2715             }
2716              
2717 15104           return 0;
2718              
2719             }
2720              
2721             static void
2722 302076           slr_es_to_span (Scanless_R * slr, Marpa_Earley_Set_ID earley_set, int *p_start,
2723             int *p_length)
2724             {
2725             dTHX;
2726             int result = 0;
2727             /* We fake the values for Earley set 0,
2728             */
2729 151038 100         if (earley_set <= 0)
2730             {
2731 27           *p_start = 0;
2732 27           *p_length = 0;
2733             }
2734             else
2735             {
2736             void *length_as_ptr;
2737 151011           result =
2738 151011           marpa_r_earley_set_values (slr->r1, earley_set, p_start,
2739             &length_as_ptr);
2740 151011           *p_length = (int) PTR2IV (length_as_ptr);
2741             }
2742 151038 50         if (result < 0)
2743             {
2744 0           croak ("failure in slr->span(%d): %s", earley_set,
2745             xs_g_error (slr->g1_wrapper));
2746             }
2747 151038           }
2748              
2749             static void
2750 137380           slr_es_to_literal_span (Scanless_R * slr,
2751             Marpa_Earley_Set_ID start_earley_set, int length,
2752             int *p_start, int *p_length)
2753             {
2754             dTHX;
2755 137380           const Marpa_Recce r1 = slr->r1;
2756 137380           const Marpa_Earley_Set_ID latest_earley_set =
2757             marpa_r_latest_earley_set (r1);
2758 137380 100         if (start_earley_set >= latest_earley_set)
2759             {
2760             /* Should only happen if length == 0 */
2761 189           *p_start = slr->pos_db_logical_size;
2762 189           *p_length = 0;
2763 189           return;
2764             }
2765 137191           slr_es_to_span (slr, start_earley_set + 1, p_start, p_length);
2766 137191 100         if (length == 0)
2767 39802           *p_length = 0;
2768 137191 100         if (length > 1)
2769             {
2770             int last_lexeme_start_position;
2771             int last_lexeme_length;
2772 10372           slr_es_to_span (slr, start_earley_set + length,
2773             &last_lexeme_start_position, &last_lexeme_length);
2774 10372           *p_length = last_lexeme_start_position + last_lexeme_length - *p_start;
2775             }
2776             }
2777              
2778             static SV*
2779 59213           slr_es_span_to_literal_sv (Scanless_R * slr,
2780             Marpa_Earley_Set_ID start_earley_set, int length)
2781             {
2782             dTHX;
2783 59213 50         if (length > 0)
2784             {
2785             int length_in_positions;
2786             int start_position;
2787 59213           slr_es_to_literal_span (slr,
2788             start_earley_set, length,
2789             &start_position, &length_in_positions);
2790 59213           return u_pos_span_to_literal_sv(slr, start_position, length_in_positions);
2791             }
2792 0           return newSVpvn ("", 0);
2793             }
2794              
2795             #define EXPECTED_LIBMARPA_MAJOR 11
2796             #define EXPECTED_LIBMARPA_MINOR 0
2797             #define EXPECTED_LIBMARPA_MICRO 2
2798              
2799             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin
2800              
2801             PROTOTYPES: DISABLE
2802              
2803             void
2804             debug_level_set(new_level)
2805             int new_level;
2806             PPCODE:
2807             {
2808 0           const int old_level = marpa_debug_level_set (new_level);
2809 0 0         if (old_level || new_level)
2810 0           marpa_r2_warn ("libmarpa debug level set to %d, was %d", new_level,
2811             old_level);
2812 0           XSRETURN_YES;
2813             }
2814              
2815             void
2816             error_names()
2817             PPCODE:
2818             {
2819             int error_code;
2820 17978 100         for (error_code = 0; error_code < MARPA_ERROR_COUNT; error_code++)
2821             {
2822 17800           const char *error_name = marpa_error_description[error_code].name;
2823 17800 100         XPUSHs (sv_2mortal (newSVpv (error_name, 0)));
2824             }
2825             }
2826              
2827             # This search is not optimized. This list is short
2828             # and the data is constant, so that
2829             # and lookup is expected to be done once by an application
2830             # and memoized.
2831             void
2832             op( op_name )
2833             char *op_name;
2834             PPCODE:
2835             {
2836 2538           const int op_id = marpa__slif_op_id (op_name);
2837 2538 50         if (op_id >= 0)
2838             {
2839 2538           XSRETURN_IV ((IV) op_id);
2840             }
2841 0           croak ("Problem with Marpa::R2::Thin->op('%s'): No such op", op_name);
2842             }
2843              
2844             # This search is not optimized. This list is short
2845             # and the data is constant. It is expected this lookup
2846             # will be done mainly for error messages.
2847             void
2848             op_name( op )
2849             IV op;
2850             PPCODE:
2851             {
2852 0           XSRETURN_PV (marpa__slif_op_name(op));
2853             }
2854              
2855             void
2856             version()
2857             PPCODE:
2858             {
2859             int version[3];
2860 1           int result = marpa_version(version);
2861 1 50         if (result < 0) { XSRETURN_UNDEF; }
2862 1 50         XPUSHs (sv_2mortal (newSViv (version[0])));
2863 1 50         XPUSHs (sv_2mortal (newSViv (version[1])));
2864 1 50         XPUSHs (sv_2mortal (newSViv (version[2])));
2865             }
2866              
2867             void
2868             tag()
2869             PPCODE:
2870             {
2871 3           const char* tag = _marpa_tag();
2872 3           XSRETURN_PV(tag);
2873             }
2874              
2875             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::G
2876              
2877             void
2878             new( ... )
2879             PPCODE:
2880             {
2881             Marpa_Grammar g;
2882             G_Wrapper *g_wrapper;
2883             int throw = 1;
2884             IV interface = 0;
2885             Marpa_Config marpa_configuration;
2886             int error_code;
2887              
2888 787           switch (items)
2889             {
2890             case 1:
2891             {
2892             /* If we are using the (deprecated) interface 0,
2893             * get the throw setting from a (deprecated) global variable
2894             */
2895 1           SV *throw_sv = get_sv ("Marpa::R2::Thin::C::THROW", 0);
2896 1 50         throw = throw_sv && SvTRUE (throw_sv);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
2897             }
2898             break;
2899             case 2:
2900             {
2901             I32 retlen;
2902             char *key;
2903             SV *arg_value;
2904 786           SV *arg = ST (1);
2905             HV *named_args;
2906 786 50         if (!SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVHV)
    50          
2907 0           croak ("Problem in $g->new(): argument is not hash ref");
2908             named_args = (HV *) SvRV (arg);
2909 786           hv_iterinit (named_args);
2910 1572 100         while ((arg_value = hv_iternextsv (named_args, &key, &retlen)))
2911             {
2912 786 50         if ((*key == 'i') && strnEQ (key, "if", (unsigned) retlen))
    50          
    0          
    0          
    0          
    50          
2913             {
2914 786 50         interface = SvIV (arg_value);
2915 786 50         if (interface != 1)
2916             {
2917 0           croak ("Problem in $g->new(): interface value must be 1");
2918             }
2919 786           continue;
2920             }
2921 0           croak ("Problem in $g->new(): unknown named argument: %s", key);
2922             }
2923 786 50         if (interface != 1)
2924             {
2925 786           croak
2926             ("Problem in $g->new(): 'interface' named argument is required");
2927             }
2928             }
2929             }
2930              
2931             /* Make sure the header is from the version we want */
2932             if (MARPA_MAJOR_VERSION != EXPECTED_LIBMARPA_MAJOR
2933             || MARPA_MINOR_VERSION != EXPECTED_LIBMARPA_MINOR
2934             || MARPA_MICRO_VERSION != EXPECTED_LIBMARPA_MICRO)
2935             {
2936             croak
2937             ("Problem in $g->new(): want Libmarpa %d.%d.%d, header was from Libmarpa %d.%d.%d",
2938             EXPECTED_LIBMARPA_MAJOR, EXPECTED_LIBMARPA_MINOR,
2939             EXPECTED_LIBMARPA_MICRO,
2940             MARPA_MAJOR_VERSION, MARPA_MINOR_VERSION,
2941             MARPA_MICRO_VERSION);
2942             }
2943              
2944             {
2945             /* Now make sure the library is from the version we want */
2946             int version[3];
2947 787           error_code = marpa_version (version);
2948 787 50         if (error_code != MARPA_ERR_NONE
2949 787 50         || version[0] != EXPECTED_LIBMARPA_MAJOR
2950 787 50         || version[1] != EXPECTED_LIBMARPA_MINOR
2951 787 50         || version[2] != EXPECTED_LIBMARPA_MICRO)
2952             {
2953 0           croak
2954             ("Problem in $g->new(): want Libmarpa %d.%d.%d, using Libmarpa %d.%d.%d",
2955             EXPECTED_LIBMARPA_MAJOR, EXPECTED_LIBMARPA_MINOR,
2956             EXPECTED_LIBMARPA_MICRO, version[0], version[1], version[2]);
2957             }
2958             }
2959              
2960 787           marpa_c_init (&marpa_configuration);
2961 787           g = marpa_g_new (&marpa_configuration);
2962 787 50         if (g)
2963             {
2964             SV *sv;
2965 787           Newx (g_wrapper, 1, G_Wrapper);
2966 787           g_wrapper->throw = throw;
2967 787           g_wrapper->g = g;
2968 787           g_wrapper->message_buffer = NULL;
2969 787           g_wrapper->libmarpa_error_code = MARPA_ERR_NONE;
2970 787           g_wrapper->libmarpa_error_string = NULL;
2971 787           g_wrapper->message_is_marpa_thin_error = 0;
2972 787           sv = sv_newmortal ();
2973 787           sv_setref_pv (sv, grammar_c_class_name, (void *) g_wrapper);
2974 787 50         XPUSHs (sv);
2975             }
2976             else
2977             {
2978 0           error_code = marpa_c_error (&marpa_configuration, NULL);
2979             }
2980              
2981 787 50         if (error_code != MARPA_ERR_NONE)
2982             {
2983             const char *error_description = "Error code out of bounds";
2984 0 0         if (error_code >= 0 && error_code < MARPA_ERROR_COUNT)
2985             {
2986 0           error_description = marpa_error_description[error_code].name;
2987             }
2988 0 0         if (throw)
2989 0           croak ("Problem in Marpa::R2->new(): %s", error_description);
2990 0 0         if (GIMME != G_ARRAY)
    0          
2991             {
2992 0           XSRETURN_UNDEF;
2993             }
2994 0 0         XPUSHs (&PL_sv_undef);
2995 0 0         XPUSHs (sv_2mortal (newSViv (error_code)));
2996             }
2997             }
2998              
2999             void
3000             DESTROY( g_wrapper )
3001             G_Wrapper *g_wrapper;
3002             PPCODE:
3003             {
3004             Marpa_Grammar grammar;
3005 787 100         if (g_wrapper->message_buffer)
3006 24           Safefree(g_wrapper->message_buffer);
3007 787           grammar = g_wrapper->g;
3008 787           marpa_g_unref( grammar );
3009 787           Safefree( g_wrapper );
3010             }
3011              
3012              
3013             void
3014             event( g_wrapper, ix )
3015             G_Wrapper *g_wrapper;
3016             int ix;
3017             PPCODE:
3018             {
3019 127           Marpa_Grammar g = g_wrapper->g;
3020             Marpa_Event event;
3021             const char *result_string = NULL;
3022 127           Marpa_Event_Type result = marpa_g_event (g, &event, ix);
3023 127 50         if (result < 0)
3024             {
3025 0 0         if (!g_wrapper->throw)
3026             {
3027 0           XSRETURN_UNDEF;
3028             }
3029 0           croak ("Problem in g->event(): %s", xs_g_error (g_wrapper));
3030             }
3031             result_string = event_type_to_string (result);
3032 127 50         if (!result_string)
3033             {
3034 0           char *error_message =
3035             form ("event(%d): unknown event code, %d", ix, result);
3036 0           set_error_from_string (g_wrapper, savepv(error_message));
3037 0           XSRETURN_UNDEF;
3038             }
3039 127 50         XPUSHs (sv_2mortal (newSVpv (result_string, 0)));
3040 127 50         XPUSHs (sv_2mortal (newSViv (marpa_g_event_value (&event))));
3041             }
3042              
3043             # Actually returns Marpa_Rule_ID, void is here to eliminate RETVAL
3044             # that remains unused with PPCODE. The same applies to all void's below
3045             # when preceded with a return type commented out, e.g.
3046             # # int
3047             # void
3048             void
3049             rule_new( g_wrapper, lhs, rhs_av )
3050             G_Wrapper *g_wrapper;
3051             Marpa_Symbol_ID lhs;
3052             AV *rhs_av;
3053             PPCODE:
3054             {
3055 46141           Marpa_Grammar g = g_wrapper->g;
3056             int length;
3057             Marpa_Symbol_ID* rhs;
3058             Marpa_Rule_ID new_rule_id;
3059 46141           length = av_len(rhs_av)+1;
3060 46141 100         if (length <= 0) {
3061             rhs = (Marpa_Symbol_ID*)NULL;
3062             } else {
3063             int i;
3064 45742 50         Newx(rhs, length, Marpa_Symbol_ID);
3065 139302 100         for (i = 0; i < length; i++) {
3066 93560           SV** elem = av_fetch(rhs_av, i, 0);
3067 93560 50         if (elem == NULL) {
3068 0           Safefree(rhs);
3069 0           XSRETURN_UNDEF;
3070             } else {
3071 93560 50         rhs[i] = (Marpa_Symbol_ID)SvIV(*elem);
3072             }
3073             }
3074             }
3075 46141           new_rule_id = marpa_g_rule_new(g, lhs, rhs, length);
3076 46141           Safefree(rhs);
3077 46141 100         if (new_rule_id < 0 && g_wrapper->throw ) {
    50          
3078 0           croak ("Problem in g->rule_new(%d, ...): %s", lhs, xs_g_error (g_wrapper));
3079             }
3080 46141 50         XPUSHs( sv_2mortal( newSViv(new_rule_id) ) );
3081             }
3082              
3083             # This function invalidates any current iteration on
3084             # the hash args. This seems to be the way things are
3085             # done in Perl -- in particular there seems to be no
3086             # easy way to prevent that.
3087             # Marpa_Rule_ID
3088             void
3089             sequence_new( g_wrapper, lhs, rhs, args )
3090             G_Wrapper *g_wrapper;
3091             Marpa_Symbol_ID lhs;
3092             Marpa_Symbol_ID rhs;
3093             HV *args;
3094             PPCODE:
3095             {
3096 4439           Marpa_Grammar g = g_wrapper->g;
3097             Marpa_Rule_ID new_rule_id;
3098             Marpa_Symbol_ID separator = -1;
3099             int min = 1;
3100             int flags = 0;
3101 4439 50         if (args)
3102             {
3103             I32 retlen;
3104             char *key;
3105             SV *arg_value;
3106 4439           hv_iterinit (args);
3107 12832 100         while ((arg_value = hv_iternextsv (args, &key, &retlen)))
3108             {
3109 8393 50         if ((*key == 'k') && strnEQ (key, "keep", (unsigned) retlen))
    0          
    0          
    0          
3110             {
3111 0 0         if (SvTRUE (arg_value))
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3112 0           flags |= MARPA_KEEP_SEPARATION;
3113 0           continue;
3114             }
3115 8393 100         if ((*key == 'm') && strnEQ (key, "min", (unsigned) retlen))
    50          
    0          
    0          
    0          
    0          
    50          
3116             {
3117 4439 50         IV raw_min = SvIV (arg_value);
3118 4439 50         if (raw_min < 0)
3119             {
3120 0           char *error_message =
3121             form ("sequence_new(): min cannot be less than 0");
3122 0           set_error_from_string (g_wrapper, savepv (error_message));
3123 0 0         if (g_wrapper->throw)
3124             {
3125 0           croak ("%s", error_message);
3126             }
3127             else
3128             {
3129 0           XSRETURN_UNDEF;
3130             }
3131             }
3132 4439 50         if (raw_min > INT_MAX)
3133             {
3134             /* IV can be larger than int */
3135 0           char *error_message =
3136             form ("sequence_new(): min cannot be greater than %d",
3137             INT_MAX);
3138 0           set_error_from_string (g_wrapper, savepv (error_message));
3139 0 0         if (g_wrapper->throw)
3140             {
3141 0           croak ("%s", error_message);
3142             }
3143             else
3144             {
3145 0           XSRETURN_UNDEF;
3146             }
3147             }
3148 4439           min = (int) raw_min;
3149 4439           continue;
3150             }
3151 3954 100         if ((*key == 'p') && strnEQ (key, "proper", (unsigned) retlen))
    50          
    0          
    50          
3152             {
3153 1977 50         if (SvTRUE (arg_value))
    50          
    50          
    0          
    0          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    0          
    100          
3154 262           flags |= MARPA_PROPER_SEPARATION;
3155 1977           continue;
3156             }
3157 1977 50         if ((*key == 's') && strnEQ (key, "separator", (unsigned) retlen))
    50          
    0          
    50          
3158             {
3159 1977 50         separator = (Marpa_Symbol_ID) SvIV (arg_value);
3160 1977           continue;
3161             }
3162             {
3163 0           char *error_message =
3164 0           form ("unknown argument to sequence_new(): %.*s", (int) retlen,
3165             key);
3166 0           set_error_from_string (g_wrapper, savepv (error_message));
3167 0 0         if (g_wrapper->throw)
3168             {
3169 0           croak ("%s", error_message);
3170             }
3171             else
3172             {
3173 8393           XSRETURN_UNDEF;
3174             }
3175             }
3176             }
3177             }
3178 4439           new_rule_id = marpa_g_sequence_new (g, lhs, rhs, separator, min, flags);
3179 4439 50         if (new_rule_id < 0 && g_wrapper->throw)
    0          
3180             {
3181 0 0         switch (marpa_g_error (g, NULL))
3182             {
3183             case MARPA_ERR_SEQUENCE_LHS_NOT_UNIQUE:
3184 0           croak ("Problem in g->sequence_new(): %s", xs_g_error (g_wrapper));
3185             default:
3186 0           croak ("Problem in g->sequence_new(%d, %d, ...): %s", lhs, rhs,
3187             xs_g_error (g_wrapper));
3188             }
3189             }
3190 4439 50         XPUSHs (sv_2mortal (newSViv (new_rule_id)));
3191             }
3192              
3193             void
3194             default_rank( g_wrapper )
3195             G_Wrapper *g_wrapper;
3196             PPCODE:
3197             {
3198 35601           Marpa_Grammar self = g_wrapper->g;
3199 35601           int gp_result = marpa_g_default_rank (self);
3200 35601 50         if (gp_result == -2 && g_wrapper->throw)
    0          
3201             {
3202 0           const int libmarpa_error_code = marpa_g_error (self, NULL);
3203 0 0         if (libmarpa_error_code != MARPA_ERR_NONE)
3204             {
3205 0           croak ("Problem in g->default_rank(): %s", xs_g_error (g_wrapper));
3206             }
3207             }
3208 35601           XSRETURN_IV (gp_result);
3209             }
3210              
3211             void
3212             default_rank_set( g_wrapper, rank )
3213             G_Wrapper *g_wrapper;
3214             Marpa_Rank rank;
3215             PPCODE:
3216             {
3217 0           Marpa_Grammar self = g_wrapper->g;
3218 0           int gp_result = marpa_g_default_rank_set (self, rank);
3219 0 0         if (gp_result == -2 && g_wrapper->throw)
    0          
3220             {
3221 0           const int libmarpa_error_code = marpa_g_error (self, NULL);
3222 0 0         if (libmarpa_error_code != MARPA_ERR_NONE)
3223 0           croak ("Problem in g->default_rank_set(%d): %s",
3224             rank, xs_g_error (g_wrapper));
3225             }
3226 0           XSRETURN_IV (gp_result);
3227             }
3228              
3229             void
3230             rule_rank( g_wrapper, rule_id )
3231             G_Wrapper *g_wrapper;
3232             Marpa_Rule_ID rule_id;
3233             PPCODE:
3234             {
3235 0           Marpa_Grammar self = g_wrapper->g;
3236 0           int gp_result = marpa_g_rule_rank (self, rule_id);
3237 0 0         if (gp_result == -2 && g_wrapper->throw)
    0          
3238             {
3239 0           const int libmarpa_error_code = marpa_g_error (self, NULL);
3240 0 0         if (libmarpa_error_code != MARPA_ERR_NONE)
3241             {
3242 0           croak ("Problem in g->rule_rank(%d): %s",
3243             rule_id, xs_g_error (g_wrapper));
3244             }
3245             }
3246 0           XSRETURN_IV (gp_result);
3247             }
3248              
3249             void
3250             rule_rank_set( g_wrapper, rule_id, rank )
3251             G_Wrapper *g_wrapper;
3252             Marpa_Rule_ID rule_id;
3253             Marpa_Rank rank;
3254             PPCODE:
3255             {
3256 35595           Marpa_Grammar self = g_wrapper->g;
3257 35595           int gp_result = marpa_g_rule_rank_set(self, rule_id, rank);
3258 35595 50         if (gp_result == -2 && g_wrapper->throw)
    0          
3259             {
3260 0           const int libmarpa_error_code = marpa_g_error (self, NULL);
3261 0 0         if (libmarpa_error_code != MARPA_ERR_NONE)
3262 0           croak ("Problem in g->rule_rank_set(%d, %d): %s",
3263             rule_id, rank, xs_g_error (g_wrapper));
3264             }
3265 35595           XSRETURN_IV (gp_result);
3266             }
3267              
3268             void
3269             symbol_rank( g_wrapper, symbol_id )
3270             G_Wrapper *g_wrapper;
3271             Marpa_Symbol_ID symbol_id;
3272             PPCODE:
3273             {
3274 0           Marpa_Grammar self = g_wrapper->g;
3275 0           int gp_result = marpa_g_symbol_rank (self, symbol_id);
3276 0 0         if (gp_result == -2 && g_wrapper->throw)
    0          
3277             {
3278 0           const int libmarpa_error_code = marpa_g_error (self, NULL);
3279 0 0         if (libmarpa_error_code != MARPA_ERR_NONE)
3280             {
3281 0           croak ("Problem in g->symbol_rank(%d): %s",
3282             symbol_id, xs_g_error (g_wrapper));
3283             }
3284             }
3285 0           XSRETURN_IV (gp_result);
3286             }
3287              
3288             void
3289             symbol_rank_set( g_wrapper, symbol_id, rank )
3290             G_Wrapper *g_wrapper;
3291             Marpa_Symbol_ID symbol_id;
3292             Marpa_Rank rank;
3293             PPCODE:
3294             {
3295 0           Marpa_Grammar self = g_wrapper->g;
3296 0           int gp_result = marpa_g_symbol_rank_set (self, symbol_id, rank);
3297 0 0         if (gp_result == -2 && g_wrapper->throw)
    0          
3298             {
3299 0           const int libmarpa_error_code = marpa_g_error (self, NULL);
3300 0 0         if (libmarpa_error_code != MARPA_ERR_NONE)
3301 0           croak ("Problem in g->symbol_rank_set(%d, %d): %s",
3302             symbol_id, rank, xs_g_error (g_wrapper));
3303             }
3304 0           XSRETURN_IV (gp_result);
3305             }
3306              
3307             void
3308             throw_set( g_wrapper, boolean )
3309             G_Wrapper *g_wrapper;
3310             int boolean;
3311             PPCODE:
3312             {
3313 75162 50         if (boolean < 0 || boolean > 1)
3314             {
3315             /* Always throws an exception if the arguments are bad */
3316 0           croak ("Problem in g->throw_set(%d): argument must be 0 or 1", boolean);
3317             }
3318 75162           g_wrapper->throw = boolean;
3319 75162 50         XPUSHs (sv_2mortal (newSViv (boolean)));
3320             }
3321              
3322             void
3323             error( g_wrapper )
3324             G_Wrapper *g_wrapper;
3325             PPCODE:
3326             {
3327 25           Marpa_Grammar g = g_wrapper->g;
3328             const char *error_message =
3329             "Problem in $g->error(): Nothing in message buffer";
3330             SV *error_code_sv = &PL_sv_undef;
3331              
3332 25           g_wrapper->libmarpa_error_code =
3333 25           marpa_g_error (g, &g_wrapper->libmarpa_error_string);
3334             /* A new Libmarpa error overrides any thin interface error */
3335 25 100         if (g_wrapper->libmarpa_error_code != MARPA_ERR_NONE)
3336 23           g_wrapper->message_is_marpa_thin_error = 0;
3337 25 50         if (g_wrapper->message_is_marpa_thin_error)
3338             {
3339 0           error_message = g_wrapper->message_buffer;
3340             }
3341             else
3342             {
3343 25           error_message = error_description_generate (g_wrapper);
3344 25           error_code_sv = sv_2mortal (newSViv (g_wrapper->libmarpa_error_code));
3345             }
3346 25 50         if (GIMME == G_ARRAY)
    50          
3347             {
3348 25 50         XPUSHs (error_code_sv);
3349             }
3350 25 50         XPUSHs (sv_2mortal (newSVpv (error_message, 0)));
3351             }
3352              
3353             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::R
3354              
3355             void
3356             new( class, g_sv )
3357             char * class;
3358             SV* g_sv;
3359             PPCODE:
3360             {
3361             SV *sv_to_return;
3362             G_Wrapper *g_wrapper;
3363             Marpa_Recce r;
3364             Marpa_Grammar g;
3365             PERL_UNUSED_ARG(class);
3366              
3367 1316 50         if (!sv_isa (g_sv, "Marpa::R2::Thin::G"))
3368             {
3369 0           croak
3370             ("Problem in Marpa::R2->new(): arg is not of type Marpa::R2::Thin::G");
3371             }
3372 1316 50         SET_G_WRAPPER_FROM_G_SV (g_wrapper, g_sv);
3373 1316           g = g_wrapper->g;
3374 1316           r = marpa_r_new (g);
3375 1316 50         if (!r)
3376             {
3377 0 0         if (!g_wrapper->throw)
3378             {
3379 0           XSRETURN_UNDEF;
3380             }
3381 0           croak ("failure in marpa_r_new(): %s", xs_g_error (g_wrapper));
3382             };
3383              
3384             {
3385 1316           R_Wrapper *r_wrapper = r_wrap (r, g_sv);
3386 1316           sv_to_return = sv_newmortal ();
3387 1316           sv_setref_pv (sv_to_return, recce_c_class_name, (void *) r_wrapper);
3388             }
3389 1316 50         XPUSHs (sv_to_return);
3390             }
3391              
3392             void
3393             DESTROY( r_wrapper )
3394             R_Wrapper *r_wrapper;
3395             PPCODE:
3396             {
3397 1316           Marpa_Recce r = r_unwrap(r_wrapper);
3398 1316           marpa_r_unref (r);
3399             }
3400              
3401             void
3402             ruby_slippers_set( r_wrapper, boolean )
3403             R_Wrapper *r_wrapper;
3404             int boolean;
3405             PPCODE:
3406             {
3407 1203 50         if (boolean < 0 || boolean > 1)
3408             {
3409             /* Always thrown */
3410 0           croak ("Problem in g->ruby_slippers_set(%d): argument must be 0 or 1", boolean);
3411             }
3412 1203           r_wrapper->ruby_slippers = boolean;
3413 1203 50         XPUSHs (sv_2mortal (newSViv (boolean)));
3414             }
3415              
3416             void
3417             start_input( r_wrapper )
3418             R_Wrapper *r_wrapper;
3419             PPCODE:
3420             {
3421 1316           Marpa_Recognizer self = r_wrapper->r;
3422 1316           int gp_result = marpa_r_start_input(self);
3423 1316 50         if ( gp_result == -1 ) { XSRETURN_UNDEF; }
3424 1316 50         if ( gp_result < 0 && r_wrapper->base->throw ) {
    0          
3425 0           croak( "Problem in r->start_input(): %s",
3426             xs_g_error( r_wrapper->base ));
3427             }
3428 1316           r_convert_events(r_wrapper);
3429 1316 50         XPUSHs (sv_2mortal (newSViv (gp_result)));
3430             }
3431              
3432             void
3433             alternative( r_wrapper, symbol_id, value, length )
3434             R_Wrapper *r_wrapper;
3435             Marpa_Symbol_ID symbol_id;
3436             int value;
3437             int length;
3438             PPCODE:
3439             {
3440 16066           struct marpa_r *r = r_wrapper->r;
3441 16066           const G_Wrapper *base = r_wrapper->base;
3442 16066           const int result = marpa_r_alternative (r, symbol_id, value, length);
3443 16066 100         if (result == MARPA_ERR_NONE || r_wrapper->ruby_slippers || !base->throw)
    100          
    50          
3444             {
3445 16066           XSRETURN_IV (result);
3446             }
3447 0           croak ("Problem in r->alternative(): %s", xs_g_error (r_wrapper->base));
3448             }
3449              
3450             void
3451             terminals_expected( r_wrapper )
3452             R_Wrapper *r_wrapper;
3453             PPCODE:
3454             {
3455             int i;
3456 2251           struct marpa_r *r = r_wrapper->r;
3457 2251           const int count =
3458 2251           marpa_r_terminals_expected (r, r_wrapper->terminals_buffer);
3459 2251 50         if (count < 0)
3460             {
3461 0           G_Wrapper* base = r_wrapper->base;
3462 0 0         if (!base->throw) { XSRETURN_UNDEF; }
3463 0           croak ("Problem in r->terminals_expected(): %s",
3464             xs_g_error (base));
3465             }
3466 2251 50         EXTEND (SP, count);
    50          
3467 54684 100         for (i = 0; i < count; i++)
3468             {
3469 52433           PUSHs (sv_2mortal (newSViv (r_wrapper->terminals_buffer[i])));
3470             }
3471             }
3472              
3473             void
3474             progress_item( r_wrapper )
3475             R_Wrapper *r_wrapper;
3476             PPCODE:
3477             {
3478 21707           struct marpa_r *const r = r_wrapper->r;
3479 21707           int position = -1;
3480 21707           Marpa_Earley_Set_ID origin = -1;
3481 21707           Marpa_Rule_ID rule_id = marpa_r_progress_item (r, &position, &origin);
3482 21707 100         if (rule_id == -1)
3483             {
3484 360           XSRETURN_UNDEF;
3485             }
3486 21347 50         if (rule_id < 0 && r_wrapper->base->throw)
    0          
3487             {
3488 0           croak ("Problem in r->progress_item(): %s",
3489             xs_g_error (r_wrapper->base));
3490             }
3491 21347 50         XPUSHs (sv_2mortal (newSViv (rule_id)));
3492 21347 50         XPUSHs (sv_2mortal (newSViv (position)));
3493 21347 50         XPUSHs (sv_2mortal (newSViv (origin)));
3494             }
3495              
3496             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::B
3497              
3498             void
3499             new( class, r_wrapper, ordinal )
3500             char * class;
3501             R_Wrapper *r_wrapper;
3502             Marpa_Earley_Set_ID ordinal;
3503             PPCODE:
3504             {
3505             SV *sv;
3506 1322           Marpa_Recognizer r = r_wrapper->r;
3507             B_Wrapper *b_wrapper;
3508 1322           Marpa_Bocage b = marpa_b_new (r, ordinal);
3509             PERL_UNUSED_ARG(class);
3510              
3511 1322 100         if (!b)
3512             {
3513 20 50         if (!r_wrapper->base->throw) { XSRETURN_UNDEF; }
3514 0           croak ("Problem in b->new(): %s", xs_g_error(r_wrapper->base));
3515             }
3516 1302           Newx (b_wrapper, 1, B_Wrapper);
3517             {
3518 1302           SV* base_sv = r_wrapper->base_sv;
3519             SvREFCNT_inc (base_sv);
3520 1302           b_wrapper->base_sv = base_sv;
3521             }
3522 1302           b_wrapper->base = r_wrapper->base;
3523 1302           b_wrapper->b = b;
3524 1302           sv = sv_newmortal ();
3525 1302           sv_setref_pv (sv, bocage_c_class_name, (void *) b_wrapper);
3526 1302 50         XPUSHs (sv);
3527             }
3528              
3529             void
3530             DESTROY( b_wrapper )
3531             B_Wrapper *b_wrapper;
3532             PPCODE:
3533             {
3534 1302           const Marpa_Bocage b = b_wrapper->b;
3535 1302           SvREFCNT_dec (b_wrapper->base_sv);
3536 1302           marpa_b_unref(b);
3537 1302           Safefree( b_wrapper );
3538             }
3539              
3540             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::O
3541              
3542             void
3543             new( class, b_wrapper )
3544             char * class;
3545             B_Wrapper *b_wrapper;
3546             PPCODE:
3547             {
3548             SV *sv;
3549 1302           Marpa_Bocage b = b_wrapper->b;
3550             O_Wrapper *o_wrapper;
3551 1302           Marpa_Order o = marpa_o_new (b);
3552             PERL_UNUSED_ARG(class);
3553              
3554 1302 50         if (!o)
3555             {
3556 0 0         if (!b_wrapper->base->throw) { XSRETURN_UNDEF; }
3557 0           croak ("Problem in o->new(): %s", xs_g_error(b_wrapper->base));
3558             }
3559 1302           Newx (o_wrapper, 1, O_Wrapper);
3560             {
3561 1302           SV* base_sv = b_wrapper->base_sv;
3562             SvREFCNT_inc (base_sv);
3563 1302           o_wrapper->base_sv = base_sv;
3564             }
3565 1302           o_wrapper->base = b_wrapper->base;
3566 1302           o_wrapper->o = o;
3567 1302           sv = sv_newmortal ();
3568 1302           sv_setref_pv (sv, order_c_class_name, (void *) o_wrapper);
3569 1302 50         XPUSHs (sv);
3570             }
3571              
3572             void
3573             DESTROY( o_wrapper )
3574             O_Wrapper *o_wrapper;
3575             PPCODE:
3576             {
3577 1302           const Marpa_Order o = o_wrapper->o;
3578 1302           SvREFCNT_dec (o_wrapper->base_sv);
3579 1302           marpa_o_unref(o);
3580 1302           Safefree( o_wrapper );
3581             }
3582              
3583             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::T
3584              
3585             void
3586             new( class, o_wrapper )
3587             char * class;
3588             O_Wrapper *o_wrapper;
3589             PPCODE:
3590             {
3591             SV *sv;
3592 1252           Marpa_Order o = o_wrapper->o;
3593             T_Wrapper *t_wrapper;
3594 1252           Marpa_Tree t = marpa_t_new (o);
3595             PERL_UNUSED_ARG(class);
3596              
3597 1252 50         if (!t)
3598             {
3599 0 0         if (!o_wrapper->base->throw) { XSRETURN_UNDEF; }
3600 0           croak ("Problem in t->new(): %s", xs_g_error(o_wrapper->base));
3601             }
3602 1252           Newx (t_wrapper, 1, T_Wrapper);
3603             {
3604 1252           SV* base_sv = o_wrapper->base_sv;
3605             SvREFCNT_inc (base_sv);
3606 1252           t_wrapper->base_sv = base_sv;
3607             }
3608 1252           t_wrapper->base = o_wrapper->base;
3609 1252           t_wrapper->t = t;
3610 1252           sv = sv_newmortal ();
3611 1252           sv_setref_pv (sv, tree_c_class_name, (void *) t_wrapper);
3612 1252 50         XPUSHs (sv);
3613             }
3614              
3615             void
3616             DESTROY( t_wrapper )
3617             T_Wrapper *t_wrapper;
3618             PPCODE:
3619             {
3620 1252           const Marpa_Tree t = t_wrapper->t;
3621 1252           SvREFCNT_dec (t_wrapper->base_sv);
3622 1252           marpa_t_unref(t);
3623 1252           Safefree( t_wrapper );
3624             }
3625              
3626             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::V
3627              
3628             void
3629             new( class, t_wrapper )
3630             char * class;
3631             T_Wrapper *t_wrapper;
3632             PPCODE:
3633             {
3634             SV *sv;
3635 8094           Marpa_Tree t = t_wrapper->t;
3636             V_Wrapper *v_wrapper;
3637 8094           Marpa_Value v = marpa_v_new (t);
3638             PERL_UNUSED_ARG(class);
3639              
3640 8094 50         if (!v)
3641             {
3642 0 0         if (!t_wrapper->base->throw)
3643             {
3644 0           XSRETURN_UNDEF;
3645             }
3646 0           croak ("Problem in v->new(): %s", xs_g_error (t_wrapper->base));
3647             }
3648 8094           Newx (v_wrapper, 1, V_Wrapper);
3649             {
3650 8094           SV *base_sv = t_wrapper->base_sv;
3651             SvREFCNT_inc (base_sv);
3652 8094           v_wrapper->base_sv = base_sv;
3653             }
3654 8094           v_wrapper->base = t_wrapper->base;
3655 8094           v_wrapper->v = v;
3656 8094           v_wrapper->event_queue = newAV ();
3657 8094           v_wrapper->token_values = newAV ();
3658 8094           av_fill(v_wrapper->token_values , TOKEN_VALUE_IS_LITERAL);
3659 8094           v_wrapper->stack = NULL;
3660 8094           v_wrapper->mode = MARPA_XS_V_MODE_IS_INITIAL;
3661 8094           v_wrapper->result = 0;
3662 8094           v_wrapper->trace_values = 0;
3663              
3664 8094           v_wrapper->constants = newAV ();
3665             /* Reserve position 0 */
3666 8094           av_push (v_wrapper->constants, &PL_sv_undef);
3667              
3668 8094           v_wrapper->rule_semantics = newAV ();
3669 8094           v_wrapper->token_semantics = newAV ();
3670 8094           v_wrapper->nulling_semantics = newAV ();
3671 8094           v_wrapper->slr = NULL;
3672 8094           sv = sv_newmortal ();
3673 8094           sv_setref_pv (sv, value_c_class_name, (void *) v_wrapper);
3674 8094 50         XPUSHs (sv);
3675             }
3676              
3677             void
3678             DESTROY( v_wrapper )
3679             V_Wrapper *v_wrapper;
3680             PPCODE:
3681             {
3682 8094           const Marpa_Value v = v_wrapper->v;
3683 8094           SvREFCNT_dec (v_wrapper->base_sv);
3684 8094           SvREFCNT_dec (v_wrapper->event_queue);
3685 8094           SvREFCNT_dec (v_wrapper->constants);
3686 8094           SvREFCNT_dec (v_wrapper->rule_semantics);
3687 8094           SvREFCNT_dec (v_wrapper->token_semantics);
3688 8094           SvREFCNT_dec (v_wrapper->nulling_semantics);
3689 8094 100         if (v_wrapper->slr) {
3690             SvREFCNT_dec (v_wrapper->slr);
3691             }
3692 8094 100         if (v_wrapper->stack)
3693             {
3694             SvREFCNT_dec (v_wrapper->stack);
3695             }
3696 8094           SvREFCNT_dec (v_wrapper->token_values);
3697 8094           marpa_v_unref (v);
3698 8094           Safefree (v_wrapper);
3699             }
3700              
3701             void
3702             trace_values( v_wrapper, level )
3703             V_Wrapper *v_wrapper;
3704             IV level;
3705             PPCODE:
3706             {
3707 7972           IV old_level = v_wrapper->trace_values;
3708 7972           v_wrapper->trace_values = level;
3709             {
3710             AV *event;
3711             SV *event_data[3];
3712 7972           event_data[0] = newSVpvs ("valuator trace level");
3713 7972           event_data[1] = newSViv (old_level);
3714 7972           event_data[2] = newSViv (level);
3715 7972           event = av_make (Dim (event_data), event_data);
3716 7972           av_push (v_wrapper->event_queue, newRV_noinc ((SV *) event));
3717             }
3718 7972           XSRETURN_IV (old_level);
3719             }
3720              
3721             void
3722             token_value_set( v_wrapper, token_ix, token_value )
3723             V_Wrapper *v_wrapper;
3724             int token_ix;
3725             SV* token_value;
3726             PPCODE:
3727             {
3728 12920 50         if (token_ix <= TOKEN_VALUE_IS_LITERAL)
3729             {
3730 0           croak
3731             ("Problem in v->token_value_set(): token_value cannot be set for index %ld",
3732             (long) token_ix);
3733             }
3734             SvREFCNT_inc (token_value);
3735 12920 50         if (!av_store (v_wrapper->token_values, (I32)token_ix, token_value))
3736             {
3737             SvREFCNT_dec (token_value);
3738             }
3739             }
3740              
3741             void
3742             slr_set( v_wrapper, slr )
3743             V_Wrapper *v_wrapper;
3744             Scanless_R *slr;
3745             PPCODE:
3746             {
3747 5691 50         if (v_wrapper->slr)
3748             {
3749 0           croak ("Problem in v->slr_set(): The SLR is already set");
3750             }
3751             SvREFCNT_inc (slr);
3752 5691           v_wrapper->slr = slr;
3753              
3754 5691           # Throw away the current token values hash
3755             SvREFCNT_dec (v_wrapper->token_values);
3756 5691            
3757             # Take a reference to the one in the SLR
3758             v_wrapper->token_values = slr->token_values;
3759             SvREFCNT_inc (v_wrapper->token_values);
3760             }
3761              
3762             void
3763             event( v_wrapper )
3764             V_Wrapper *v_wrapper;
3765             PPCODE:
3766             {
3767 114           SV* event = av_shift(v_wrapper->event_queue);
3768 114 50         XPUSHs (sv_2mortal (event));
3769             }
3770              
3771             void
3772             step( v_wrapper )
3773             V_Wrapper *v_wrapper;
3774             PPCODE:
3775             {
3776 8228           const Marpa_Value v = v_wrapper->v;
3777             Marpa_Symbol_ID token_id;
3778             Marpa_Rule_ID rule_id;
3779             const char *result_string;
3780 8228           const Marpa_Step_Type step_type = marpa_v_step (v);
3781              
3782 8228 100         if (v_wrapper->mode == MARPA_XS_V_MODE_IS_INITIAL) {
3783 122           v_wrapper->mode = MARPA_XS_V_MODE_IS_RAW;
3784             }
3785 8228 50         if (v_wrapper->mode != MARPA_XS_V_MODE_IS_RAW) {
3786 0 0         if (v_wrapper->stack) {
3787 0           croak ("Problem in v->step(): Cannot call when valuator is in 'stack' mode");
3788             }
3789             }
3790 8228           av_clear (v_wrapper->event_queue);
3791 8228 100         if (step_type == MARPA_STEP_INACTIVE)
3792             {
3793 122           XSRETURN_EMPTY;
3794             }
3795 8106 50         if (step_type < 0)
3796             {
3797 0           const char *error_message = xs_g_error (v_wrapper->base);
3798 0 0         if (v_wrapper->base->throw)
3799             {
3800 0           croak ("Problem in v->step(): %s", error_message);
3801             }
3802 0 0         XPUSHs (sv_2mortal
3803             (newSVpvf ("Problem in v->step(): %s", error_message)));
3804 0           XSRETURN (1);
3805             }
3806             result_string = step_type_to_string (step_type);
3807 8106 50         if (!result_string)
3808             {
3809 0           char *error_message =
3810             form ("Problem in v->step(): unknown step type %d", step_type);
3811 0           set_error_from_string (v_wrapper->base, savepv(error_message));
3812 0 0         if (v_wrapper->base->throw)
3813             {
3814 0           croak ("%s", error_message);
3815             }
3816 0 0         XPUSHs (sv_2mortal (newSVpv (error_message, 0)));
3817 0           XSRETURN (1);
3818             }
3819 8106 50         XPUSHs (sv_2mortal (newSVpv (result_string, 0)));
3820 8106 100         if (step_type == MARPA_STEP_TOKEN)
3821             {
3822 2660           token_id = marpa_v_token (v);
3823 2660 50         XPUSHs (sv_2mortal (newSViv (token_id)));
3824 2660 50         XPUSHs (sv_2mortal (newSViv (marpa_v_token_value (v))));
3825 2660 50         XPUSHs (sv_2mortal (newSViv (marpa_v_result (v))));
3826             }
3827 8106 100         if (step_type == MARPA_STEP_NULLING_SYMBOL)
3828             {
3829 638           token_id = marpa_v_token (v);
3830 638 50         XPUSHs (sv_2mortal (newSViv (token_id)));
3831 638 50         XPUSHs (sv_2mortal (newSViv (marpa_v_result (v))));
3832             }
3833 8106 100         if (step_type == MARPA_STEP_RULE)
3834             {
3835 4808           rule_id = marpa_v_rule (v);
3836 4808 50         XPUSHs (sv_2mortal (newSViv (rule_id)));
3837 4808 50         XPUSHs (sv_2mortal (newSViv (marpa_v_arg_0 (v))));
3838 4808 50         XPUSHs (sv_2mortal (newSViv (marpa_v_arg_n (v))));
3839             }
3840             }
3841              
3842             void
3843             stack_mode_set( v_wrapper )
3844             V_Wrapper *v_wrapper;
3845             PPCODE:
3846             {
3847 7972           Marpa_Grammar g = v_wrapper->base->g;
3848 7972 50         if (v_wrapper->mode != MARPA_XS_V_MODE_IS_INITIAL)
3849             {
3850 0 0         if (v_wrapper->stack)
3851             {
3852 0           croak ("Problem in v->stack_mode_set(): Cannot re-set stack mode");
3853             }
3854             }
3855 7972 50         if (v_create_stack (v_wrapper) == -1)
3856             {
3857 0           croak ("Problem in v->stack_mode_set(): Could not create stack");
3858             }
3859              
3860              
3861             {
3862             int ix;
3863             IV ops[3];
3864 7972           const int highest_rule_id = marpa_g_highest_rule_id (g);
3865 7972           AV *av = v_wrapper->rule_semantics;
3866 7972           av_extend (av, highest_rule_id);
3867 7972           ops[0] = MARPA_OP_PUSH_VALUES;
3868 7972           ops[1] = MARPA_OP_CALLBACK;
3869 7972           ops[2] = 0;
3870 97651 100         for (ix = 0; ix <= highest_rule_id; ix++)
3871             {
3872 89679           SV **p_sv = av_fetch (av, ix, 1);
3873 89679 50         if (!p_sv)
3874             {
3875 0           croak
3876             ("Internal error in v->stack_mode_set(): av_fetch(%p,%ld,1) failed",
3877             (void *) av, (long) ix);
3878             }
3879 89679           sv_setpvn (*p_sv, (char *) ops, Dim(ops)*sizeof (ops[0]));
3880             }
3881             }
3882              
3883             { /* Set the default nulling symbol semantics */
3884             int ix;
3885             IV ops[2];
3886 7972           const int highest_symbol_id = marpa_g_highest_symbol_id (g);
3887 7972           AV *av = v_wrapper->nulling_semantics;
3888 7972           av_extend (av, highest_symbol_id);
3889 7972           ops[0] = MARPA_OP_RESULT_IS_UNDEF;
3890 7972           ops[1] = 0;
3891 104128 100         for (ix = 0; ix <= highest_symbol_id; ix++)
3892             {
3893 96156           SV **p_sv = av_fetch (av, ix, 1);
3894 96156 50         if (!p_sv)
3895             {
3896 0           croak
3897             ("Internal error in v->stack_mode_set(): av_fetch(%p,%ld,1) failed",
3898             (void *) av, (long) ix);
3899             }
3900 96156           sv_setpvn (*p_sv, (char *) ops, Dim(ops) *sizeof (ops[0]));
3901             }
3902             }
3903              
3904             { /* Set the default token semantics */
3905             int ix;
3906             IV ops[2];
3907 7972           const int highest_symbol_id = marpa_g_highest_symbol_id (g);
3908 7972           AV *av = v_wrapper->token_semantics;
3909 7972           av_extend (av, highest_symbol_id);
3910 7972           ops[0] = MARPA_OP_RESULT_IS_TOKEN_VALUE;
3911 7972           ops[1] = 0;
3912 104128 100         for (ix = 0; ix <= highest_symbol_id; ix++)
3913             {
3914 96156           SV **p_sv = av_fetch (av, ix, 1);
3915 96156 50         if (!p_sv)
3916             {
3917 0           croak
3918             ("Internal error in v->stack_mode_set(): av_fetch(%p,%ld,1) failed",
3919             (void *) av, (long) ix);
3920             }
3921 96156           sv_setpvn (*p_sv, (char *) ops, Dim(ops)*sizeof (ops[0]));
3922             }
3923             }
3924              
3925 7972           XSRETURN_YES;
3926             }
3927              
3928             void
3929             rule_register( v_wrapper, rule_id, ... )
3930             V_Wrapper *v_wrapper;
3931             Marpa_Rule_ID rule_id;
3932             PPCODE:
3933             {
3934             /* OP Count is args less two */
3935 89679           const STRLEN op_count = items - 2;
3936             STRLEN op_ix;
3937             STRLEN dummy;
3938             IV *ops;
3939             SV *ops_sv;
3940 89679           AV *rule_semantics = v_wrapper->rule_semantics;
3941              
3942 89679 50         if (!rule_semantics)
3943             {
3944 0           croak ("Problem in v->rule_register(): valuator is not in stack mode");
3945             }
3946              
3947             /* Leave room for final 0 */
3948 89679           ops_sv = newSV ((op_count+1) * sizeof (ops[0]));
3949              
3950 89679           SvPOK_on (ops_sv);
3951 89679 50         ops = (IV *) SvPV (ops_sv, dummy);
3952 490353 100         for (op_ix = 0; op_ix < op_count; op_ix++)
3953             {
3954 400674 50         ops[op_ix] = SvUV (ST (op_ix+2));
3955             }
3956 89679           ops[op_ix] = 0;
3957 89679 50         if (!av_store (rule_semantics, (I32) rule_id, ops_sv)) {
3958             SvREFCNT_dec(ops_sv);
3959             }
3960             }
3961              
3962             void
3963             token_register( v_wrapper, token_id, ... )
3964             V_Wrapper *v_wrapper;
3965             Marpa_Symbol_ID token_id;
3966             PPCODE:
3967             {
3968             /* OP Count is args less two */
3969 96156           const STRLEN op_count = items - 2;
3970             STRLEN op_ix;
3971             STRLEN dummy;
3972             IV *ops;
3973             SV *ops_sv;
3974 96156           AV *token_semantics = v_wrapper->token_semantics;
3975              
3976 96156 50         if (!token_semantics)
3977             {
3978 0           croak ("Problem in v->token_register(): valuator is not in stack mode");
3979             }
3980              
3981             /* Leave room for final 0 */
3982 96156           ops_sv = newSV ((op_count+1) * sizeof (ops[0]));
3983              
3984 96156           SvPOK_on (ops_sv);
3985 96156 50         ops = (IV *) SvPV (ops_sv, dummy);
3986 212839 100         for (op_ix = 0; op_ix < op_count; op_ix++)
3987             {
3988 116683 50         ops[op_ix] = SvIV (ST (op_ix+2));
3989             }
3990 96156           ops[op_ix] = 0;
3991 96156 50         if (!av_store (token_semantics, (I32) token_id, ops_sv)) {
3992             SvREFCNT_dec(ops_sv);
3993             }
3994             }
3995              
3996             void
3997             nulling_symbol_register( v_wrapper, symbol_id, ... )
3998             V_Wrapper *v_wrapper;
3999             Marpa_Symbol_ID symbol_id;
4000             PPCODE:
4001             {
4002             /* OP Count is args less two */
4003 7371           const STRLEN op_count = items - 2;
4004             STRLEN op_ix;
4005             STRLEN dummy;
4006             IV *ops;
4007             SV *ops_sv;
4008 7371           AV *nulling_semantics = v_wrapper->nulling_semantics;
4009              
4010 7371 50         if (!nulling_semantics)
4011             {
4012 0           croak ("Problem in v->nulling_symbol_register(): valuator is not in stack mode");
4013             }
4014              
4015             /* Leave room for final 0 */
4016 7371           ops_sv = newSV ((op_count+1) * sizeof (ops[0]));
4017              
4018 7371           SvPOK_on (ops_sv);
4019 7371 50         ops = (IV *) SvPV (ops_sv, dummy);
4020 21790 100         for (op_ix = 0; op_ix < op_count; op_ix++)
4021             {
4022 14419 50         ops[op_ix] = SvIV (ST (op_ix+2));
4023             }
4024 7371           ops[op_ix] = 0;
4025 7371 50         if (!av_store (nulling_semantics, (I32) symbol_id, ops_sv)) {
4026             SvREFCNT_dec(ops_sv);
4027             }
4028             }
4029              
4030             void
4031             constant_register( v_wrapper, sv )
4032             V_Wrapper *v_wrapper;
4033             SV* sv;
4034             PPCODE:
4035             {
4036 29416           AV *constants = v_wrapper->constants;
4037              
4038 29416 50         if (!constants)
4039             {
4040 0           croak
4041             ("Problem in v->constant_register(): valuator is not in stack mode");
4042             }
4043 29416 50         if (SvTAINTED(sv)) {
    0          
4044 0           croak
4045             ("Problem in v->constant_register(): Attempt to register a tainted constant with Marpa::R2\n"
4046             "Marpa::R2 is insecure for use with tainted data\n");
4047             }
4048              
4049 29416           av_push (constants, SvREFCNT_inc_simple_NN (sv));
4050 29416           XSRETURN_IV (av_len (constants));
4051             }
4052              
4053             void
4054             highest_index( v_wrapper )
4055             V_Wrapper *v_wrapper;
4056             PPCODE:
4057             {
4058 0           AV* stack = v_wrapper->stack;
4059 0 0         IV length = stack ? av_len(stack) : -1;
4060 0           XSRETURN_IV(length);
4061             }
4062              
4063             void
4064             absolute( v_wrapper, index )
4065             V_Wrapper *v_wrapper;
4066             IV index;
4067             PPCODE:
4068             {
4069             SV** p_sv;
4070 7962           AV* stack = v_wrapper->stack;
4071 7962 50         if (!stack) { XSRETURN_UNDEF; }
4072 7962           p_sv = av_fetch(stack, index, 0);
4073 7962 100         if (!p_sv) { XSRETURN_UNDEF; }
4074 6232 50         XPUSHs (sv_mortalcopy(*p_sv));
4075             }
4076              
4077             void
4078             relative( v_wrapper, index )
4079             V_Wrapper *v_wrapper;
4080             IV index;
4081             PPCODE:
4082             {
4083             SV** p_sv;
4084 0           AV* stack = v_wrapper->stack;
4085 0 0         if (!stack) { XSRETURN_UNDEF; }
4086 0           p_sv = av_fetch(stack, index+v_wrapper->result, 0);
4087 0 0         if (!p_sv) { XSRETURN_UNDEF; }
4088 0 0         XPUSHs (sv_mortalcopy(*p_sv));
4089             }
4090              
4091             void
4092             result_set( v_wrapper, sv )
4093             V_Wrapper *v_wrapper;
4094             SV* sv;
4095             PPCODE:
4096             {
4097             IV result_ix;
4098             SV **p_stored_sv;
4099 128453           AV *stack = v_wrapper->stack;
4100 128453 50         if (!stack)
4101             {
4102 0           croak ("Problem in v->result_set(): valuator is not in stack mode");
4103             }
4104 128453           result_ix = v_wrapper->result;
4105 128453           av_fill(stack, result_ix);
4106              
4107             SvREFCNT_inc (sv);
4108 128453           p_stored_sv = av_store (stack, result_ix, sv);
4109 128453 50         if (!p_stored_sv)
4110             {
4111             SvREFCNT_dec (sv);
4112             }
4113             }
4114              
4115             void
4116             stack_step( v_wrapper )
4117             V_Wrapper *v_wrapper;
4118             PPCODE:
4119             {
4120              
4121 136504           av_clear (v_wrapper->event_queue);
4122              
4123 136504 50         if (v_wrapper->mode != MARPA_XS_V_MODE_IS_STACK)
4124             {
4125 0 0         if (v_wrapper->stack)
4126             {
4127 136504           croak
4128             ("Problem in v->stack_step(): Cannot call unless valuator is in 'stack' mode");
4129             }
4130             }
4131              
4132             while (1)
4133             {
4134 275446           Marpa_Step_Type step_type = marpa_v_step (v_wrapper->v);
4135 275446           switch (step_type)
4136             {
4137             case MARPA_STEP_INACTIVE:
4138 7962           XSRETURN_EMPTY;
4139              
4140             /* NOTREACHED */
4141             case MARPA_STEP_RULE:
4142             case MARPA_STEP_NULLING_SYMBOL:
4143             case MARPA_STEP_TOKEN:
4144             {
4145             int ix;
4146             SV *stack_results[3];
4147 267435           int stack_offset = v_do_stack_ops (v_wrapper, stack_results);
4148 267435 100         if (stack_offset < 0)
4149             {
4150             goto NEXT_STEP;
4151             }
4152 512594 100         for (ix = 0; ix < stack_offset; ix++)
4153             {
4154 384131 50         XPUSHs (stack_results[ix]);
4155             }
4156 128463           XSRETURN (stack_offset);
4157             }
4158             /* NOTREACHED */
4159              
4160             default:
4161             /* Default is just return the step_type string and let the upper
4162             * layer deal with it.
4163             */
4164             {
4165             const char *step_type_string = step_type_to_string (step_type);
4166 49 50         if (!step_type_string)
4167             {
4168             step_type_string = "Unknown";
4169             }
4170 49 50         XPUSHs (sv_2mortal (newSVpv (step_type_string, 0)));
4171 49           XSRETURN (1);
4172             }
4173             }
4174              
4175             NEXT_STEP:;
4176 138972 100         if (v_wrapper->trace_values)
4177             {
4178 30           XSRETURN_PV ("trace");
4179             }
4180             }
4181             }
4182              
4183             void
4184             step_type( v_wrapper )
4185             V_Wrapper *v_wrapper;
4186             PPCODE:
4187             {
4188 12           const Marpa_Value v = v_wrapper->v;
4189 12           const Marpa_Step_Type status = marpa_v_step_type (v);
4190             const char *result_string;
4191             result_string = step_type_to_string (status);
4192 12 50         if (!result_string)
4193             {
4194 0           result_string =
4195             form ("Problem in v->step(): unknown step type %d", status);
4196 0           set_error_from_string (v_wrapper->base, savepv (result_string));
4197 0 0         if (v_wrapper->base->throw)
4198             {
4199 0           croak ("%s", result_string);
4200             }
4201             }
4202 12 50         XPUSHs (sv_2mortal (newSVpv (result_string, 0)));
4203             }
4204              
4205             void
4206             location( v_wrapper )
4207             V_Wrapper *v_wrapper;
4208             PPCODE:
4209             {
4210 6385           const Marpa_Value v = v_wrapper->v;
4211 6385           const Marpa_Step_Type status = marpa_v_step_type (v);
4212 6385 100         if (status == MARPA_STEP_RULE)
4213             {
4214 4725 50         XPUSHs (sv_2mortal (newSViv (marpa_v_rule_start_es_id (v))));
4215 4725 50         XPUSHs (sv_2mortal (newSViv (marpa_v_es_id (v))));
4216 4725           XSRETURN (2);
4217             }
4218 1660 50         if (status == MARPA_STEP_NULLING_SYMBOL)
4219             {
4220 0 0         XPUSHs (sv_2mortal (newSViv (marpa_v_token_start_es_id (v))));
4221 0 0         XPUSHs (sv_2mortal (newSViv (marpa_v_es_id (v))));
4222 0           XSRETURN (2);
4223             }
4224 1660 50         if (status == MARPA_STEP_TOKEN)
4225             {
4226 1660 50         XPUSHs (sv_2mortal (newSViv (marpa_v_token_start_es_id (v))));
4227 1660 50         XPUSHs (sv_2mortal (newSViv (marpa_v_es_id (v))));
4228 1660           XSRETURN (2);
4229             }
4230 0           XSRETURN_EMPTY;
4231             }
4232              
4233             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::G
4234              
4235             void
4236             _marpa_g_nsy_is_nulling( g_wrapper, nsy_id )
4237             G_Wrapper *g_wrapper;
4238             Marpa_NSY_ID nsy_id;
4239             PPCODE:
4240             {
4241 3202           Marpa_Grammar g = g_wrapper->g;
4242 3202           int result = _marpa_g_nsy_is_nulling (g, nsy_id);
4243 3202 50         if (result < 0)
4244             {
4245 0           croak ("Problem in g->_marpa_g_nsy_is_nulling(%d): %s", nsy_id,
4246             xs_g_error (g_wrapper));
4247             }
4248 3202 100         if (result)
4249 339           XSRETURN_YES;
4250 2863           XSRETURN_NO;
4251             }
4252              
4253             void
4254             _marpa_g_nsy_is_start( g_wrapper, nsy_id )
4255             G_Wrapper *g_wrapper;
4256             Marpa_NSY_ID nsy_id;
4257             PPCODE:
4258             {
4259 3629           Marpa_Grammar g = g_wrapper->g;
4260 3629           int result = _marpa_g_nsy_is_start (g, nsy_id);
4261 3629 50         if (result < 0)
4262             {
4263 0           croak ("Invalid nsy %d", nsy_id);
4264             }
4265 3629 100         if (result)
4266 90           XSRETURN_YES;
4267 3539           XSRETURN_NO;
4268             }
4269              
4270             # Marpa_Symbol_ID
4271             void
4272             _marpa_g_source_xsy( g_wrapper, symbol_id )
4273             G_Wrapper *g_wrapper;
4274             Marpa_Symbol_ID symbol_id;
4275             PPCODE:
4276             {
4277 3963           Marpa_Grammar g = g_wrapper->g;
4278 3963           Marpa_Symbol_ID source_xsy = _marpa_g_source_xsy (g, symbol_id);
4279 3963 50         if (source_xsy < -1)
4280             {
4281 0           croak ("problem with g->_marpa_g_source_xsy: %s", xs_g_error (g_wrapper));
4282             }
4283 3963 50         if (source_xsy < 0)
4284             {
4285 0           XSRETURN_UNDEF;
4286             }
4287 3963 50         XPUSHs (sv_2mortal (newSViv (source_xsy)));
4288             }
4289              
4290             # Marpa_Rule_ID
4291             void
4292             _marpa_g_nsy_lhs_xrl( g_wrapper, nsy_id )
4293             G_Wrapper *g_wrapper;
4294             Marpa_NSY_ID nsy_id;
4295             PPCODE:
4296             {
4297 3539           Marpa_Grammar g = g_wrapper->g;
4298 3539           Marpa_Rule_ID rule_id = _marpa_g_nsy_lhs_xrl (g, nsy_id);
4299 3539 50         if (rule_id < -1)
4300             {
4301 0           croak ("problem with g->_marpa_g_nsy_lhs_xrl: %s",
4302             xs_g_error (g_wrapper));
4303             }
4304 3539 100         if (rule_id < 0)
4305             {
4306 2213           XSRETURN_UNDEF;
4307             }
4308 1326 50         XPUSHs (sv_2mortal (newSViv (rule_id)));
4309             }
4310              
4311             # Marpa_Rule_ID
4312             void
4313             _marpa_g_nsy_xrl_offset( g_wrapper, nsy_id )
4314             G_Wrapper *g_wrapper;
4315             Marpa_NSY_ID nsy_id;
4316             PPCODE:
4317             {
4318 3506           Marpa_Grammar g = g_wrapper->g;
4319 3506           int offset = _marpa_g_nsy_xrl_offset (g, nsy_id);
4320 3506 100         if (offset == -1)
4321             {
4322 2213           XSRETURN_UNDEF;
4323             }
4324 1293 50         if (offset < 0)
4325             {
4326 0           croak ("problem with g->_marpa_g_nsy_xrl_offset: %s",
4327             xs_g_error (g_wrapper));
4328             }
4329 1293 50         XPUSHs (sv_2mortal (newSViv (offset)));
4330             }
4331              
4332             # int
4333             void
4334             _marpa_g_virtual_start( g_wrapper, irl_id )
4335             G_Wrapper *g_wrapper;
4336             Marpa_IRL_ID irl_id;
4337             PPCODE:
4338             {
4339 0           Marpa_Grammar g = g_wrapper->g;
4340 0           int result = _marpa_g_virtual_start (g, irl_id);
4341 0 0         if (result == -1)
4342             {
4343 0           XSRETURN_UNDEF;
4344             }
4345 0 0         if (result < 0)
4346             {
4347 0           croak ("Problem in g->_marpa_g_virtual_start(%d): %s", irl_id,
4348             xs_g_error (g_wrapper));
4349             }
4350 0 0         XPUSHs( sv_2mortal( newSViv(result) ) );
4351             }
4352              
4353             # int
4354             void
4355             _marpa_g_virtual_end( g_wrapper, irl_id )
4356             G_Wrapper *g_wrapper;
4357             Marpa_IRL_ID irl_id;
4358             PPCODE:
4359             {
4360 0           Marpa_Grammar g = g_wrapper->g;
4361 0           int result = _marpa_g_virtual_end (g, irl_id);
4362 0 0         if (result <= -2)
4363             {
4364 0           croak ("Problem in g->_marpa_g_virtual_end(%d): %s", irl_id,
4365             xs_g_error (g_wrapper));
4366             }
4367 0 0         XPUSHs (sv_2mortal (newSViv (result)));
4368             }
4369              
4370             void
4371             _marpa_g_rule_is_used( g_wrapper, rule_id )
4372             G_Wrapper *g_wrapper;
4373             Marpa_Rule_ID rule_id;
4374             PPCODE:
4375             {
4376 135           Marpa_Grammar g = g_wrapper->g;
4377 135           int result = _marpa_g_rule_is_used (g, rule_id);
4378 135 50         if (result < 0)
4379             {
4380 0           croak ("Problem in g->_marpa_g_rule_is_used(%d): %s", rule_id,
4381             xs_g_error (g_wrapper));
4382             }
4383 135 100         if (result)
4384 117           XSRETURN_YES;
4385 18           XSRETURN_NO;
4386             }
4387              
4388             void
4389             _marpa_g_irl_is_virtual_lhs( g_wrapper, irl_id )
4390             G_Wrapper *g_wrapper;
4391             Marpa_IRL_ID irl_id;
4392             PPCODE:
4393             {
4394 32           Marpa_Grammar g = g_wrapper->g;
4395 32           int result = _marpa_g_irl_is_virtual_lhs (g, irl_id);
4396 32 50         if (result < 0)
4397             {
4398 0           croak ("Problem in g->_marpa_g_irl_is_virtual_lhs(%d): %s", irl_id,
4399             xs_g_error (g_wrapper));
4400             }
4401 32 100         if (result)
4402 2           XSRETURN_YES;
4403 30           XSRETURN_NO;
4404             }
4405              
4406             void
4407             _marpa_g_irl_is_virtual_rhs( g_wrapper, irl_id )
4408             G_Wrapper *g_wrapper;
4409             Marpa_IRL_ID irl_id;
4410             PPCODE:
4411             {
4412 32           Marpa_Grammar g = g_wrapper->g;
4413 32           int result = _marpa_g_irl_is_virtual_rhs (g, irl_id);
4414 32 50         if (result < 0)
4415             {
4416 0           croak ("Problem in g->_marpa_g_irl_is_virtual_rhs(%d): %s", irl_id,
4417             xs_g_error (g_wrapper));
4418             }
4419 32 50         if (result)
4420 0           XSRETURN_YES;
4421 32           XSRETURN_NO;
4422             }
4423              
4424             # Marpa_Rule_ID
4425             void
4426             _marpa_g_real_symbol_count( g_wrapper, rule_id )
4427             G_Wrapper *g_wrapper;
4428             Marpa_Rule_ID rule_id;
4429             PPCODE:
4430             {
4431 2           Marpa_Grammar g = g_wrapper->g;
4432 2           int result = _marpa_g_real_symbol_count(g, rule_id);
4433 2 50         if (result <= -2)
4434             {
4435 0           croak ("Problem in g->_marpa_g_real_symbol_count(%d): %s", rule_id,
4436             xs_g_error (g_wrapper));
4437             }
4438 2 50         if (result == -1)
4439             {
4440 0           XSRETURN_UNDEF;
4441             }
4442 2 50         XPUSHs (sv_2mortal (newSViv (result)));
4443             }
4444              
4445             # Marpa_Rule_ID
4446             void
4447             _marpa_g_source_xrl ( g_wrapper, irl_id )
4448             G_Wrapper *g_wrapper;
4449             Marpa_IRL_ID irl_id;
4450             PPCODE:
4451             {
4452 661           Marpa_Grammar g = g_wrapper->g;
4453 661           int result = _marpa_g_source_xrl (g, irl_id);
4454 661 50         if (result <= -2)
4455             {
4456 0           croak ("Problem in g->_marpa_g_source_xrl (%d): %s", irl_id,
4457             xs_g_error (g_wrapper));
4458             }
4459 661 50         if (result == -1)
4460             {
4461 0           XSRETURN_UNDEF;
4462             }
4463 661 50         XPUSHs (sv_2mortal (newSViv (result)));
4464             }
4465              
4466             # Marpa_Rule_ID
4467             void
4468             _marpa_g_irl_semantic_equivalent( g_wrapper, irl_id )
4469             G_Wrapper *g_wrapper;
4470             Marpa_IRL_ID irl_id;
4471             PPCODE:
4472             {
4473 0           Marpa_Grammar g = g_wrapper->g;
4474 0           int result = _marpa_g_irl_semantic_equivalent (g, irl_id);
4475 0 0         if (result <= -2)
4476             {
4477 0           croak ("Problem in g->_marpa_g_irl_semantic_equivalent(%d): %s", irl_id,
4478             xs_g_error (g_wrapper));
4479             }
4480 0 0         if (result == -1)
4481             {
4482 0           XSRETURN_UNDEF;
4483             }
4484 0 0         XPUSHs (sv_2mortal (newSViv (result)));
4485             }
4486              
4487             # int
4488             void
4489             _marpa_g_ahm_count( g_wrapper )
4490             G_Wrapper *g_wrapper;
4491             PPCODE:
4492             {
4493 14           Marpa_Grammar g = g_wrapper->g;
4494 14           int result = _marpa_g_ahm_count (g);
4495 14 50         if (result <= -2)
4496             {
4497 0           croak ("Problem in g->_marpa_g_ahm_count(): %s", xs_g_error (g_wrapper));
4498             }
4499 14 50         if (result < 0)
4500             {
4501 0           XSRETURN_UNDEF;
4502             }
4503 14 50         XPUSHs (sv_2mortal (newSViv (result)));
4504             }
4505              
4506             # int
4507             void
4508             _marpa_g_irl_count( g_wrapper )
4509             G_Wrapper *g_wrapper;
4510             PPCODE:
4511             {
4512 3           Marpa_Grammar g = g_wrapper->g;
4513 3           int result = _marpa_g_irl_count (g);
4514 3 50         if (result < -1)
4515             {
4516 0           croak ("Problem in g->_marpa_g_irl_count(): %s", xs_g_error (g_wrapper));
4517             }
4518 3 50         if (result < 0)
4519             {
4520 0           XSRETURN_UNDEF;
4521             }
4522 3 50         XPUSHs (sv_2mortal (newSViv (result)));
4523             }
4524              
4525             # int
4526             void
4527             _marpa_g_nsy_count( g_wrapper )
4528             G_Wrapper *g_wrapper;
4529             PPCODE:
4530             {
4531 3           Marpa_Grammar g = g_wrapper->g;
4532 3           int result = _marpa_g_nsy_count (g);
4533 3 50         if (result < -1)
4534             {
4535 0           croak ("Problem in g->_marpa_g_nsy_count(): %s", xs_g_error (g_wrapper));
4536             }
4537 3 50         if (result < 0)
4538             {
4539 0           XSRETURN_UNDEF;
4540             }
4541 3 50         XPUSHs (sv_2mortal (newSViv (result)));
4542             }
4543              
4544             # Marpa_IRL_ID
4545             void
4546             _marpa_g_ahm_irl( g_wrapper, item_id )
4547             G_Wrapper *g_wrapper;
4548             Marpa_AHM_ID item_id;
4549             PPCODE:
4550             {
4551 2996           Marpa_Grammar g = g_wrapper->g;
4552 2996           int result = _marpa_g_ahm_irl(g, item_id);
4553 2996 50         if (result < 0) { XSRETURN_UNDEF; }
4554 2996 50         XPUSHs (sv_2mortal (newSViv (result)));
4555             }
4556              
4557             # -1 is a valid return value, so -2 indicates an error
4558             # int
4559             void
4560             _marpa_g_ahm_position( g_wrapper, item_id )
4561             G_Wrapper *g_wrapper;
4562             Marpa_AHM_ID item_id;
4563             PPCODE:
4564             {
4565 2990           Marpa_Grammar g = g_wrapper->g;
4566 2990           int result = _marpa_g_ahm_position(g, item_id);
4567 2990 50         if (result <= -2) { XSRETURN_UNDEF; }
4568 2990 50         XPUSHs (sv_2mortal (newSViv (result)));
4569             }
4570              
4571             # -1 is a valid return value, and -2 indicates an error
4572             # Marpa_Symbol_ID
4573             void
4574             _marpa_g_ahm_postdot( g_wrapper, item_id )
4575             G_Wrapper *g_wrapper;
4576             Marpa_AHM_ID item_id;
4577             PPCODE:
4578             {
4579 598           Marpa_Grammar g = g_wrapper->g;
4580 598           int result = _marpa_g_ahm_postdot(g, item_id);
4581 598 50         if (result <= -2) { XSRETURN_UNDEF; }
4582 598 50         XPUSHs (sv_2mortal (newSViv (result)));
4583             }
4584              
4585             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::R
4586              
4587             void
4588             _marpa_r_is_use_leo_set( r_wrapper, boolean )
4589             R_Wrapper *r_wrapper;
4590             int boolean;
4591             PPCODE:
4592             {
4593 7           struct marpa_r *r = r_wrapper->r;
4594 7           int result = _marpa_r_is_use_leo_set (r, (boolean ? TRUE : FALSE));
4595 7 50         if (result < 0)
4596             {
4597 0           croak ("Problem in _marpa_r_is_use_leo_set(): %s",
4598             xs_g_error(r_wrapper->base));
4599             }
4600 7           XSRETURN_YES;
4601             }
4602              
4603             void
4604             _marpa_r_is_use_leo( r_wrapper )
4605             R_Wrapper *r_wrapper;
4606             PPCODE:
4607             {
4608 0           struct marpa_r *r = r_wrapper->r;
4609 0           int boolean = _marpa_r_is_use_leo (r);
4610 0 0         if (boolean < 0)
4611             {
4612 0           croak ("Problem in _marpa_r_is_use_leo(): %s", xs_g_error(r_wrapper->base));
4613             }
4614 0 0         if (boolean)
4615 0           XSRETURN_YES;
4616 0           XSRETURN_NO;
4617             }
4618              
4619             void
4620             _marpa_r_earley_set_size( r_wrapper, set_ordinal )
4621             R_Wrapper *r_wrapper;
4622             Marpa_Earley_Set_ID set_ordinal;
4623             PPCODE:
4624             {
4625 179           struct marpa_r *r = r_wrapper->r;
4626 179           int earley_set_size = _marpa_r_earley_set_size (r, set_ordinal);
4627 179 50         if (earley_set_size < 0) {
4628 0           croak ("Problem in r->_marpa_r_earley_set_size(): %s", xs_g_error(r_wrapper->base));
4629             }
4630 179 50         XPUSHs (sv_2mortal (newSViv (earley_set_size)));
4631             }
4632              
4633             void
4634             _marpa_r_earley_set_trace( r_wrapper, set_ordinal )
4635             R_Wrapper *r_wrapper;
4636             Marpa_Earley_Set_ID set_ordinal;
4637             PPCODE:
4638 91           { struct marpa_r* r = r_wrapper->r;
4639 91           Marpa_AHM_ID result = _marpa_r_earley_set_trace(
4640             r, set_ordinal );
4641 91 100         if (result == -1) { XSRETURN_UNDEF; }
4642 83 50         if (result < 0) { croak("problem with r->_marpa_r_earley_set_trace: %s", xs_g_error(r_wrapper->base)); }
4643 83 50         XPUSHs( sv_2mortal( newSViv(result) ) );
4644             }
4645              
4646             void
4647             _marpa_r_earley_item_trace( r_wrapper, item_ordinal )
4648             R_Wrapper *r_wrapper;
4649             Marpa_Earley_Item_ID item_ordinal;
4650             PPCODE:
4651 770           { struct marpa_r* r = r_wrapper->r;
4652 770           Marpa_AHM_ID result = _marpa_r_earley_item_trace(
4653             r, item_ordinal);
4654 770 100         if (result == -1) { XSRETURN_UNDEF; }
4655 697 50         if (result < 0) { croak("problem with r->_marpa_r_earley_item_trace: %s", xs_g_error(r_wrapper->base)); }
4656 697 50         XPUSHs( sv_2mortal( newSViv(result) ) );
4657             }
4658              
4659             void
4660             _marpa_r_earley_item_origin( r_wrapper )
4661             R_Wrapper *r_wrapper;
4662             PPCODE:
4663             {
4664 1034           struct marpa_r *r = r_wrapper->r;
4665 1034           int origin_earleme = _marpa_r_earley_item_origin (r);
4666 1034 50         if (origin_earleme < 0)
4667             {
4668 0           croak ("Problem with r->_marpa_r_earley_item_origin(): %s",
4669             xs_g_error(r_wrapper->base));
4670             }
4671 1034 50         XPUSHs (sv_2mortal (newSViv (origin_earleme)));
4672             }
4673              
4674             void
4675             _marpa_r_first_token_link_trace( r_wrapper )
4676             R_Wrapper *r_wrapper;
4677             PPCODE:
4678 697           { struct marpa_r* r = r_wrapper->r;
4679 697           int token_id = _marpa_r_first_token_link_trace(r);
4680 697 50         if (token_id <= -2) { croak("Trace first token link problem: %s", xs_g_error(r_wrapper->base)); }
4681 697 100         if (token_id == -1) { XSRETURN_UNDEF; }
4682 101 50         XPUSHs( sv_2mortal( newSViv(token_id) ) );
4683             }
4684              
4685             void
4686             _marpa_r_next_token_link_trace( r_wrapper )
4687             R_Wrapper *r_wrapper;
4688             PPCODE:
4689 101           { struct marpa_r* r = r_wrapper->r;
4690 101           int token_id = _marpa_r_next_token_link_trace(r);
4691 101 50         if (token_id <= -2) { croak("Trace next token link problem: %s", xs_g_error(r_wrapper->base)); }
4692 101 50         if (token_id == -1) { XSRETURN_UNDEF; }
4693 0 0         XPUSHs( sv_2mortal( newSViv(token_id) ) );
4694             }
4695              
4696             void
4697             _marpa_r_first_completion_link_trace( r_wrapper )
4698             R_Wrapper *r_wrapper;
4699             PPCODE:
4700 697           { struct marpa_r* r = r_wrapper->r;
4701 697           int AHFA_state_id = _marpa_r_first_completion_link_trace(r);
4702 697 50         if (AHFA_state_id <= -2) { croak("Trace first completion link problem: %s", xs_g_error(r_wrapper->base)); }
4703 697 100         if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
4704 210 50         XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
4705             }
4706              
4707             void
4708             _marpa_r_next_completion_link_trace( r_wrapper )
4709             R_Wrapper *r_wrapper;
4710             PPCODE:
4711 236           { struct marpa_r* r = r_wrapper->r;
4712 236           int AHFA_state_id = _marpa_r_next_completion_link_trace(r);
4713 236 50         if (AHFA_state_id <= -2) { croak("Trace next completion link problem: %s", xs_g_error(r_wrapper->base)); }
4714 236 100         if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
4715 26 50         XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
4716             }
4717              
4718             void
4719             _marpa_r_first_leo_link_trace( r_wrapper )
4720             R_Wrapper *r_wrapper;
4721             PPCODE:
4722 697           { struct marpa_r* r = r_wrapper->r;
4723 697           int AHFA_state_id = _marpa_r_first_leo_link_trace(r);
4724 697 50         if (AHFA_state_id <= -2) { croak("Trace first completion link problem: %s", xs_g_error(r_wrapper->base)); }
4725 697 100         if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
4726 27 50         XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
4727             }
4728              
4729             void
4730             _marpa_r_next_leo_link_trace( r_wrapper )
4731             R_Wrapper *r_wrapper;
4732             PPCODE:
4733 27           { struct marpa_r* r = r_wrapper->r;
4734 27           int AHFA_state_id = _marpa_r_next_leo_link_trace(r);
4735 27 50         if (AHFA_state_id <= -2) { croak("Trace next completion link problem: %s", xs_g_error(r_wrapper->base)); }
4736 27 50         if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
4737 0 0         XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
4738             }
4739              
4740             void
4741             _marpa_r_source_predecessor_state( r_wrapper )
4742             R_Wrapper *r_wrapper;
4743             PPCODE:
4744 674           { struct marpa_r* r = r_wrapper->r;
4745 674           int state_id = _marpa_r_source_predecessor_state(r);
4746 674 50         if (state_id <= -2) { croak("Problem finding trace source predecessor state: %s", xs_g_error(r_wrapper->base)); }
4747 674 50         if (state_id == -1) { XSRETURN_UNDEF; }
4748 674 50         XPUSHs( sv_2mortal( newSViv(state_id) ) );
4749             }
4750              
4751             void
4752             _marpa_r_source_leo_transition_symbol( r_wrapper )
4753             R_Wrapper *r_wrapper;
4754             PPCODE:
4755 54           { struct marpa_r* r = r_wrapper->r;
4756 54           int symbol_id = _marpa_r_source_leo_transition_symbol(r);
4757 54 50         if (symbol_id <= -2) { croak("Problem finding trace source leo transition symbol: %s", xs_g_error(r_wrapper->base)); }
4758 54 50         if (symbol_id == -1) { XSRETURN_UNDEF; }
4759 54 50         XPUSHs( sv_2mortal( newSViv(symbol_id) ) );
4760             }
4761              
4762             void
4763             _marpa_r_source_token( r_wrapper )
4764             R_Wrapper *r_wrapper;
4765             PPCODE:
4766 101           { struct marpa_r* r = r_wrapper->r;
4767             int value;
4768 101           int symbol_id = _marpa_r_source_token(r, &value);
4769 101 50         if (symbol_id == -1) { XSRETURN_UNDEF; }
4770 101 50         if (symbol_id < 0) { croak("Problem with r->source_token(): %s", xs_g_error(r_wrapper->base)); }
4771 101 50         XPUSHs( sv_2mortal( newSViv(symbol_id) ) );
4772 101 50         XPUSHs( sv_2mortal( newSViv(value) ) );
4773             }
4774              
4775             void
4776             _marpa_r_source_middle( r_wrapper )
4777             R_Wrapper *r_wrapper;
4778             PPCODE:
4779 728           { struct marpa_r* r = r_wrapper->r;
4780 728           int middle = _marpa_r_source_middle(r);
4781 728 50         if (middle <= -2) { croak("Problem with r->source_middle(): %s", xs_g_error(r_wrapper->base)); }
4782 728 50         if (middle == -1) { XSRETURN_UNDEF; }
4783 728 50         XPUSHs( sv_2mortal( newSViv(middle) ) );
4784             }
4785              
4786             void
4787             _marpa_r_first_postdot_item_trace( r_wrapper )
4788             R_Wrapper *r_wrapper;
4789             PPCODE:
4790 83           { struct marpa_r* r = r_wrapper->r;
4791 83           int postdot_symbol_id = _marpa_r_first_postdot_item_trace(r);
4792 83 50         if (postdot_symbol_id <= -2) { croak("Trace first postdot item problem: %s", xs_g_error(r_wrapper->base)); }
4793 83 100         if (postdot_symbol_id == -1) { XSRETURN_UNDEF; }
4794 82 50         XPUSHs( sv_2mortal( newSViv(postdot_symbol_id) ) );
4795             }
4796              
4797             void
4798             _marpa_r_next_postdot_item_trace( r_wrapper )
4799             R_Wrapper *r_wrapper;
4800             PPCODE:
4801 708           { struct marpa_r* r = r_wrapper->r;
4802 708           int postdot_symbol_id = _marpa_r_next_postdot_item_trace(r);
4803 708 50         if (postdot_symbol_id <= -2) { croak("Trace next postdot item problem: %s", xs_g_error(r_wrapper->base)); }
4804 708 100         if (postdot_symbol_id == -1) { XSRETURN_UNDEF; }
4805 626 50         XPUSHs( sv_2mortal( newSViv(postdot_symbol_id) ) );
4806             }
4807              
4808             void
4809             _marpa_r_postdot_symbol_trace( r_wrapper, symid )
4810             R_Wrapper *r_wrapper;
4811             Marpa_Symbol_ID symid;
4812             PPCODE:
4813             {
4814 0           struct marpa_r *r = r_wrapper->r;
4815 0           int postdot_symbol_id = _marpa_r_postdot_symbol_trace (r, symid);
4816 0 0         if (postdot_symbol_id == -1)
4817             {
4818 0           XSRETURN_UNDEF;
4819             }
4820 0 0         if (postdot_symbol_id <= 0)
4821             {
4822 0           croak ("Problem in r->postdot_symbol_trace: %s", xs_g_error(r_wrapper->base));
4823             }
4824 0 0         XPUSHs (sv_2mortal (newSViv (postdot_symbol_id)));
4825             }
4826              
4827             void
4828             _marpa_r_leo_base_state( r_wrapper )
4829             R_Wrapper *r_wrapper;
4830             PPCODE:
4831             {
4832 670           struct marpa_r *r = r_wrapper->r;
4833 670           int leo_base_state = _marpa_r_leo_base_state (r);
4834 670 100         if (leo_base_state == -1) { XSRETURN_UNDEF; }
4835 188 50         if (leo_base_state < 0) {
4836 0           croak ("Problem in r->leo_base_state(): %s", xs_g_error(r_wrapper->base));
4837             }
4838 188 50         XPUSHs (sv_2mortal (newSViv (leo_base_state)));
4839             }
4840              
4841             void
4842             _marpa_r_leo_top_ahm( r_wrapper )
4843             R_Wrapper *r_wrapper;
4844             PPCODE:
4845             {
4846 38           struct marpa_r *r = r_wrapper->r;
4847 38           int leo_top_ahm = _marpa_r_leo_top_ahm (r);
4848 38 100         if (leo_top_ahm == -1) { XSRETURN_UNDEF; }
4849 6 50         if (leo_top_ahm < 0) {
4850 0           croak ("Problem in r->leo_top_ahm(): %s", xs_g_error(r_wrapper->base));
4851             }
4852 6 50         XPUSHs (sv_2mortal (newSViv (leo_top_ahm)));
4853             }
4854              
4855             void
4856             _marpa_r_leo_base_origin( r_wrapper )
4857             R_Wrapper *r_wrapper;
4858             PPCODE:
4859             {
4860 194           struct marpa_r *r = r_wrapper->r;
4861 194           int leo_base_origin = _marpa_r_leo_base_origin (r);
4862 194 50         if (leo_base_origin == -1) { XSRETURN_UNDEF; }
4863 194 50         if (leo_base_origin < 0) {
4864 0           croak ("Problem in r->leo_base_origin(): %s", xs_g_error(r_wrapper->base));
4865             }
4866 194 50         XPUSHs (sv_2mortal (newSViv (leo_base_origin)));
4867             }
4868              
4869             void
4870             _marpa_r_trace_earley_set( r_wrapper )
4871             R_Wrapper *r_wrapper;
4872             PPCODE:
4873             {
4874 194           struct marpa_r *r = r_wrapper->r;
4875 194           int trace_earley_set = _marpa_r_trace_earley_set (r);
4876 194 50         if (trace_earley_set < 0) {
4877 0           croak ("Problem in r->trace_earley_set(): %s", xs_g_error(r_wrapper->base));
4878             }
4879 194 50         XPUSHs (sv_2mortal (newSViv (trace_earley_set)));
4880             }
4881              
4882             void
4883             _marpa_r_postdot_item_symbol( r_wrapper )
4884             R_Wrapper *r_wrapper;
4885             PPCODE:
4886             {
4887 194           struct marpa_r *r = r_wrapper->r;
4888 194           int postdot_item_symbol = _marpa_r_postdot_item_symbol (r);
4889 194 50         if (postdot_item_symbol < 0) {
4890 0           croak ("Problem in r->postdot_item_symbol(): %s", xs_g_error(r_wrapper->base));
4891             }
4892 194 50         XPUSHs (sv_2mortal (newSViv (postdot_item_symbol)));
4893             }
4894              
4895             void
4896             _marpa_r_leo_predecessor_symbol( r_wrapper )
4897             R_Wrapper *r_wrapper;
4898             PPCODE:
4899             {
4900 188           struct marpa_r *r = r_wrapper->r;
4901 188           int leo_predecessor_symbol = _marpa_r_leo_predecessor_symbol (r);
4902 188 100         if (leo_predecessor_symbol == -1) { XSRETURN_UNDEF; }
4903 185 50         if (leo_predecessor_symbol < 0) {
4904 0           croak ("Problem in r->leo_predecessor_symbol(): %s", xs_g_error(r_wrapper->base));
4905             }
4906 185 50         XPUSHs (sv_2mortal (newSViv (leo_predecessor_symbol)));
4907             }
4908              
4909             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::B
4910              
4911             # Move of bocage modules to gp_generate.pl is now complete
4912              
4913             void
4914             _marpa_b_and_node_token( b_wrapper, and_node_id )
4915             B_Wrapper *b_wrapper;
4916             Marpa_And_Node_ID and_node_id;
4917             PPCODE:
4918             {
4919 0           Marpa_Bocage b = b_wrapper->b;
4920 0           int value = -1;
4921 0           int result = _marpa_b_and_node_token (b, and_node_id, &value);
4922 0 0         if (result == -1)
4923             {
4924 0           XSRETURN_UNDEF;
4925             }
4926 0 0         if (result < 0)
4927             {
4928 0           croak ("Problem in b->_marpa_b_and_node_symbol(): %s",
4929             xs_g_error(b_wrapper->base));
4930             }
4931 0 0         XPUSHs (sv_2mortal (newSViv (result)));
4932 0 0         XPUSHs (sv_2mortal (newSViv (value)));
4933             }
4934              
4935             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::O
4936              
4937             # int
4938             void
4939             _marpa_o_and_node_order_get( o_wrapper, or_node_id, and_ix )
4940             O_Wrapper *o_wrapper;
4941             Marpa_Or_Node_ID or_node_id;
4942             int and_ix;
4943             PPCODE:
4944             {
4945 153           Marpa_Order o = o_wrapper->o;
4946             int result;
4947 153           result = _marpa_o_and_order_get(o, or_node_id, and_ix);
4948 153 100         if (result == -1) { XSRETURN_UNDEF; }
4949 113 50         if (result < 0) {
4950 0           croak ("Problem in o->_marpa_o_and_node_order_get(): %s", xs_g_error(o_wrapper->base));
4951             }
4952 113 50         XPUSHs( sv_2mortal( newSViv(result) ) );
4953             }
4954              
4955             void
4956             _marpa_o_or_node_and_node_count( o_wrapper, or_node_id )
4957             O_Wrapper *o_wrapper;
4958             Marpa_Or_Node_ID or_node_id;
4959             PPCODE:
4960             {
4961 0           Marpa_Order o = o_wrapper->o;
4962 0           int count = _marpa_o_or_node_and_node_count(o, or_node_id);
4963 0 0         if (count < 0) { croak("Invalid or node ID %d", or_node_id); }
4964 0 0         XPUSHs( sv_2mortal( newSViv(count) ) );
4965             }
4966              
4967             void
4968             _marpa_o_or_node_and_node_ids( o_wrapper, or_node_id )
4969             O_Wrapper *o_wrapper;
4970             Marpa_Or_Node_ID or_node_id;
4971             PPCODE:
4972             {
4973 1759           Marpa_Order o = o_wrapper->o;
4974 1759           int count = _marpa_o_or_node_and_node_count(o, or_node_id);
4975 1759 100         if (count == -1) {
4976 49 50         if (GIMME != G_ARRAY) { XSRETURN_NO; }
    50          
4977             count = 0; /* will return an empty array */
4978             }
4979 1759 50         if (count < 0) { croak("Invalid or node ID %d", or_node_id); }
4980             {
4981             int ix;
4982 1759 50         EXTEND(SP, count);
    50          
4983 3824 100         for (ix = 0; ix < count; ix++) {
4984 2065           Marpa_And_Node_ID and_node_id
4985             = _marpa_o_or_node_and_node_id_by_ix(o, or_node_id, ix);
4986 2065           PUSHs( sv_2mortal( newSViv(and_node_id) ) );
4987             }
4988             }
4989             }
4990              
4991             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::T
4992              
4993             # int
4994             void
4995             _marpa_t_size( t_wrapper )
4996             T_Wrapper *t_wrapper;
4997             PPCODE:
4998             {
4999 0           Marpa_Tree t = t_wrapper->t;
5000             int result;
5001 0           result = _marpa_t_size (t);
5002 0 0         if (result == -1)
5003             {
5004 0           XSRETURN_UNDEF;
5005             }
5006 0 0         if (result < 0)
5007             {
5008 0           croak ("Problem in t->_marpa_t_size(): %s", xs_g_error(t_wrapper->base));
5009             }
5010 0 0         XPUSHs (sv_2mortal (newSViv (result)));
5011             }
5012              
5013             # int
5014             void
5015             _marpa_t_nook_or_node( t_wrapper, nook_id )
5016             T_Wrapper *t_wrapper;
5017             Marpa_Nook_ID nook_id;
5018             PPCODE:
5019             {
5020 108           Marpa_Tree t = t_wrapper->t;
5021             int result;
5022 108           result = _marpa_t_nook_or_node (t, nook_id);
5023 108 100         if (result == -1)
5024             {
5025 4           XSRETURN_UNDEF;
5026             }
5027 104 50         if (result < 0)
5028             {
5029 0           croak ("Problem in t->_marpa_t_nook_or_node(): %s", xs_g_error(t_wrapper->base));
5030             }
5031 104 50         XPUSHs (sv_2mortal (newSViv (result)));
5032             }
5033              
5034             # int
5035             void
5036             _marpa_t_nook_choice( t_wrapper, nook_id )
5037             T_Wrapper *t_wrapper;
5038             Marpa_Nook_ID nook_id;
5039             PPCODE:
5040             {
5041 104           Marpa_Tree t = t_wrapper->t;
5042             int result;
5043 104           result = _marpa_t_nook_choice (t, nook_id);
5044 104 50         if (result == -1)
5045             {
5046 0           XSRETURN_UNDEF;
5047             }
5048 104 50         if (result < 0)
5049             {
5050 0           croak ("Problem in t->_marpa_t_nook_choice(): %s", xs_g_error(t_wrapper->base));
5051             }
5052 104 50         XPUSHs (sv_2mortal (newSViv (result)));
5053             }
5054              
5055             # int
5056             void
5057             _marpa_t_nook_parent( t_wrapper, nook_id )
5058             T_Wrapper *t_wrapper;
5059             Marpa_Nook_ID nook_id;
5060             PPCODE:
5061             {
5062 40           Marpa_Tree t = t_wrapper->t;
5063             int result;
5064 40           result = _marpa_t_nook_parent (t, nook_id);
5065 40 100         if (result == -1)
5066             {
5067 4           XSRETURN_UNDEF;
5068             }
5069 36 50         if (result < 0)
5070             {
5071 0           croak ("Problem in t->_marpa_t_nook_parent(): %s", xs_g_error(t_wrapper->base));
5072             }
5073 36 50         XPUSHs (sv_2mortal (newSViv (result)));
5074             }
5075              
5076             # int
5077             void
5078             _marpa_t_nook_is_cause( t_wrapper, nook_id )
5079             T_Wrapper *t_wrapper;
5080             Marpa_Nook_ID nook_id;
5081             PPCODE:
5082             {
5083 40           Marpa_Tree t = t_wrapper->t;
5084             int result;
5085 40           result = _marpa_t_nook_is_cause (t, nook_id);
5086 40 50         if (result == -1)
5087             {
5088 0           XSRETURN_UNDEF;
5089             }
5090 40 50         if (result < 0)
5091             {
5092 0           croak ("Problem in t->_marpa_t_nook_is_cause(): %s", xs_g_error(t_wrapper->base));
5093             }
5094 40 50         XPUSHs (sv_2mortal (newSViv (result)));
5095             }
5096              
5097             # int
5098             void
5099             _marpa_t_nook_cause_is_ready( t_wrapper, nook_id )
5100             T_Wrapper *t_wrapper;
5101             Marpa_Nook_ID nook_id;
5102             PPCODE:
5103             {
5104 40           Marpa_Tree t = t_wrapper->t;
5105             int result;
5106 40           result = _marpa_t_nook_cause_is_ready (t, nook_id);
5107 40 50         if (result == -1)
5108             {
5109 0           XSRETURN_UNDEF;
5110             }
5111 40 50         if (result < 0)
5112             {
5113 0           croak ("Problem in t->_marpa_t_nook_cause_is_ready(): %s", xs_g_error(t_wrapper->base));
5114             }
5115 40 50         XPUSHs (sv_2mortal (newSViv (result)));
5116             }
5117              
5118              
5119             # int
5120             void
5121             _marpa_t_nook_is_predecessor( t_wrapper, nook_id )
5122             T_Wrapper *t_wrapper;
5123             Marpa_Nook_ID nook_id;
5124             PPCODE:
5125             {
5126 16           Marpa_Tree t = t_wrapper->t;
5127             int result;
5128 16           result = _marpa_t_nook_is_predecessor (t, nook_id);
5129 16 50         if (result == -1)
5130             {
5131 0           XSRETURN_UNDEF;
5132             }
5133 16 50         if (result < 0)
5134             {
5135 0           croak ("Problem in t->_marpa_t_nook_is_predecessor(): %s", xs_g_error(t_wrapper->base));
5136             }
5137 16 50         XPUSHs (sv_2mortal (newSViv (result)));
5138             }
5139              
5140             # int
5141             void
5142             _marpa_t_nook_predecessor_is_ready( t_wrapper, nook_id )
5143             T_Wrapper *t_wrapper;
5144             Marpa_Nook_ID nook_id;
5145             PPCODE:
5146             {
5147 40           Marpa_Tree t = t_wrapper->t;
5148             int result;
5149 40           result = _marpa_t_nook_predecessor_is_ready (t, nook_id);
5150 40 50         if (result == -1)
5151             {
5152 0           XSRETURN_UNDEF;
5153             }
5154 40 50         if (result < 0)
5155             {
5156 0           croak ("Problem in t->_marpa_t_nook_predecessor_is_ready(): %s",
5157             xs_g_error(t_wrapper->base));
5158             }
5159 40 50         XPUSHs (sv_2mortal (newSViv (result)));
5160             }
5161              
5162             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::V
5163              
5164             void
5165             _marpa_v_trace( v_wrapper, flag )
5166             V_Wrapper *v_wrapper;
5167             int flag;
5168             PPCODE:
5169             {
5170 7972           const Marpa_Value v = v_wrapper->v;
5171             int status;
5172 7972           status = _marpa_v_trace (v, flag);
5173 7972 50         if (status == -1)
5174             {
5175 0           XSRETURN_UNDEF;
5176             }
5177 7972 50         if (status < 0)
5178             {
5179 0           croak ("Problem in v->trace(): %s", xs_g_error(v_wrapper->base));
5180             }
5181 7972 50         XPUSHs (sv_2mortal (newSViv (status)));
5182             }
5183              
5184             void
5185             _marpa_v_nook( v_wrapper )
5186             V_Wrapper *v_wrapper;
5187             PPCODE:
5188             {
5189 64           const Marpa_Value v = v_wrapper->v;
5190             int status;
5191 64           status = _marpa_v_nook (v);
5192 64 50         if (status == -1)
5193             {
5194 0           XSRETURN_UNDEF;
5195             }
5196 64 50         if (status < 0)
5197             {
5198 0           croak ("Problem in v->_marpa_v_nook(): %s", xs_g_error(v_wrapper->base));
5199             }
5200 64 50         XPUSHs (sv_2mortal (newSViv (status)));
5201             }
5202              
5203             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::SLG
5204              
5205             void
5206             new( class, l0_sv, g1_sv )
5207             char * class;
5208             SV *l0_sv;
5209             SV *g1_sv;
5210             PPCODE:
5211             {
5212             SV* new_sv;
5213             Scanless_G *slg;
5214             PERL_UNUSED_ARG(class);
5215              
5216 273 50         if (!sv_isa (l0_sv, "Marpa::R2::Thin::G"))
5217             {
5218 0           croak ("Problem in u->new(): L0 arg is not of type Marpa::R2::Thin::G");
5219             }
5220 273 50         if (!sv_isa (g1_sv, "Marpa::R2::Thin::G"))
5221             {
5222 0           croak ("Problem in u->new(): G1 arg is not of type Marpa::R2::Thin::G");
5223             }
5224 273           Newx (slg, 1, Scanless_G);
5225              
5226 273           slg->g1_sv = g1_sv;
5227             SvREFCNT_inc (g1_sv);
5228              
5229 273 50         # These do not need references, because parent objects
5230 273           # hold references to them
5231 273           SET_G_WRAPPER_FROM_G_SV(slg->g1_wrapper, g1_sv)
5232             slg->g1 = slg->g1_wrapper->g;
5233 273           slg->precomputed = 0;
5234              
5235             slg->l0_sv = l0_sv;
5236 273 50         SvREFCNT_inc (l0_sv);
5237              
5238             # Wrapper does not need reference, because parent objects
5239             # holds references to it
5240 273           SET_G_WRAPPER_FROM_G_SV (slg->l0_wrapper, l0_sv);
5241 35217 100          
5242             {
5243 34944           int i;
5244             slg->per_codepoint_hash = newHV ();
5245             for (i = 0; i < (int)Dim (slg->per_codepoint_array); i++)
5246             {
5247             slg->per_codepoint_array[i] = NULL;
5248             }
5249 273           }
5250 273            
5251 273 50         {
5252             int symbol_ix;
5253 15120 100         int g1_symbol_count =
5254 14847           marpa_g_highest_symbol_id ( slg->g1 ) + 1;
5255             Newx (slg->g1_lexeme_to_assertion, g1_symbol_count,
5256 14847           Marpa_Assertion_ID);
5257             for (symbol_ix = 0; symbol_ix < g1_symbol_count;
5258             symbol_ix++)
5259             {
5260             slg->g1_lexeme_to_assertion[symbol_ix] = -1;
5261             }
5262 273           }
5263 273 50          
5264 15120 100         {
5265 14847           Marpa_Symbol_ID symbol_id;
5266 14847           int g1_symbol_count = marpa_g_highest_symbol_id (slg->g1) + 1;
5267 14847           Newx (slg->symbol_g_properties, g1_symbol_count, struct symbol_g_properties);
5268 14847           for (symbol_id = 0; symbol_id < g1_symbol_count; symbol_id++) {
5269 14847           slg->symbol_g_properties[symbol_id].priority = 0;
5270 14847           slg->symbol_g_properties[symbol_id].latm = 0;
5271 14847           slg->symbol_g_properties[symbol_id].is_lexeme = 0;
5272             slg->symbol_g_properties[symbol_id].t_pause_before = 0;
5273             slg->symbol_g_properties[symbol_id].t_pause_before_active = 0;
5274             slg->symbol_g_properties[symbol_id].t_pause_after = 0;
5275             slg->symbol_g_properties[symbol_id].t_pause_after_active = 0;
5276             }
5277 273           }
5278 273 50          
5279 23410 100         {
5280 23137           Marpa_Rule_ID rule_id;
5281 23137           int g1_rule_count = marpa_g_highest_rule_id (slg->l0_wrapper->g) + 1;
5282 23137           Newx (slg->l0_rule_g_properties, g1_rule_count, struct l0_rule_g_properties);
5283             for (rule_id = 0; rule_id < g1_rule_count; rule_id++) {
5284             slg->l0_rule_g_properties[rule_id].g1_lexeme = -1;
5285             slg->l0_rule_g_properties[rule_id].t_event_on_discard = 0;
5286 273           slg->l0_rule_g_properties[rule_id].t_event_on_discard_active = 0;
5287 273           }
5288 273 50         }
5289              
5290             new_sv = sv_newmortal ();
5291             sv_setref_pv (new_sv, scanless_g_class_name, (void *) slg);
5292             XPUSHs (new_sv);
5293             }
5294              
5295             void
5296             DESTROY( slg )
5297             Scanless_G *slg;
5298             PPCODE:
5299             {
5300             unsigned int i = 0;
5301 273           SvREFCNT_dec (slg->g1_sv);
5302 273           SvREFCNT_dec (slg->l0_sv);
5303 273           Safefree (slg->symbol_g_properties);
5304 273           Safefree (slg->l0_rule_g_properties);
5305 273           Safefree (slg->g1_lexeme_to_assertion);
5306 273           SvREFCNT_dec (slg->per_codepoint_hash);
5307 35217 100         for (i = 0; i < Dim(slg->per_codepoint_array); i++) {
5308 34944           Safefree(slg->per_codepoint_array[i]);
5309             }
5310 273           Safefree (slg);
5311             }
5312              
5313             # it does not create a new one
5314             #
5315             void
5316             g1( slg )
5317             Scanless_G *slg;
5318             PPCODE:
5319             {
5320             /* Not mortalized because,
5321             * held for the length of the scanless object.
5322             */
5323 0 0         XPUSHs (sv_2mortal (SvREFCNT_inc_NN (slg->g1_sv)));
5324             }
5325              
5326             void
5327             lexer_rule_to_g1_lexeme_set( slg, lexer_rule, g1_lexeme, assertion_id )
5328             Scanless_G *slg;
5329             Marpa_Rule_ID lexer_rule;
5330             Marpa_Symbol_ID g1_lexeme;
5331             Marpa_Assertion_ID assertion_id;
5332             PPCODE:
5333             {
5334             Marpa_Rule_ID highest_lexer_rule_id;
5335             Marpa_Symbol_ID highest_g1_symbol_id;
5336             Marpa_Assertion_ID highest_assertion_id;
5337              
5338 23127           highest_lexer_rule_id = marpa_g_highest_rule_id (slg->l0_wrapper->g);
5339 23127           highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5340 23127           highest_assertion_id = marpa_g_highest_zwa_id (slg->l0_wrapper->g);
5341 23127 50         if (slg->precomputed)
5342             {
5343 0           croak
5344             ("slg->lexer_rule_to_g1_lexeme_set(%ld, %ld) called after SLG is precomputed",
5345             (long) lexer_rule, (long) g1_lexeme);
5346             }
5347 23127 50         if (lexer_rule > highest_lexer_rule_id)
5348             {
5349 0           croak
5350             ("Problem in slg->lexer_rule_to_g1_lexeme_set(%ld, %ld): rule ID was %ld, but highest lexer rule ID = %ld",
5351             (long) lexer_rule,
5352             (long) g1_lexeme, (long) lexer_rule, (long) highest_lexer_rule_id);
5353             }
5354 23127 50         if (g1_lexeme > highest_g1_symbol_id)
5355             {
5356 0           croak
5357             ("Problem in slg->lexer_rule_to_g1_lexeme_set(%ld, %ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
5358             (long) lexer_rule,
5359             (long) g1_lexeme, (long) lexer_rule, (long) highest_g1_symbol_id);
5360             }
5361 23127 50         if (assertion_id > highest_assertion_id)
5362             {
5363 0           croak
5364             ("Problem in slg->lexer_rule_to_g1_lexeme_set(%ld, %ld, %ld):"
5365             "assertion ID was %ld, but highest assertion ID = %ld",
5366             (long) lexer_rule,
5367             (long) g1_lexeme, (long) lexer_rule,
5368             (long) assertion_id,
5369             (long) highest_assertion_id);
5370             }
5371 23127 50         if (lexer_rule < -2)
5372             {
5373 0           croak
5374             ("Problem in slg->lexer_rule_to_g1_lexeme_set(%ld, %ld): rule ID was %ld, a disallowed value",
5375             (long) lexer_rule, (long) g1_lexeme,
5376             (long) lexer_rule);
5377             }
5378 23127 50         if (g1_lexeme < -2)
5379             {
5380 0           croak
5381             ("Problem in slg->lexer_rule_to_g1_lexeme_set(%ld, %ld): symbol ID was %ld, a disallowed value",
5382             (long) lexer_rule, (long) g1_lexeme,
5383             (long) g1_lexeme);
5384             }
5385 23127 50         if (assertion_id < -2)
5386             {
5387 0           croak
5388             ("Problem in slg->lexer_rule_to_g1_lexeme_set(%ld, %ld, %ld): assertion ID was %ld, a disallowed value",
5389             (long) lexer_rule, (long) g1_lexeme,
5390             (long) g1_lexeme, (long)assertion_id);
5391             }
5392 23127 50         if (lexer_rule >= 0) {
5393 23127           struct l0_rule_g_properties * const l0_rule_g_properties = slg->l0_rule_g_properties + lexer_rule;
5394 23127           l0_rule_g_properties->g1_lexeme = g1_lexeme;
5395             }
5396 23127 100         if (g1_lexeme >= 0) {
5397 8969           slg->g1_lexeme_to_assertion[g1_lexeme] = assertion_id;
5398             }
5399 23127           XSRETURN_YES;
5400             }
5401              
5402             # Mark the symbol as a lexeme.
5403             # A priority is required.
5404             #
5405             void
5406             g1_lexeme_set( slg, g1_lexeme, priority )
5407             Scanless_G *slg;
5408             Marpa_Symbol_ID g1_lexeme;
5409             int priority;
5410             PPCODE:
5411             {
5412 8969           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5413 8969 50         if (slg->precomputed)
5414             {
5415 0           croak
5416             ("slg->lexeme_priority_set(%ld, %ld) called after SLG is precomputed",
5417             (long) g1_lexeme, (long) priority);
5418             }
5419 8969 50         if (g1_lexeme > highest_g1_symbol_id)
5420             {
5421 0           croak
5422             ("Problem in slg->g1_lexeme_priority_set(%ld, %ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
5423             (long) g1_lexeme,
5424             (long) priority,
5425             (long) g1_lexeme,
5426             (long) highest_g1_symbol_id
5427             );
5428             }
5429 8969 50         if (g1_lexeme < 0) {
5430 0           croak
5431             ("Problem in slg->g1_lexeme_priority(%ld, %ld): symbol ID was %ld, a disallowed value",
5432             (long) g1_lexeme,
5433             (long) priority,
5434             (long) g1_lexeme);
5435             }
5436 8969           slg->symbol_g_properties[g1_lexeme].priority = priority;
5437 8969           slg->symbol_g_properties[g1_lexeme].is_lexeme = 1;
5438 8969           XSRETURN_YES;
5439             }
5440              
5441             void
5442             g1_lexeme_priority( slg, g1_lexeme )
5443             Scanless_G *slg;
5444             Marpa_Symbol_ID g1_lexeme;
5445             PPCODE:
5446             {
5447 0           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5448 0 0         if (g1_lexeme > highest_g1_symbol_id)
5449             {
5450 0           croak
5451             ("Problem in slg->g1_lexeme_priority(%ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
5452             (long) g1_lexeme,
5453             (long) g1_lexeme,
5454             (long) highest_g1_symbol_id
5455             );
5456             }
5457 0 0         if (g1_lexeme < 0) {
5458 0           croak
5459             ("Problem in slg->g1_lexeme_priority(%ld): symbol ID was %ld, a disallowed value",
5460             (long) g1_lexeme,
5461             (long) g1_lexeme);
5462             }
5463 0           XSRETURN_IV( slg->symbol_g_properties[g1_lexeme].priority);
5464             }
5465              
5466             void
5467             g1_lexeme_pause_set( slg, g1_lexeme, pause )
5468             Scanless_G *slg;
5469             Marpa_Symbol_ID g1_lexeme;
5470             int pause;
5471             PPCODE:
5472             {
5473 54           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5474 54           struct symbol_g_properties * g_properties = slg->symbol_g_properties + g1_lexeme;
5475 54 50         if (slg->precomputed)
5476             {
5477 0           croak
5478             ("slg->lexeme_pause_set(%ld, %ld) called after SLG is precomputed",
5479             (long) g1_lexeme, (long) pause);
5480             }
5481 54 50         if (g1_lexeme > highest_g1_symbol_id)
5482             {
5483 0           croak
5484             ("Problem in slg->g1_lexeme_pause_set(%ld, %ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
5485             (long) g1_lexeme,
5486             (long) pause,
5487             (long) g1_lexeme,
5488             (long) highest_g1_symbol_id
5489             );
5490             }
5491 54 50         if (g1_lexeme < 0) {
5492 0           croak
5493             ("Problem in slg->lexeme_pause_set(%ld, %ld): symbol ID was %ld, a disallowed value",
5494             (long) g1_lexeme,
5495             (long) pause,
5496             (long) g1_lexeme);
5497             }
5498 54           switch (pause) {
5499             case 0: /* No pause */
5500 0           g_properties->t_pause_after = 0;
5501 0           g_properties->t_pause_before = 0;
5502 0           break;
5503             case 1: /* Pause after */
5504 44           g_properties->t_pause_after = 1;
5505 44           g_properties->t_pause_before = 0;
5506 44           break;
5507             case -1: /* Pause before */
5508 10           g_properties->t_pause_after = 0;
5509 10           g_properties->t_pause_before = 1;
5510 10           break;
5511             default:
5512 0           croak
5513             ("Problem in slg->lexeme_pause_set(%ld, %ld): value of pause must be -1,0 or 1",
5514             (long) g1_lexeme,
5515             (long) pause);
5516             }
5517 54           XSRETURN_YES;
5518             }
5519              
5520             void
5521             g1_lexeme_pause_activate( slg, g1_lexeme, activate )
5522             Scanless_G *slg;
5523             Marpa_Symbol_ID g1_lexeme;
5524             int activate;
5525             PPCODE:
5526             {
5527 54           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5528 54           struct symbol_g_properties *g_properties =
5529 54           slg->symbol_g_properties + g1_lexeme;
5530 54 50         if (slg->precomputed)
5531             {
5532 0           croak
5533             ("slg->lexeme_pause_activate(%ld, %ld) called after SLG is precomputed",
5534             (long) g1_lexeme, (long) activate);
5535             }
5536 54 50         if (g1_lexeme > highest_g1_symbol_id)
5537             {
5538 0           croak
5539             ("Problem in slg->g1_lexeme_pause_activate(%ld, %ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
5540             (long) g1_lexeme,
5541             (long) activate, (long) g1_lexeme, (long) highest_g1_symbol_id);
5542             }
5543 54 50         if (g1_lexeme < 0)
5544             {
5545 0           croak
5546             ("Problem in slg->lexeme_pause_activate(%ld, %ld): symbol ID was %ld, a disallowed value",
5547             (long) g1_lexeme, (long) activate, (long) g1_lexeme);
5548             }
5549              
5550 54 50         if (activate != 0 && activate != 1)
5551             {
5552 0           croak
5553             ("Problem in slg->lexeme_pause_activate(%ld, %ld): value of activate must be 0 or 1",
5554             (long) g1_lexeme, (long) activate);
5555             }
5556              
5557 54 100         if (g_properties->t_pause_before)
5558             {
5559 10           g_properties->t_pause_before_active = activate;
5560             }
5561 44 50         else if (g_properties->t_pause_after)
5562             {
5563 44           g_properties->t_pause_after_active = activate;
5564             }
5565             else
5566             {
5567 0           croak
5568             ("Problem in slg->lexeme_pause_activate(%ld, %ld): no pause event is enabled",
5569             (long) g1_lexeme, (long) activate);
5570             }
5571 54           XSRETURN_YES;
5572             }
5573              
5574             void
5575             discard_event_set( slg, l0_rule_id, boolean )
5576             Scanless_G *slg;
5577             Marpa_Rule_ID l0_rule_id;
5578             int boolean;
5579             PPCODE:
5580             {
5581 60           Marpa_Rule_ID highest_l0_rule_id = marpa_g_highest_rule_id (slg->l0_wrapper->g);
5582 60           struct l0_rule_g_properties * g_properties = slg->l0_rule_g_properties + l0_rule_id;
5583 60 50         if (slg->precomputed)
5584             {
5585 0           croak
5586             ("slg->discard_event_set(%ld, %ld) called after SLG is precomputed",
5587             (long) l0_rule_id, (long) boolean);
5588             }
5589 60 50         if (l0_rule_id > highest_l0_rule_id)
5590             {
5591 0           croak
5592             ("Problem in slg->discard_event_set(%ld, %ld): rule ID was %ld, but highest L0 rule ID = %ld",
5593             (long) l0_rule_id,
5594             (long) boolean,
5595             (long) l0_rule_id,
5596             (long) highest_l0_rule_id
5597             );
5598             }
5599 60 50         if (l0_rule_id < 0) {
5600 0           croak
5601             ("Problem in slg->discard_event_set(%ld, %ld): rule ID was %ld, a disallowed value",
5602             (long) l0_rule_id,
5603             (long) boolean,
5604             (long) l0_rule_id);
5605             }
5606 60 50         switch (boolean) {
5607             case 0:
5608             case 1:
5609 60           g_properties->t_event_on_discard = boolean;
5610             break;
5611             default:
5612 0           croak
5613             ("Problem in slg->discard_event_set(%ld, %ld): value must be 0 or 1",
5614             (long) l0_rule_id,
5615             (long) boolean);
5616             }
5617 60           XSRETURN_YES;
5618             }
5619              
5620             void
5621             discard_event_activate( slg, l0_rule_id, activate )
5622             Scanless_G *slg;
5623             Marpa_Rule_ID l0_rule_id;
5624             int activate;
5625             PPCODE:
5626             {
5627 41           Marpa_Rule_ID highest_l0_rule_id = marpa_g_highest_rule_id (slg->l0_wrapper->g);
5628 41           struct l0_rule_g_properties *g_properties =
5629 41           slg->l0_rule_g_properties + l0_rule_id;
5630 41 50         if (slg->precomputed)
5631             {
5632 0           croak
5633             ("slg->discard_event_activate(%ld, %ld) called after SLG is precomputed",
5634             (long) l0_rule_id, (long) activate);
5635             }
5636 41 50         if (l0_rule_id > highest_l0_rule_id)
5637             {
5638 0           croak
5639             ("Problem in slg->discard_event_activate(%ld, %ld): rule ID was %ld, but highest L0 rule ID = %ld",
5640             (long) l0_rule_id,
5641             (long) activate, (long) l0_rule_id, (long) highest_l0_rule_id);
5642             }
5643 41 50         if (l0_rule_id < 0)
5644             {
5645 0           croak
5646             ("Problem in slg->discard_event_activate(%ld, %ld): rule ID was %ld, a disallowed value",
5647             (long) l0_rule_id, (long) activate, (long) l0_rule_id);
5648             }
5649              
5650 41 50         if (activate != 0 && activate != 1)
5651             {
5652 0           croak
5653             ("Problem in slg->discard_event_activate(%ld, %ld): value of activate must be 0 or 1",
5654             (long) l0_rule_id, (long) activate);
5655             }
5656              
5657 41 50         if (g_properties->t_event_on_discard)
5658             {
5659 41           g_properties->t_event_on_discard_active = activate;
5660             }
5661             else
5662             {
5663 0           croak
5664             ("Problem in slg->discard_event_activate(%ld, %ld): discard event is not enabled",
5665             (long) l0_rule_id, (long) activate);
5666             }
5667 41           XSRETURN_YES;
5668             }
5669              
5670             void
5671             g1_lexeme_latm_set( slg, g1_lexeme, latm )
5672             Scanless_G *slg;
5673             Marpa_Symbol_ID g1_lexeme;
5674             int latm;
5675             PPCODE:
5676             {
5677 8969           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5678 8969           struct symbol_g_properties * g_properties = slg->symbol_g_properties + g1_lexeme;
5679 8969 50         if (slg->precomputed)
5680             {
5681 0           croak
5682             ("slg->lexeme_latm_set(%ld, %ld) called after SLG is precomputed",
5683             (long) g1_lexeme, (long) latm);
5684             }
5685 8969 50         if (g1_lexeme > highest_g1_symbol_id)
5686             {
5687 0           croak
5688             ("Problem in slg->g1_lexeme_latm(%ld, %ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
5689             (long) g1_lexeme,
5690             (long) latm,
5691             (long) g1_lexeme,
5692             (long) highest_g1_symbol_id
5693             );
5694             }
5695 8969 50         if (g1_lexeme < 0) {
5696 0           croak
5697             ("Problem in slg->lexeme_latm(%ld, %ld): symbol ID was %ld, a disallowed value",
5698             (long) g1_lexeme,
5699             (long) latm,
5700             (long) g1_lexeme);
5701             }
5702 8969 50         switch (latm) {
5703             case 0: case 1:
5704 8969           g_properties->latm = latm;
5705             break;
5706             default:
5707 0           croak
5708             ("Problem in slg->lexeme_latm(%ld, %ld): value of latm must be 0 or 1",
5709             (long) g1_lexeme,
5710             (long) latm);
5711             }
5712 8969           XSRETURN_YES;
5713             }
5714              
5715             void
5716             precompute( slg )
5717             Scanless_G *slg;
5718             PPCODE:
5719             {
5720             /* Currently this routine does nothing except set a flag to
5721             * enforce the * separation of the precomputation phase
5722             * from the main processing.
5723             */
5724 269 50         if (!slg->precomputed)
5725             {
5726             /*
5727             * Ensure that I can call this multiple times safely, even
5728             * if I do some real processing here.
5729             */
5730 269           slg->precomputed = 1;
5731             }
5732 269           XSRETURN_IV (1);
5733             }
5734              
5735             MODULE = Marpa::R2 PACKAGE = Marpa::R2::Thin::SLR
5736              
5737             void
5738             new( class, slg_sv, r1_sv )
5739             char * class;
5740             SV *slg_sv;
5741             SV *r1_sv;
5742             PPCODE:
5743             {
5744             SV *new_sv;
5745             Scanless_R *slr;
5746             Scanless_G *slg;
5747             PERL_UNUSED_ARG(class);
5748              
5749 975 50         if (!sv_isa (slg_sv, "Marpa::R2::Thin::SLG"))
5750             {
5751 0           croak
5752             ("Problem in u->new(): slg arg is not of type Marpa::R2::Thin::SLG");
5753             }
5754 975 50         if (!sv_isa (r1_sv, "Marpa::R2::Thin::R"))
5755             {
5756 0           croak ("Problem in u->new(): r1 arg is not of type Marpa::R2::Thin::R");
5757             }
5758 975           Newx (slr, 1, Scanless_R);
5759              
5760 975           slr->throw = 1;
5761 975           slr->trace_lexers = 0;
5762 975           slr->trace_terminals = 0;
5763 975           slr->r0 = NULL;
5764              
5765 975           # Copy and take references to the "parent objects",
5766             # the ones responsible for holding references.
5767 975           slr->slg_sv = slg_sv;
5768             SvREFCNT_inc (slg_sv);
5769             slr->r1_sv = r1_sv;
5770 975 50         SvREFCNT_inc (r1_sv);
5771 975 50          
5772 975 50         # These do not need references, because parent objects
5773             # hold references to them
5774 0           SET_R_WRAPPER_FROM_R_SV (slr->r1_wrapper, r1_sv);
5775             SET_SLG_FROM_SLG_SV (slg, slg_sv);
5776             if (!slg->precomputed)
5777 975           {
5778 975           croak
5779 975 50         ("Problem in u->new(): Attempted to create SLIF recce from unprecomputed SLIF grammar");
5780             }
5781 975           slr->slg = slg;
5782 975           slr->r1 = slr->r1_wrapper->r;
5783 975           SET_G_WRAPPER_FROM_G_SV (slr->g1_wrapper, slr->r1_wrapper->base_sv);
5784              
5785 975           slr->start_of_lexeme = 0;
5786 975           slr->end_of_lexeme = 0;
5787 975           slr->is_external_scanning = 0;
5788              
5789 975           slr->perl_pos = 0;
5790 975           slr->last_perl_pos = -1;
5791             slr->problem_pos = -1;
5792              
5793             slr->token_values = newAV ();
5794 975           av_fill (slr->token_values, TOKEN_VALUE_IS_LITERAL);
5795 975            
5796 975 50         {
5797             Marpa_Symbol_ID symbol_id;
5798 40877 100         const Marpa_Symbol_ID g1_symbol_count =
5799             marpa_g_highest_symbol_id (slg->g1) + 1;
5800 39902           Newx (slr->symbol_r_properties, g1_symbol_count,
5801 39902           struct symbol_r_properties);
5802 79804           for (symbol_id = 0; symbol_id < g1_symbol_count; symbol_id++)
5803 39902           {
5804 79804           const struct symbol_g_properties *g_properties =
5805 39902           slg->symbol_g_properties + symbol_id;
5806 79804           slr->symbol_r_properties[symbol_id].lexeme_priority =
5807 39902           g_properties->priority;
5808             slr->symbol_r_properties[symbol_id].t_pause_before_active =
5809             g_properties->t_pause_before_active;
5810             slr->symbol_r_properties[symbol_id].t_pause_after_active =
5811             g_properties->t_pause_after_active;
5812             }
5813 975           }
5814 975            
5815 975 50         {
5816             Marpa_Rule_ID l0_rule_id;
5817 63752 100         const Marpa_Rule_ID l0_rule_count =
5818             marpa_g_highest_rule_id (slg->l0_wrapper->g) + 1;
5819 62777           Newx (slr->l0_rule_r_properties, l0_rule_count,
5820 62777           struct l0_rule_r_properties);
5821 125554           for (l0_rule_id = 0; l0_rule_id < l0_rule_count; l0_rule_id++)
5822 62777           {
5823             const struct l0_rule_g_properties *g_properties =
5824             slg->l0_rule_g_properties + l0_rule_id;
5825             slr->l0_rule_r_properties[l0_rule_id].t_event_on_discard_active =
5826 975           g_properties->t_event_on_discard_active;
5827 975           }
5828 975           }
5829 975            
5830 975           slr->lexer_start_pos = slr->perl_pos;
5831 975           slr->lexer_read_result = 0;
5832             slr->r1_earleme_complete_result = 0;
5833 975           slr->start_of_pause_lexeme = -1;
5834 975           slr->end_of_pause_lexeme = -1;
5835 975           slr->pause_lexeme = -1;
5836              
5837 975           slr->pos_db = 0;
5838 975           slr->pos_db_logical_size = -1;
5839 975           slr->pos_db_physical_size = -1;
5840 975            
5841             slr->input_symbol_id = -1;
5842 975           slr->input = newSVpvn ("", 0);
5843             slr->end_pos = 0;
5844 975           slr->too_many_earley_items = -1;
5845 975            
5846 975 50         slr->gift = marpa__slr_new();
5847              
5848             new_sv = sv_newmortal ();
5849             sv_setref_pv (new_sv, scanless_r_class_name, (void *) slr);
5850             XPUSHs (new_sv);
5851             }
5852              
5853             void
5854             DESTROY( slr )
5855             Scanless_R *slr;
5856             PPCODE:
5857             {
5858 975           const Marpa_Recce r0 = slr->r0;
5859 975 100         if (r0)
5860             {
5861 952           marpa_r_unref (r0);
5862             }
5863              
5864 975           marpa__slr_unref(slr->gift);
5865              
5866 975           Safefree(slr->pos_db);
5867 975           SvREFCNT_dec (slr->slg_sv);
5868 975           SvREFCNT_dec (slr->r1_sv);
5869 975           Safefree(slr->symbol_r_properties);
5870 975           Safefree(slr->l0_rule_r_properties);
5871 975 50         if (slr->token_values)
5872             {
5873             SvREFCNT_dec ((SV *) slr->token_values);
5874             }
5875 975           SvREFCNT_dec (slr->input);
5876 975           Safefree (slr);
5877             }
5878              
5879             void throw_set(slr, throw_setting)
5880             Scanless_R *slr;
5881             int throw_setting;
5882             PPCODE:
5883             {
5884 0           slr->throw = throw_setting;
5885             }
5886              
5887             void
5888             trace_lexers( slr, new_level )
5889             Scanless_R *slr;
5890             int new_level;
5891             PPCODE:
5892             {
5893 0           IV old_level = slr->trace_lexers;
5894 0           slr->trace_lexers = new_level;
5895 0 0         if (new_level)
5896             {
5897 0           warn
5898             ("Setting trace_lexers to %ld; was %ld",
5899             (long) new_level, (long) old_level);
5900             }
5901 0           XSRETURN_IV (old_level);
5902             }
5903              
5904             void
5905             trace_terminals( slr, new_level )
5906             Scanless_R *slr;
5907             int new_level;
5908             PPCODE:
5909             {
5910 2           IV old_level = slr->trace_terminals;
5911 2           slr->trace_terminals = new_level;
5912 2           XSRETURN_IV(old_level);
5913             }
5914              
5915             void
5916             earley_item_warning_threshold( slr )
5917             Scanless_R *slr;
5918             PPCODE:
5919             {
5920 0           XSRETURN_IV(slr->too_many_earley_items);
5921             }
5922              
5923             void
5924             earley_item_warning_threshold_set( slr, too_many_earley_items )
5925             Scanless_R *slr;
5926             int too_many_earley_items;
5927             PPCODE:
5928             {
5929 1           slr->too_many_earley_items = too_many_earley_items;
5930             }
5931              
5932             # Always returns the same SV for a given Scanless recce object --
5933             # it does not create a new one
5934             #
5935             void
5936             g1( slr )
5937             Scanless_R *slr;
5938             PPCODE:
5939             {
5940 0 0         XPUSHs (sv_2mortal (SvREFCNT_inc_NN ( slr->r1_wrapper->base_sv)));
5941             }
5942              
5943             void
5944             pos( slr )
5945             Scanless_R *slr;
5946             PPCODE:
5947             {
5948 6990           XSRETURN_IV(slr->perl_pos);
5949             }
5950              
5951             void
5952             pos_set( slr, start_pos, length )
5953             Scanless_R *slr;
5954             int start_pos;
5955             int length;
5956             PPCODE:
5957             {
5958 1911           u_pos_set(slr, "slr->pos_set", start_pos, length);
5959 1911           slr->lexer_start_pos = slr->perl_pos;
5960 1911           XSRETURN_YES;
5961             }
5962              
5963             void
5964             substring(slr, start_pos, length)
5965             Scanless_R *slr;
5966             int start_pos;
5967             int length;
5968             PPCODE:
5969             {
5970 216           SV* literal_sv = u_substring(slr, "slr->substring()", start_pos, length);
5971 216 50         XPUSHs (sv_2mortal (literal_sv));
5972             }
5973              
5974             # An internal function for converting an Earley set span to
5975             # one in terms of the input locations.
5976             # This is only meaningful in the context of an SLR
5977             void
5978             _es_to_literal_span(slr, start_earley_set, length)
5979             Scanless_R *slr;
5980             Marpa_Earley_Set_ID start_earley_set;
5981             int length;
5982             PPCODE:
5983             {
5984             int literal_start;
5985             int literal_length;
5986 0           const Marpa_Recce r1 = slr->r1;
5987 0           const Marpa_Earley_Set_ID latest_earley_set =
5988             marpa_r_latest_earley_set (r1);
5989 0 0         if (start_earley_set < 0 || start_earley_set > latest_earley_set)
5990             {
5991 0           croak
5992             ("_es_to_literal_span: earley set is %d, must be between 0 and %d",
5993             start_earley_set, latest_earley_set);
5994             }
5995 0 0         if (length < 0)
5996             {
5997 0           croak ("_es_to_literal_span: length is %d, cannot be negative", length);
5998             }
5999 0 0         if (start_earley_set + length > latest_earley_set)
6000             {
6001 0           croak
6002             ("_es_to_literal_span: final earley set is %d, must be no greater than %d",
6003             start_earley_set + length, latest_earley_set);
6004             }
6005 0           slr_es_to_literal_span (slr,
6006             start_earley_set, length,
6007             &literal_start, &literal_length);
6008 0 0         XPUSHs (sv_2mortal (newSViv ((IV) literal_start)));
6009 0 0         XPUSHs (sv_2mortal (newSViv ((IV) literal_length)));
6010             }
6011              
6012             void
6013             read(slr)
6014             Scanless_R *slr;
6015             PPCODE:
6016             {
6017             int lexer_read_result = 0;
6018 6472           const int trace_lexers = slr->trace_lexers;
6019              
6020 6472 50         if (slr->is_external_scanning)
6021             {
6022 0           XSRETURN_PV ("unpermitted mix of external and internal scanning");
6023             }
6024              
6025 6472           slr->lexer_read_result = 0;
6026 6472           slr->r1_earleme_complete_result = 0;
6027 6472           slr->start_of_pause_lexeme = -1;
6028 6472           slr->end_of_pause_lexeme = -1;
6029 6472           slr->pause_lexeme = -1;
6030              
6031             /* Clear event queue */
6032 6472           av_clear (slr->r1_wrapper->event_queue);
6033 6472           marpa__slr_event_clear (slr->gift);
6034              
6035             /* Application intervention resets perl_pos */
6036 6472           slr->last_perl_pos = -1;
6037              
6038             while (1)
6039             {
6040 34115 100         if (slr->lexer_start_pos >= 0)
6041             {
6042 29585 100         if (slr->lexer_start_pos >= slr->end_pos)
6043             {
6044 861           XSRETURN_PV ("");
6045             }
6046              
6047 28724           slr->start_of_lexeme = slr->perl_pos = slr->lexer_start_pos;
6048 28724           slr->lexer_start_pos = -1;
6049             u_r0_clear (slr);
6050 28724 50         if (trace_lexers >= 1)
6051             {
6052 0           union marpa_slr_event_s *event =
6053 0           marpa__slr_event_push (slr->gift);
6054 0           MARPA_SLREV_TYPE (event) = MARPA_SLREV_LEXER_RESTARTED_RECCE;
6055 0           event->t_lexer_restarted_recce.t_perl_pos = slr->perl_pos;
6056             }
6057             }
6058              
6059 33254 50         lexer_read_result = slr->lexer_read_result = u_read (slr);
    100          
    50          
    0          
6060             switch (lexer_read_result)
6061             {
6062             case U_READ_TRACING:
6063 0           XSRETURN_PV ("trace");
6064             case U_READ_UNREGISTERED_CHAR:
6065 4530           XSRETURN_PV ("unregistered char");
6066             default:
6067 0 0         if (lexer_read_result < 0)
6068             {
6069 0           croak
6070             ("Internal Marpa SLIF error: u_read returned unknown code: %ld",
6071             (long) lexer_read_result);
6072             }
6073             break;
6074             case U_READ_OK:
6075             case U_READ_INVALID_CHAR:
6076             case U_READ_REJECTED_CHAR:
6077             case U_READ_EXHAUSTED_ON_FAILURE:
6078             case U_READ_EXHAUSTED_ON_SUCCESS:
6079             break;
6080             }
6081              
6082              
6083 28724 100         if (marpa_r_is_exhausted (slr->r1))
6084             {
6085 677           int discard_result = slr_discard (slr);
6086 677 100         if (discard_result < 0)
6087             {
6088 10           XSRETURN_PV ("R1 exhausted before end");
6089             }
6090             }
6091             else
6092             {
6093 28047           const char *result_string = slr_alternatives (slr);
6094 28047 100         if (result_string)
6095             {
6096 29           XSRETURN_PV (result_string);
6097             }
6098             }
6099              
6100             {
6101 28685           int event_count = av_len (slr->r1_wrapper->event_queue) + 1;
6102 57370           event_count += marpa__slr_event_count (slr->gift);
6103 28685 100         if (event_count)
6104             {
6105 1042           XSRETURN_PV ("event");
6106             }
6107             }
6108              
6109 27643 50         if (slr->trace_terminals || slr->trace_lexers)
    50          
6110             {
6111 0           XSRETURN_PV ("trace");
6112             }
6113              
6114             }
6115              
6116             /* Never reached */
6117             XSRETURN_PV ("");
6118             }
6119              
6120             void
6121             lexer_read_result (slr)
6122             Scanless_R *slr;
6123             PPCODE:
6124             {
6125 0 0         XPUSHs (sv_2mortal (newSViv ((IV) slr->lexer_read_result)));
6126             }
6127              
6128             void
6129             r1_earleme_complete_result (slr)
6130             Scanless_R *slr;
6131             PPCODE:
6132             {
6133 0 0         XPUSHs (sv_2mortal (newSViv ((IV) slr->r1_earleme_complete_result)));
6134             }
6135              
6136             void
6137             pause_span (slr)
6138             Scanless_R *slr;
6139             PPCODE:
6140             {
6141 242           Marpa_Symbol_ID pause_lexeme = slr->pause_lexeme;
6142 242 50         if (pause_lexeme < 0)
6143             {
6144 0           XSRETURN_UNDEF;
6145             }
6146 242 50         XPUSHs (sv_2mortal (newSViv ((IV) slr->start_of_pause_lexeme)));
6147 242 50         XPUSHs (sv_2mortal
6148             (newSViv
6149             ((IV) slr->end_of_pause_lexeme - slr->start_of_pause_lexeme)));
6150             }
6151              
6152             void
6153             pause_lexeme (slr)
6154             Scanless_R *slr;
6155             PPCODE:
6156             {
6157 67           Marpa_Symbol_ID pause_lexeme = slr->pause_lexeme;
6158 67 100         if (pause_lexeme < 0)
6159             {
6160 1           XSRETURN_UNDEF;
6161             }
6162 66 50         XPUSHs (sv_2mortal (newSViv ((IV) pause_lexeme)));
6163             }
6164              
6165             void
6166             events(slr)
6167             Scanless_R *slr;
6168             PPCODE:
6169             {
6170             int i;
6171             int queue_length;
6172 6787           AV *const event_queue_av = slr->r1_wrapper->event_queue;
6173              
6174 8038 100         for (i = 0; i < slr->gift->t_event_count; i++)
6175             {
6176 1251           union marpa_slr_event_s *const slr_event = slr->gift->t_events + i;
6177              
6178 1251           const int event_type = MARPA_SLREV_TYPE (slr_event);
6179 1251           switch (event_type)
6180             {
6181             case MARPA_SLREV_DELETED:
6182             break;
6183              
6184             case MARPA_SLRTR_CODEPOINT_READ:
6185             {
6186 0           AV *event_av = newAV ();
6187              
6188 0           av_push (event_av, newSVpvs ("'trace"));
6189 0           av_push (event_av, newSVpvs ("lexer reading codepoint"));
6190 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_read.t_codepoint));
6191 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_read.t_perl_pos));
6192 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6193 0           break;
6194             }
6195              
6196             case MARPA_SLRTR_CODEPOINT_REJECTED:
6197             {
6198 0           AV *event_av = newAV ();
6199 0           av_push (event_av, newSVpvs ("'trace"));
6200 0           av_push (event_av, newSVpvs ("lexer rejected codepoint"));
6201 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_rejected.t_codepoint));
6202 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_rejected.t_perl_pos));
6203 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_rejected.t_symbol_id));
6204 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6205 0           break;
6206             }
6207              
6208             case MARPA_SLRTR_CODEPOINT_ACCEPTED:
6209             {
6210 0           AV *event_av = newAV ();
6211 0           av_push (event_av, newSVpvs ("'trace"));
6212 0           av_push (event_av, newSVpvs ("lexer accepted codepoint"));
6213 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_accepted.t_codepoint));
6214 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_accepted.t_perl_pos));
6215 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_codepoint_accepted.t_symbol_id));
6216 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6217 0           break;
6218             }
6219              
6220             case MARPA_SLRTR_LEXEME_DISCARDED:
6221             {
6222 13           AV *event_av = newAV ();
6223 13           av_push (event_av, newSVpvs ("'trace"));
6224 13           av_push (event_av, newSVpvs ("discarded lexeme"));
6225             /* We do not have the lexeme, but we have the
6226             * lexer rule.
6227             * The upper level will have to figure things out.
6228             */
6229 13           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_discarded.t_rule_id));
6230 13           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_discarded.t_start_of_lexeme));
6231 13           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_discarded.t_end_of_lexeme));
6232 13 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6233 13           break;
6234             }
6235              
6236             case MARPA_SLRTR_LEXEME_IGNORED:
6237             {
6238 0           AV *event_av = newAV ();
6239 0           av_push (event_av, newSVpvs ("'trace"));
6240 0           av_push (event_av, newSVpvs ("ignored lexeme"));
6241 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_ignored.t_lexeme));
6242 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_ignored.t_start_of_lexeme));
6243 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_ignored.t_end_of_lexeme));
6244 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6245 0           break;
6246             }
6247              
6248             case MARPA_SLREV_LEXEME_DISCARDED:
6249             {
6250 485           AV *event_av = newAV ();
6251 485           av_push (event_av, newSVpvs ("discarded lexeme"));
6252 485           av_push (event_av, newSViv ((IV) slr_event->t_lexeme_discarded.t_rule_id));
6253 485           av_push (event_av, newSViv ((IV) slr_event->t_lexeme_discarded.t_start_of_lexeme));
6254 485           av_push (event_av, newSViv ((IV) slr_event->t_lexeme_discarded.t_end_of_lexeme));
6255 485           av_push (event_av, newSViv ((IV) slr_event->t_lexeme_discarded.t_last_g1_location));
6256 485 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6257 485           break;
6258             }
6259              
6260             case MARPA_SLREV_SYMBOL_COMPLETED:
6261             {
6262 240           AV *event_av = newAV ();
6263 240           av_push (event_av, newSVpvs ("symbol completed"));
6264 240           av_push (event_av, newSViv ((IV) slr_event->t_symbol_completed.t_symbol));
6265 240 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6266 240           break;
6267             }
6268              
6269             case MARPA_SLREV_SYMBOL_NULLED:
6270             {
6271 41           AV *event_av = newAV ();
6272 41           av_push (event_av, newSVpvs ("symbol nulled"));
6273 41           av_push (event_av, newSViv ((IV) slr_event->t_symbol_nulled.t_symbol));
6274 41 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6275 41           break;
6276             }
6277              
6278             case MARPA_SLREV_SYMBOL_PREDICTED:
6279             {
6280 59           AV *event_av = newAV ();
6281 59           av_push (event_av, newSVpvs ("symbol predicted"));
6282 59           av_push (event_av, newSViv ((IV) slr_event->t_symbol_predicted.t_symbol));
6283 59 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6284 59           break;
6285             }
6286              
6287             case MARPA_SLREV_MARPA_R_UNKNOWN:
6288             {
6289             /* An unknown Marpa_Recce event */
6290 0           AV *event_av = newAV ();
6291 0           const int r_event_ix = slr_event->t_marpa_r_unknown.t_event;
6292             const char *result_string = event_type_to_string (r_event_ix);
6293 0 0         if (!result_string)
6294             {
6295 0           result_string =
6296             form ("unknown marpa_r event code, %d", r_event_ix);
6297             }
6298 0           av_push (event_av, newSVpvs ("unknown marpa_r event"));
6299 0           av_push (event_av, newSVpv (result_string, 0));
6300 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6301 0           break;
6302             }
6303              
6304             case MARPA_SLRTR_LEXEME_REJECTED:
6305             {
6306 9           AV *event_av = newAV ();
6307 9           av_push (event_av, newSVpvs ("'trace"));
6308 9           av_push (event_av, newSVpvs ("rejected lexeme"));
6309 9           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_rejected.t_start_of_lexeme)); /* start */
6310 9           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_rejected.t_end_of_lexeme)); /* end */
6311 9           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_rejected.t_lexeme)); /* lexeme */
6312 9 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6313 9           break;
6314             }
6315              
6316             case MARPA_SLRTR_LEXEME_EXPECTED:
6317             {
6318 0           AV *event_av = newAV ();
6319 0           av_push (event_av, newSVpvs ("'trace"));
6320 0           av_push (event_av, newSVpvs ("expected lexeme"));
6321 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_expected.t_perl_pos));
6322 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_expected.t_lexeme));
6323 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_expected.t_assertion));
6324 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6325 0           break;
6326             }
6327              
6328             case MARPA_SLRTR_LEXEME_OUTPRIORITIZED:
6329             {
6330             /* Uses same structure as "acceptable" lexeme */
6331 0           AV *event_av = newAV ();
6332 0           av_push (event_av, newSVpvs ("'trace"));
6333 0           av_push (event_av, newSVpvs ("outprioritized lexeme"));
6334 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_acceptable.t_start_of_lexeme)); /* start */
6335 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_acceptable.t_end_of_lexeme)); /* end */
6336 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_acceptable.t_lexeme)); /* lexeme */
6337 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_acceptable.t_priority));
6338 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_lexeme_acceptable.t_required_priority));
6339 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6340 0           break;
6341             }
6342              
6343             case MARPA_SLRTR_BEFORE_LEXEME:
6344             {
6345 0           AV *event_av = newAV ();
6346 0           av_push (event_av, newSVpvs ("'trace"));
6347 0           av_push (event_av, newSVpvs ("g1 before lexeme event"));
6348 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_before_lexeme.t_start_of_pause_lexeme)); /* start */
6349 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_before_lexeme.t_end_of_pause_lexeme)); /* end */
6350 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_before_lexeme.t_pause_lexeme)); /* lexeme */
6351 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6352 0           break;
6353             }
6354              
6355             case MARPA_SLREV_BEFORE_LEXEME:
6356             {
6357 192           AV *event_av = newAV ();
6358 192           av_push (event_av, newSVpvs ("before lexeme"));
6359 192           av_push (event_av, newSViv ((IV) slr_event->t_before_lexeme.t_pause_lexeme)); /* lexeme */
6360 192 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6361 192           break;
6362             }
6363              
6364             case MARPA_SLRTR_G1_ATTEMPTING_LEXEME:
6365             {
6366 0           AV *event_av = newAV ();
6367 0           av_push (event_av, newSVpvs ("'trace"));
6368 0           av_push (event_av, newSVpvs ("g1 attempting lexeme"));
6369 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_attempting_lexeme.t_start_of_lexeme)); /* start */
6370 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_attempting_lexeme.t_end_of_lexeme)); /* end */
6371 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_attempting_lexeme.t_lexeme)); /* lexeme */
6372 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6373 0           break;
6374             }
6375              
6376             case MARPA_SLRTR_G1_DUPLICATE_LEXEME:
6377             {
6378 0           AV *event_av = newAV ();
6379 0           av_push (event_av, newSVpvs ("'trace"));
6380 0           av_push (event_av, newSVpvs ("g1 duplicate lexeme"));
6381 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_duplicate_lexeme.t_start_of_lexeme)); /* start */
6382 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_duplicate_lexeme.t_end_of_lexeme)); /* end */
6383 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_duplicate_lexeme.t_lexeme)); /* lexeme */
6384 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6385 0           break;
6386             }
6387              
6388             case MARPA_SLRTR_G1_ACCEPTED_LEXEME:
6389             {
6390 16           AV *event_av = newAV ();
6391 16           av_push (event_av, newSVpvs ("'trace"));
6392 16           av_push (event_av, newSVpvs ("g1 accepted lexeme"));
6393 16           av_push (event_av, newSViv ((IV) slr_event->t_trace_accepted_lexeme.t_start_of_lexeme)); /* start */
6394 16           av_push (event_av, newSViv ((IV) slr_event->t_trace_accepted_lexeme.t_end_of_lexeme)); /* end */
6395 16           av_push (event_av, newSViv ((IV) slr_event->t_trace_accepted_lexeme.t_lexeme)); /* lexeme */
6396 16 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6397 16           break;
6398             }
6399              
6400             case MARPA_SLRTR_AFTER_LEXEME:
6401             {
6402 0           AV *event_av = newAV ();
6403 0           av_push (event_av, newSVpvs ("'trace"));
6404 0           av_push (event_av, newSVpvs ("g1 pausing after lexeme"));
6405 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_after_lexeme.t_start_of_lexeme)); /* start */
6406 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_after_lexeme.t_end_of_lexeme)); /* end */
6407 0           av_push (event_av, newSViv ((IV) slr_event->t_trace_after_lexeme.t_lexeme)); /* lexeme */
6408 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6409 0           break;
6410             }
6411              
6412             case MARPA_SLREV_AFTER_LEXEME:
6413             {
6414 196           AV *event_av = newAV ();;
6415 196           av_push (event_av, newSVpvs ("after lexeme"));
6416 196           av_push (event_av, newSViv ((IV) slr_event->t_after_lexeme.t_lexeme)); /* lexeme */
6417 196 50         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6418 196           break;
6419             }
6420              
6421             case MARPA_SLREV_LEXER_RESTARTED_RECCE:
6422             {
6423 0           AV *event_av = newAV ();
6424 0           av_push (event_av, newSVpvs ("'trace"));
6425 0           av_push (event_av, newSVpv ("lexer restarted recognizer", 0));
6426 0           av_push (event_av,
6427             newSViv ((IV) slr_event->t_lexer_restarted_recce.
6428             t_perl_pos));
6429 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6430 0           break;
6431             }
6432              
6433             case MARPA_SLREV_NO_ACCEPTABLE_INPUT:
6434             {
6435 0           AV *event_av = newAV ();
6436 0           av_push (event_av, newSVpvs ("no acceptable input"));
6437 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6438 0           break;
6439             }
6440              
6441             default:
6442             {
6443 0           AV *event_av = newAV ();
6444 0           av_push (event_av, newSVpvs ("unknown SLR event"));
6445 0           av_push (event_av, newSViv ((IV) event_type));
6446 0 0         XPUSHs (sv_2mortal (newRV_noinc ((SV *) event_av)));
6447 0           break;
6448             }
6449             }
6450             }
6451              
6452 6787           queue_length = av_len (event_queue_av);
6453 6853 100         for (i = 0; i <= queue_length; i++)
6454             {
6455 66           SV *event = av_shift (event_queue_av);
6456 66 50         XPUSHs (sv_2mortal (event));
6457             }
6458             }
6459              
6460             void
6461             span(slr, earley_set)
6462             Scanless_R *slr;
6463             IV earley_set;
6464             PPCODE:
6465             {
6466             int start_position;
6467             int length;
6468 3475           slr_es_to_span(slr, earley_set, &start_position, &length);
6469 3475 50         XPUSHs (sv_2mortal (newSViv ((IV) start_position)));
6470 3475 50         XPUSHs (sv_2mortal (newSViv ((IV) length)));
6471             }
6472              
6473             void
6474             lexeme_span (slr)
6475             Scanless_R *slr;
6476             PPCODE:
6477             {
6478 2           STRLEN length = slr->end_of_lexeme - slr->start_of_lexeme;
6479 2 50         XPUSHs (sv_2mortal (newSViv ((IV) slr->start_of_lexeme)));
6480 2 50         XPUSHs (sv_2mortal (newSViv ((IV) length)));
6481             }
6482              
6483             # Return values are 1-based, as is the tradition
6484             # EOF is reported as the last line, last column plus one.
6485             void
6486             line_column(slr, pos)
6487             Scanless_R *slr;
6488             IV pos;
6489             PPCODE:
6490             {
6491             int line = 1;
6492             int column = 1;
6493             int linecol;
6494             int at_eof = 0;
6495 438           const int logical_size = slr->pos_db_logical_size;
6496              
6497 438 50         if (pos < 0)
6498             {
6499 0           pos = slr->perl_pos;
6500             }
6501 438 50         if (pos > logical_size)
6502             {
6503 0 0         if (logical_size < 0) {
6504 0           croak ("Problem in slr->line_column(%ld): line/column information not available",
6505             (long) pos);
6506             }
6507 0           croak ("Problem in slr->line_column(%ld): position out of range",
6508             (long) pos);
6509             }
6510              
6511             /* At EOF, find data for position - 1 */
6512 438 100         if (pos == logical_size) { at_eof = 1; pos--; }
6513 438           linecol = slr->pos_db[pos].linecol;
6514 438 100         if (linecol >= 0)
6515             { /* Zero should not happen */
6516             line = linecol;
6517             }
6518             else
6519             {
6520 367           line = slr->pos_db[pos + linecol].linecol;
6521 367           column = -linecol + 1;
6522             }
6523 438 100         if (at_eof) { column++; }
6524 438 50         XPUSHs (sv_2mortal (newSViv ((IV) line)));
6525 438 50         XPUSHs (sv_2mortal (newSViv ((IV) column)));
6526             }
6527              
6528             # Variable arg as opposed to a ref,
6529             # because there seems to be no
6530             # easy, forward-compatible way
6531             # to determine whether the de-referenced value will cause
6532             # a "bizarre copy" error.
6533             #
6534             # All errors are returned, not thrown
6535             void
6536             g1_alternative (slr, symbol_id, ...)
6537             Scanless_R *slr;
6538             Marpa_Symbol_ID symbol_id;
6539             PPCODE:
6540             {
6541             int result;
6542             int token_ix;
6543 194           switch (items)
6544             {
6545             case 2:
6546             token_ix = TOKEN_VALUE_IS_LITERAL; /* default */
6547             break;
6548             case 3:
6549             {
6550 159           SV *token_value = ST (2);
6551 159 50         if (IS_PERL_UNDEF (token_value))
6552             {
6553             token_ix = TOKEN_VALUE_IS_UNDEF; /* default */
6554             break;
6555             }
6556             /* Fail fast with a tainted input token value */
6557 159 50         if (SvTAINTED(token_value)) {
    0          
6558 0           croak
6559             ("Problem in Marpa::R2: Attempt to use a tainted token value\n"
6560             "Marpa::R2 is insecure for use with tainted data\n");
6561             }
6562 159           av_push (slr->token_values, newSVsv (token_value));
6563 159           token_ix = av_len (slr->token_values);
6564             }
6565 159           break;
6566             default:
6567 0           croak
6568             ("Usage: Marpa::R2::Thin::SLR::g1_alternative(slr, symbol_id, [value])");
6569             }
6570              
6571 194           result = marpa_r_alternative (slr->r1, symbol_id, token_ix, 1);
6572 194 50         if (result >= MARPA_ERR_NONE) {
6573 194           slr->is_external_scanning = 1;
6574             }
6575 194           XSRETURN_IV (result);
6576             }
6577              
6578             # Returns current position on success, 0 on unthrown failure
6579             void
6580             g1_lexeme_complete (slr, start_pos_arg, lexeme_length_arg)
6581             Scanless_R *slr;
6582             int start_pos_arg;
6583             int lexeme_length_arg;
6584             PPCODE:
6585             {
6586             int result;
6587 194           const int input_length = slr->pos_db_logical_size;
6588             int start_pos = start_pos_arg;
6589             int lexeme_length = lexeme_length_arg;
6590              
6591             /* User intervention resets last |perl_pos| */
6592 194           slr->last_perl_pos = -1;
6593              
6594 194 50         start_pos = start_pos < 0 ? input_length + start_pos : start_pos;
6595 194 50         if (start_pos < 0 || start_pos > input_length)
6596             {
6597             /* Undef start_pos_sv should not cause error */
6598 0           croak ("Bad start position in slr->g1_lexeme_complete(... %ld, %ld)",
6599             (long) start_pos_arg, (long) lexeme_length_arg);
6600             }
6601 194           slr->perl_pos = start_pos;
6602              
6603             {
6604             const int end_pos =
6605             lexeme_length <
6606 194 50         0 ? input_length + lexeme_length + 1 : start_pos + lexeme_length;
6607 194 50         if (end_pos < 0 || end_pos > input_length)
6608             {
6609             /* Undef length_sv should not cause error */
6610 0           croak ("Bad length in slr->g1_lexeme_complete(... %ld, %ld)",
6611             (long) start_pos_arg, (long) lexeme_length_arg);
6612             }
6613 194           lexeme_length = end_pos - start_pos;
6614             }
6615              
6616 194           av_clear (slr->r1_wrapper->event_queue);
6617 194           marpa__slr_event_clear(slr->gift);
6618 194           result = marpa_r_earleme_complete (slr->r1);
6619 194           slr->is_external_scanning = 0;
6620 194 50         if (result >= 0)
6621             {
6622 194           r_convert_events (slr->r1_wrapper);
6623 194           marpa_r_latest_earley_set_values_set (slr->r1, start_pos,
6624 194           INT2PTR (void *, (ptrdiff_t)lexeme_length));
6625 194           slr->perl_pos = start_pos + lexeme_length;
6626 194           XSRETURN_IV (slr->perl_pos);
6627             }
6628 0 0         if (result == -2)
6629             {
6630 0           const int error = marpa_g_error (slr->g1_wrapper->g, NULL);
6631 0 0         if (error == MARPA_ERR_PARSE_EXHAUSTED)
6632             {
6633 0           union marpa_slr_event_s *event = marpa__slr_event_push(slr->gift);
6634 0           MARPA_SLREV_TYPE (event) = MARPA_SLREV_NO_ACCEPTABLE_INPUT;
6635             }
6636 0           XSRETURN_IV (0);
6637             }
6638 0 0         if (slr->throw)
6639             {
6640 0           croak ("Problem in slr->g1_lexeme_complete(): %s",
6641             xs_g_error (slr->g1_wrapper));
6642             }
6643 0           XSRETURN_IV (0);
6644             }
6645              
6646             void
6647             discard_event_activate( slr, l0_rule_id, reactivate )
6648             Scanless_R *slr;
6649             Marpa_Rule_ID l0_rule_id;
6650             int reactivate;
6651             PPCODE:
6652             {
6653             struct l0_rule_r_properties *l0_rule_r_properties;
6654 390           const Scanless_G *slg = slr->slg;
6655 390           const Marpa_Rule_ID highest_l0_rule_id = marpa_g_highest_rule_id (slg->l0_wrapper->g);
6656 390 50         if (l0_rule_id > highest_l0_rule_id)
6657             {
6658 0           croak
6659             ("Problem in slr->discard_event_activate(..., %ld, %ld): rule ID was %ld, but highest L0 rule ID = %ld",
6660             (long) l0_rule_id, (long) reactivate,
6661             (long) l0_rule_id, (long) highest_l0_rule_id);
6662             }
6663 390 50         if (l0_rule_id < 0)
6664             {
6665 0           croak
6666             ("Problem in slr->discard_event_activate(..., %ld, %ld): rule ID was %ld, a disallowed value",
6667             (long) l0_rule_id, (long) reactivate, (long) l0_rule_id);
6668             }
6669 390           l0_rule_r_properties = slr->l0_rule_r_properties + l0_rule_id;
6670 390           switch (reactivate)
6671             {
6672             case 0:
6673 195           l0_rule_r_properties->t_event_on_discard_active = 0;
6674 195           break;
6675             case 1:
6676             {
6677 195           const struct l0_rule_g_properties* g_properties = slg->l0_rule_g_properties + l0_rule_id;
6678             /* Only activate events which are enabled */
6679 195           l0_rule_r_properties->t_event_on_discard_active = g_properties->t_event_on_discard;
6680             }
6681 195           break;
6682             default:
6683 0           croak
6684             ("Problem in slr->discard_event_activate(..., %ld, %ld): reactivate flag is %ld, a disallowed value",
6685             (long) l0_rule_id, (long) reactivate, (long) reactivate);
6686             }
6687 390 50         XPUSHs (sv_2mortal (newSViv (reactivate)));
6688             }
6689              
6690             void
6691             lexeme_event_activate( slr, g1_lexeme_id, reactivate )
6692             Scanless_R *slr;
6693             Marpa_Symbol_ID g1_lexeme_id;
6694             int reactivate;
6695             PPCODE:
6696             {
6697             struct symbol_r_properties *symbol_r_properties;
6698 29           const Scanless_G *slg = slr->slg;
6699 29           const Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
6700 29 50         if (g1_lexeme_id > highest_g1_symbol_id)
6701             {
6702 0           croak
6703             ("Problem in slr->lexeme_event_activate(..., %ld, %ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
6704             (long) g1_lexeme_id, (long) reactivate,
6705             (long) g1_lexeme_id, (long) highest_g1_symbol_id);
6706             }
6707 29 50         if (g1_lexeme_id < 0)
6708             {
6709 0           croak
6710             ("Problem in slr->lexeme_event_activate(..., %ld, %ld): symbol ID was %ld, a disallowed value",
6711             (long) g1_lexeme_id, (long) reactivate, (long) g1_lexeme_id);
6712             }
6713 29           symbol_r_properties = slr->symbol_r_properties + g1_lexeme_id;
6714 29           switch (reactivate)
6715             {
6716             case 0:
6717 17           symbol_r_properties->t_pause_after_active = 0;
6718 17           symbol_r_properties->t_pause_before_active = 0;
6719 17           break;
6720             case 1:
6721             {
6722 12           const struct symbol_g_properties* g_properties = slg->symbol_g_properties + g1_lexeme_id;
6723             /* Only activate events which are enabled */
6724 12           symbol_r_properties->t_pause_after_active = g_properties->t_pause_after;
6725 12           symbol_r_properties->t_pause_before_active = g_properties->t_pause_before;
6726             }
6727 12           break;
6728             default:
6729 0           croak
6730             ("Problem in slr->lexeme_event_activate(..., %ld, %ld): reactivate flag is %ld, a disallowed value",
6731             (long) g1_lexeme_id, (long) reactivate, (long) reactivate);
6732             }
6733 29 50         XPUSHs (sv_2mortal (newSViv (reactivate)));
6734             }
6735              
6736             void
6737             problem_pos( slr )
6738             Scanless_R *slr;
6739             PPCODE:
6740             {
6741 7 50         if (slr->problem_pos < 0) {
6742 0           XSRETURN_UNDEF;
6743             }
6744 7           XSRETURN_IV(slr->problem_pos);
6745             }
6746              
6747             void
6748             lexer_latest_earley_set( slr )
6749             Scanless_R *slr;
6750             PPCODE:
6751             {
6752 0           const Marpa_Recce r0 = slr->r0;
6753 0 0         if (!r0)
6754             {
6755 0           XSRETURN_UNDEF;
6756             }
6757 0           XSRETURN_IV (marpa_r_latest_earley_set (r0));
6758             }
6759              
6760             void
6761             lexer_progress_report_start( slr, ordinal )
6762             Scanless_R *slr;
6763             Marpa_Earley_Set_ID ordinal;
6764             PPCODE:
6765             {
6766             int gp_result;
6767             G_Wrapper* lexer_wrapper;
6768 0           const Marpa_Recognizer recce = slr->r0;
6769 0 0         if (!recce)
6770             {
6771 0           croak ("Problem in r->progress_item(): No lexer recognizer");
6772             }
6773 0           lexer_wrapper = slr->slg->l0_wrapper;
6774 0           gp_result = marpa_r_progress_report_start(recce, ordinal);
6775 0 0         if ( gp_result == -1 ) { XSRETURN_UNDEF; }
6776 0 0         if ( gp_result < 0 && lexer_wrapper->throw ) {
    0          
6777 0           croak( "Problem in r->progress_report_start(%d): %s",
6778             ordinal, xs_g_error( lexer_wrapper ));
6779             }
6780 0 0         XPUSHs (sv_2mortal (newSViv (gp_result)));
6781             }
6782              
6783             void
6784             lexer_progress_report_finish( slr )
6785             Scanless_R *slr;
6786             PPCODE:
6787             {
6788             int gp_result;
6789             G_Wrapper* lexer_wrapper;
6790 0           const Marpa_Recognizer recce = slr->r0;
6791 0 0         if (!recce)
6792             {
6793 0           croak ("Problem in r->progress_item(): No lexer recognizer");
6794             }
6795 0           lexer_wrapper = slr->slg->l0_wrapper;
6796 0           gp_result = marpa_r_progress_report_finish(recce);
6797 0 0         if ( gp_result == -1 ) { XSRETURN_UNDEF; }
6798 0 0         if ( gp_result < 0 && lexer_wrapper->throw ) {
    0          
6799 0           croak( "Problem in r->progress_report_finish(): %s",
6800             xs_g_error( lexer_wrapper ));
6801             }
6802 0 0         XPUSHs (sv_2mortal (newSViv (gp_result)));
6803             }
6804              
6805             void
6806             lexer_progress_item( slr )
6807             Scanless_R *slr;
6808             PPCODE:
6809             {
6810             Marpa_Rule_ID rule_id;
6811 0           Marpa_Earley_Set_ID origin = -1;
6812 0           int position = -1;
6813             G_Wrapper* lexer_wrapper;
6814 0           const Marpa_Recognizer recce = slr->r0;
6815 0 0         if (!recce)
6816             {
6817 0           croak ("Problem in r->progress_item(): No lexer recognizer");
6818             }
6819 0           lexer_wrapper = slr->slg->l0_wrapper;
6820 0           rule_id = marpa_r_progress_item (recce, &position, &origin);
6821 0 0         if (rule_id == -1)
6822             {
6823 0           XSRETURN_UNDEF;
6824             }
6825 0 0         if (rule_id < 0 && lexer_wrapper->throw)
    0          
6826             {
6827 0           croak ("Problem in r->progress_item(): %s",
6828             xs_g_error (lexer_wrapper));
6829             }
6830 0 0         XPUSHs (sv_2mortal (newSViv (rule_id)));
6831 0 0         XPUSHs (sv_2mortal (newSViv (position)));
6832 0 0         XPUSHs (sv_2mortal (newSViv (origin)));
6833             }
6834              
6835             void
6836             string_set( slr, string )
6837             Scanless_R *slr;
6838             SVREF string;
6839             PPCODE:
6840             {
6841             U8 *p;
6842             U8 *start_of_string;
6843             U8 *end_of_string;
6844             int input_is_utf8;
6845              
6846             /* Initialized to a Unicode non-character. In fact, anything
6847             * but a CR would work here.
6848             */
6849             UV previous_codepoint = 0xFDD0;
6850             /* Counts are 1-based */
6851             int this_line = 1;
6852             int this_column = 1;
6853              
6854             STRLEN pv_length;
6855              
6856             /* Fail fast with a tainted input string */
6857 975 100         if (SvTAINTED (string))
    100          
6858             {
6859 1           croak
6860             ("Problem in v->string_set(): Attempt to use a tainted input string with Marpa::R2\n"
6861             "Marpa::R2 is insecure for use with tainted data\n");
6862             }
6863              
6864             /* Get our own copy and coerce it to a PV.
6865             * Stealing is OK, magic is not.
6866             */
6867 974 50         SvSetSV (slr->input, string);
6868 974 50         start_of_string = (U8 *) SvPV_force_nomg (slr->input, pv_length);
6869 974           end_of_string = start_of_string + pv_length;
6870 974           input_is_utf8 = SvUTF8 (slr->input);
6871              
6872 974           slr->pos_db_logical_size = 0;
6873             /* This original buffer size my be too small.
6874             */
6875 974           slr->pos_db_physical_size = 1024;
6876 974           Newx (slr->pos_db, slr->pos_db_physical_size, Pos_Entry);
6877              
6878 91599 100         for (p = start_of_string; p < end_of_string;)
6879             {
6880             STRLEN codepoint_length;
6881             UV codepoint;
6882 90625 100         if (input_is_utf8)
6883             {
6884 7033 50         codepoint = utf8_to_uvchr_buf (p, end_of_string, &codepoint_length);
6885             /* Perl API documents that return value is 0 and length is -1 on error,
6886             * "if possible". length can be, and is, in fact unsigned.
6887             * I deal with this by noting that 0 is a valid UTF8 char but should
6888             * have a length of 1, when valid.
6889             */
6890 7033 50         if (codepoint == 0 && codepoint_length != 1)
    0          
6891             {
6892 0           croak ("Problem in slr->string_set(): invalid UTF8 character");
6893             }
6894             }
6895             else
6896             {
6897 83592           codepoint = (UV) * p;
6898 83592           codepoint_length = 1;
6899             }
6900             /* Ensure that there is enough space */
6901 90625 100         if (slr->pos_db_logical_size >= slr->pos_db_physical_size)
6902             {
6903 24           slr->pos_db_physical_size *= 2;
6904 24 50         Renew (slr->pos_db, slr->pos_db_physical_size, Pos_Entry);
6905             }
6906 90625           p += codepoint_length;
6907 90625           slr->pos_db[slr->pos_db_logical_size].next_offset = p - start_of_string;
6908              
6909             /* The definition of newline here follows the Unicode standard TR13 */
6910 90625 100         if (codepoint == 0x0a && previous_codepoint == 0x0d)
6911             {
6912             /* Set the next column to one after the last column,
6913             * instead of using the next line and column.
6914             * Delay using those until the next pass through this
6915             * loop.
6916             */
6917 8           const int pos = slr->pos_db_logical_size - 1;
6918 8           const int previous_linecol = slr->pos_db[pos].linecol;
6919 8 100         if (previous_linecol < 0)
6920             {
6921 1           slr->pos_db[slr->pos_db_logical_size].linecol = previous_linecol-1;
6922             } else {
6923 7           slr->pos_db[slr->pos_db_logical_size].linecol = -1;
6924             }
6925             }
6926             else
6927             {
6928 181234           slr->pos_db[slr->pos_db_logical_size].linecol =
6929 90617 100         this_column > 1 ? 1-this_column : this_line;
6930 90617 100         switch (codepoint)
6931             {
6932             case 0x0a:
6933             case 0x0b:
6934             case 0x0c:
6935             case 0x0d:
6936             case 0x85:
6937             case 0x2028:
6938             case 0x2029:
6939 3118           this_line++;
6940             this_column = 1;
6941 3118           break;
6942             default:
6943 87499           this_column++;
6944             }
6945             }
6946 90625           slr->pos_db_logical_size++;
6947             previous_codepoint = codepoint;
6948             }
6949 974           XSRETURN_YES;
6950             }
6951              
6952             void
6953             input_length( slr )
6954             Scanless_R *slr;
6955             PPCODE:
6956             {
6957 109           XSRETURN_IV(slr->pos_db_logical_size);
6958             }
6959              
6960             void
6961             codepoint( slr )
6962             Scanless_R *slr;
6963             PPCODE:
6964             {
6965 4530           XSRETURN_UV(slr->codepoint);
6966             }
6967              
6968             void
6969             symbol_id( slr )
6970             Scanless_R *slr;
6971             PPCODE:
6972             {
6973 0           XSRETURN_IV(slr->input_symbol_id);
6974             }
6975              
6976             void
6977             char_register( slr, codepoint, ... )
6978             Scanless_R *slr;
6979             UV codepoint;
6980             PPCODE:
6981             {
6982             /* OP Count is args less two, then plus two for codepoint and length fields */
6983             const STRLEN op_count = items;
6984             STRLEN op_ix;
6985             IV *ops;
6986             SV *ops_sv = NULL;
6987             const unsigned array_size = Dim (slr->slg->per_codepoint_array);
6988 4530           const int use_array = codepoint < array_size;
6989              
6990 4530 100         if (use_array)
6991             {
6992 4442           ops = slr->slg->per_codepoint_array[codepoint];
6993 4442 50         Renew (ops, op_count, IV);
6994 4442           slr->slg->per_codepoint_array[codepoint] = ops;
6995             }
6996             else
6997             {
6998             STRLEN dummy;
6999 88           ops_sv = newSV (op_count * sizeof (ops[0]));
7000 88           SvPOK_on (ops_sv);
7001 88 50         ops = (IV *) SvPV (ops_sv, dummy);
7002             }
7003 4530           ops[0] = codepoint;
7004 4530           ops[1] = op_count;
7005 99580 100         for (op_ix = 2; op_ix < op_count; op_ix++)
7006             {
7007             /* By coincidence, offset of individual ops is 2 both in the
7008             * method arguments and in the op_list, so that arg IX == op_ix
7009             */
7010 95050 50         ops[op_ix] = SvUV (ST (op_ix));
7011             }
7012 4530 100         if (ops_sv)
7013             {
7014 88           (void)hv_store (slr->slg->per_codepoint_hash, (char *) &codepoint,
7015             sizeof (codepoint), ops_sv, 0);
7016             }
7017             }
7018              
7019             # Untested
7020             void
7021             lexeme_priority( slr, g1_lexeme )
7022             Scanless_R *slr;
7023             Marpa_Symbol_ID g1_lexeme;
7024             PPCODE:
7025             {
7026 0           const Scanless_G *slg = slr->slg;
7027 0           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
7028 0 0         if (g1_lexeme > highest_g1_symbol_id)
7029             {
7030 0           croak
7031             ("Problem in slr->g1_lexeme_priority(%ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
7032             (long) g1_lexeme,
7033             (long) g1_lexeme,
7034             (long) highest_g1_symbol_id
7035             );
7036             }
7037 0 0         if (g1_lexeme < 0) {
7038 0           croak
7039             ("Problem in slr->g1_lexeme_priority(%ld): symbol ID was %ld, a disallowed value",
7040             (long) g1_lexeme,
7041             (long) g1_lexeme);
7042             }
7043 0 0         if ( ! slg->symbol_g_properties[g1_lexeme].is_lexeme ) {
7044 0           croak
7045             ("Problem in slr->g1_lexeme_priority(%ld): symbol ID %ld is not a lexeme",
7046             (long) g1_lexeme,
7047             (long) g1_lexeme);
7048             }
7049 0           XSRETURN_IV( slr->symbol_r_properties[g1_lexeme].lexeme_priority);
7050             }
7051              
7052             void
7053             lexeme_priority_set( slr, g1_lexeme, new_priority )
7054             Scanless_R *slr;
7055             Marpa_Symbol_ID g1_lexeme;
7056             int new_priority;
7057             PPCODE:
7058             {
7059             int old_priority;
7060 12           const Scanless_G *slg = slr->slg;
7061 12           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
7062 12 50         if (g1_lexeme > highest_g1_symbol_id)
7063             {
7064 0           croak
7065             ("Problem in slr->g1_lexeme_priority(%ld): symbol ID was %ld, but highest G1 symbol ID = %ld",
7066             (long) g1_lexeme,
7067             (long) g1_lexeme,
7068             (long) highest_g1_symbol_id
7069             );
7070             }
7071 12 50         if (g1_lexeme < 0) {
7072 0           croak
7073             ("Problem in slr->g1_lexeme_priority(%ld): symbol ID was %ld, a disallowed value",
7074             (long) g1_lexeme,
7075             (long) g1_lexeme);
7076             }
7077 12 50         if ( ! slg->symbol_g_properties[g1_lexeme].is_lexeme ) {
7078 0           croak
7079             ("Problem in slr->g1_lexeme_priority(%ld): symbol ID %ld is not a lexeme",
7080             (long) g1_lexeme,
7081             (long) g1_lexeme);
7082             }
7083 12           old_priority = slr->symbol_r_properties[g1_lexeme].lexeme_priority;
7084 12           slr->symbol_r_properties[g1_lexeme].lexeme_priority = new_priority;
7085 12           XSRETURN_IV( old_priority );
7086             }
7087              
7088             INCLUDE: general_pattern.xsh
7089              
7090             BOOT:
7091 153           marpa_debug_handler_set(marpa_r2_warn);
7092              
7093             /* vim: set expandtab shiftwidth=2: */