File Coverage

lib/Marpa/R2.xs
Criterion Covered Total %
statement 1741 2468 70.5
branch 823 1716 47.9
condition n/a
subroutine n/a
pod n/a
total 2564 4184 61.2


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 967           static Marpa_SLR marpa__slr_new(void)
296             {
297             SLR slr;
298 967           Newx (slr, 1, struct marpa_slr_s);
299 967           slr->t_ref_count = 1;
300              
301 967           slr->t_count_of_deleted_events = 0;
302 967           slr->t_event_count = 0;
303 967           slr->t_event_capacity = MAX (1024 / sizeof (union marpa_slr_event_s), 16);
304 967           Newx (slr->t_events, slr->t_event_capacity, union marpa_slr_event_s);
305              
306 967           slr->t_lexeme_count = 0;
307 967           slr->t_lexeme_capacity = MAX (1024 / sizeof (union marpa_slr_event_s), 16);
308 967           Newx (slr->t_lexemes, slr->t_lexeme_capacity, union marpa_slr_event_s);
309              
310 967           return slr;
311             }
312              
313 967           static void slr_free(SLR slr)
314             {
315 967           Safefree(slr->t_events);
316 967           Safefree(slr->t_lexemes);
317 967           Safefree( slr);
318 967           }
319              
320             static void
321             slr_unref (Marpa_SLR slr)
322             {
323             /* MARPA_ASSERT (slr->t_ref_count > 0) */
324 967           slr->t_ref_count--;
325 967 50         if (slr->t_ref_count <= 0)
326             {
327 967           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 2475           marpa__slif_op_id (const char *name)
352             {
353             int lo = 0;
354             int hi = Dim (op_by_name_object) - 1;
355 9614 50         while (hi >= lo)
356             {
357 9614           const int trial = lo + (hi - lo) / 2;
358 9614           const char *trial_name = op_by_name_object[trial].name;
359 9614           int cmp = strcmp (name, trial_name);
360 9614 100         if (!cmp)
361 2475           return op_by_name_object[trial].op;
362 7139 100         if (cmp < 0)
363             {
364 3214           hi = trial - 1;
365             }
366             else
367             {
368 7139           lo = trial + 1;
369             }
370             }
371             return -1;
372             }
373              
374             static void marpa__slr_event_clear( Marpa_SLR slr )
375             {
376 6569           slr->t_event_count = 0;
377 6569           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 28192           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 27554           slr->t_lexeme_count = 0;
399             }
400              
401 30835           static union marpa_slr_event_s * marpa__slr_lexeme_push( Marpa_SLR slr )
402             {
403 30835 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 30835           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 33356 50         if (step_type >= 0 && step_type < MARPA_STEP_COUNT) {
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
622 33356           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 1308           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 1308 50         SET_G_WRAPPER_FROM_G_SV(g_wrapper, g_sv);
753 1308           g = g_wrapper->g;
754              
755 1308           highest_symbol_id = marpa_g_highest_symbol_id (g);
756 1308 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 1308           Newx (r_wrapper, 1, R_Wrapper);
766 1308           r_wrapper->r = r;
767 1308 50         Newx (r_wrapper->terminals_buffer, highest_symbol_id + 1, Marpa_Symbol_ID);
768 1308           r_wrapper->ruby_slippers = 0;
769             SvREFCNT_inc (g_sv);
770 1308           r_wrapper->base_sv = g_sv;
771 1308           r_wrapper->base = g_wrapper;
772 1308           r_wrapper->event_queue = newAV();
773 1308           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 1308           r_unwrap (R_Wrapper * r_wrapper)
781             {
782             dTHX;
783 1308           Marpa_Recce r = r_wrapper->r;
784             /* The wrapper should always have had a ref to its base grammar's SV */
785 1308           SvREFCNT_dec (r_wrapper->base_sv);
786 1308           SvREFCNT_dec ((SV *) r_wrapper->event_queue);
787 1308           Safefree (r_wrapper->terminals_buffer);
788 1308           Safefree (r_wrapper);
789             /* The wrapper should always have had a ref to the Libmarpa recce */
790 1308           return r;
791             }
792              
793             static void
794             u_r0_clear (Scanless_R * slr)
795             {
796             dTHX;
797 28231           Marpa_Recce r0 = slr->r0;
798 28231 100         if (!r0)
799             return;
800 27287           marpa_r_unref (r0);
801 27287           slr->r0 = NULL;
802             }
803              
804             static Marpa_Recce
805 28231           u_r0_new (Scanless_R * slr)
806             {
807             dTHX;
808 28231           Marpa_Recce r0 = slr->r0;
809 28231           const IV trace_lexers = slr->trace_lexers;
810 28231           const IV trace_terminals = slr->trace_terminals;
811 28231           G_Wrapper *lexer_wrapper = slr->slg->l0_wrapper;
812 28231           const int too_many_earley_items = slr->too_many_earley_items;
813              
814 28231 50         if (r0)
815             {
816 0           marpa_r_unref (r0);
817             }
818 28231           slr->r0 = r0 = marpa_r_new (lexer_wrapper->g);
819 28231 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 28231 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 28231           Marpa_Symbol_ID *terminals_buffer = slr->r1_wrapper->terminals_buffer;
832 28231           const int count = marpa_r_terminals_expected (slr->r1, terminals_buffer);
833 28231 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 583559 100         for (i = 0; i < count; i++)
839             {
840 555328           const Marpa_Symbol_ID terminal = terminals_buffer[i];
841 555328           const Marpa_Assertion_ID assertion =
842 555328           slr->slg->g1_lexeme_to_assertion[terminal];
843 555328 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 555328 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 28231           int gp_result = marpa_r_start_input (r0);
864 28231 50         if (gp_result == -1)
865             return 0;
866 28231 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 17588           u_convert_events (Scanless_R * slr)
884             {
885             dTHX;
886             int event_ix;
887 8794           Marpa_Grammar g = slr->slg->l0_wrapper->g;
888 8794           const int event_count = marpa_g_event_count (g);
889 17588 100         for (event_ix = 0; event_ix < event_count; event_ix++)
890             {
891             Marpa_Event marpa_event;
892 8794           Marpa_Event_Type event_type =
893             marpa_g_event (g, &marpa_event, event_ix);
894 8794           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 8794           }
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 32672           u_read (Scanless_R * slr)
952             {
953             dTHX;
954             U8 *input;
955             STRLEN len;
956             int input_is_utf8;
957              
958 32672           const IV trace_lexers = slr->trace_lexers;
959 32672           Marpa_Recognizer r = slr->r0;
960              
961 32672 100         if (!r)
962             {
963 28231           r = u_r0_new (slr);
964 28231 50         if (!r)
965 0           croak ("Problem in u_read(): %s",
966 0           xs_g_error (slr->slg->l0_wrapper));
967             }
968 32672           input_is_utf8 = SvUTF8 (slr->input);
969 32672 50         input = (U8 *) SvPV (slr->input, len);
970             for (;;)
971             {
972             UV codepoint;
973 112181           STRLEN codepoint_length = 1;
974             STRLEN op_ix;
975             STRLEN op_count;
976             IV *ops;
977             int tokens_accepted = 0;
978 112181 100         if (slr->perl_pos >= slr->end_pos)
979             break;
980              
981 111846 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 102444 100         codepoint = (UV) input[OFFSET_IN_INPUT (slr)];
1001             codepoint_length = 1;
1002             }
1003              
1004 111846 100         if (codepoint < Dim (slr->slg->per_codepoint_array))
1005             {
1006 111519           ops = slr->slg->per_codepoint_array[codepoint];
1007 111519 100         if (!ops)
1008             {
1009 4353           slr->codepoint = codepoint;
1010 32337           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 107405 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 107405           op_count = ops[1];
1037 795611 100         for (op_ix = 2; op_ix < op_count; op_ix++)
1038             {
1039 716102           IV op_code = ops[op_ix];
1040 716102           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 608697           op_ix++;
1050 608697 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 608697           symbol_id = (int) ops[op_ix];
1058 608697 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 608697           value = (int) ops[++op_ix];
1066 608697           length = (int) ops[++op_ix];
1067 608697           result = marpa_r_alternative (r, symbol_id, value, length);
1068 608697           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 511777           slr->input_symbol_id = symbol_id;
1076 511777 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 96920 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 96920           tokens_accepted++;
1095 96920           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 107403 100         if (tokens_accepted < 1)
1118             {
1119 19100           slr->codepoint = codepoint;
1120 19100           return U_READ_REJECTED_CHAR;
1121             }
1122 88303           result = marpa_r_earleme_complete (r);
1123 88303 100         if (result > 0)
1124             {
1125 8794           u_convert_events (slr);
1126             /* Advance one character before returning */
1127 8794 50         if (marpa_r_is_exhausted (r))
1128             {
1129             return U_READ_EXHAUSTED_ON_SUCCESS;
1130             }
1131             goto ADVANCE_ONE_CHAR;
1132             }
1133 79509 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 79509 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 79509           slr->perl_pos++;
1158 79509 50         if (trace_lexers)
1159             {
1160             return U_READ_TRACING;
1161             }
1162 79509           }
1163 335           return U_READ_OK;
1164             }
1165              
1166             /* It is OK to set pos to last codepoint + 1 */
1167             static STRLEN
1168 1903           u_pos_set (Scanless_R * slr, const char* name, int start_pos_arg, int length_arg)
1169             {
1170             dTHX;
1171 1903           const STRLEN old_perl_pos = slr->perl_pos;
1172 1903           const STRLEN input_length = slr->pos_db_logical_size;
1173             int new_perl_pos;
1174             int new_end_pos;
1175              
1176 1903 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 1903 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 1903 100         if (length_arg < 0) {
1187 1708           new_end_pos = input_length + length_arg + 1;
1188             } else {
1189 195           new_end_pos = new_perl_pos + length_arg;
1190             }
1191 1903 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 1903           slr->last_perl_pos = -1;
1198 1903           slr->perl_pos = new_perl_pos;
1199 1903           slr->end_pos = new_end_pos;
1200 1903           return old_perl_pos;
1201             }
1202              
1203             static SV *
1204 44088           u_pos_span_to_literal_sv (Scanless_R * slr,
1205             int start_pos, int length_in_positions)
1206             {
1207             dTHX;
1208             STRLEN dummy;
1209 22044 50         char *input = SvPV (slr->input, dummy);
1210             SV* new_sv;
1211 22044 100         int start_offset = POS_TO_OFFSET (slr, start_pos);
1212 22044           int length_in_bytes =
1213 22044 50         POS_TO_OFFSET (slr,
1214             start_pos + length_in_positions) - start_offset;
1215 22044           new_sv = newSVpvn (input + start_offset, length_in_bytes);
1216 22044 100         if (SvUTF8(slr->input)) {
1217 1525           SvUTF8_on(new_sv);
1218             }
1219 22044           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 7600           v_create_stack(V_Wrapper* v_wrapper)
1254             {
1255             dTHX;
1256 3800 50         if (v_wrapper->mode == MARPA_XS_V_MODE_IS_RAW)
1257             {
1258             return -1;
1259             }
1260 3800           v_wrapper->stack = newAV ();
1261 3800           av_extend (v_wrapper->stack, 1023);
1262 3800           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 121870           v_do_stack_ops (V_Wrapper * v_wrapper, SV ** stack_results)
1278             {
1279             dTHX;
1280 121870           AV *stack = v_wrapper->stack;
1281 121870           const Marpa_Value v = v_wrapper->v;
1282 121870           const Marpa_Step_Type step_type = marpa_v_step_type (v);
1283 121870           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 121870           v_wrapper->result = result_ix;
1295              
1296 121870           switch (step_type)
1297             {
1298             STRLEN dummy;
1299             case MARPA_STEP_RULE:
1300             {
1301 68244           SV **p_ops_sv =
1302 68244           av_fetch (v_wrapper->rule_semantics, marpa_v_rule (v), 0);
1303 68244 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 68244 50         ops = (IV *) SvPV (*p_ops_sv, dummy);
1309             }
1310 121870           break;
1311             case MARPA_STEP_TOKEN:
1312             {
1313 44767           SV **p_ops_sv =
1314 44767           av_fetch (v_wrapper->token_semantics, marpa_v_token (v), 0);
1315 44767 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 44767 50         ops = (IV *) SvPV (*p_ops_sv, dummy);
1321             }
1322             break;
1323             case MARPA_STEP_NULLING_SYMBOL:
1324             {
1325 8859           SV **p_ops_sv =
1326 8859           av_fetch (v_wrapper->nulling_semantics, marpa_v_token (v), 0);
1327 8859 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 8859 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 330619           IV op_code = ops[op_ix++];
1345              
1346 330619 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 330619           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 2361           IV stack_offset = ops[op_ix++];
1418             IV fetch_ix;
1419              
1420 2361 50         if (step_type != MARPA_STEP_RULE)
1421             {
1422 0           av_fill (stack, result_ix - 1);
1423 0           return -1;
1424             }
1425 2361 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 2353           av_fill (stack, result_ix);
1432 2353           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 40640 100         if (!values_av)
1494             {
1495 8           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1496             }
1497 40640           ref_to_values_av = newRV_inc ((SV *) values_av);
1498 40640 100         if (blessing)
1499             {
1500 39215           SV **p_blessing_sv =
1501 39215           av_fetch (v_wrapper->constants, blessing, 0);
1502 39215 50         if (p_blessing_sv && SvPOK (*p_blessing_sv))
    50          
1503             {
1504             STRLEN blessing_length;
1505 39215 50         char *classname = SvPV (*p_blessing_sv, blessing_length);
1506 39215           sv_bless (ref_to_values_av, gv_stashpv (classname, 1));
1507             }
1508             }
1509 40640           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 40640 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 40640           av_fill (stack, result_ix);
1521             }
1522 40640           return -1;
1523              
1524             case MARPA_OP_PUSH_VALUES:
1525             case MARPA_OP_PUSH_SEQUENCE:
1526             {
1527              
1528 14136 100         if (!values_av)
1529             {
1530 749           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1531             }
1532              
1533 14136           switch (step_type)
1534             {
1535             case MARPA_STEP_TOKEN:
1536             {
1537             SV **p_token_value_sv;
1538 8529           int token_ix = marpa_v_token_value (v);
1539 8529           Scanless_R *slr = v_wrapper->slr;
1540 8529 50         if (slr && token_ix == TOKEN_VALUE_IS_LITERAL)
1541             {
1542             SV *sv;
1543 8529           Marpa_Earley_Set_ID start_earley_set =
1544             marpa_v_token_start_es_id (v);
1545 8529           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1546 8529           sv =
1547 8529           slr_es_span_to_literal_sv (slr, start_earley_set,
1548             end_earley_set -
1549             start_earley_set);
1550 8529           av_push (values_av, sv);
1551 208749           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 5588           const int arg_n = marpa_v_arg_n (v);
1571 5588 100         int increment = op_code == MARPA_OP_PUSH_SEQUENCE ? 2 : 1;
1572              
1573 17667 100         for (stack_ix = result_ix; stack_ix <= arg_n;
1574 12079           stack_ix += increment)
1575             {
1576 12079           SV **p_sv = av_fetch (stack, stack_ix, 0);
1577 12079 100         if (!p_sv)
1578             {
1579 121           av_push (values_av, &PL_sv_undef);
1580             }
1581             else
1582             {
1583 11958           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 75142           offset = ops[op_ix++];
1635 75142 100         if (!values_av)
1636             {
1637 23797           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1638             }
1639 75142 100         if (step_type != MARPA_STEP_RULE)
1640             {
1641 1699           av_push (values_av, &PL_sv_undef);
1642 1699           goto NEXT_OP_CODE;
1643             }
1644 73443           p_sv = av_fetch (stack, result_ix + offset, 0);
1645 73443 100         if (!p_sv)
1646             {
1647 706           av_push (values_av, &PL_sv_undef);
1648             }
1649             else
1650             {
1651 72737           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 39106           Scanless_R *slr = v_wrapper->slr;
1660             Marpa_Earley_Set_ID start_earley_set;
1661             int dummy;
1662              
1663 39106 100         if (!values_av)
1664             {
1665 38914           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1666             }
1667 39106 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 39106           switch (step_type)
1673             {
1674             case MARPA_STEP_RULE:
1675 28971           start_earley_set = marpa_v_rule_start_es_id (v);
1676 28971           break;
1677             case MARPA_STEP_NULLING_SYMBOL:
1678             case MARPA_STEP_TOKEN:
1679 10135           start_earley_set = marpa_v_token_start_es_id (v);
1680 10135           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 39106           slr_es_to_literal_span (slr, start_earley_set, 0, &start_location,
1687             &dummy);
1688 39106           av_push (values_av, newSViv ((IV) start_location));
1689             }
1690 39106           goto NEXT_OP_CODE;
1691              
1692             case MARPA_OP_PUSH_LENGTH:
1693             {
1694             int length;
1695 39106           Scanless_R *slr = v_wrapper->slr;
1696              
1697 39106 50         if (!values_av)
1698             {
1699 0           values_av = (AV *) sv_2mortal ((SV *) newAV ());
1700             }
1701 39106 50         if (!slr)
1702             {
1703 0           croak
1704             ("Problem in v->stack_step: 'push_length' op attempted when no slr is set");
1705             }
1706 39106           switch (step_type)
1707             {
1708             case MARPA_STEP_NULLING_SYMBOL:
1709 1799           length = 0;
1710 1799           break;
1711             case MARPA_STEP_RULE:
1712             {
1713             int dummy;
1714 28971           Marpa_Earley_Set_ID start_earley_set =
1715             marpa_v_rule_start_es_id (v);
1716 28971           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1717 28971           slr_es_to_literal_span (slr, start_earley_set,
1718             end_earley_set - start_earley_set,
1719             &dummy, &length);
1720             }
1721 28971           break;
1722             case MARPA_STEP_TOKEN:
1723             {
1724             int dummy;
1725 8336           Marpa_Earley_Set_ID start_earley_set =
1726             marpa_v_token_start_es_id (v);
1727 8336           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1728 8336           slr_es_to_literal_span (slr, start_earley_set,
1729             end_earley_set - start_earley_set,
1730             &dummy, &length);
1731             }
1732 8336           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 39106           av_push (values_av, newSViv ((IV) length));
1739             }
1740 39106           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 39215           blessing = ops[op_ix++];
1832             }
1833 39215           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 25175           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 23841 50         if (!values_av)
1847             {
1848 0           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 25175           *p_stack_results++ = sv_2mortal (newSVpv (result_string, 0));
1858 50350           *p_stack_results++ =
1859 25175 100         sv_2mortal (newSViv
1860             (step_type ==
1861             MARPA_STEP_RULE ? marpa_v_rule (v) :
1862             marpa_v_token (v)));
1863              
1864 25175 100         if (values_av)
1865             {
1866             /* De-mortalize av_values */
1867 23917           SV *ref_to_values_av =
1868 23917           sv_2mortal (newRV_inc ((SV *) values_av));
1869 23917 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 23917           *p_stack_results++ = ref_to_values_av;
1883             }
1884 25175           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 36238           Scanless_R *slr = v_wrapper->slr;
1892 36238           int token_ix = marpa_v_token_value (v);
1893              
1894 36238 50         if (step_type != MARPA_STEP_TOKEN)
1895             {
1896 0           av_fill (stack, result_ix - 1);
1897 0           return -1;
1898             }
1899 36238 100         if (slr && token_ix == TOKEN_VALUE_IS_LITERAL)
1900             {
1901             SV **stored_sv;
1902             SV *token_literal_sv;
1903 13299           Marpa_Earley_Set_ID start_earley_set =
1904             marpa_v_token_start_es_id (v);
1905 13299           Marpa_Earley_Set_ID end_earley_set = marpa_v_es_id (v);
1906 13299           token_literal_sv =
1907 13299           slr_es_span_to_literal_sv (slr, start_earley_set,
1908             end_earley_set -
1909             start_earley_set);
1910 13299           stored_sv = av_store (stack, result_ix, token_literal_sv);
1911 13299 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 774           slr_convert_events (Scanless_R * slr)
2138             {
2139             dTHX;
2140             int event_ix;
2141 387           Marpa_Grammar g = slr->r1_wrapper->base->g;
2142 387           const int event_count = marpa_g_event_count (g);
2143 977 100         for (event_ix = 0; event_ix < event_count; event_ix++)
2144             {
2145             Marpa_Event marpa_event;
2146 590           Marpa_Event_Type event_type = marpa_g_event (g, &marpa_event, event_ix);
2147 590           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 387           }
2200              
2201             /* Called after marpa_r_start_input() and
2202             * marpa_r_earleme_complete().
2203             */
2204             static void
2205 3004           r_convert_events (R_Wrapper * r_wrapper)
2206             {
2207             dTHX;
2208             int event_ix;
2209 1502           Marpa_Grammar g = r_wrapper->base->g;
2210 1502           const int event_count = marpa_g_event_count (g);
2211 1857 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 1502           }
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 27554           slr_alternatives (Scanless_R * slr)
2303             {
2304             dTHX;
2305             Marpa_Recce r0;
2306 27554           Marpa_Recce r1 = slr->r1;
2307             Marpa_Earley_Set_ID earley_set;
2308 27554           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 27554           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 27554           r0 = slr->r0;
2321 27554 50         if (!r0)
2322             {
2323 0           croak ("Problem in slr->read(): No R0 at %s %d", __FILE__, __LINE__);
2324             }
2325              
2326 27554           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 27560 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 27533           working_pos = slr->start_of_lexeme + earley_set;
2337              
2338 27533           return_value = marpa_r_progress_report_start (r0, earley_set);
2339 27533 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 136211 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 108678           Marpa_Rule_ID rule_id =
2357             marpa_r_progress_item (r0, &dot_position, &origin);
2358 108678 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 108678 100         if (rule_id == -1)
2364             {
2365             end_of_earley_items = 1;
2366             goto NEXT_PASS1_REPORT_ITEM;
2367             }
2368 81145 100         if (origin != 0)
2369             goto NEXT_PASS1_REPORT_ITEM;
2370 76914 100         if (dot_position != -1)
2371             goto NEXT_PASS1_REPORT_ITEM;
2372 74721           l0_rule_g_properties = slg->l0_rule_g_properties + rule_id;
2373 74721           g1_lexeme = l0_rule_g_properties->g1_lexeme;
2374 74721 100         if (g1_lexeme == -1)
2375             goto NEXT_PASS1_REPORT_ITEM;
2376 30835           slr->end_of_lexeme = working_pos;
2377             /* -2 means a discarded item */
2378 30835 100         if (g1_lexeme <= -2)
2379             {
2380 12492           union marpa_slr_event_s *lexeme_entry =
2381 12492           marpa__slr_lexeme_push (slr->gift);
2382 12492           MARPA_SLREV_TYPE (lexeme_entry) = MARPA_SLRTR_LEXEME_DISCARDED;
2383 12492           lexeme_entry->t_trace_lexeme_discarded.t_rule_id = rule_id;
2384 12492           lexeme_entry->t_trace_lexeme_discarded.t_start_of_lexeme =
2385 12492           slr->start_of_lexeme;
2386 12492           lexeme_entry->t_trace_lexeme_discarded.t_end_of_lexeme =
2387 12492           slr->end_of_lexeme;
2388 12492           discarded++;
2389              
2390 12492           goto NEXT_PASS1_REPORT_ITEM;
2391             }
2392 18343           symbol_g_properties = slg->symbol_g_properties + g1_lexeme;
2393             l0_rule_g_properties = slg->l0_rule_g_properties + rule_id;
2394 18343           symbol_r_properties = slr->symbol_r_properties + g1_lexeme;
2395 18343           is_expected = marpa_r_terminal_is_expected (r1, g1_lexeme);
2396 18343 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 17970           this_lexeme_priority = symbol_r_properties->lexeme_priority;
2426 17970 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 17970           union marpa_slr_event_s *lexeme_entry =
2434 17970           marpa__slr_lexeme_push (slr->gift);
2435 17970           MARPA_SLREV_TYPE (lexeme_entry) = MARPA_SLRTR_LEXEME_ACCEPTABLE;
2436 17970           lexeme_entry->t_lexeme_acceptable.t_start_of_lexeme =
2437 17970           slr->start_of_lexeme;
2438 17970           lexeme_entry->t_lexeme_acceptable.t_end_of_lexeme =
2439 17970           slr->end_of_lexeme;
2440 17970           lexeme_entry->t_lexeme_acceptable.t_lexeme = g1_lexeme;
2441 17970           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 108678           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 27533 100         if (discarded || rejected || is_priority_set)
2454             break;
2455              
2456             }
2457              
2458             /* Figure out what the result of pass 1 was */
2459 27554 100         if (is_priority_set)
2460             {
2461             pass1_result = accept;
2462 12518 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 58389 100         for (i = 0; i < slr->gift->t_lexeme_count; i++)
2478             {
2479 30835           union marpa_slr_event_s *const lexeme_stack_event = slr->gift->t_lexemes + i;
2480 30835           const int event_type = MARPA_SLREV_TYPE (lexeme_stack_event);
2481 30835           switch (event_type)
2482             {
2483             case MARPA_SLRTR_LEXEME_ACCEPTABLE:
2484 17970 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 12492 100         if (slr->trace_terminals)
2506             {
2507 13           *(marpa__slr_event_push (slr->gift)) = *lexeme_stack_event;
2508             }
2509 12492 100         if (pass1_result == discard)
2510             {
2511             union marpa_slr_event_s *new_event;
2512 12489           const Marpa_Rule_ID l0_rule_id =
2513             lexeme_stack_event->t_trace_lexeme_discarded.t_rule_id;
2514 12489           struct l0_rule_r_properties *l0_rule_r_properties
2515 12489           = slr->l0_rule_r_properties + l0_rule_id;
2516 12489 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 27554 100         if (pass1_result == discard) {
2538 12489           slr->perl_pos = slr->lexer_start_pos = working_pos;
2539 12489           return 0;
2540             }
2541              
2542 15065 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 33378 100         for (i = 0; i < slr->gift->t_lexeme_count; i++)
2558             {
2559 18342           union marpa_slr_event_s *const lexeme_entry = slr->gift->t_lexemes + i;
2560 18342           const int event_type = MARPA_SLREV_TYPE (lexeme_entry);
2561 18342 100         if (event_type == MARPA_SLRTR_LEXEME_ACCEPTABLE)
2562             {
2563 17956           const Marpa_Symbol_ID lexeme_id =
2564             lexeme_entry->t_lexeme_acceptable.t_lexeme;
2565 17956           const struct symbol_r_properties *symbol_r_properties =
2566 17956           slr->symbol_r_properties + lexeme_id;
2567 17956 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 15036 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 32994 100         for (i = 0; i < slr->gift->t_lexeme_count; i++)
2607             {
2608 18150           union marpa_slr_event_s *const event = slr->gift->t_lexemes + i;
2609 18150           const int event_type = MARPA_SLREV_TYPE (event);
2610 18150 100         if (event_type == MARPA_SLRTR_LEXEME_ACCEPTABLE)
2611             {
2612 17764           const Marpa_Symbol_ID g1_lexeme =
2613             event->t_lexeme_acceptable.t_lexeme;
2614 17764           const struct symbol_r_properties *symbol_r_properties =
2615 17764           slr->symbol_r_properties + g1_lexeme;
2616              
2617 17764 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 17764           return_value =
2627             marpa_r_alternative (r1, g1_lexeme, TOKEN_VALUE_IS_LITERAL, 1);
2628 17764           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 17764 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 17764 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 14844           return_value = slr->r1_earleme_complete_result =
2699 14844           marpa_r_earleme_complete (r1);
2700 14844 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 14844           slr->lexer_start_pos = slr->perl_pos = slr->end_of_lexeme;
2706 14844 100         if (return_value > 0)
2707             {
2708 387           slr_convert_events (slr);
2709             }
2710              
2711 14844           marpa_r_latest_earley_set_values_set (r1, slr->start_of_lexeme,
2712 14844           INT2PTR (void *,
2713             (slr->end_of_lexeme -
2714             slr->start_of_lexeme)));
2715             }
2716              
2717 14844           return 0;
2718              
2719             }
2720              
2721             static void
2722 223162           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 111581 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 111554           result =
2738 111554           marpa_r_earley_set_values (slr->r1, earley_set, p_start,
2739             &length_as_ptr);
2740 111554           *p_length = (int) PTR2IV (length_as_ptr);
2741             }
2742 111581 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 111581           }
2748              
2749             static void
2750 98241           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 98241           const Marpa_Recce r1 = slr->r1;
2756 98241           const Marpa_Earley_Set_ID latest_earley_set =
2757             marpa_r_latest_earley_set (r1);
2758 98241 100         if (start_earley_set >= latest_earley_set)
2759             {
2760             /* Should only happen if length == 0 */
2761 187           *p_start = slr->pos_db_logical_size;
2762 187           *p_length = 0;
2763 187           return;
2764             }
2765 98054           slr_es_to_span (slr, start_earley_set + 1, p_start, p_length);
2766 98054 100         if (length == 0)
2767 38919           *p_length = 0;
2768 98054 100         if (length > 1)
2769             {
2770             int last_lexeme_start_position;
2771             int last_lexeme_length;
2772 10052           slr_es_to_span (slr, start_earley_set + length,
2773             &last_lexeme_start_position, &last_lexeme_length);
2774 10052           *p_length = last_lexeme_start_position + last_lexeme_length - *p_start;
2775             }
2776             }
2777              
2778             static SV*
2779 21828           slr_es_span_to_literal_sv (Scanless_R * slr,
2780             Marpa_Earley_Set_ID start_earley_set, int length)
2781             {
2782             dTHX;
2783 21828 50         if (length > 0)
2784             {
2785             int length_in_positions;
2786             int start_position;
2787 21828           slr_es_to_literal_span (slr,
2788             start_earley_set, length,
2789             &start_position, &length_in_positions);
2790 21828           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 17675 100         for (error_code = 0; error_code < MARPA_ERROR_COUNT; error_code++)
2821             {
2822 17500           const char *error_name = marpa_error_description[error_code].name;
2823 17500 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 2475           const int op_id = marpa__slif_op_id (op_name);
2837 2475 50         if (op_id >= 0)
2838             {
2839 2475           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 773           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 772           SV *arg = ST (1);
2905             HV *named_args;
2906 772 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 772           hv_iterinit (named_args);
2910 1544 100         while ((arg_value = hv_iternextsv (named_args, &key, &retlen)))
2911             {
2912 772 50         if ((*key == 'i') && strnEQ (key, "if", (unsigned) retlen))
    50          
    0          
    0          
    0          
    50          
2913             {
2914 772 50         interface = SvIV (arg_value);
2915 772 50         if (interface != 1)
2916             {
2917 0           croak ("Problem in $g->new(): interface value must be 1");
2918             }
2919 772           continue;
2920             }
2921 0           croak ("Problem in $g->new(): unknown named argument: %s", key);
2922             }
2923 772 50         if (interface != 1)
2924             {
2925 772           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 773           error_code = marpa_version (version);
2948 773 50         if (error_code != MARPA_ERR_NONE
2949 773 50         || version[0] != EXPECTED_LIBMARPA_MAJOR
2950 773 50         || version[1] != EXPECTED_LIBMARPA_MINOR
2951 773 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 773           marpa_c_init (&marpa_configuration);
2961 773           g = marpa_g_new (&marpa_configuration);
2962 773 50         if (g)
2963             {
2964             SV *sv;
2965 773           Newx (g_wrapper, 1, G_Wrapper);
2966 773           g_wrapper->throw = throw;
2967 773           g_wrapper->g = g;
2968 773           g_wrapper->message_buffer = NULL;
2969 773           g_wrapper->libmarpa_error_code = MARPA_ERR_NONE;
2970 773           g_wrapper->libmarpa_error_string = NULL;
2971 773           g_wrapper->message_is_marpa_thin_error = 0;
2972 773           sv = sv_newmortal ();
2973 773           sv_setref_pv (sv, grammar_c_class_name, (void *) g_wrapper);
2974 773 50         XPUSHs (sv);
2975             }
2976             else
2977             {
2978 0           error_code = marpa_c_error (&marpa_configuration, NULL);
2979             }
2980              
2981 773 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 773 100         if (g_wrapper->message_buffer)
3006 24           Safefree(g_wrapper->message_buffer);
3007 773           grammar = g_wrapper->g;
3008 773           marpa_g_unref( grammar );
3009 773           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 45064           Marpa_Grammar g = g_wrapper->g;
3056             int length;
3057             Marpa_Symbol_ID* rhs;
3058             Marpa_Rule_ID new_rule_id;
3059 45064           length = av_len(rhs_av)+1;
3060 45064 100         if (length <= 0) {
3061             rhs = (Marpa_Symbol_ID*)NULL;
3062             } else {
3063             int i;
3064 44668 50         Newx(rhs, length, Marpa_Symbol_ID);
3065 135826 100         for (i = 0; i < length; i++) {
3066 91158           SV** elem = av_fetch(rhs_av, i, 0);
3067 91158 50         if (elem == NULL) {
3068 0           Safefree(rhs);
3069 0           XSRETURN_UNDEF;
3070             } else {
3071 91158 50         rhs[i] = (Marpa_Symbol_ID)SvIV(*elem);
3072             }
3073             }
3074             }
3075 45064           new_rule_id = marpa_g_rule_new(g, lhs, rhs, length);
3076 45064           Safefree(rhs);
3077 45064 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 45064 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 4379           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 4379 50         if (args)
3102             {
3103             I32 retlen;
3104             char *key;
3105             SV *arg_value;
3106 4379           hv_iterinit (args);
3107 12592 100         while ((arg_value = hv_iternextsv (args, &key, &retlen)))
3108             {
3109 8213 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 8213 100         if ((*key == 'm') && strnEQ (key, "min", (unsigned) retlen))
    50          
    0          
    0          
    0          
    0          
    50          
3116             {
3117 4379 50         IV raw_min = SvIV (arg_value);
3118 4379 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 4379 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 4379           min = (int) raw_min;
3149 4379           continue;
3150             }
3151 3834 100         if ((*key == 'p') && strnEQ (key, "proper", (unsigned) retlen))
    50          
    0          
    50          
3152             {
3153 1917 50         if (SvTRUE (arg_value))
    50          
    50          
    0          
    0          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    0          
    100          
3154 253           flags |= MARPA_PROPER_SEPARATION;
3155 1917           continue;
3156             }
3157 1917 50         if ((*key == 's') && strnEQ (key, "separator", (unsigned) retlen))
    50          
    0          
    50          
3158             {
3159 1917 50         separator = (Marpa_Symbol_ID) SvIV (arg_value);
3160 1917           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 8213           XSRETURN_UNDEF;
3174             }
3175             }
3176             }
3177             }
3178 4379           new_rule_id = marpa_g_sequence_new (g, lhs, rhs, separator, min, flags);
3179 4379 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 4379 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 34464           Marpa_Grammar self = g_wrapper->g;
3199 34464           int gp_result = marpa_g_default_rank (self);
3200 34464 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 34464           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 34458           Marpa_Grammar self = g_wrapper->g;
3257 34458           int gp_result = marpa_g_rule_rank_set(self, rule_id, rank);
3258 34458 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 34458           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 72844 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 72844           g_wrapper->throw = boolean;
3319 72844 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 1308 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 1308 50         SET_G_WRAPPER_FROM_G_SV (g_wrapper, g_sv);
3373 1308           g = g_wrapper->g;
3374 1308           r = marpa_r_new (g);
3375 1308 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 1308           R_Wrapper *r_wrapper = r_wrap (r, g_sv);
3386 1308           sv_to_return = sv_newmortal ();
3387 1308           sv_setref_pv (sv_to_return, recce_c_class_name, (void *) r_wrapper);
3388             }
3389 1308 50         XPUSHs (sv_to_return);
3390             }
3391              
3392             void
3393             DESTROY( r_wrapper )
3394             R_Wrapper *r_wrapper;
3395             PPCODE:
3396             {
3397 1308           Marpa_Recce r = r_unwrap(r_wrapper);
3398 1308           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 1195 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 1195           r_wrapper->ruby_slippers = boolean;
3413 1195 50         XPUSHs (sv_2mortal (newSViv (boolean)));
3414             }
3415              
3416             void
3417             start_input( r_wrapper )
3418             R_Wrapper *r_wrapper;
3419             PPCODE:
3420             {
3421 1308           Marpa_Recognizer self = r_wrapper->r;
3422 1308           int gp_result = marpa_r_start_input(self);
3423 1308 50         if ( gp_result == -1 ) { XSRETURN_UNDEF; }
3424 1308 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 1308           r_convert_events(r_wrapper);
3429 1308 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 1314           Marpa_Recognizer r = r_wrapper->r;
3507             B_Wrapper *b_wrapper;
3508 1314           Marpa_Bocage b = marpa_b_new (r, ordinal);
3509             PERL_UNUSED_ARG(class);
3510              
3511 1314 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 1294           Newx (b_wrapper, 1, B_Wrapper);
3517             {
3518 1294           SV* base_sv = r_wrapper->base_sv;
3519             SvREFCNT_inc (base_sv);
3520 1294           b_wrapper->base_sv = base_sv;
3521             }
3522 1294           b_wrapper->base = r_wrapper->base;
3523 1294           b_wrapper->b = b;
3524 1294           sv = sv_newmortal ();
3525 1294           sv_setref_pv (sv, bocage_c_class_name, (void *) b_wrapper);
3526 1294 50         XPUSHs (sv);
3527             }
3528              
3529             void
3530             DESTROY( b_wrapper )
3531             B_Wrapper *b_wrapper;
3532             PPCODE:
3533             {
3534 1294           const Marpa_Bocage b = b_wrapper->b;
3535 1294           SvREFCNT_dec (b_wrapper->base_sv);
3536 1294           marpa_b_unref(b);
3537 1294           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 1294           Marpa_Bocage b = b_wrapper->b;
3550             O_Wrapper *o_wrapper;
3551 1294           Marpa_Order o = marpa_o_new (b);
3552             PERL_UNUSED_ARG(class);
3553              
3554 1294 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 1294           Newx (o_wrapper, 1, O_Wrapper);
3560             {
3561 1294           SV* base_sv = b_wrapper->base_sv;
3562             SvREFCNT_inc (base_sv);
3563 1294           o_wrapper->base_sv = base_sv;
3564             }
3565 1294           o_wrapper->base = b_wrapper->base;
3566 1294           o_wrapper->o = o;
3567 1294           sv = sv_newmortal ();
3568 1294           sv_setref_pv (sv, order_c_class_name, (void *) o_wrapper);
3569 1294 50         XPUSHs (sv);
3570             }
3571              
3572             void
3573             DESTROY( o_wrapper )
3574             O_Wrapper *o_wrapper;
3575             PPCODE:
3576             {
3577 1294           const Marpa_Order o = o_wrapper->o;
3578 1294           SvREFCNT_dec (o_wrapper->base_sv);
3579 1294           marpa_o_unref(o);
3580 1294           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 1244           Marpa_Order o = o_wrapper->o;
3593             T_Wrapper *t_wrapper;
3594 1244           Marpa_Tree t = marpa_t_new (o);
3595             PERL_UNUSED_ARG(class);
3596              
3597 1244 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 1244           Newx (t_wrapper, 1, T_Wrapper);
3603             {
3604 1244           SV* base_sv = o_wrapper->base_sv;
3605             SvREFCNT_inc (base_sv);
3606 1244           t_wrapper->base_sv = base_sv;
3607             }
3608 1244           t_wrapper->base = o_wrapper->base;
3609 1244           t_wrapper->t = t;
3610 1244           sv = sv_newmortal ();
3611 1244           sv_setref_pv (sv, tree_c_class_name, (void *) t_wrapper);
3612 1244 50         XPUSHs (sv);
3613             }
3614              
3615             void
3616             DESTROY( t_wrapper )
3617             T_Wrapper *t_wrapper;
3618             PPCODE:
3619             {
3620 1244           const Marpa_Tree t = t_wrapper->t;
3621 1244           SvREFCNT_dec (t_wrapper->base_sv);
3622 1244           marpa_t_unref(t);
3623 1244           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 3922           Marpa_Tree t = t_wrapper->t;
3636             V_Wrapper *v_wrapper;
3637 3922           Marpa_Value v = marpa_v_new (t);
3638             PERL_UNUSED_ARG(class);
3639              
3640 3922 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 3922           Newx (v_wrapper, 1, V_Wrapper);
3649             {
3650 3922           SV *base_sv = t_wrapper->base_sv;
3651             SvREFCNT_inc (base_sv);
3652 3922           v_wrapper->base_sv = base_sv;
3653             }
3654 3922           v_wrapper->base = t_wrapper->base;
3655 3922           v_wrapper->v = v;
3656 3922           v_wrapper->event_queue = newAV ();
3657 3922           v_wrapper->token_values = newAV ();
3658 3922           av_fill(v_wrapper->token_values , TOKEN_VALUE_IS_LITERAL);
3659 3922           v_wrapper->stack = NULL;
3660 3922           v_wrapper->mode = MARPA_XS_V_MODE_IS_INITIAL;
3661 3922           v_wrapper->result = 0;
3662 3922           v_wrapper->trace_values = 0;
3663              
3664 3922           v_wrapper->constants = newAV ();
3665             /* Reserve position 0 */
3666 3922           av_push (v_wrapper->constants, &PL_sv_undef);
3667              
3668 3922           v_wrapper->rule_semantics = newAV ();
3669 3922           v_wrapper->token_semantics = newAV ();
3670 3922           v_wrapper->nulling_semantics = newAV ();
3671 3922           v_wrapper->slr = NULL;
3672 3922           sv = sv_newmortal ();
3673 3922           sv_setref_pv (sv, value_c_class_name, (void *) v_wrapper);
3674 3922 50         XPUSHs (sv);
3675             }
3676              
3677             void
3678             DESTROY( v_wrapper )
3679             V_Wrapper *v_wrapper;
3680             PPCODE:
3681             {
3682 3922           const Marpa_Value v = v_wrapper->v;
3683 3922           SvREFCNT_dec (v_wrapper->base_sv);
3684 3922           SvREFCNT_dec (v_wrapper->event_queue);
3685 3922           SvREFCNT_dec (v_wrapper->constants);
3686 3922           SvREFCNT_dec (v_wrapper->rule_semantics);
3687 3922           SvREFCNT_dec (v_wrapper->token_semantics);
3688 3922           SvREFCNT_dec (v_wrapper->nulling_semantics);
3689 3922 100         if (v_wrapper->slr) {
3690             SvREFCNT_dec (v_wrapper->slr);
3691             }
3692 3922 100         if (v_wrapper->stack)
3693             {
3694             SvREFCNT_dec (v_wrapper->stack);
3695             }
3696 3922           SvREFCNT_dec (v_wrapper->token_values);
3697 3922           marpa_v_unref (v);
3698 3922           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 3800           IV old_level = v_wrapper->trace_values;
3708 3800           v_wrapper->trace_values = level;
3709             {
3710             AV *event;
3711             SV *event_data[3];
3712 3800           event_data[0] = newSVpvs ("valuator trace level");
3713 3800           event_data[1] = newSViv (old_level);
3714 3800           event_data[2] = newSViv (level);
3715 3800           event = av_make (Dim (event_data), event_data);
3716 3800           av_push (v_wrapper->event_queue, newRV_noinc ((SV *) event));
3717             }
3718 3800           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 1519 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 1519           v_wrapper->slr = slr;
3753              
3754 1519           # Throw away the current token values hash
3755             SvREFCNT_dec (v_wrapper->token_values);
3756 1519            
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 3800           Marpa_Grammar g = v_wrapper->base->g;
3848 3800 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 3800 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 3800           const int highest_rule_id = marpa_g_highest_rule_id (g);
3865 3800           AV *av = v_wrapper->rule_semantics;
3866 3800           av_extend (av, highest_rule_id);
3867 3800           ops[0] = MARPA_OP_PUSH_VALUES;
3868 3800           ops[1] = MARPA_OP_CALLBACK;
3869 3800           ops[2] = 0;
3870 51351 100         for (ix = 0; ix <= highest_rule_id; ix++)
3871             {
3872 47551           SV **p_sv = av_fetch (av, ix, 1);
3873 47551 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 47551           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 3800           const int highest_symbol_id = marpa_g_highest_symbol_id (g);
3887 3800           AV *av = v_wrapper->nulling_semantics;
3888 3800           av_extend (av, highest_symbol_id);
3889 3800           ops[0] = MARPA_OP_RESULT_IS_UNDEF;
3890 3800           ops[1] = 0;
3891 57656 100         for (ix = 0; ix <= highest_symbol_id; ix++)
3892             {
3893 53856           SV **p_sv = av_fetch (av, ix, 1);
3894 53856 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 53856           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 3800           const int highest_symbol_id = marpa_g_highest_symbol_id (g);
3908 3800           AV *av = v_wrapper->token_semantics;
3909 3800           av_extend (av, highest_symbol_id);
3910 3800           ops[0] = MARPA_OP_RESULT_IS_TOKEN_VALUE;
3911 3800           ops[1] = 0;
3912 57656 100         for (ix = 0; ix <= highest_symbol_id; ix++)
3913             {
3914 53856           SV **p_sv = av_fetch (av, ix, 1);
3915 53856 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 53856           sv_setpvn (*p_sv, (char *) ops, Dim(ops)*sizeof (ops[0]));
3922             }
3923             }
3924              
3925 3800           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 47551           const STRLEN op_count = items - 2;
3936             STRLEN op_ix;
3937             STRLEN dummy;
3938             IV *ops;
3939             SV *ops_sv;
3940 47551           AV *rule_semantics = v_wrapper->rule_semantics;
3941              
3942 47551 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 47551           ops_sv = newSV ((op_count+1) * sizeof (ops[0]));
3949              
3950 47551           SvPOK_on (ops_sv);
3951 47551 50         ops = (IV *) SvPV (ops_sv, dummy);
3952 291237 100         for (op_ix = 0; op_ix < op_count; op_ix++)
3953             {
3954 243686 50         ops[op_ix] = SvUV (ST (op_ix+2));
3955             }
3956 47551           ops[op_ix] = 0;
3957 47551 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 53856           const STRLEN op_count = items - 2;
3970             STRLEN op_ix;
3971             STRLEN dummy;
3972             IV *ops;
3973             SV *ops_sv;
3974 53856           AV *token_semantics = v_wrapper->token_semantics;
3975              
3976 53856 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 53856           ops_sv = newSV ((op_count+1) * sizeof (ops[0]));
3983              
3984 53856           SvPOK_on (ops_sv);
3985 53856 50         ops = (IV *) SvPV (ops_sv, dummy);
3986 127879 100         for (op_ix = 0; op_ix < op_count; op_ix++)
3987             {
3988 74023 50         ops[op_ix] = SvIV (ST (op_ix+2));
3989             }
3990 53856           ops[op_ix] = 0;
3991 53856 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 7359           const STRLEN op_count = items - 2;
4004             STRLEN op_ix;
4005             STRLEN dummy;
4006             IV *ops;
4007             SV *ops_sv;
4008 7359           AV *nulling_semantics = v_wrapper->nulling_semantics;
4009              
4010 7359 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 7359           ops_sv = newSV ((op_count+1) * sizeof (ops[0]));
4017              
4018 7359           SvPOK_on (ops_sv);
4019 7359 50         ops = (IV *) SvPV (ops_sv, dummy);
4020 21706 100         for (op_ix = 0; op_ix < op_count; op_ix++)
4021             {
4022 14347 50         ops[op_ix] = SvIV (ST (op_ix+2));
4023             }
4024 7359           ops[op_ix] = 0;
4025 7359 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 28896           AV *constants = v_wrapper->constants;
4037              
4038 28896 50         if (!constants)
4039             {
4040 0           croak
4041             ("Problem in v->constant_register(): valuator is not in stack mode");
4042             }
4043 28896 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 28896           av_push (constants, SvREFCNT_inc_simple_NN (sv));
4050 28896           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 3790           AV* stack = v_wrapper->stack;
4071 3790 50         if (!stack) { XSRETURN_UNDEF; }
4072 3790           p_sv = av_fetch(stack, index, 0);
4073 3790 100         if (!p_sv) { XSRETURN_UNDEF; }
4074 2060 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 25165           AV *stack = v_wrapper->stack;
4100 25165 50         if (!stack)
4101             {
4102 0           croak ("Problem in v->result_set(): valuator is not in stack mode");
4103             }
4104 25165           result_ix = v_wrapper->result;
4105 25165           av_fill(stack, result_ix);
4106              
4107             SvREFCNT_inc (sv);
4108 25165           p_stored_sv = av_store (stack, result_ix, sv);
4109 25165 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 29044           av_clear (v_wrapper->event_queue);
4122              
4123 29044 50         if (v_wrapper->mode != MARPA_XS_V_MODE_IS_STACK)
4124             {
4125 0 0         if (v_wrapper->stack)
4126             {
4127 29044           croak
4128             ("Problem in v->stack_step(): Cannot call unless valuator is in 'stack' mode");
4129             }
4130             }
4131              
4132             while (1)
4133             {
4134 125709           Marpa_Step_Type step_type = marpa_v_step (v_wrapper->v);
4135 125709           switch (step_type)
4136             {
4137             case MARPA_STEP_INACTIVE:
4138 3790           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 121870           int stack_offset = v_do_stack_ops (v_wrapper, stack_results);
4148 121870 100         if (stack_offset < 0)
4149             {
4150             goto NEXT_STEP;
4151             }
4152 99442 100         for (ix = 0; ix < stack_offset; ix++)
4153             {
4154 74267 50         XPUSHs (stack_results[ix]);
4155             }
4156 25175           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 96695 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 3800           const Marpa_Value v = v_wrapper->v;
5171             int status;
5172 3800           status = _marpa_v_trace (v, flag);
5173 3800 50         if (status == -1)
5174             {
5175 0           XSRETURN_UNDEF;
5176             }
5177 3800 50         if (status < 0)
5178             {
5179 0           croak ("Problem in v->trace(): %s", xs_g_error(v_wrapper->base));
5180             }
5181 3800 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 266 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 266 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 266           Newx (slg, 1, Scanless_G);
5225              
5226 266           slg->g1_sv = g1_sv;
5227             SvREFCNT_inc (g1_sv);
5228              
5229 266 50         # These do not need references, because parent objects
5230 266           # hold references to them
5231 266           SET_G_WRAPPER_FROM_G_SV(slg->g1_wrapper, g1_sv)
5232             slg->g1 = slg->g1_wrapper->g;
5233 266           slg->precomputed = 0;
5234              
5235             slg->l0_sv = l0_sv;
5236 266 50         SvREFCNT_inc (l0_sv);
5237              
5238             # Wrapper does not need reference, because parent objects
5239             # holds references to it
5240 266           SET_G_WRAPPER_FROM_G_SV (slg->l0_wrapper, l0_sv);
5241 34314 100          
5242             {
5243 34048           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 266           }
5250 266            
5251 266 50         {
5252             int symbol_ix;
5253 14600 100         int g1_symbol_count =
5254 14334           marpa_g_highest_symbol_id ( slg->g1 ) + 1;
5255             Newx (slg->g1_lexeme_to_assertion, g1_symbol_count,
5256 14334           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 266           }
5263 266 50          
5264 14600 100         {
5265 14334           Marpa_Symbol_ID symbol_id;
5266 14334           int g1_symbol_count = marpa_g_highest_symbol_id (slg->g1) + 1;
5267 14334           Newx (slg->symbol_g_properties, g1_symbol_count, struct symbol_g_properties);
5268 14334           for (symbol_id = 0; symbol_id < g1_symbol_count; symbol_id++) {
5269 14334           slg->symbol_g_properties[symbol_id].priority = 0;
5270 14334           slg->symbol_g_properties[symbol_id].latm = 0;
5271 14334           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 266           }
5278 266 50          
5279 22638 100         {
5280 22372           Marpa_Rule_ID rule_id;
5281 22372           int g1_rule_count = marpa_g_highest_rule_id (slg->l0_wrapper->g) + 1;
5282 22372           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 266           slg->l0_rule_g_properties[rule_id].t_event_on_discard_active = 0;
5287 266           }
5288 266 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 266           SvREFCNT_dec (slg->g1_sv);
5302 266           SvREFCNT_dec (slg->l0_sv);
5303 266           Safefree (slg->symbol_g_properties);
5304 266           Safefree (slg->l0_rule_g_properties);
5305 266           Safefree (slg->g1_lexeme_to_assertion);
5306 266           SvREFCNT_dec (slg->per_codepoint_hash);
5307 34314 100         for (i = 0; i < Dim(slg->per_codepoint_array); i++) {
5308 34048           Safefree(slg->per_codepoint_array[i]);
5309             }
5310 266           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 22362           highest_lexer_rule_id = marpa_g_highest_rule_id (slg->l0_wrapper->g);
5339 22362           highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5340 22362           highest_assertion_id = marpa_g_highest_zwa_id (slg->l0_wrapper->g);
5341 22362 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 22362 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 22362 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 22362 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 22362 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 22362 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 22362 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 22362 50         if (lexer_rule >= 0) {
5393 22362           struct l0_rule_g_properties * const l0_rule_g_properties = slg->l0_rule_g_properties + lexer_rule;
5394 22362           l0_rule_g_properties->g1_lexeme = g1_lexeme;
5395             }
5396 22362 100         if (g1_lexeme >= 0) {
5397 8666           slg->g1_lexeme_to_assertion[g1_lexeme] = assertion_id;
5398             }
5399 22362           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 8666           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5413 8666 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 8666 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 8666 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 8666           slg->symbol_g_properties[g1_lexeme].priority = priority;
5437 8666           slg->symbol_g_properties[g1_lexeme].is_lexeme = 1;
5438 8666           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 8666           Marpa_Symbol_ID highest_g1_symbol_id = marpa_g_highest_symbol_id (slg->g1);
5678 8666           struct symbol_g_properties * g_properties = slg->symbol_g_properties + g1_lexeme;
5679 8666 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 8666 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 8666 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 8666 50         switch (latm) {
5703             case 0: case 1:
5704 8666           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 8666           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 262 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 262           slg->precomputed = 1;
5731             }
5732 262           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 967 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 967 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 967           Newx (slr, 1, Scanless_R);
5759              
5760 967           slr->throw = 1;
5761 967           slr->trace_lexers = 0;
5762 967           slr->trace_terminals = 0;
5763 967           slr->r0 = NULL;
5764              
5765 967           # Copy and take references to the "parent objects",
5766             # the ones responsible for holding references.
5767 967           slr->slg_sv = slg_sv;
5768             SvREFCNT_inc (slg_sv);
5769             slr->r1_sv = r1_sv;
5770 967 50         SvREFCNT_inc (r1_sv);
5771 967 50          
5772 967 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 967           {
5778 967           croak
5779 967 50         ("Problem in u->new(): Attempted to create SLIF recce from unprecomputed SLIF grammar");
5780             }
5781 967           slr->slg = slg;
5782 967           slr->r1 = slr->r1_wrapper->r;
5783 967           SET_G_WRAPPER_FROM_G_SV (slr->g1_wrapper, slr->r1_wrapper->base_sv);
5784              
5785 967           slr->start_of_lexeme = 0;
5786 967           slr->end_of_lexeme = 0;
5787 967           slr->is_external_scanning = 0;
5788              
5789 967           slr->perl_pos = 0;
5790 967           slr->last_perl_pos = -1;
5791             slr->problem_pos = -1;
5792              
5793             slr->token_values = newAV ();
5794 967           av_fill (slr->token_values, TOKEN_VALUE_IS_LITERAL);
5795 967            
5796 967 50         {
5797             Marpa_Symbol_ID symbol_id;
5798 40197 100         const Marpa_Symbol_ID g1_symbol_count =
5799             marpa_g_highest_symbol_id (slg->g1) + 1;
5800 39230           Newx (slr->symbol_r_properties, g1_symbol_count,
5801 39230           struct symbol_r_properties);
5802 78460           for (symbol_id = 0; symbol_id < g1_symbol_count; symbol_id++)
5803 39230           {
5804 78460           const struct symbol_g_properties *g_properties =
5805 39230           slg->symbol_g_properties + symbol_id;
5806 78460           slr->symbol_r_properties[symbol_id].lexeme_priority =
5807 39230           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 967           }
5814 967            
5815 967 50         {
5816             Marpa_Rule_ID l0_rule_id;
5817 62728 100         const Marpa_Rule_ID l0_rule_count =
5818             marpa_g_highest_rule_id (slg->l0_wrapper->g) + 1;
5819 61761           Newx (slr->l0_rule_r_properties, l0_rule_count,
5820 61761           struct l0_rule_r_properties);
5821 123522           for (l0_rule_id = 0; l0_rule_id < l0_rule_count; l0_rule_id++)
5822 61761           {
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 967           g_properties->t_event_on_discard_active;
5827 967           }
5828 967           }
5829 967            
5830 967           slr->lexer_start_pos = slr->perl_pos;
5831 967           slr->lexer_read_result = 0;
5832             slr->r1_earleme_complete_result = 0;
5833 967           slr->start_of_pause_lexeme = -1;
5834 967           slr->end_of_pause_lexeme = -1;
5835 967           slr->pause_lexeme = -1;
5836              
5837 967           slr->pos_db = 0;
5838 967           slr->pos_db_logical_size = -1;
5839 967           slr->pos_db_physical_size = -1;
5840 967            
5841             slr->input_symbol_id = -1;
5842 967           slr->input = newSVpvn ("", 0);
5843             slr->end_pos = 0;
5844 967           slr->too_many_earley_items = -1;
5845 967            
5846 967 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 967           const Marpa_Recce r0 = slr->r0;
5859 967 100         if (r0)
5860             {
5861 944           marpa_r_unref (r0);
5862             }
5863              
5864 967           marpa__slr_unref(slr->gift);
5865              
5866 967           Safefree(slr->pos_db);
5867 967           SvREFCNT_dec (slr->slg_sv);
5868 967           SvREFCNT_dec (slr->r1_sv);
5869 967           Safefree(slr->symbol_r_properties);
5870 967           Safefree(slr->l0_rule_r_properties);
5871 967 50         if (slr->token_values)
5872             {
5873             SvREFCNT_dec ((SV *) slr->token_values);
5874             }
5875 967           SvREFCNT_dec (slr->input);
5876 967           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 6893           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 1903           u_pos_set(slr, "slr->pos_set", start_pos, length);
5959 1903           slr->lexer_start_pos = slr->perl_pos;
5960 1903           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 6375           const int trace_lexers = slr->trace_lexers;
6019              
6020 6375 50         if (slr->is_external_scanning)
6021             {
6022 0           XSRETURN_PV ("unpermitted mix of external and internal scanning");
6023             }
6024              
6025 6375           slr->lexer_read_result = 0;
6026 6375           slr->r1_earleme_complete_result = 0;
6027 6375           slr->start_of_pause_lexeme = -1;
6028 6375           slr->end_of_pause_lexeme = -1;
6029 6375           slr->pause_lexeme = -1;
6030              
6031             /* Clear event queue */
6032 6375           av_clear (slr->r1_wrapper->event_queue);
6033 6375           marpa__slr_event_clear (slr->gift);
6034              
6035             /* Application intervention resets perl_pos */
6036 6375           slr->last_perl_pos = -1;
6037              
6038             while (1)
6039             {
6040 33525 100         if (slr->lexer_start_pos >= 0)
6041             {
6042 29084 100         if (slr->lexer_start_pos >= slr->end_pos)
6043             {
6044 853           XSRETURN_PV ("");
6045             }
6046              
6047 28231           slr->start_of_lexeme = slr->perl_pos = slr->lexer_start_pos;
6048 28231           slr->lexer_start_pos = -1;
6049             u_r0_clear (slr);
6050 28231 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 32672 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 4441           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 28231 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 27554           const char *result_string = slr_alternatives (slr);
6094 27554 100         if (result_string)
6095             {
6096 29           XSRETURN_PV (result_string);
6097             }
6098             }
6099              
6100             {
6101 28192           int event_count = av_len (slr->r1_wrapper->event_queue) + 1;
6102 56384           event_count += marpa__slr_event_count (slr->gift);
6103 28192 100         if (event_count)
6104             {
6105 1042           XSRETURN_PV ("event");
6106             }
6107             }
6108              
6109 27150 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 6690           AV *const event_queue_av = slr->r1_wrapper->event_queue;
6173              
6174 7941 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 6690           queue_length = av_len (event_queue_av);
6453 6756 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 967 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 966 50         SvSetSV (slr->input, string);
6868 966 50         start_of_string = (U8 *) SvPV_force_nomg (slr->input, pv_length);
6869 966           end_of_string = start_of_string + pv_length;
6870 966           input_is_utf8 = SvUTF8 (slr->input);
6871              
6872 966           slr->pos_db_logical_size = 0;
6873             /* This original buffer size my be too small.
6874             */
6875 966           slr->pos_db_physical_size = 1024;
6876 966           Newx (slr->pos_db, slr->pos_db_physical_size, Pos_Entry);
6877              
6878 90436 100         for (p = start_of_string; p < end_of_string;)
6879             {
6880             STRLEN codepoint_length;
6881             UV codepoint;
6882 89470 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 82437           codepoint = (UV) * p;
6898 82437           codepoint_length = 1;
6899             }
6900             /* Ensure that there is enough space */
6901 89470 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 89470           p += codepoint_length;
6907 89470           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 89470 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 178924           slr->pos_db[slr->pos_db_logical_size].linecol =
6929 89462 100         this_column > 1 ? 1-this_column : this_line;
6930 89462 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 3068           this_line++;
6940             this_column = 1;
6941 3068           break;
6942             default:
6943 86394           this_column++;
6944             }
6945             }
6946 89470           slr->pos_db_logical_size++;
6947             previous_codepoint = codepoint;
6948             }
6949 966           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 4441           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 4441           const int use_array = codepoint < array_size;
6989              
6990 4441 100         if (use_array)
6991             {
6992 4353           ops = slr->slg->per_codepoint_array[codepoint];
6993 4353 50         Renew (ops, op_count, IV);
6994 4353           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 4441           ops[0] = codepoint;
7004 4441           ops[1] = op_count;
7005 97102 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 92661 50         ops[op_ix] = SvUV (ST (op_ix));
7011             }
7012 4441 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 150           marpa_debug_handler_set(marpa_r2_warn);
7092              
7093             /* vim: set expandtab shiftwidth=2: */