view anagram/guisupport/conflictdc.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-2002 Parsifal Software. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 *
 * conflictdc.cpp - Conflict Display module
 */

#include "cd.h"
#include "conflictdc.h"
#include "dc.h"
#include "conflicttrc.h"
#include "items.h"
#include "nckwtr.h"
#include "rule.h"
#include "stexpdc.h"
#include "stacks.h"
#include "token.h"
#include "ut.h"
#include "wm1.h"
#include "ws.h"

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


dc_ref build_rule_derivation(int sn, int fn) {
  LOGSECTION("build_rule_derivation");

  LOGV(sn) LCV(fn);
  dc_ref new_window;
  AgString foot = AgString::format("S%03d:R%03d",sn, fn);

  return new derivation_dc(new_rule_derivation, "Rule Derivation",
			   foot, 1);
}

int conflict_table_dc::derive_rule_ok(unsigned ln) {
  int sn, fn;
  int tn, n;
  return locate_conflict(ln, &sn, &tn, &fn, &n) != 0;
}

dc_ref conflict_table_dc::derive_rule(unsigned ln) {
  LOGSECTION("conflict_table_dc::derive_rule");
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  analyze_conflict(sn, tn, fn, 0);
  return build_rule_derivation(sn, fn);
}

dc_ref conflict_table_dc::derive_token(unsigned ln) {
  LOGSECTION("conflict_table_dc::derive_token");
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  analyze_conflict(sn, tn, fn, 0);
  return new_derive_token(sn, tn, fn);
}

int conflict_table_dc::expansion_chain_ok(unsigned ln) {
  int sn, fn;
  int tn, n;

  screen_rule(ln, &sn, &tn, &fn, &n);
  return n == 0;
}

dc_ref conflict_table_dc::expansion_chain(unsigned ln) {
  int sn, fn;
  int tn, n;

  if (screen_rule(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  return expansion_chain_window(sn, fn, n);
}

static int conflict_tabs[] = {7,13,0};

void conflict_table_dc::init(void) {
  LOGSECTION("conflict_table_dc::init");
  unsigned i,n;
  unsigned dw;
  unsigned ns = sort_con();

  tab_stops = conflict_tabs;

  n = conflict_table->nt;
  for (i = dw = 0; i < n; i++) {
    int sn, tn, fn, fx;
    unsigned length;

    xtxf(conflict_table,i, &sn, &tn, &fn, &fx);
    ics();
    atkn(tn);
    length = conflict_tabs[1] + rcs();
    if (length > dw) {
      dw = length;
    }
    ics();
    append_item(fn, fx);
    length = 2 + rcs();
    if (length > dw) {
      dw = length;
    }
  }

  n = conflict_table->nt + ns;
  des->d_size = cint(dw, n);
  LOGV(dw) LCV(n);
}

int conflict_table_dc::locate_conflict(unsigned ln, 
				       int *snp, int *tnp, int *fnp,
				       int *fxp) {
  LOGSECTION("conflict_table_dc::locate_conflict");
  int k;

  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if (ln == permutation[k] + k) {
    ln++;
  }
  while (ln < permutation[k+1] + k+1)  {
    int kk = ln - k - 1;
    xtxf(conflict_table, kk, snp, tnp, fnp, fxp);
    if (*tnp == 0) {
      return 0;
    }
    if (*fxp >= map_form_number[*fnp].length()) {
      break;
    }
    ln++;
  }
  return 1;
}

dc_ref conflict_table_dc::new_derive_token (int sn, int tn, int fn) {
  dc_ref window;
  LOGSECTION("new_derive_token");
  AgString foot = AgString::format("S%03d:R%03d:T%03d",sn, fn, tn);

  return dc_ref(new derivation_dc(token_derivation, "Token Derivation",
				  foot, 0));
}

void conflict_table_dc::synchCursor(unsigned ln) const {
  int k, sn, fn;
  int tn, n;

  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if ((int) ln == permutation[k] + k) {
    return;
  }
  k = ln - k - 1;
  xtx(conflict_table, k, &sn, &tn, &fn, &n);
  set_rule_line(fn);
}

dc_ref conflict_table_dc::problem_states(unsigned ln) {
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  return problem_states_window(sn, fn, map_form_number[fn].length(), tn);
}

int conflict_table_dc::reduction_states_ok(unsigned ln) {
  LOGSECTION("conflict_table_dc::reduction_states_ok");
  LOGV(ln);
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return 0;
  }
  return reduction_states_window_ok(fn, map_form_number[fn].length());
}

dc_ref conflict_table_dc::reduction_states(unsigned ln) {
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  return reduction_states_window(sn, fn, map_form_number[fn].length());
}

dc_ref conflict_table_dc::rule_context(unsigned ln) {
  int k;
  int sn, tn, fn, fx;


  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if (ln == permutation[k] + k) {
    ln++;
  }
  xtx(conflict_table, ln - k - 1, &sn, &tn, &fn, &fx);
  return rule_context_window(fn);
}

int conflict_table_dc::screen_rule(unsigned ln, 
				   int *snp, int *tnp, int *fnp,
				   int *fxp) {
  int k;
  int kk;

  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if (ln == permutation[k] + k) {
    return 0;
  }
  kk = ln - k - 1;
  xtx(conflict_table, kk, snp, tnp, fnp, fxp);
  return *tnp != 0;
}

dc_ref conflict_table_dc::select_conflict(unsigned ln) {
  int sn, tn, fn, n;
  int k;

  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if (ln == permutation[k] + k) {
    ln++;
  }
  while (ln < permutation[k+1] + k+1)  {
    int kk = ln - k - 1;
    xtx(conflict_table, kk, &sn, &tn, &fn, &n);
    if (tn == 0) {
      return NULL;
    }
    if (n >= map_form_number[fn].length()) {
      break;
    }
    ln++;
  }
  return build_conflict_trace(sn, tn, fn);
}

dc_ref conflict_table_dc::state_definition(unsigned ln) {
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  return conflict_state_window(sn);
}

dc_ref conflict_table_dc::state_expansion(unsigned ln) {
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  return state_expansion_window(sn);
}

dc_ref conflict_table_dc::usage(unsigned ln) {
  int sn, fn;
  int tn, n;

  if (locate_conflict(ln, &sn, &tn, &fn, &n) == 0) {
    return NULL;
  }
  return token_usage_window(tn);
}

unsigned conflict_table_dc::sort_con() {
  int psn, ptn;
  unsigned k;
  unsigned ns;

  ptn = psn = -1;
  ns = 0;
  for (k = 0; k < conflict_table->nt; k++) {
    int sn, tn, fn, n;

    xtxf(conflict_table, k, &sn, &tn, &fn, &n);
    if (sn == psn && tn == ptn) {
      continue;
    }

    ns++;
    psn = sn;
    ptn = tn;
  }
  permutation = AgArray<int>(ns+1);

  psn = ptn = -1;
  ns = 0;
  for (k = 0; k < conflict_table->nt; k++) {
    int sn, tn, fn, n;
    xtxf(conflict_table, k, &sn, &tn, &fn, &n);
    if (sn == psn && tn == ptn) {
      continue;
    }
    permutation[ns++] = k;
    psn = sn;
    ptn = tn;
  }
  permutation[ns] = k;
  return ns;
}

dc_ref conflict_table_dc::reduction_trace(unsigned ln) {
  int sn, tn, fn, n;
  int k;

  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if (ln == permutation[k] + k) {
    ln++;
  }
  while (ln < permutation[k+1] + k+1)  {
    int kk = ln - k - 1;
    xtx(conflict_table, kk, &sn, &tn, &fn, &n);
    if (n >= map_form_number[fn].length()) {
      break;
    }
    if (tn == 0) {
      return NULL;
    }
    ln++;
  }
  return conflict_red_trace(sn, tn, fn);
}

derivation_dc::derivation_dc(tsd *td, const AgString head, const AgString foot,
			     int brkt)
  : dc(head, foot)
{
  LOGSECTION("derivation_dc::derivation_dc");
  derivation = copy_tuple_set(td);
  bracket = brkt;
  des->c_loc_doc.y = td->nt - 1;
  des->d_size.y = derivation->nt;
}

derivation_dc::~derivation_dc(void) {
  delete_tsd(derivation);
}

void derivation_dc::getLine(unsigned tln) const {
  int brkt;
  int fn, fx;
  int ln = derivation->nt - tln - 1;

  LOGSECTION("derivation_dc::getLine");
  LOGV(tln) LCV(ln) LCV(bracket);

  //???if (ln < derivation->nt-1) xtxf(derivation, ln+1, &fn, &fx);
  xtxf(derivation, ln, &fn, &fx);
  if (ln == 0 && bracket) {
    brkt = -1;
  }
  else {
    brkt = fx - bracket;
  }
/*
  LOGV(fn) LCV(fx) LCV(brkt);
  //int token = lstptr(map_form_number[fn],tokens)[brkt];
  Token token = Rule(fn).token(brkt > 0 ? brkt : 0);
  LOGV(token);
  LOGV(brkt);
  if (bracket && ln && token->zero_length_flag) {
    int derivedRule;
    int derivedRuleIndex;
    xtxf(derivation, ln-1, &derivedRule, &derivedRuleIndex);
    while (brkt >= 0 && token->zero_length_flag && !token.isExpansionRule(derivedRule)) {
      //token = lstptr(map_form_number[fn],tokens)[--brkt];
      token = Rule(fn).token(--brkt);
      LOGV(token);
      LOGV(brkt);
    }
  }
 */
  ics();
  append_item_brkt(fn, brkt);
}

void derivation_dc::synchCursor(unsigned ln) const {
  int fn, fx;

  ln = derivation->nt - 1 - ln;
  xtx(derivation, ln, &fn, &fx);
  set_rule_line(fn);
}

unsigned derivation_dc::token(unsigned tln) {
  int fn, fx;
  int brkt;
  unsigned ln;

  ln = derivation->nt - tln - 1;
  if (ln == 0 && bracket) {
    return 0;
  }
  xtx(derivation, ln, &fn, &fx);
  brkt = fx - bracket;
  if (brkt < 0) {
    return 0;
  }
  //return lstptr(map_form_number[fn], tokens)[brkt];
  return Rule(fn).token(brkt);
}

int derivation_dc::expansion_rules_ok(unsigned ln) {
//  int fn, fx;

  ln = derivation->nt - 1 - ln;
  if (ln == 0 && bracket) {
    return 0;
  }
  return 1;
}

dc_ref derivation_dc::expansion_rules(unsigned ln) {
  int fn, fx;

  ln = derivation->nt - 1 - ln;
  if (ln == 0 && bracket) {
    return NULL;
  }
  xtx(derivation, ln, &fn, &fx);
  return expand_specific_item(this, fn, fx-bracket);
}

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

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

dc_ref derivation_dc::rule_context(unsigned ln) {
  int fn, fx;

  ln = derivation->nt - 1 - ln;
  xtx(derivation, ln, &fn, &fx);
  return rule_context_window(fn);
}

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

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

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

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

void res_con_dc::getLine(unsigned ln) const {
  LOGSECTION("res_con_dc::getLine");
  int sn, tn, fn;
  unsigned x, k, n;
  int a, f;
  int cs;

  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if (ln == permutation[k] + k) {
    x = (ln - k);
    xtxf(res_con, x, &sn, &tn, &fn, &n);
    //ssprintf("S%03d: T%03d ", sn, tn);
    LOGV(sn) LCV(tn);
    ssprintf("S%03d:\tT%03d   ", sn, tn);
    atkn(tn);
    LOGV(string_base);
    return;
  }
  k = ln - k - 1;
  xtxf(res_con, k, &sn, &tn, &fn, &n);
  for (k = prr->nt; k--; ) {
    int s, t;
    xtxf(prr, k, &s, &a, &t, &f);
    if (s != sn || t != tn) {
      continue;
    }
    break;
  }
  k = map_form_number[fn].length();
  if ((a && f == fn && n == k) || (a == 0 && n < k)) {
    cs = '*';
  }
  else {
    cs = ' ';
  }
  ssprintf("%c\t", cs);
  append_item(fn, n);
}

void unres_con_dc::getLine(unsigned ln) const {
  LOGSECTION("unres_con_dc::getLine");
  LOGV(ln);
  unsigned sn, tn, fn, n;
  unsigned k, x;

  for (k = 1; ln >= permutation[k] + k; k++);
  k--;
  if (ln == permutation[k] + k) {
    x = (ln - k);
    xtxf(unres_con, x, &sn, &tn, &fn, &n);
    ssprintf("S%03d:\tT%03d   ", sn, tn);
    atkn(tn);
    return;
  }
  k = ln - k - 1;
  xtxf(unres_con, k, &sn, &tn, &fn, &n);
  scs('\t');
  append_item(fn, n);
}