view anagram/guisupport/conflicttrc.cpp @ 15:f5acaf0c8a29

Don't cast through "volatile int". Causes a gcc warning nowadays. XXX: should put something else back here to frighten the optimizer
author David A. Holland
date Tue, 31 May 2022 01:00:55 -0400
parents 13d2b8934445
children
line wrap: on
line source

/*
 * AnaGram, A System for Syntax Directed Programming
 * Copyright 1993-1999 Parsifal Software. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 *
 * conflicttrc.cpp - Conflict trace display
 */

#include <stdio.h>
#include "port.h"

#include "arrays.h"
#include "assert.h"
#include "cd.h"
#include "conflictdc.h"
#include "conflicttrc.h"
#include "data.h"
#include "dc.h"
#include "items.h"
#include "nckwtr.h"
#include "p.h"
#include "q1a.h"
#include "q1glbl.h"
#include "rule.h"
#include "stexpdc.h"
#include "stacks.h"
#include "tracedc.h"
#include "ut.h"
#include "wm1.h"
#include "ws.h"

//#define INCLUDE_LOGGING
#include "log.h"


//int *reduction_stack;
//int reduction_stack_depth;

dc_ref new_item_stack_kernel(dc_ref d, tsd *isl) {
  dc_ref window;

  check_tsd(isl);
  return dc_ref(new rule_stack_dc(isl, d->des->c_loc_doc.y, d->head_title));
}

//class rule_stack_dc

static int rule_stack_tabs[] = {4, 12, 0};

rule_stack_dc::rule_stack_dc(tsd *stack, unsigned ln, const AgString foot)
  : dc("Rule Stack", foot)
  , parser_stack(stack)
{
  int k;
  int sx, sn, fn, fx;

  k = stack->nt;
  while (k--) {
    xtxf(parser_stack, k, &sx, &sn, &fn, &fx);
    if (ln == (unsigned) sx) {
      break;
    }
  }
  assert(k >= 0);
  //des->c_size = cursor_bar_size;
  des->d_size.y = parser_stack->nt;
  tab_stops = rule_stack_tabs;
  columnHeadTitle = "Level\tState\tRules";
  //getWidth();
  //manual_resize = 0;
  //resize_window();
  des->c_loc_doc.y = parser_stack->nt-1;
  //bound_cursor_ver(des);
  //k = parser_stack->nt - 1 - k;
  des->c_loc_doc.y = k;
  //bound_cursor_ver(des);
}

void rule_stack_dc::getLine(unsigned tln) const {
  int sx, psx=0, sn, psn=0, fn, fx;
  unsigned ln;

  LOGSECTION("rule_stack_dc::getLine");
  LOGV(tln);
  ln = parser_stack->nt - tln - 1;
  LOGV(ln);
  if (ln < parser_stack->nt-1) {
    xtx(parser_stack, ln+1, &psx, &psn, &fn, &fx);
  }
  xtx(parser_stack, ln, &sx, &sn, &fn, &fx);
  LOGV(sx);
  if (tln && sn == psn && sx == psx) {
    sss("\t\t");
  }
  else {
    ssprintf("%2d\tS%03d:\t",sx,sn);
  }
  append_item(fn, fx);
  return;
}


rule_stack_dc::item::item(tsd* stack, unsigned ln) {
  LOGSECTION("rule_stack_dc::item::item");
  int sn;
  int csd;

  LOGV(ln) LCV(stack->nt);
  ln = stack->nt - 1 - ln;
  LOGV(ln);
  xtx(stack, ln, &csd, &sn, &rule, &index);
  LOGV(sn) LCV(rule) LCV(index);
}

rule_stack_dc::item rule_stack_dc::getItem(unsigned ln) const {
  return item(parser_stack, ln);
}

unsigned rule_stack_dc::state(unsigned ln) {
  int csd;
  int sn, fn, fx;

  ln = parser_stack->nt - 1 - ln;
  xtx(parser_stack, ln, &csd, &sn, &fn, &fx);
  return sn;
}

unsigned rule_stack_dc::token(unsigned ln) {
  item x = getItem(ln);
  if (map_form_number[x.rule].length() <= x.index) {
    return 0;
  }
  //return lstptr(map_form_number[x.rule], tokens)[x.index];
  return Rule(x.rule).token(x.index);
}

void rule_stack_dc::synchCursor(unsigned ln) const {
  LOGSECTION("rule_stack_dc::synchCursor");
  LOGV(ln);
  set_rule_line(getItem(ln).rule);
  LOGS("set_rule_line returned");
}

dc_ref rule_stack_dc::expansion_chain(unsigned ln) {
  int csd;
  int sn, fn, fx;

  ln = parser_stack->nt - 1 - ln;
  xtx(parser_stack, ln, &csd, &sn, &fn, &fx);
  return expansion_chain_window(sn, fn, fx);
}

int rule_stack_dc::expansion_chain_ok(unsigned ln) {
  LOGSECTION("rule_stack_dc::expansion_chain_ok");
  int csd;
  int sn, fn, fx;

  ln = parser_stack->nt - 1 - ln;
  xtx(parser_stack, ln, &csd, &sn, &fn, &fx);
  LOGV(fn) LCV(fx);
  return fn != 0 && fx == 0;
}

int rule_stack_dc::rule_context_ok(unsigned ln) {
  int csd;
  int sn, fn, fx;

  ln = parser_stack->nt - 1 - ln;
  xtx(parser_stack, ln, &csd, &sn, &fn, &fx);
  return fn != 0;
}

dc_ref rule_stack_dc::expansion_rules(unsigned ln) {
  item x = getItem(ln);
  return expand_specific_item(this, x.rule, x.index);
}

int rule_stack_dc::expansion_rules_ok(unsigned ln) {
  item x = getItem(ln);
  return build_item_list_ok(token(ln));
}

dc_ref rule_stack_dc::state_expansion(unsigned ln) {
  return state_expansion_window(state(ln));
}

int rule_stack_dc::keywords_ok(unsigned ln) {
  return keywords_window_ok(state(ln));
}

dc_ref rule_stack_dc::keywords(unsigned ln) {
  return keywords_window(state(ln));
}

int rule_stack_dc::productions_ok(unsigned ln) {
  return productions_window_ok(token(ln));
}

dc_ref rule_stack_dc::productions(unsigned ln) {
  return productions_window(token(ln));
}

dc_ref rule_stack_dc::rule_context(unsigned ln) {
  item x = getItem(ln);
  return rule_context_window(x.rule);
}

int rule_stack_dc::set_elements_ok(unsigned ln) {
  return token_set_window_ok(token(ln));
}

dc_ref rule_stack_dc::set_elements(unsigned ln) {
  return token_set_window(token(ln));
}

dc_ref rule_stack_dc::state_definition(unsigned ln) {
  return conflict_state_window(state(ln));
}

int rule_stack_dc::usage_ok(unsigned ln) {
  return token_usage_window_ok(token(ln));
}

dc_ref rule_stack_dc::usage(unsigned ln) {
  return token_usage_window(token(ln));
}

dc_ref problem_states_window(int sn, int fn, int fx, int ct) {
  int cfn;
  unsigned *list;
  dc_ref new_window;
  tsd *table;
  int i, ns;

  if (fx < map_form_number[fn].length()) {
    return NULL;
  }
  AgString foot = AgString::format("S%03d:R%03d:T%03d", sn, fn, ct);
  cfn = get_reduction_states(sn, fn, fx);
  list = lstptr(map_completed_form[cfn], reduction_states);
  ns = map_completed_form[cfn].n_reduction_states;
  iws();
  for (i = 0; i < ns; i++) {
    if (x2d(list[i], ct)) {
      aws(list[i]);
    }
  }
  table = build_states_table((unsigned *) list_base, tis());
  rws();
  new_window = new state_list_dc("Problem States", table, foot);
  return new_window;
}

dc_ref build_conflict_trace(int s, int t, int f) {
  LOGSECTION("build_conflict_trace");
  tsd *stack;
  dc_ref new_window;
  analyze_conflict(s, t, f, 0);
  stack = make_stored_trace(&new_conflict_stack[0],
			    new_conflict_stack_depth, conflict_token);
  new_window = new trace_window_dc("Conflict Trace", stack, s, t, f);
  delete_tsd(stack);
  return new_window;
}


dc_ref build_red_trace(int s, int t, int f) {
  dc_ref window;
  tsd *stack;
  stack = make_stored_trace(&new_reduction_stack[0],
			    new_reduction_stack_depth, 0);
  window = dc_ref(new trace_window_dc("Reduction Trace", stack, s, t, f));
  delete_tsd(stack);
  return window;
}

dc_ref conflict_red_trace(int s, int t, int f) {
  dc_ref new_window;

  analyze_conflict(s, t, f, 0);
  new_window = build_red_trace(s, t, f);
  return new_window;
}


dc_ref set_up_stack_window(AgString name) {
  tsd *stack;
  dc_ref window;

  stack = init_tsd(2);
  at(stack, 0, 0);

  window = dc_ref(new trace_window_dc(name, stack));
  delete_tsd(stack);
  return window;
}

tsd *build_et(FILE *f) {
  tsd *et = init_tsd(2);
  int s1, s2, tn;
  int ns;

  int flag = 0 != fscanf(f, "%d", &ns);
  flag &= 0 != fscanf(f, "%d", &s1);

  while (flag && ns--) {
    flag &= 0 != fscanf(f,"%d", &s2);
    if (!flag) {
      break;
    }

    const unsigned *goto_list;
    int n = find_gotos(s1, &goto_list);
    int found = 0;
    while (n) {
      //unsigned t = *goto_list++;
      goto_list++;
      unsigned s = *goto_list++;
      if (s == s2) {
        found = 1;
        break;
      }
      n--;
    }
    flag &= found;
    if (!flag) {
      break;
    }
    at(et, s1, map_state_number[s2].char_token);
    s1 = s2;
  }
  flag &= 0 != fscanf(f, "%d", &tn);
  if (!flag) {
    delete_tsd(et);
    return 0;
  }
  at(et, s1, tn);
  return et;
}

dc_ref build_et_window(void) {
  LOGSECTION("build_et_window");
  LOGV(etr_file_name.pointer());
  LOGV((int) &etr_file_name);

  if (!etr_file_name.exists()) {
    return NULL;
  }

  FILE *f = fopen(etr_file_name.pointer(), "r");
  tsd *et = build_et(f);
  fclose(f);
  if (et == 0) {
    return dc_ref();
  }

  dc_ref window;
  window = dc_ref(new trace_window_dc("Error Trace", et));
  window->foot_title = etr_file_name;
  delete_tsd(et);

  return window;
}