view anagram/guisupport/stexpdc.cpp @ 18:562c313f14f4

some minor updates for 2022
author David A. Holland
date Tue, 31 May 2022 02:03:50 -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.
 *
 * stexpdc.cpp
 */

#include "dc.h"
#include "dict.h"
#include "items.h"
#include "q1glbl.h"
#include "q5.h"
#include "rule.h"
#include "stexpdc.h"
#include "stacks.h"
#include "token.h"
#include "ut.h"
#include "wm1.h"
#include "ws.h"


static int chain_element(int t, int f) {
  //unsigned *fp;
  int n;
  Token token = t;
  //if (x4(t,f) == 0) return 0;
  if (!token.isExpansionRule(f)) return 0;
  //fp = lstptr(map_token_number[t], forms);
  //n = map_token_number[t].n_forms;
  //n = token->n_forms;
  n = token->ruleList.size();
  //while (n--) {
  for (int i = 0; i < n; i++) {
    //Rule fn = *fp++;
    Rule fn = token.rule(i);
    int tn;
    if ((int) fn == f) return 1;
    if (fn->length() == 0) continue;
    if (xws(fn)) continue;
    //tn = lstptr(map_form_number[fn], tokens)[0];
    tn = Rule(fn).token(0);
    if (chain_element(tn, f)) {
      return 1;
    }
    fws();
  }
  return 0;
}

static tsd *expand_chain(int sn, int f) {
  int *list = dict_str(isht_dict, sn);
  int n = (*list++ - 1)/2;
  int fn, fx, k = n;
  tsd *sx = init_tsd(2);
  iws();
  while (k--) {
    int tn;

    fn = *list++;
    fx = *list++;

    if (fx >= map_form_number[fn].length()) {
      continue;
    }
    //tn = lstptr(map_form_number[fn], tokens)[fx];
    tn = Rule(fn).token(fx);
    if (chain_element(tn, f) == 0) {
      continue;
    }
    at(sx, fn, fx);
    xws(f);
    k = tis();
    list = list_base;
    while (k--) {
      at(sx, *list++, 0);
    }
    rws();
    break;
  }
  return sx;
}

dc_ref expansion_chain_window(int sn, int fn, int fx) {
  dc_ref window;

  if (fx || fn == 0) {
    return dc_ref();
  }

  const AgString foot = AgString::format("S%03d:R%03d", sn, fn);
  //window = find_on_screen("Expansion Chain", foot);
  //if (window) return window;
  return dc_ref(new expansion_chain_dc(sn, fn, foot));
}

expansion_chain_dc::expansion_chain_dc(unsigned sn, unsigned rn, AgString foot)
: state_expansion_dc(sn, "Expansion Chain", foot)
{
  state_number = sn;
  rule_number = rn;
  delete_tsd(expansion);
  expansion = expand_chain(sn, rn);
  //des->c_size = cursor_bar_size;
  des->d_size.y = expansion->nt;

  //getWidth();
  //resize_window();
}

dc_ref state_expansion_window(int sn) {
  //dc_ref window;

  //if (sn == 0) return dc_ref();
  const AgString foot = AgString::format("S%03d", sn);
  //window = find_on_screen("State Expansion", foot);
  //if (window.exists()) return window;
  return dc_ref(new state_expansion_dc(sn, "State Expansion", foot));
}

dc_ref state_expansion_dc::aux_trace(unsigned) {
  return aux_trace_window(state_number);
}

int state_expansion_dc::expansion_chain_ok(unsigned ln) {
  int fn, fx;
  xtx(expansion, ln, &fn, &fx);
  return fn && fx == 0;
}

dc_ref state_expansion_dc::expansion_chain(unsigned ln) {
  int fn, fx;
  xtx(expansion, ln, &fn, &fx);
  return expansion_chain_window(state_number, fn, fx);
}

int state_expansion_dc::expansion_rules_ok(unsigned ln) {
  return build_item_list_ok(token(ln));
}

dc_ref state_expansion_dc::expansion_rules(unsigned ln) {
  return build_item_list(token(ln));
}

void state_expansion_dc::getLine(unsigned ln) const {
  int rn, rx;
  xtx(expansion, ln, &rn, &rx);
  ics();
  append_item(rn, rx);
}

void state_expansion_dc::synchCursor(unsigned ln) const {
  int rn, rx;
  xtx(expansion, ln, &rn, &rx);
  if (rn) {
    set_rule_line(rn);
  }
}

int state_expansion_dc::previous_states_ok(unsigned) {
  return previous_states_window_ok(state_number);
}

dc_ref state_expansion_dc::previous_states(unsigned) {
  return previous_states_window(state_number);
}

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

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

int state_expansion_dc::reduction_states_ok(unsigned ln) {
  int fn, fx;
  xtx(expansion, ln, &fn, &fx);
  return reduction_states_window_ok(fn, fx);
}

dc_ref state_expansion_dc::reduction_states(unsigned ln) {
  int fn, fx;
  xtx(expansion, ln, &fn, &fx);
  return reduction_states_window(state_number, fn, fx);
}

dc_ref state_expansion_dc::rule_context(unsigned ln) {
  int rn, rx;
  xtx(expansion, ln, &rn, &rx);
  return rule_context_window(rn);
}

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

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

state_expansion_dc::state_expansion_dc(unsigned sn,
				       const AgString head,
				       const AgString foot)
  : dc(head, foot)
  , expansion(expand_state(sn))
{
  state_number = sn;
  //des->c_size = cursor_bar_size;
  des->d_size.y = expansion->nt;

  //getWidth();
  //resize_window();
}

state_expansion_dc::~state_expansion_dc(void) {
  //if (!clone() && (expansion != NULL)) delete_tsd(expansion);
  if (expansion != NULL) {
    delete_tsd(expansion);
  }
}

unsigned state_expansion_dc::token(unsigned ln) {
  int fn, fx;
  xtx(expansion, ln, &fn, &fx);
  if (fx >= map_form_number[fn].length()) {
    return 0;
  }
  //return lstptr(map_form_number[fn], tokens)[fx];
  return Rule(fn).token(fx);
}

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

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