view anagram/guisupport/conflicttrc.cpp @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -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;
}