view anagram/guisupport/stexpdc.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-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));
}