summaryrefslogtreecommitdiff
path: root/src/pdarun.c
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2019-09-08 21:11:17 -0600
committerAdrian Thurston <thurston@colm.net>2019-09-08 21:11:17 -0600
commitc860c61607117582abd8f23881eed87957197484 (patch)
tree4d4e65dddc710e15f008189a9308d95924350c3f /src/pdarun.c
parentf37c916aed2600951b8966a86020406b0b0542cf (diff)
downloadcolm-c860c61607117582abd8f23881eed87957197484.tar.gz
moved the original colm src dir to /colm
Diffstat (limited to 'src/pdarun.c')
-rw-r--r--src/pdarun.c2290
1 files changed, 0 insertions, 2290 deletions
diff --git a/src/pdarun.c b/src/pdarun.c
deleted file mode 100644
index 327f801a..00000000
--- a/src/pdarun.c
+++ /dev/null
@@ -1,2290 +0,0 @@
-/*
- * Copyright 2007-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "pdarun.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <assert.h>
-
-#include "config.h"
-#include "debug.h"
-#include "bytecode.h"
-#include "tree.h"
-#include "pool.h"
-#include "internal.h"
-
-#define act_sb 0x1
-#define act_rb 0x2
-
-#define read_word_p( i, p ) do { \
- i = ((word_t) p[0]); \
- i |= ((word_t) p[1]) << 8; \
- i |= ((word_t) p[2]) << 16; \
- i |= ((word_t) p[3]) << 24; \
-} while(0)
-
-#define read_tree_p( i, p ) do { \
- word_t w; \
- w = ((word_t) p[0]); \
- w |= ((word_t) p[1]) << 8; \
- w |= ((word_t) p[2]) << 16; \
- w |= ((word_t) p[3]) << 24; \
- i = (tree_t*)w; \
-} while(0)
-
-/* bit 0: data needed. bit 1: loc needed */
-#define RN_NONE 0x0
-#define RN_DATA 0x1
-#define RN_LOC 0x2
-#define RN_BOTH 0x3
-
-
-static void init_fsm_run( program_t *prg, struct pda_run *pda_run )
-{
- pda_run->fsm_tables = prg->rtd->fsm_tables;
-
- pda_run->consume_buf = 0;
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->scan_eof = 0;
-
- pda_run->pre_region = -1;
-}
-
-static void clear_fsm_run( program_t *prg, struct pda_run *pda_run )
-{
- if ( pda_run->consume_buf != 0 ) {
- /* Transfer the run buf list to the program */
- struct run_buf *head = pda_run->consume_buf;
- struct run_buf *tail = head;
- while ( tail->next != 0 )
- tail = tail->next;
-
- tail->next = prg->alloc_run_buf;
- prg->alloc_run_buf = head;
- }
-}
-
-void colm_increment_steps( struct pda_run *pda_run )
-{
- pda_run->steps += 1;
- //debug( prg, REALM_PARSE, "steps up to %ld\n", pdaRun->steps );
-}
-
-void colm_decrement_steps( struct pda_run *pda_run )
-{
- pda_run->steps -= 1;
- //debug( prg, REALM_PARSE, "steps down to %ld\n", pdaRun->steps );
-}
-
-head_t *colm_stream_pull( program_t *prg, tree_t **sp, struct pda_run *pda_run,
- struct input_impl *is, long length )
-{
- if ( pda_run != 0 ) {
- struct run_buf *run_buf = pda_run->consume_buf;
- if ( length > ( FSM_BUFSIZE - run_buf->length ) ) {
- run_buf = new_run_buf( 0 );
- run_buf->next = pda_run->consume_buf;
- pda_run->consume_buf = run_buf;
- }
-
- char *dest = run_buf->data + run_buf->length;
-
- is->funcs->get_data( prg, is, dest, length );
- location_t *loc = location_allocate( prg );
- is->funcs->consume_data( prg, is, length, loc );
-
- run_buf->length += length;
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
-
- head_t *tokdata = colm_string_alloc_pointer( prg, dest, length );
- tokdata->location = loc;
-
- return tokdata;
- }
- else {
- head_t *head = init_str_space( length );
- char *dest = (char*)head->data;
-
- is->funcs->get_data( prg, is, dest, length );
- location_t *loc = location_allocate( prg );
- is->funcs->consume_data( prg, is, length, loc );
- head->location = loc;
-
- return head;
- }
-}
-
-void colm_stream_push_text( struct colm_program *prg, struct input_impl *is, const char *data, long length )
-{
- is->funcs->prepend_data( prg, is, data, length );
-}
-
-void colm_stream_push_tree( struct colm_program *prg, struct input_impl *is, tree_t *tree, int ignore )
-{
- is->funcs->prepend_tree( prg, is, tree, ignore );
-}
-
-void colm_stream_push_stream( struct colm_program *prg, struct input_impl *is, stream_t *stream )
-{
- is->funcs->prepend_stream( prg, is, stream );
-}
-
-void colm_undo_stream_push( program_t *prg, tree_t **sp, struct input_impl *is, long length )
-{
- if ( length < 0 ) {
- /* tree_t *tree = */ is->funcs->undo_prepend_tree( prg, is );
- // colm_tree_downref( prg, sp, tree );
- }
- else {
- is->funcs->undo_prepend_data( prg, is, length );
- }
-}
-
-/* Should only be sending back whole tokens/ignores, therefore the send back
- * should never cross a buffer boundary. Either we slide back data, or we move to
- * a previous buffer and slide back data. */
-static void send_back_text( struct colm_program *prg, struct input_impl *is, const char *data, long length )
-{
- //debug( REALM_PARSE, "push back of %ld characters\n", length );
-
- if ( length == 0 )
- return;
-
- //debug( REALM_PARSE, "sending back text: %.*s\n",
- // (int)length, data );
-
- is->funcs->undo_consume_data( prg, is, data, length );
-}
-
-static void send_back_tree( struct colm_program *prg, struct input_impl *is, tree_t *tree )
-{
- is->funcs->undo_consume_tree( prg, is, tree, false );
-}
-
-/*
- * Stops on:
- * PCR_REVERSE
- */
-static void send_back_ignore( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is, parse_tree_t *parse_tree )
-{
- #ifdef DEBUG
- struct lang_el_info *lel_info = prg->rtd->lel_info;
- debug( prg, REALM_PARSE, "sending back: %s%s\n",
- lel_info[parse_tree->shadow->tree->id].name,
- parse_tree->flags & PF_ARTIFICIAL ? " (artificial)" : "" );
- #endif
-
- head_t *head = parse_tree->shadow->tree->tokdata;
- int artificial = parse_tree->flags & PF_ARTIFICIAL;
-
- if ( head != 0 ) {
- if ( artificial )
- send_back_tree( prg, is, parse_tree->shadow->tree );
- else
- send_back_text( prg, is, string_data( head ), head->length );
- }
-
- colm_decrement_steps( pda_run );
-
- /* Check for reverse code. */
- if ( parse_tree->flags & PF_HAS_RCODE ) {
- pda_run->on_deck = true;
- parse_tree->flags &= ~PF_HAS_RCODE;
- }
-
- if ( pda_run->steps == pda_run->target_steps ) {
- debug( prg, REALM_PARSE, "trigger parse stop, steps = "
- "target = %d\n", pda_run->target_steps );
- pda_run->stop = true;
- }
-}
-
-static void reset_token( struct pda_run *pda_run )
-{
- /* If there is a token started, but never finished for a lack of data, we
- * must first backup over it. */
- if ( pda_run->tokstart != 0 ) {
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->scan_eof = 0;
- }
-}
-
-/* Stops on:
- * PCR_REVERSE
- */
-
-static void send_back( program_t *prg, tree_t **sp, struct pda_run *pda_run,
- struct input_impl *is, parse_tree_t *parse_tree )
-{
- debug( prg, REALM_PARSE, "sending back: %s\n",
- prg->rtd->lel_info[parse_tree->id].name );
-
- if ( parse_tree->flags & PF_NAMED ) {
- /* Send the named lang el back first, then send back any leading
- * whitespace. */
- is->funcs->undo_consume_lang_el( prg, is );
- }
-
- colm_decrement_steps( pda_run );
-
- /* Artifical were not parsed, instead sent in as items. */
- if ( parse_tree->flags & PF_ARTIFICIAL ) {
- /* Check for reverse code. */
- if ( parse_tree->flags & PF_HAS_RCODE ) {
- debug( prg, REALM_PARSE, "tree has rcode, setting on deck\n" );
- pda_run->on_deck = true;
- parse_tree->flags &= ~PF_HAS_RCODE;
- }
-
- colm_tree_upref( prg, parse_tree->shadow->tree );
-
- send_back_tree( prg, is, parse_tree->shadow->tree );
- }
- else {
- /* Check for reverse code. */
- if ( parse_tree->flags & PF_HAS_RCODE ) {
- debug( prg, REALM_PARSE, "tree has rcode, setting on deck\n" );
- pda_run->on_deck = true;
- parse_tree->flags &= ~PF_HAS_RCODE;
- }
-
- /* Push back the token data. */
- send_back_text( prg, is, string_data( parse_tree->shadow->tree->tokdata ),
- string_length( parse_tree->shadow->tree->tokdata ) );
-
- /* If eof was just sent back remember that it needs to be sent again. */
- if ( parse_tree->id == prg->rtd->eof_lel_ids[pda_run->parser_id] )
- pda_run->eof_term_recvd = false;
-
- /* If the item is bound then store remove it from the bindings array. */
- prg->rtd->pop_binding( pda_run, parse_tree );
- }
-
- if ( pda_run->steps == pda_run->target_steps ) {
- debug( prg, REALM_PARSE, "trigger parse stop, "
- "steps = target = %d\n", pda_run->target_steps );
- pda_run->stop = true;
- }
-
- /* Downref the tree that was sent back and free the kid. */
- colm_tree_downref( prg, sp, parse_tree->shadow->tree );
- kid_free( prg, parse_tree->shadow );
- parse_tree_free( pda_run, parse_tree );
-}
-
-static void set_region( struct pda_run *pda_run, int empty_ignore, parse_tree_t *tree )
-{
- if ( empty_ignore ) {
- /* Recording the next region. */
- tree->retry_region = pda_run->next_region_ind;
- if ( pda_run->pda_tables->token_regions[tree->retry_region+1] != 0 )
- pda_run->num_retry += 1;
- }
-}
-
-static void ignore_tree( program_t *prg, struct pda_run *pda_run, tree_t *tree )
-{
- int empty_ignore = pda_run->accum_ignore == 0;
-
- colm_increment_steps( pda_run );
-
- parse_tree_t *parse_tree = parse_tree_allocate( pda_run );
- parse_tree->shadow = kid_allocate( prg );
- parse_tree->shadow->tree = tree;
-
- parse_tree->next = pda_run->accum_ignore;
- pda_run->accum_ignore = parse_tree;
-
- colm_transfer_reverse_code( pda_run, parse_tree );
-
- if ( pda_run->pre_region >= 0 )
- parse_tree->flags |= PF_RIGHT_IGNORE;
-
- set_region( pda_run, empty_ignore, pda_run->accum_ignore );
-}
-
-static void ignore_tree_art( program_t *prg, struct pda_run *pda_run, tree_t *tree )
-{
- int empty_ignore = pda_run->accum_ignore == 0;
-
- colm_increment_steps( pda_run );
-
- parse_tree_t *parse_tree = parse_tree_allocate( pda_run );
- parse_tree->flags |= PF_ARTIFICIAL;
- parse_tree->shadow = kid_allocate( prg );
- parse_tree->shadow->tree = tree;
-
- parse_tree->next = pda_run->accum_ignore;
- pda_run->accum_ignore = parse_tree;
-
- colm_transfer_reverse_code( pda_run, parse_tree );
-
- set_region( pda_run, empty_ignore, pda_run->accum_ignore );
-}
-
-kid_t *make_token_with_data( program_t *prg, struct pda_run *pda_run,
- struct input_impl *is, int id, head_t *tokdata )
-{
- /* Make the token object. */
- long object_length = prg->rtd->lel_info[id].object_length;
- kid_t *attrs = alloc_attrs( prg, object_length );
-
- kid_t *input = 0;
- input = kid_allocate( prg );
- input->tree = tree_allocate( prg );
-
- debug( prg, REALM_PARSE, "made token %p\n", input->tree );
-
- input->tree->refs = 1;
- input->tree->id = id;
- input->tree->tokdata = tokdata;
-
- /* No children and ignores get added later. */
- input->tree->child = attrs;
-
- struct lang_el_info *lel_info = prg->rtd->lel_info;
- if ( lel_info[id].num_capture_attr > 0 ) {
- int i;
- for ( i = 0; i < lel_info[id].num_capture_attr; i++ ) {
- CaptureAttr *ca = &prg->rtd->capture_attr[lel_info[id].capture_attr + i];
- head_t *data = string_alloc_full( prg,
- pda_run->mark[ca->mark_enter],
- pda_run->mark[ca->mark_leave] -
- pda_run->mark[ca->mark_enter] );
- tree_t *string = construct_string( prg, data );
- colm_tree_upref( prg, string );
- colm_tree_set_field( prg, input->tree, ca->offset, string );
- }
- }
-
- return input;
-}
-
-static void report_parse_error( program_t *prg, tree_t **sp, struct pda_run *pda_run )
-{
- kid_t *kid = pda_run->bt_point;
- head_t *deepest = 0;
- while ( kid != 0 ) {
- head_t *head = kid->tree->tokdata;
- if ( head != 0 && head->location != 0 ) {
- if ( deepest == 0 || head->location->byte > deepest->location->byte )
- deepest = head;
- }
- kid = kid->next;
- }
-
- head_t *error_head = 0;
-
- /* If there are no error points on record assume the error occurred at the
- * beginning of the stream. */
- if ( deepest == 0 ) {
- error_head = string_alloc_full( prg, "<input>:1:1: parse error", 32 );
- error_head->location = location_allocate( prg );
- error_head->location->line = 1;
- error_head->location->column = 1;
- }
- else {
- debug( prg, REALM_PARSE, "deepest location byte: %d\n",
- deepest->location->byte );
-
- const char *name = deepest->location->name;
- long line = deepest->location->line;
- long i, column = deepest->location->column;
- long byte = deepest->location->byte;
-
- for ( i = 0; i < deepest->length; i++ ) {
- if ( deepest->data[i] != '\n' )
- column += 1;
- else {
- line += 1;
- column = 1;
- }
- byte += 1;
- }
-
- if ( name == 0 )
- name = "<input>";
- char *formatted = malloc( strlen( name ) + 128 );
- sprintf( formatted, "%s:%ld:%ld: parse error", name, line, column );
- error_head = string_alloc_full( prg, formatted, strlen(formatted) );
- free( formatted );
-
- error_head->location = location_allocate( prg );
-
- error_head->location->name = deepest->location->name;
- error_head->location->line = line;
- error_head->location->column = column;
- error_head->location->byte = byte;
- }
-
- tree_t *tree = construct_string( prg, error_head );
- colm_tree_downref( prg, sp, pda_run->parse_error_text );
- pda_run->parse_error_text = tree;
- colm_tree_upref( prg, pda_run->parse_error_text );
-}
-
-static void attach_right_ignore( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, parse_tree_t *parse_tree )
-{
- if ( pda_run->accum_ignore == 0 )
- return;
-
- if ( pda_run->stack_top->id > 0 &&
- pda_run->stack_top->id < prg->rtd->first_non_term_id )
- {
- /* OK, do it */
- debug( prg, REALM_PARSE, "attaching right ignore\n" );
-
- /* Reset. */
- assert( ! ( parse_tree->flags & PF_RIGHT_IL_ATTACHED ) );
-
- parse_tree_t *accum = pda_run->accum_ignore;
-
- parse_tree_t *stop_at = 0, *use = accum;
- while ( use != 0 ) {
- if ( ! (use->flags & PF_RIGHT_IGNORE) )
- stop_at = use;
- use = use->next;
- }
-
- if ( stop_at != 0 ) {
- /* Stop at was set. Make it the last item in the igore list. Take
- * the rest. */
- accum = stop_at->next;
- stop_at->next = 0;
- }
- else {
- /* Stop at was never set. All right ignore. Use it all. */
- pda_run->accum_ignore = 0;
- }
-
- /* The data list needs to be extracted and reversed. The parse tree list
- * can remain in stack order. */
- parse_tree_t *child = accum, *last = 0;
- kid_t *data_child = 0, *data_last = 0;
-
- while ( child ) {
- data_child = child->shadow;
- parse_tree_t *next = child->next;
-
- /* Reverse the lists. */
- data_child->next = data_last;
- child->next = last;
-
- /* Detach the parse tree from the data tree. */
- child->shadow = 0;
-
- /* Keep the last for reversal. */
- data_last = data_child;
- last = child;
-
- child = next;
- }
-
- /* Last is now the first. */
- parse_tree->right_ignore = last;
-
- if ( data_child != 0 ) {
- debug( prg, REALM_PARSE, "attaching ignore right\n" );
-
- kid_t *ignore_kid = data_last;
-
- /* Copy the ignore list first if we need to attach it as a right
- * ignore. */
- tree_t *right_ignore = 0;
-
- right_ignore = tree_allocate( prg );
- right_ignore->id = LEL_ID_IGNORE;
- right_ignore->child = ignore_kid;
-
- tree_t *push_to = parse_tree->shadow->tree;
-
- push_to = push_right_ignore( prg, push_to, right_ignore );
-
- parse_tree->shadow->tree = push_to;
-
- parse_tree->flags |= PF_RIGHT_IL_ATTACHED;
- }
- }
-}
-
-static void attach_left_ignore( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, parse_tree_t *parse_tree )
-{
- /* Reset. */
- assert( ! ( parse_tree->flags & PF_LEFT_IL_ATTACHED ) );
-
- parse_tree_t *accum = pda_run->accum_ignore;
- pda_run->accum_ignore = 0;
-
- /* The data list needs to be extracted and reversed. The parse tree list
- * can remain in stack order. */
- parse_tree_t *child = accum, *last = 0;
- kid_t *data_child = 0, *data_last = 0;
-
- while ( child ) {
- data_child = child->shadow;
- parse_tree_t *next = child->next;
-
- /* Reverse the lists. */
- data_child->next = data_last;
- child->next = last;
-
- /* Detach the parse tree from the data tree. */
- child->shadow = 0;
-
- /* Keep the last for reversal. */
- data_last = data_child;
- last = child;
-
- child = next;
- }
-
- /* Last is now the first. */
- parse_tree->left_ignore = last;
-
- if ( data_child != 0 ) {
- debug( prg, REALM_PARSE, "attaching left ignore\n" );
-
- kid_t *ignore_kid = data_child;
-
- /* Make the ignore list for the left-ignore. */
- tree_t *left_ignore = tree_allocate( prg );
- left_ignore->id = LEL_ID_IGNORE;
- left_ignore->child = ignore_kid;
-
- tree_t *push_to = parse_tree->shadow->tree;
-
- push_to = push_left_ignore( prg, push_to, left_ignore );
-
- parse_tree->shadow->tree = push_to;
-
- parse_tree->flags |= PF_LEFT_IL_ATTACHED;
- }
-}
-
-/* Not currently used. Need to revive this. WARNING: untested changes here */
-static void detach_right_ignore( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, parse_tree_t *parse_tree )
-{
- /* Right ignore are immediately discarded since they are copies of
- * left-ignores. */
- tree_t *right_ignore = 0;
- if ( parse_tree->flags & PF_RIGHT_IL_ATTACHED ) {
- tree_t *pop_from = parse_tree->shadow->tree;
-
- pop_from = pop_right_ignore( prg, sp, pop_from, &right_ignore );
-
- parse_tree->shadow->tree = pop_from;
-
- parse_tree->flags &= ~PF_RIGHT_IL_ATTACHED;
- }
-
- if ( parse_tree->right_ignore != 0 ) {
- assert( right_ignore != 0 );
-
- /* Transfer the trees to accumIgnore. */
- parse_tree_t *ignore = parse_tree->right_ignore;
- parse_tree->right_ignore = 0;
-
- kid_t *data_ignore = right_ignore->child;
- right_ignore->child = 0;
-
- parse_tree_t *last = 0;
- kid_t *data_last = 0;
- while ( ignore != 0 ) {
- parse_tree_t *next = ignore->next;
- kid_t *data_next = data_ignore->next;
-
- /* Put the data trees underneath the parse trees. */
- ignore->shadow = data_ignore;
-
- /* Reverse. */
- ignore->next = last;
- data_ignore->next = data_last;
-
- /* Keep last for reversal. */
- last = ignore;
- data_last = data_ignore;
-
- ignore = next;
- data_ignore = data_next;
- }
-
- pda_run->accum_ignore = last;
-
- colm_tree_downref( prg, sp, right_ignore );
- }
-}
-
-static void detach_left_ignore( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, parse_tree_t *parse_tree )
-{
- /* Detach left. */
- tree_t *left_ignore = 0;
- if ( parse_tree->flags & PF_LEFT_IL_ATTACHED ) {
- tree_t *pop_from = parse_tree->shadow->tree;
-
- pop_from = pop_left_ignore( prg, sp, pop_from, &left_ignore );
-
- parse_tree->shadow->tree = pop_from;
-
- parse_tree->flags &= ~PF_LEFT_IL_ATTACHED;
- }
-
- if ( parse_tree->left_ignore != 0 ) {
- assert( left_ignore != 0 );
-
- /* Transfer the trees to accumIgnore. */
- parse_tree_t *ignore = parse_tree->left_ignore;
- parse_tree->left_ignore = 0;
-
- kid_t *data_ignore = left_ignore->child;
- left_ignore->child = 0;
-
- parse_tree_t *last = 0;
- kid_t *data_last = 0;
- while ( ignore != 0 ) {
- parse_tree_t *next = ignore->next;
- kid_t *data_next = data_ignore->next;
-
- /* Put the data trees underneath the parse trees. */
- ignore->shadow = data_ignore;
-
- /* Reverse. */
- ignore->next = last;
- data_ignore->next = data_last;
-
- /* Keep last for reversal. */
- last = ignore;
- data_last = data_ignore;
-
- ignore = next;
- data_ignore = data_next;
- }
-
- pda_run->accum_ignore = last;
- }
-
- colm_tree_downref( prg, sp, left_ignore );
-}
-
-static int is_parser_stop_finished( struct pda_run *pda_run )
-{
- int done =
- pda_run->stack_top->next != 0 &&
- pda_run->stack_top->next->next == 0 &&
- pda_run->stack_top->id == pda_run->stop_target;
- return done;
-}
-
-static void handle_error( program_t *prg, tree_t **sp, struct pda_run *pda_run )
-{
- /* Check the result. */
- if ( pda_run->parse_error ) {
- /* Error occured in the top-level parser. */
- report_parse_error( prg, sp, pda_run );
- }
- else {
- if ( is_parser_stop_finished( pda_run ) ) {
- debug( prg, REALM_PARSE, "stopping the parse\n" );
- pda_run->stop_parsing = true;
- }
- }
-}
-
-static head_t *extract_match( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is )
-{
- long length = pda_run->toklen;
-
- //debug( prg, REALM_PARSE, "extracting token of length: %ld\n", length );
-
- struct run_buf *run_buf = pda_run->consume_buf;
- if ( run_buf == 0 || length > ( FSM_BUFSIZE - run_buf->length ) ) {
- run_buf = new_run_buf( length );
- run_buf->next = pda_run->consume_buf;
- pda_run->consume_buf = run_buf;
- }
-
- char *dest = run_buf->data + run_buf->length;
-
- is->funcs->get_data( prg, is, dest, length );
- location_t *location = location_allocate( prg );
- is->funcs->consume_data( prg, is, length, location );
-
- run_buf->length += length;
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->tokstart = 0;
-
- head_t *head = colm_string_alloc_pointer( prg, dest, length );
-
- head->location = location;
-
- debug( prg, REALM_PARSE, "location byte: %d\n", head->location->byte );
-
- return head;
-}
-
-static head_t *extract_no_d( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is )
-{
- long length = pda_run->toklen;
-
- /* Just a consume, no data allocate. */
- location_t *location = location_allocate( prg );
- is->funcs->consume_data( prg, is, length, location );
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->tokstart = 0;
-
- head_t *head = colm_string_alloc_pointer( prg, 0, 0 );
-
- head->location = location;
-
- debug( prg, REALM_PARSE, "location byte: %d\n", head->location->byte );
-
- return head;
-}
-
-static head_t *extract_no_l( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is )
-{
- long length = pda_run->toklen;
-
- //debug( prg, REALM_PARSE, "extracting token of length: %ld\n", length );
-
- struct run_buf *run_buf = pda_run->consume_buf;
- if ( run_buf == 0 || length > ( FSM_BUFSIZE - run_buf->length ) ) {
- run_buf = new_run_buf( length );
- run_buf->next = pda_run->consume_buf;
- pda_run->consume_buf = run_buf;
- }
-
- char *dest = run_buf->data + run_buf->length;
-
- is->funcs->get_data( prg, is, dest, length );
-
- /* Using a dummpy location. */
- location_t location;
- memset( &location, 0, sizeof( location ) );
- is->funcs->consume_data( prg, is, length, &location );
-
- run_buf->length += length;
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->tokstart = 0;
-
- head_t *head = colm_string_alloc_pointer( prg, dest, length );
-
- /* Don't pass the location. */
- head->location = 0;
-
- debug( prg, REALM_PARSE, "location byte: %d\n", location.byte );
-
- return head;
-}
-
-static head_t *consume_match( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is )
-{
- long length = pda_run->toklen;
-
- /* No data or location returned. We just consume the data. */
- location_t dummy_loc;
- memset( &dummy_loc, 0, sizeof(dummy_loc) );
- is->funcs->consume_data( prg, is, length, &dummy_loc );
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->tokstart = 0;
-
- debug( prg, REALM_PARSE, "location byte: %d\n", dummy_loc.byte );
-
- return 0;
-}
-
-
-static head_t *peek_match( program_t *prg, struct pda_run *pda_run, struct input_impl *is )
-{
- long length = pda_run->toklen;
-
- struct run_buf *run_buf = pda_run->consume_buf;
- if ( run_buf == 0 || length > ( FSM_BUFSIZE - run_buf->length ) ) {
- run_buf = new_run_buf( 0 );
- run_buf->next = pda_run->consume_buf;
- pda_run->consume_buf = run_buf;
- }
-
- char *dest = run_buf->data + run_buf->length;
-
- is->funcs->get_data( prg, is, dest, length );
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
-
- head_t *head = colm_string_alloc_pointer( prg, dest, length );
-
- head->location = location_allocate( prg );
- is->funcs->transfer_loc( prg, head->location, is );
-
- debug( prg, REALM_PARSE, "location byte: %d\n", head->location->byte );
-
- return head;
-}
-
-
-static void send_ignore( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is, long id )
-{
- if ( prg->rtd->reducer_need_ign( prg, pda_run ) == RN_NONE ) {
- consume_match( prg, sp, pda_run, is );
- }
- else {
- debug( prg, REALM_PARSE, "ignoring: %s\n", prg->rtd->lel_info[id].name );
-
- /* Make the ignore string. */
- head_t *ignore_str = extract_match( prg, sp, pda_run, is );
-
- debug( prg, REALM_PARSE, "ignoring: %.*s\n", ignore_str->length, ignore_str->data );
-
- tree_t *tree = tree_allocate( prg );
- tree->refs = 1;
- tree->id = id;
- tree->tokdata = ignore_str;
-
- /* Send it to the pdaRun. */
- ignore_tree( prg, pda_run, tree );
- }
-}
-
-static void send_token( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is, long id )
-{
- int empty_ignore = pda_run->accum_ignore == 0;
-
- /* Make the token data. */
- head_t *tokdata = 0;
- int rn = prg->rtd->reducer_need_tok( prg, pda_run, id );
-
- switch ( rn ) {
- case RN_NONE:
- tokdata = consume_match( prg, sp, pda_run, is );
- break;
- case RN_DATA:
- tokdata = extract_no_l( prg, sp, pda_run, is );
- break;
- case RN_LOC:
- tokdata = extract_no_d( prg, sp, pda_run, is );
- break;
- case RN_BOTH:
- tokdata = extract_match( prg, sp, pda_run, is );
- break;
- }
-
- debug( prg, REALM_PARSE, "token: %s text: %.*s\n",
- prg->rtd->lel_info[id].name,
- string_length(tokdata), string_data(tokdata) );
-
- kid_t *input = make_token_with_data( prg, pda_run, is, id, tokdata );
-
- colm_increment_steps( pda_run );
-
- parse_tree_t *parse_tree = parse_tree_allocate( pda_run );
- parse_tree->id = input->tree->id;
- parse_tree->shadow = input;
-
- pda_run->parse_input = parse_tree;
-
- /* Store any alternate scanning region. */
- if ( input != 0 && pda_run->pda_cs >= 0 )
- set_region( pda_run, empty_ignore, parse_tree );
-}
-
-static void send_tree( program_t *prg, tree_t **sp, struct pda_run *pda_run,
- struct input_impl *is )
-{
- kid_t *input = kid_allocate( prg );
- input->tree = is->funcs->consume_tree( prg, is );
-
- colm_increment_steps( pda_run );
-
- parse_tree_t *parse_tree = parse_tree_allocate( pda_run );
- parse_tree->id = input->tree->id;
- parse_tree->flags |= PF_ARTIFICIAL;
- parse_tree->shadow = input;
-
- pda_run->parse_input = parse_tree;
-}
-
-static void send_ignore_tree( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is )
-{
- tree_t *tree = is->funcs->consume_tree( prg, is );
- ignore_tree_art( prg, pda_run, tree );
-}
-
-static void send_collect_ignore( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is, int id )
-{
- debug( prg, REALM_PARSE, "token: CI\n" );
-
- int empty_ignore = pda_run->accum_ignore == 0;
-
- /* Make the token data. */
- head_t *tokdata = head_allocate( prg );
- tokdata->location = location_allocate( prg );
- is->funcs->transfer_loc( prg, tokdata->location, is );
-
- debug( prg, REALM_PARSE, "token: %s text: %.*s\n",
- prg->rtd->lel_info[id].name,
- string_length(tokdata), string_data(tokdata) );
-
- kid_t *input = make_token_with_data( prg, pda_run, is, id, tokdata );
-
- colm_increment_steps( pda_run );
-
- parse_tree_t *parse_tree = parse_tree_allocate( pda_run );
- parse_tree->id = input->tree->id;
- parse_tree->shadow = input;
-
- pda_run->parse_input = parse_tree;
-
- /* Store any alternate scanning region. */
- if ( input != 0 && pda_run->pda_cs >= 0 )
- set_region( pda_run, empty_ignore, parse_tree );
-}
-
-/* Offset can be used to look at the next nextRegionInd. */
-static int get_next_region( struct pda_run *pda_run, int offset )
-{
- return pda_run->pda_tables->token_regions[pda_run->next_region_ind+offset];
-}
-
-static int get_next_pre_region( struct pda_run *pda_run )
-{
- return pda_run->pda_tables->token_pre_regions[pda_run->next_region_ind];
-}
-
-static void send_eof( program_t *prg, tree_t **sp, struct pda_run *pda_run,
- struct input_impl *is )
-{
- debug( prg, REALM_PARSE, "token: _EOF\n" );
-
- colm_increment_steps( pda_run );
-
- head_t *head = head_allocate( prg );
- head->location = location_allocate( prg );
- is->funcs->transfer_loc( prg, head->location, is );
-
- kid_t *input = kid_allocate( prg );
- input->tree = tree_allocate( prg );
-
- input->tree->refs = 1;
- input->tree->id = prg->rtd->eof_lel_ids[pda_run->parser_id];
- input->tree->tokdata = head;
-
- /* Set the state using the state of the parser. */
- pda_run->region = get_next_region( pda_run, 0 );
- pda_run->pre_region = get_next_pre_region( pda_run );
- pda_run->fsm_cs = pda_run->fsm_tables->entry_by_region[pda_run->region];
-
- parse_tree_t *parse_tree = parse_tree_allocate( pda_run );
- parse_tree->id = input->tree->id;
- parse_tree->shadow = input;
-
- pda_run->parse_input = parse_tree;
-}
-
-static void new_token( program_t *prg, struct pda_run *pda_run )
-{
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->scan_eof = 0;
-
- /* Init the scanner vars. */
- pda_run->act = 0;
- pda_run->tokstart = 0;
- pda_run->tokend = 0;
- pda_run->matched_token = 0;
-
- /* Set the state using the state of the parser. */
- pda_run->region = get_next_region( pda_run, 0 );
- pda_run->pre_region = get_next_pre_region( pda_run );
- if ( pda_run->pre_region > 0 ) {
- pda_run->fsm_cs = pda_run->fsm_tables->entry_by_region[pda_run->pre_region];
- pda_run->next_cs = pda_run->fsm_tables->entry_by_region[pda_run->region];
- }
- else {
- pda_run->fsm_cs = pda_run->fsm_tables->entry_by_region[pda_run->region];
- }
-
-
- /* Clear the mark array. */
- memset( pda_run->mark, 0, sizeof(pda_run->mark) );
-}
-
-static void push_bt_point( program_t *prg, struct pda_run *pda_run )
-{
- tree_t *tree = 0;
- if ( pda_run->accum_ignore != 0 )
- tree = pda_run->accum_ignore->shadow->tree;
- else if ( pda_run->token_list != 0 )
- tree = pda_run->token_list->kid->tree;
-
- if ( tree != 0 ) {
- debug( prg, REALM_PARSE, "pushing bt point with location byte %d\n",
- ( tree != 0 && tree->tokdata != 0 && tree->tokdata->location != 0 ) ?
- tree->tokdata->location->byte : 0 );
-
- kid_t *kid = kid_allocate( prg );
- kid->tree = tree;
- colm_tree_upref( prg, tree );
- kid->next = pda_run->bt_point;
- pda_run->bt_point = kid;
- }
-}
-
-
-#define SCAN_UNDO -7
-#define SCAN_IGNORE -6
-#define SCAN_TREE -5
-#define SCAN_TRY_AGAIN_LATER -4
-#define SCAN_ERROR -3
-#define SCAN_LANG_EL -2
-#define SCAN_EOF -1
-
-static long scan_token( program_t *prg, struct pda_run *pda_run, struct input_impl *is )
-{
- if ( pda_run->trigger_undo )
- return SCAN_UNDO;
-
- while ( true ) {
- char *pd = 0;
- int len = 0;
- int toklen = pda_run->toklen;
- int type = is->funcs->get_parse_block( prg, is, &toklen, &pd, &len );
-
- switch ( type ) {
- case INPUT_DATA:
- pda_run->p = pd;
- pda_run->pe = pd + len;
- break;
-
- case INPUT_EOS:
- pda_run->p = pda_run->pe = 0;
- if ( pda_run->tokstart != 0 )
- pda_run->scan_eof = 1;
- debug( prg, REALM_SCAN, "EOS *******************\n" );
- break;
-
- case INPUT_EOF:
- pda_run->p = pda_run->pe = 0;
- if ( pda_run->tokstart != 0 )
- pda_run->scan_eof = 1;
- else
- return SCAN_EOF;
- break;
-
- case INPUT_EOD:
- pda_run->p = pda_run->pe = 0;
- return SCAN_TRY_AGAIN_LATER;
-
- case INPUT_LANG_EL:
- if ( pda_run->tokstart != 0 )
- pda_run->scan_eof = 1;
- else
- return SCAN_LANG_EL;
- break;
-
- case INPUT_TREE:
- if ( pda_run->tokstart != 0 )
- pda_run->scan_eof = 1;
- else
- return SCAN_TREE;
- break;
- case INPUT_IGNORE:
- if ( pda_run->tokstart != 0 )
- pda_run->scan_eof = 1;
- else
- return SCAN_IGNORE;
- break;
- }
-
- prg->rtd->fsm_execute( pda_run, is );
-
- /* First check if scanning stopped because we have a token. */
- if ( pda_run->matched_token > 0 ) {
- /* If the token has a marker indicating the end (due to trailing
- * context) then adjust data now. */
- struct lang_el_info *lel_info = prg->rtd->lel_info;
- if ( lel_info[pda_run->matched_token].mark_id >= 0 )
- pda_run->p = pda_run->mark[lel_info[pda_run->matched_token].mark_id];
-
- return pda_run->matched_token;
- }
-
- /* Check for error. */
- if ( pda_run->fsm_cs == pda_run->fsm_tables->error_state ) {
- /* If a token was started, but not finished (tokstart != 0) then
- * restore data to the beginning of that token. */
- if ( pda_run->tokstart != 0 )
- pda_run->p = pda_run->tokstart;
-
- /* Check for a default token in the region. If one is there
- * then send it and continue with the processing loop. */
- if ( prg->rtd->region_info[pda_run->region].default_token >= 0 ) {
- pda_run->toklen = 0;
- return prg->rtd->region_info[pda_run->region].default_token;
- }
-
- return SCAN_ERROR;
- }
-
- /* Check for no match on eof (trailing data that partially matches a token). */
- if ( pda_run->scan_eof )
- return SCAN_ERROR;
-
- /* Got here because the state machine didn't match a token or encounter
- * an error. Must be because we got to the end of the buffer data. */
- assert( pda_run->p == pda_run->pe );
- }
-
- /* Should not be reached. */
- return SCAN_ERROR;
-}
-
-tree_t *get_parsed_root( struct pda_run *pda_run, int stop )
-{
- if ( pda_run->parse_error )
- return 0;
- else if ( stop ) {
- if ( pda_run->stack_top->shadow != 0 )
- return pda_run->stack_top->shadow->tree;
- }
- else {
- if ( pda_run->stack_top->next->shadow != 0 )
- return pda_run->stack_top->next->shadow->tree;
- }
- return 0;
-}
-
-static void clear_parse_tree( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, parse_tree_t *pt )
-{
- tree_t **top = vm_ptop();
-
- if ( pt == 0 )
- return;
-
-free_tree:
- if ( pt->next != 0 ) {
- vm_push_ptree( pt->next );
- }
-
- if ( pt->left_ignore != 0 ) {
- vm_push_ptree( pt->left_ignore );
- }
-
- if ( pt->child != 0 ) {
- vm_push_ptree( pt->child );
- }
-
- if ( pt->right_ignore != 0 ) {
- vm_push_ptree( pt->right_ignore );
- }
-
- if ( pt->shadow != 0 ) {
- colm_tree_downref( prg, sp, pt->shadow->tree );
- kid_free( prg, pt->shadow );
- }
-
- parse_tree_free( pda_run, pt );
-
- /* Any trees to downref? */
- if ( sp != top ) {
- pt = vm_pop_ptree();
- goto free_tree;
- }
-}
-
-void colm_pda_clear( program_t *prg, tree_t **sp, struct pda_run *pda_run )
-{
- clear_fsm_run( prg, pda_run );
-
- /* Remaining stack and parse trees underneath. */
- clear_parse_tree( prg, sp, pda_run, pda_run->stack_top );
- pda_run->stack_top = 0;
-
- /* Traverse the token list downreffing. */
- ref_t *ref = pda_run->token_list;
- while ( ref != 0 ) {
- ref_t *next = ref->next;
- kid_free( prg, (kid_t*)ref );
- ref = next;
- }
- pda_run->token_list = 0;
-
- /* Traverse the btPoint list downreffing */
- kid_t *btp = pda_run->bt_point;
- while ( btp != 0 ) {
- kid_t *next = btp->next;
- colm_tree_downref( prg, sp, btp->tree );
- kid_free( prg, (kid_t*)btp );
- btp = next;
- }
- pda_run->bt_point = 0;
-
- /* Clear out any remaining ignores. */
- clear_parse_tree( prg, sp, pda_run, pda_run->accum_ignore );
- pda_run->accum_ignore = 0;
-
- /* Clear the input list (scanned tokes, sent trees). */
- clear_parse_tree( prg, sp, pda_run, pda_run->parse_input );
- pda_run->parse_input = 0;
-
- colm_rcode_downref_all( prg, sp, &pda_run->reverse_code );
- colm_rt_code_vect_empty( &pda_run->reverse_code );
- colm_rt_code_vect_empty( &pda_run->rcode_collect );
-
- colm_tree_downref( prg, sp, pda_run->parse_error_text );
-
- if ( pda_run->reducer ) {
- long local_lost = pool_alloc_num_lost( &pda_run->local_pool );
-
- if ( local_lost )
- message( "warning: reducer local lost parse trees: %ld\n", local_lost );
- pool_alloc_clear( &pda_run->local_pool );
- }
-}
-
-void colm_pda_init( program_t *prg, struct pda_run *pda_run, struct pda_tables *tables,
- int parser_id, long stop_target, int revert_on, struct_t *context, int reducer )
-{
- memset( pda_run, 0, sizeof(struct pda_run) );
-
- pda_run->pda_tables = tables;
- pda_run->parser_id = parser_id;
- pda_run->stop_target = stop_target;
- pda_run->revert_on = revert_on;
- pda_run->target_steps = -1;
- pda_run->reducer = reducer;
-
- /* An initial commit shift count of -1 means we won't ever back up to zero
- * shifts and think parsing cannot continue. */
- pda_run->shift_count = 0;
- pda_run->commit_shift_count = -1;
-
- if ( reducer ) {
- init_pool_alloc( &pda_run->local_pool, sizeof(parse_tree_t) +
- prg->rtd->commit_union_sz(reducer) );
- pda_run->parse_tree_pool = &pda_run->local_pool;
- }
- else {
- pda_run->parse_tree_pool = &prg->parse_tree_pool;
- }
-
- debug( prg, REALM_PARSE, "initializing struct pda_run %s\n",
- prg->rtd->lel_info[prg->rtd->parser_lel_ids[parser_id]].name );
-
- /* FIXME: need the right one here. */
- pda_run->pda_cs = prg->rtd->start_states[pda_run->parser_id];
-
- kid_t *sentinal = kid_allocate( prg );
- sentinal->tree = tree_allocate( prg );
- sentinal->tree->refs = 1;
-
- /* Init the element allocation variables. */
- pda_run->stack_top = parse_tree_allocate( pda_run );
- pda_run->stack_top->state = -1;
- pda_run->stack_top->shadow = sentinal;
-
- pda_run->num_retry = 0;
- pda_run->next_region_ind = pda_run->pda_tables->token_region_inds[pda_run->pda_cs];
- pda_run->stop_parsing = false;
- pda_run->accum_ignore = 0;
- pda_run->bt_point = 0;
- pda_run->check_next = false;
- pda_run->check_stop = false;
-
- prg->rtd->init_bindings( pda_run );
-
- init_rt_code_vect( &pda_run->reverse_code );
- init_rt_code_vect( &pda_run->rcode_collect );
-
- pda_run->context = context;
- pda_run->parse_error = 0;
- pda_run->parse_input = 0;
- pda_run->trigger_undo = 0;
-
- pda_run->token_id = 0;
-
- pda_run->on_deck = false;
- pda_run->parsed = 0;
- pda_run->reject = false;
-
- pda_run->rc_block_count = 0;
- pda_run->eof_term_recvd = 0;
-
- init_fsm_run( prg, pda_run );
- new_token( prg, pda_run );
-}
-
-static long stack_top_target( program_t *prg, struct pda_run *pda_run )
-{
- long state;
- if ( pda_run->stack_top->state < 0 )
- state = prg->rtd->start_states[pda_run->parser_id];
- else {
- unsigned shift = pda_run->stack_top->id -
- pda_run->pda_tables->keys[pda_run->stack_top->state<<1];
- unsigned offset = pda_run->pda_tables->offsets[pda_run->stack_top->state] + shift;
- int index = pda_run->pda_tables->indicies[offset];
- state = pda_run->pda_tables->targs[index];
- }
- return state;
-}
-
-/*
- * shift: retry goes into lower of shifted node.
- * reduce: retry goes into upper of reduced node.
- * shift-reduce: cannot be a retry
- */
-
-/* Stops on:
- * PCR_REDUCTION
- * PCR_REVERSE
- */
-static long parse_token( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, struct input_impl *is, long entry )
-{
- int pos;
- unsigned int *action;
- int rhs_len;
- int owner;
- int induce_reject;
- int ind_pos;
-
- /* COROUTINE */
- switch ( entry ) {
- case PCR_START:
-
- /* The scanner will send a null token if it can't find a token. */
- if ( pda_run->parse_input == 0 )
- goto parse_error;
-
- /* This will cause parseInput to be lost. This
- * path should be traced. */
- if ( pda_run->pda_cs < 0 )
- return PCR_DONE;
-
- /* Record the state in the parse tree. */
- pda_run->parse_input->state = pda_run->pda_cs;
-
-again:
- if ( pda_run->parse_input == 0 )
- goto _out;
-
- pda_run->lel = pda_run->parse_input;
- pda_run->cur_state = pda_run->pda_cs;
-
- if ( pda_run->lel->id < pda_run->pda_tables->keys[pda_run->cur_state<<1] ||
- pda_run->lel->id > pda_run->pda_tables->keys[(pda_run->cur_state<<1)+1] )
- {
- debug( prg, REALM_PARSE, "parse error, no transition 1\n" );
- push_bt_point( prg, pda_run );
- goto parse_error;
- }
-
- ind_pos = pda_run->pda_tables->offsets[pda_run->cur_state] +
- (pda_run->lel->id - pda_run->pda_tables->keys[pda_run->cur_state<<1]);
-
- owner = pda_run->pda_tables->owners[ind_pos];
- if ( owner != pda_run->cur_state ) {
- debug( prg, REALM_PARSE, "parse error, no transition 2\n" );
- push_bt_point( prg, pda_run );
- goto parse_error;
- }
-
- pos = pda_run->pda_tables->indicies[ind_pos];
- if ( pos < 0 ) {
- debug( prg, REALM_PARSE, "parse error, no transition 3\n" );
- push_bt_point( prg, pda_run );
- goto parse_error;
- }
-
- /* Checking complete. */
-
- induce_reject = false;
- pda_run->pda_cs = pda_run->pda_tables->targs[pos];
- action = pda_run->pda_tables->actions + pda_run->pda_tables->act_inds[pos];
- if ( pda_run->lel->retry_lower )
- action += pda_run->lel->retry_lower;
-
- /*
- * Shift
- */
-
- if ( *action & act_sb ) {
- debug( prg, REALM_PARSE, "shifted: %s\n",
- prg->rtd->lel_info[pda_run->lel->id].name );
- /* Consume. */
- pda_run->parse_input = pda_run->parse_input->next;
-
- pda_run->lel->state = pda_run->cur_state;
-
- /* If its a token then attach ignores and record it in the token list
- * of the next ignore attachment to use. */
- if ( pda_run->lel->id < prg->rtd->first_non_term_id ) {
- if ( pda_run->lel->cause_reduce == 0 )
- attach_right_ignore( prg, sp, pda_run, pda_run->stack_top );
- }
-
- pda_run->lel->next = pda_run->stack_top;
- pda_run->stack_top = pda_run->lel;
-
- /* If its a token then attach ignores and record it in the token list
- * of the next ignore attachment to use. */
- if ( pda_run->lel->id < prg->rtd->first_non_term_id ) {
- attach_left_ignore( prg, sp, pda_run, pda_run->lel );
-
- ref_t *ref = (ref_t*)kid_allocate( prg );
- ref->kid = pda_run->lel->shadow;
- //colm_tree_upref( prg, pdaRun->tree );
- ref->next = pda_run->token_list;
- pda_run->token_list = ref;
- }
-
- if ( action[1] == 0 )
- pda_run->lel->retry_lower = 0;
- else {
- debug( prg, REALM_PARSE, "retry: %p\n", pda_run->stack_top );
- pda_run->lel->retry_lower += 1;
- assert( pda_run->lel->retry_upper == 0 );
- /* FIXME: Has the retry already been counted? */
- pda_run->num_retry += 1;
- }
-
- pda_run->shift_count += 1;
- }
-
- /*
- * Commit
- */
-
- if ( pda_run->pda_tables->commit_len[pos] != 0 ) {
- debug( prg, REALM_PARSE, "commit point\n" );
- pda_run->commit_shift_count = pda_run->shift_count;
-
- /* Not in a reverting context and the parser result is not used. */
- if ( pda_run->reducer )
- commit_reduce( prg, sp, pda_run );
-
- if ( pda_run->fail_parsing )
- goto fail;
-
- }
-
- /*
- * Reduce
- */
-
- if ( *action & act_rb ) {
- int r, object_length;
- parse_tree_t *last, *child;
- kid_t *attrs;
- kid_t *data_last, *data_child;
-
- /* If there was shift don't attach again. */
- if ( !( *action & act_sb ) && pda_run->lel->id < prg->rtd->first_non_term_id )
- attach_right_ignore( prg, sp, pda_run, pda_run->stack_top );
-
- pda_run->reduction = *action >> 2;
-
- if ( pda_run->parse_input != 0 )
- pda_run->parse_input->cause_reduce += 1;
-
- kid_t *value = kid_allocate( prg );
- value->tree = tree_allocate( prg );
- value->tree->refs = 1;
- value->tree->id = prg->rtd->prod_info[pda_run->reduction].lhs_id;
- value->tree->prod_num = prg->rtd->prod_info[pda_run->reduction].prod_num;
-
- pda_run->red_lel = parse_tree_allocate( pda_run );
- pda_run->red_lel->id = prg->rtd->prod_info[pda_run->reduction].lhs_id;
- pda_run->red_lel->next = 0;
- pda_run->red_lel->cause_reduce = 0;
- pda_run->red_lel->retry_lower = 0;
- pda_run->red_lel->shadow = value;
-
- /* Transfer. */
- pda_run->red_lel->retry_upper = pda_run->lel->retry_lower;
- pda_run->lel->retry_lower = 0;
-
- /* Allocate the attributes. */
- object_length = prg->rtd->lel_info[pda_run->red_lel->id].object_length;
- attrs = alloc_attrs( prg, object_length );
-
- /* Build the list of children. We will be giving up a reference when we
- * detach parse tree and data tree, but gaining the reference when we
- * put the children under the new data tree. No need to alter refcounts
- * here. */
- rhs_len = prg->rtd->prod_info[pda_run->reduction].length;
- child = last = 0;
- data_child = data_last = 0;
- for ( r = 0; r < rhs_len; r++ ) {
-
- /* The child. */
- child = pda_run->stack_top;
- data_child = child->shadow;
-
- /* Pop. */
- pda_run->stack_top = pda_run->stack_top->next;
-
- /* Detach the parse tree from the data. */
- child->shadow = 0;
-
- /* Reverse list. */
- child->next = last;
- data_child->next = data_last;
-
- /* Track last for reversal. */
- last = child;
- data_last = data_child;
- }
-
- pda_run->red_lel->child = child;
- pda_run->red_lel->shadow->tree->child = kid_list_concat( attrs, data_child );
-
- debug( prg, REALM_PARSE, "reduced: %s rhsLen %d\n",
- prg->rtd->prod_info[pda_run->reduction].name, rhs_len );
- if ( action[1] == 0 )
- pda_run->red_lel->retry_upper = 0;
- else {
- pda_run->red_lel->retry_upper += 1;
- assert( pda_run->lel->retry_lower == 0 );
- pda_run->num_retry += 1;
- debug( prg, REALM_PARSE, "retry: %p\n", pda_run->red_lel );
- }
-
- /* When the production is of zero length we stay in the same state.
- * Otherwise we use the state stored in the first child. */
- pda_run->pda_cs = rhs_len == 0 ? pda_run->cur_state : child->state;
-
- if ( prg->ctx_dep_parsing && prg->rtd->prod_info[pda_run->reduction].frame_id >= 0 ) {
- /* Frame info for reduction. */
- pda_run->fi = &prg->rtd->frame_info[prg->rtd->prod_info[pda_run->reduction].frame_id];
- pda_run->frame_id = prg->rtd->prod_info[pda_run->reduction].frame_id;
- pda_run->reject = false;
- pda_run->parsed = 0;
- pda_run->code = pda_run->fi->codeWV;
-
- /* COROUTINE */
- return PCR_REDUCTION;
- case PCR_REDUCTION:
-
- if ( prg->induce_exit )
- goto fail;
-
- /* If the lhs was stored and it changed then we need to restore the
- * original upon backtracking, otherwise downref since we took a
- * copy above. */
- if ( pda_run->parsed != 0 ) {
- if ( pda_run->parsed != pda_run->red_lel->shadow->tree ) {
- debug( prg, REALM_PARSE, "lhs tree was modified, "
- "adding a restore instruction\n" );
-//
-// /* Make it into a parse tree. */
-// tree_t *newPt = prepParseTree( prg, sp, pdaRun->redLel->tree );
-// colm_tree_downref( prg, sp, pdaRun->redLel->tree );
-//
-// /* Copy it in. */
-// pdaRun->redLel->tree = newPt;
-// colm_tree_upref( prg, pdaRun->redLel->tree );
-
- /* Add the restore instruct. */
- append_code_val( &pda_run->rcode_collect, IN_RESTORE_LHS );
- append_word( &pda_run->rcode_collect, (word_t)pda_run->parsed );
- append_code_val( &pda_run->rcode_collect, SIZEOF_CODE + SIZEOF_WORD );
- }
- else {
- /* Not changed. Done with parsed. */
- colm_tree_downref( prg, sp, pda_run->parsed );
- }
- pda_run->parsed = 0;
- }
-
- /* Pull out the reverse code, if any. */
- colm_make_reverse_code( pda_run );
- colm_transfer_reverse_code( pda_run, pda_run->red_lel );
-
- /* Perhaps the execution environment is telling us we need to
- * reject the reduction. */
- induce_reject = pda_run->reject;
- }
-
- /* If the left hand side was replaced then the only parse algorithm
- * data that is contained in it will the PF_HAS_RCODE flag. Everthing
- * else will be in the original. This requires that we restore first
- * when going backwards and when doing a commit. */
-
- if ( induce_reject ) {
- debug( prg, REALM_PARSE, "error induced during reduction of %s\n",
- prg->rtd->lel_info[pda_run->red_lel->id].name );
- pda_run->red_lel->state = pda_run->cur_state;
- pda_run->red_lel->next = pda_run->stack_top;
- pda_run->stack_top = pda_run->red_lel;
- /* FIXME: What is the right argument here? */
- push_bt_point( prg, pda_run );
- goto parse_error;
- }
-
- pda_run->red_lel->next = pda_run->parse_input;
- pda_run->parse_input = pda_run->red_lel;
- }
-
- goto again;
-
-parse_error:
- debug( prg, REALM_PARSE, "hit error, backtracking\n" );
-
-#if 0
- if ( pda_run->num_retry == 0 ) {
- debug( prg, REALM_PARSE, "out of retries failing parse\n" );
- goto fail;
- }
-#endif
-
- while ( 1 ) {
- if ( pda_run->on_deck ) {
- debug( prg, REALM_BYTECODE, "dropping out for reverse code call\n" );
-
- pda_run->frame_id = -1;
- pda_run->code = colm_pop_reverse_code( &pda_run->reverse_code );
-
- /* COROUTINE */
- return PCR_REVERSE;
- case PCR_REVERSE:
-
- colm_decrement_steps( pda_run );
- }
- else if ( pda_run->check_next ) {
- pda_run->check_next = false;
-
- if ( pda_run->next > 0 && pda_run->pda_tables->token_regions[pda_run->next] != 0 ) {
- debug( prg, REALM_PARSE, "found a new region\n" );
- pda_run->num_retry -= 1;
- pda_run->pda_cs = stack_top_target( prg, pda_run );
- pda_run->next_region_ind = pda_run->next;
- return PCR_DONE;
- }
- }
- else if ( pda_run->check_stop ) {
- pda_run->check_stop = false;
-
- if ( pda_run->stop ) {
- debug( prg, REALM_PARSE, "stopping the backtracking, "
- "steps is %d\n", pda_run->steps );
-
- pda_run->pda_cs = stack_top_target( prg, pda_run );
- goto _out;
- }
- }
- else if ( pda_run->parse_input != 0 ) {
- /* Either we are dealing with a terminal that was shifted or a
- * nonterminal that was reduced. */
- if ( pda_run->parse_input->id < prg->rtd->first_non_term_id ) {
- /* This is a terminal. */
- assert( pda_run->parse_input->retry_upper == 0 );
-
- if ( pda_run->parse_input->retry_lower != 0 ) {
- debug( prg, REALM_PARSE, "found retry targ: %p\n", pda_run->parse_input );
-
- pda_run->num_retry -= 1;
- pda_run->pda_cs = pda_run->parse_input->state;
- goto again;
- }
-
- if ( pda_run->parse_input->cause_reduce != 0 ) {
- /* The terminal caused a reduce. Unshift the reduced thing
- * (will unreduce in the next step. */
- if ( pda_run->shift_count == pda_run->commit_shift_count ) {
- debug( prg, REALM_PARSE, "backed up to commit point, "
- "failing parse\n" );
- goto fail;
- }
- pda_run->shift_count -= 1;
-
- pda_run->undo_lel = pda_run->stack_top;
-
- /* Check if we've arrived at the stack sentinal. This guard
- * is here to allow us to initially set numRetry to one to
- * cause the parser to backup all the way to the beginning
- * when an error occurs. */
- if ( pda_run->undo_lel->next == 0 )
- break;
-
- /* Either we are dealing with a terminal that was
- * shifted or a nonterminal that was reduced. */
- assert( !(pda_run->stack_top->id < prg->rtd->first_non_term_id) );
-
- debug( prg, REALM_PARSE, "backing up over non-terminal: %s\n",
- prg->rtd->lel_info[pda_run->stack_top->id].name );
-
- /* Pop the item from the stack. */
- pda_run->stack_top = pda_run->stack_top->next;
-
- /* Queue it as next parseInput item. */
- pda_run->undo_lel->next = pda_run->parse_input;
- pda_run->parse_input = pda_run->undo_lel;
- }
- else {
- long region = pda_run->parse_input->retry_region;
- pda_run->next = region > 0 ? region + 1 : 0;
- pda_run->check_next = true;
- pda_run->check_stop = true;
-
- send_back( prg, sp, pda_run, is, pda_run->parse_input );
-
- pda_run->parse_input = 0;
- }
- }
- else if ( pda_run->parse_input->flags & PF_HAS_RCODE ) {
- debug( prg, REALM_PARSE, "tree has rcode, setting on deck\n" );
- pda_run->on_deck = true;
- pda_run->parsed = 0;
-
- /* Only the RCODE flag was in the replaced lhs. All the rest is in
- * the the original. We read it after restoring. */
-
- pda_run->parse_input->flags &= ~PF_HAS_RCODE;
- }
- else {
- /* Remove it from the input queue. */
- pda_run->undo_lel = pda_run->parse_input;
- pda_run->parse_input = pda_run->parse_input->next;
-
- /* Extract children from the child list. */
- parse_tree_t *first = pda_run->undo_lel->child;
- pda_run->undo_lel->child = 0;
-
- /* This will skip the ignores/attributes, etc. */
- kid_t *data_first = tree_extract_child( prg, pda_run->undo_lel->shadow->tree );
-
- /* Walk the child list and and push the items onto the parsing
- * stack one at a time. */
- while ( first != 0 ) {
- /* Get the next item ahead of time. */
- parse_tree_t *next = first->next;
- kid_t *data_next = data_first->next;
-
- /* Push onto the stack. */
- first->next = pda_run->stack_top;
- pda_run->stack_top = first;
-
- /* Reattach the data and the parse tree. */
- first->shadow = data_first;
-
- first = next;
- data_first = data_next;
- }
-
- /* If there is an parseInput queued, this is one less reduction it has
- * caused. */
- if ( pda_run->parse_input != 0 )
- pda_run->parse_input->cause_reduce -= 1;
-
- if ( pda_run->undo_lel->retry_upper != 0 ) {
- /* There is always an parseInput item here because reduce
- * conflicts only happen on a lookahead character. */
- assert( pda_run->parse_input != pda_run->undo_lel );
- assert( pda_run->parse_input != 0 );
- assert( pda_run->undo_lel->retry_lower == 0 );
- assert( pda_run->parse_input->retry_upper == 0 );
-
- /* Transfer the retry from undoLel to parseInput. */
- pda_run->parse_input->retry_lower = pda_run->undo_lel->retry_upper;
- pda_run->parse_input->retry_upper = 0;
- pda_run->parse_input->state = stack_top_target( prg, pda_run );
- }
-
- /* Free the reduced item. */
- colm_tree_downref( prg, sp, pda_run->undo_lel->shadow->tree );
- kid_free( prg, pda_run->undo_lel->shadow );
- parse_tree_free( pda_run, pda_run->undo_lel );
-
- /* If the stacktop had right ignore attached, detach now. */
- if ( pda_run->stack_top->flags & PF_RIGHT_IL_ATTACHED )
- detach_right_ignore( prg, sp, pda_run, pda_run->stack_top );
- }
- }
- else if ( pda_run->accum_ignore != 0 ) {
- debug( prg, REALM_PARSE, "have accumulated ignore to undo\n" );
-
- /* Send back any accumulated ignore tokens, then trigger error
- * in the the parser. */
- parse_tree_t *ignore = pda_run->accum_ignore;
- pda_run->accum_ignore = pda_run->accum_ignore->next;
- ignore->next = 0;
-
- long region = ignore->retry_region;
- pda_run->next = region > 0 ? region + 1 : 0;
- pda_run->check_next = true;
- pda_run->check_stop = true;
-
- send_back_ignore( prg, sp, pda_run, is, ignore );
-
- colm_tree_downref( prg, sp, ignore->shadow->tree );
- kid_free( prg, ignore->shadow );
- parse_tree_free( pda_run, ignore );
- }
- else {
- if ( pda_run->shift_count == pda_run->commit_shift_count ) {
- debug( prg, REALM_PARSE, "backed up to commit point, failing parse\n" );
- goto fail;
- }
-
- pda_run->shift_count -= 1;
-
- /* Now it is time to undo something. Pick an element from the top of
- * the stack. */
- pda_run->undo_lel = pda_run->stack_top;
-
- /* Check if we've arrived at the stack sentinal. This guard is
- * here to allow us to initially set numRetry to one to cause the
- * parser to backup all the way to the beginning when an error
- * occurs. */
- if ( pda_run->undo_lel->next == 0 )
- break;
-
- /* Either we are dealing with a terminal that was
- * shifted or a nonterminal that was reduced. */
- if ( pda_run->stack_top->id < prg->rtd->first_non_term_id ) {
- debug( prg, REALM_PARSE, "backing up over effective terminal: %s\n",
- prg->rtd->lel_info[pda_run->stack_top->id].name );
-
- /* Pop the item from the stack. */
- pda_run->stack_top = pda_run->stack_top->next;
-
- /* Queue it as next parseInput item. */
- pda_run->undo_lel->next = pda_run->parse_input;
- pda_run->parse_input = pda_run->undo_lel;
-
- /* Pop from the token list. */
- ref_t *ref = pda_run->token_list;
- pda_run->token_list = ref->next;
- kid_free( prg, (kid_t*)ref );
-
- assert( pda_run->accum_ignore == 0 );
- detach_left_ignore( prg, sp, pda_run, pda_run->parse_input );
- }
- else {
- debug( prg, REALM_PARSE, "backing up over non-terminal: %s\n",
- prg->rtd->lel_info[pda_run->stack_top->id].name );
-
- /* Pop the item from the stack. */
- pda_run->stack_top = pda_run->stack_top->next;
-
- /* Queue it as next parseInput item. */
- pda_run->undo_lel->next = pda_run->parse_input;
- pda_run->parse_input = pda_run->undo_lel;
- }
-
- /* Undo attach of right ignore. */
- if ( pda_run->stack_top->flags & PF_RIGHT_IL_ATTACHED )
- detach_right_ignore( prg, sp, pda_run, pda_run->stack_top );
- }
- }
-
-fail:
- pda_run->pda_cs = -1;
- pda_run->parse_error = 1;
-
- /* FIXME: do we still need to fall through here? A fail is permanent now,
- * no longer called into again. */
-
- return PCR_DONE;
-
-_out:
- pda_run->next_region_ind = pda_run->pda_tables->token_region_inds[pda_run->pda_cs];
-
- /* COROUTINE */
- case PCR_DONE:
- break; }
-
- return PCR_DONE;
-}
-
-/*
- * colm_parse_loop
- *
- * Stops on:
- * PCR_PRE_EOF
- * PCR_GENERATION
- * PCR_REDUCTION
- * PCR_REVERSE
- */
-
-long colm_parse_loop( program_t *prg, tree_t **sp, struct pda_run *pda_run,
- struct input_impl *is, long entry )
-{
- struct lang_el_info *lel_info = prg->rtd->lel_info;
-
- /* COROUTINE */
- switch ( entry ) {
- case PCR_START:
-
- pda_run->stop = false;
-
- while ( true ) {
- debug( prg, REALM_PARSE, "parse loop start\n" );
-
- /* Pull the current scanner from the parser. This can change during
- * parsing due to inputStream pushes, usually for the purpose of includes.
- * */
- pda_run->token_id = scan_token( prg, pda_run, is );
-
- if ( pda_run->token_id == SCAN_ERROR ) {
- if ( pda_run->pre_region >= 0 ) {
- pda_run->pre_region = -1;
- pda_run->fsm_cs = pda_run->next_cs;
- continue;
- }
- }
-
- if ( pda_run->token_id == SCAN_ERROR &&
- ( prg->rtd->region_info[pda_run->region].ci_lel_id > 0 ) )
- {
- debug( prg, REALM_PARSE, "sending a collect ignore\n" );
- send_collect_ignore( prg, sp, pda_run, is,
- prg->rtd->region_info[pda_run->region].ci_lel_id );
- goto yes;
- }
-
- if ( pda_run->token_id == SCAN_TRY_AGAIN_LATER ) {
- debug( prg, REALM_PARSE, "scanner says try again later\n" );
- break;
- }
-
- assert( pda_run->parse_input == 0 );
- pda_run->parse_input = 0;
-
- /* Check for EOF. */
- if ( pda_run->token_id == SCAN_EOF ) {
- pda_run->eof_term_recvd = true;
- send_eof( prg, sp, pda_run, is );
-
- pda_run->frame_id = prg->rtd->region_info[pda_run->region].eof_frame_id;
-
- if ( prg->ctx_dep_parsing && pda_run->frame_id >= 0 ) {
- debug( prg, REALM_PARSE, "HAVE PRE_EOF BLOCK\n" );
-
- pda_run->fi = &prg->rtd->frame_info[pda_run->frame_id];
- pda_run->code = pda_run->fi->codeWV;
-
- /* COROUTINE */
- return PCR_PRE_EOF;
- case PCR_PRE_EOF:
-
- colm_make_reverse_code( pda_run );
- }
- }
- else if ( pda_run->token_id == SCAN_UNDO ) {
- /* Fall through with parseInput = 0. FIXME: Do we need to send back ignore? */
- debug( prg, REALM_PARSE, "invoking undo from the scanner\n" );
- }
- else if ( pda_run->token_id == SCAN_ERROR ) {
- /* Scanner error, maybe retry. */
- if ( pda_run->accum_ignore == 0 && get_next_region( pda_run, 1 ) != 0 ) {
- debug( prg, REALM_PARSE, "scanner failed, trying next region\n" );
-
- pda_run->next_region_ind += 1;
- goto skip_send;
- }
- else { // if ( pdaRun->numRetry > 0 ) {
- debug( prg, REALM_PARSE, "invoking parse error from the scanner\n" );
-
- /* Fall through to send null (error). */
- push_bt_point( prg, pda_run );
- }
-#if 0
- else {
- debug( prg, REALM_PARSE, "no alternate scanning regions\n" );
-
- /* There are no alternative scanning regions to try, nor are
- * there any alternatives stored in the current parse tree. No
- * choice but to end the parse. */
- push_bt_point( prg, pda_run );
-
- report_parse_error( prg, sp, pda_run );
- pda_run->parse_error = 1;
- goto skip_send;
- }
-#endif
- }
- else if ( pda_run->token_id == SCAN_LANG_EL ) {
- debug( prg, REALM_PARSE, "sending an named lang el\n" );
-
- /* A named language element (parsing colm program). */
- prg->rtd->send_named_lang_el( prg, sp, pda_run, is );
- }
- else if ( pda_run->token_id == SCAN_TREE ) {
- debug( prg, REALM_PARSE, "sending a tree\n" );
-
- /* A tree already built. */
- send_tree( prg, sp, pda_run, is );
- }
- else if ( pda_run->token_id == SCAN_IGNORE ) {
- debug( prg, REALM_PARSE, "sending an ignore token\n" );
-
- /* A tree to ignore. */
- send_ignore_tree( prg, sp, pda_run, is );
- goto skip_send;
- }
- else if ( prg->ctx_dep_parsing && lel_info[pda_run->token_id].frame_id >= 0 ) {
- /* Has a generation action. */
- debug( prg, REALM_PARSE, "token gen action: %s\n",
- prg->rtd->lel_info[pda_run->token_id].name );
-
- /* Make the token data. */
- pda_run->tokdata = peek_match( prg, pda_run, is );
-
- /* Note that we don't update the position now. It is done when the token
- * data is pulled from the inputStream. */
-
- pda_run->p = pda_run->pe = 0;
- pda_run->toklen = 0;
- pda_run->scan_eof = 0;
-
- pda_run->fi = &prg->rtd->frame_info[prg->rtd->lel_info[pda_run->token_id].frame_id];
- pda_run->frame_id = prg->rtd->lel_info[pda_run->token_id].frame_id;
- pda_run->code = pda_run->fi->codeWV;
-
- /* COROUTINE */
- return PCR_GENERATION;
- case PCR_GENERATION:
-
- colm_make_reverse_code( pda_run );
-
- /* Finished with the match text. */
- string_free( prg, pda_run->tokdata );
-
- goto skip_send;
- }
- else if ( lel_info[pda_run->token_id].ignore ) {
- debug( prg, REALM_PARSE, "sending an ignore token: %s\n",
- prg->rtd->lel_info[pda_run->token_id].name );
-
- /* Is an ignore token. */
- send_ignore( prg, sp, pda_run, is, pda_run->token_id );
- goto skip_send;
- }
- else {
- debug( prg, REALM_PARSE, "sending a plain old token: %s\n",
- prg->rtd->lel_info[pda_run->token_id].name );
-
- /* Is a plain token. */
- send_token( prg, sp, pda_run, is, pda_run->token_id );
- }
-yes:
-
- if ( pda_run->parse_input != 0 )
- colm_transfer_reverse_code( pda_run, pda_run->parse_input );
-
- if ( pda_run->parse_input != 0 ) {
- /* If it's a nonterminal with a termdup then flip the parse tree to
- * the terminal. */
- if ( pda_run->parse_input->id >= prg->rtd->first_non_term_id ) {
- pda_run->parse_input->id =
- prg->rtd->lel_info[pda_run->parse_input->id].term_dup_id;
- pda_run->parse_input->flags |= PF_TERM_DUP;
- }
- }
-
- long pcr = parse_token( prg, sp, pda_run, is, PCR_START );
-
- while ( pcr != PCR_DONE ) {
-
- /* COROUTINE */
- return pcr;
- case PCR_REDUCTION:
- case PCR_REVERSE:
-
- pcr = parse_token( prg, sp, pda_run, is, entry );
- }
-
- assert( pcr == PCR_DONE );
-
- handle_error( prg, sp, pda_run );
-
-skip_send:
- new_token( prg, pda_run );
-
- /* Various stop conditions. This should all be coverned by one test
- * eventually. */
-
- if ( pda_run->trigger_undo ) {
- debug( prg, REALM_PARSE, "parsing stopped by triggerUndo\n" );
- break;
- }
-
- if ( pda_run->eof_term_recvd ) {
- debug( prg, REALM_PARSE, "parsing stopped by EOF\n" );
- break;
- }
-
- if ( pda_run->stop_parsing ) {
- debug( prg, REALM_PARSE, "scanner has been stopped\n" );
- break;
- }
-
- if ( pda_run->stop ) {
- debug( prg, REALM_PARSE, "parsing has been stopped by consumedCount\n" );
- break;
- }
-
- if ( prg->induce_exit ) {
- debug( prg, REALM_PARSE, "parsing has been stopped by a call to exit\n" );
- break;
- }
-
- if ( pda_run->parse_error ) {
- debug( prg, REALM_PARSE, "parsing stopped by a parse error\n" );
- break;
- }
-
- /* Disregard any alternate parse paths, just go right to failure. */
- if ( pda_run->fail_parsing ) {
- debug( prg, REALM_PARSE, "parsing failed by explicit request\n" );
- break;
- }
- }
-
- /* COROUTINE */
- case PCR_DONE:
- break; }
-
- return PCR_DONE;
-}
-
-
-long colm_parse_frag( program_t *prg, tree_t **sp,
- struct pda_run *pda_run, input_t *input, long entry )
-{
- /* COROUTINE */
- switch ( entry ) {
- case PCR_START:
-
- if ( ! pda_run->parse_error ) {
- long pcr = colm_parse_loop( prg, sp, pda_run,
- input_to_impl( input ), entry );
-
- while ( pcr != PCR_DONE ) {
-
- /* COROUTINE */
- return pcr;
- case PCR_REDUCTION:
- case PCR_GENERATION:
- case PCR_PRE_EOF:
- case PCR_REVERSE:
-
- pcr = colm_parse_loop( prg, sp, pda_run,
- input_to_impl( input ), entry );
- }
- }
-
- /* COROUTINE */
- case PCR_DONE:
- break; }
-
- return PCR_DONE;
-}
-
-long colm_parse_undo_frag( program_t *prg, tree_t **sp, struct pda_run *pda_run,
- input_t *input, long entry, long steps )
-{
- debug( prg, REALM_PARSE,
- "undo parse frag, target steps: %ld, pdarun steps: %ld\n",
- steps, pda_run->steps );
-
- reset_token( pda_run );
-
- /* COROUTINE */
- switch ( entry ) {
- case PCR_START:
-
- if ( steps < pda_run->steps ) {
- /* Setup environment for going backwards until we reduced steps to
- * what we want. */
- pda_run->num_retry += 1;
- pda_run->target_steps = steps;
- pda_run->trigger_undo = 1;
-
- /* The parse loop will recognise the situation. */
- long pcr = colm_parse_loop( prg, sp, pda_run, input_to_impl(input), entry );
- while ( pcr != PCR_DONE ) {
-
- /* COROUTINE */
- return pcr;
- case PCR_REDUCTION:
- case PCR_GENERATION:
- case PCR_PRE_EOF:
- case PCR_REVERSE:
-
- pcr = colm_parse_loop( prg, sp, pda_run, input_to_impl(input), entry );
- }
-
- /* Reset environment. */
- pda_run->trigger_undo = 0;
- pda_run->target_steps = -1;
- pda_run->num_retry -= 1;
- }
-
- /* COROUTINE */
- case PCR_DONE:
- break; }
-
- return PCR_DONE;
-}
-
-void colm_parse_reduce_commit( program_t *prg, tree_t **sp,
- struct pda_run *pda_run )
-{
- /* Flush out anything not committed. */
- if ( pda_run->reducer )
- commit_reduce( prg, sp, pda_run );
-}
-