view anagram/agcore/rpz.cpp @ 4:bebb2ba69e1d

maybe help with getting tex to fail properly on error
author David A. Holland
date Sat, 18 Apr 2020 17:12:17 -0400
parents 13d2b8934445
children 607e3be6bad8
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.
 *
 * rpz.cpp
 */

#include "arrays.h"
#include "assert.h"
#include "bpe3.h"
#include "config.h"
#include "csexp.h"
#include "dict.h"
#include "error.h"
#include "keyword.h"
#include "myalloc.h"
#include "pgg24-defs.h"
#include "pgg24.h"
#include "q1glbl.h"
#include "rpk.h"
#include "rpz.h"
#include "rproc.h"
#include "rule.h"
#include "symbol.h"
#include "stacks.h"
#include "token.h"
#include "tree.h"
#include "tsd.h"
#include "ut.h"

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


#define PCB pgcb


void definition_1(CharSetExpression *x) {
  LOGSECTION("definition_1");
  int k;
  Symbol id = Symbol::create();
  LOGV(id);
  if (x->recursive(id)) {
    LOGS("Recursive definition");
    warning_here("Recursive definition of character set %s",
		 id->string.pointer());
    delete x;
    return;
  }
  if (id->parse_tree.isNotNull()) {
    warning_here("Redefinition of %s", id->string.pointer());
    delete x;
    return;
  }
  if ((k = id->token_number) != 0) {
    if (Token(k)->non_terminal_flag) {
      warning_here("Redefinition of token T%03d: %s", k, id->string.pointer());
      delete x;
      return;
    }
  }
  LOGS("Ready to identify parse tree");
  ParseTree tree(x);
  LOGV((int) tree) LCV((int) tree->expression);
  id->parse_tree = tree;
  tree->token_name = id;
}


void definition_3(int cn) {
  LOGSECTION("definition_3");
  definition_1(new IndividualCode(cn));
}

void definition_2(int tn) {
  LOGSECTION("definition_2");
  LOGV(tn);
  int t;
  token_number_map *mtn;
  unsigned name;

  Symbol id = Symbol::create();
  LOGV(id);
  if (id->parse_tree.isNotNull()) {
    warning_here("Redefinition of %s", id->string.pointer());
    return;
  }
  if ((t = id->token_number) != 0) {
    mtn = &map_token_number[t];
    if (mtn->non_terminal_flag || mtn->key) {
      warning_here("Redefinition of token T%03d: %s",t, id->string.pointer());
      return;
    }
    shell_production(t,tn);
    return;
  }
  name = map_token_number[tn].token_name;
  if (name == (unsigned) id) {
    return;
  }
  if (name) {
    LOGS("call shell_production") LV(t) LCV(tn);
    shell_production(t,tn);
    return;
  }
  map_token_number[tn].token_name = id;
  id->token_number = tn;
  LOGV(tn) LCV(id);
}

int form_spec_2(int fn, int pn)   {
  LOGSECTION("form_spec_2");
  LOGV(fn) LCV(pn);
  Procedure reductionProc(pn);
  Rule rule(fn);

  rule->proc_name = pn;
  LOGV(rule) LCV(rule->proc_name);
  reductionProc->form_number = rule;
  return fn;
}

int head_list_2(int flag) {
  LOGSECTION("head_list_2");
  unsigned tn;
  token_name();
  tn = fis();
  LOGV(tn) LCV(ntkns);
  assert(tn <= ntkns);
  if (flag) {
    if (grammar_token) {
      log_error("Redefinition of grammar token");
    }
    grammar_token = tn;
  }
  return tn;
}

int mid_line(int pn) {
  LOGSECTION("mid_line");
  Rule rule = form1();
  Procedure proc(pn);
  LOGV(rule);
  LOGV(ruleElementStack.size());
  int bias = ruleElementStack.top().size();
  LOGV(bias);
  rule->immediate_proc = 1;
  rule->proc_name = pn;
  proc->form_number = rule;
  LOGV(rule) LCV(rule->proc_name);
  rule->hostElementList = AgArray<RuleElement>(ruleElementStack.top());
  rule->op_bias = bias;
  return rule;
}

int proc_spec_4(int flag) {
  LOGSECTION("proc_spec_4");

  CSegment cSegment = cSegmentStack.pop();
  Procedure proc(cSegment);
  LOGV(proc);
  proc->value_flag = flag;
  proc->line = PRULE_CONTEXT(PCB)->y;
  proc->col = PRULE_CONTEXT(PCB)->x;
  return proc;
}

static int proc_spec_6(int, int fn) {
  LOGSECTION("proc_spec_6");

  CSegment segment;
  segment.end = segment.begin;
  Procedure proc(segment);
  proc->value_flag = 1;
  proc->form_number = fn;
  return proc;
}


int semantic_productions = 0;


void production(int type) {
  LOGSECTION("production");
  unsigned *fl, *tl, nf, nt,i,j, zl;

  zl = 0;
  fl = (unsigned *) build_list();
  nf = fis();
  tl = (unsigned *) build_list();
  ok_ptr(tl);
  LOGV((int) tl);
  nt = fis();
  LOGV(nt) LCV(nf);
  if (nt > 1) {
    semantic_productions = 1;
  }
  for (j = 0; j < nf; j++) {
    ok_ptr(tl);
    LOGV(fl[j]);
    Rule rule(fl[j]);
    //int pn = rule->proc_name;
    //const unsigned *rp = rule->tokens();
    int rl = rule->length(), i = rl;

    ok_ptr(tl);
    LOGV(fl[j]);
    iws();
    int tokenIndex = 0;
    //while (i--) aws(*rp++);
    while (i--) {
      aws(rule.token(tokenIndex++));
    }
    i = nt;
    rl++;
    while (i--) {
      aws(tl[i]);
      if (list_in_dict(list_base, rl, prod_dict)) {
        log_error("Duplicate production");
      }
      fws();
    }
    rws();
    //check_size(map_proc_name,pn, pn + pn/2);
    rule->prim_tkn = tl[0];
    rule->fast_loop = nt == 1 &&
                     rule->length() == 2 &&
                     tl[0] == (unsigned) rule.token(0);
                     //tl[0] == lstptr(*mfn,tokens)[0];
    if (rule->length() == 0) zl = 1;
    if (rule-> length() == 1) {
      int i = nt;
      unsigned t = rule.token(0);
      while (i--) {
        if (t != tl[i]) {
	  continue;
	}
        warning_here("Suspicious production for %s",
		     Token(t)->token_name->string.pointer());
      }
    }
    if (nt > 1) {
      rule->not_unique_reduction = 1;
      if (rule->proc_name == 0) {
	rule->proc_name = proc_spec_6(rule->line, fl[j]);
      }
    }
  }
  for (i = 0; i < nt; i++) {
    token_number_map *tp = &map_token_number[tl[i]];
    int vt = tp->value_type;
    ok_ptr(tl);
    LOGV((int) tl);
    LOGV(tl[i]) LCV(vt);
    if (nf) {
      tp->non_terminal_flag = 1;
    }
    tp->zero_length_flag = zl;
    tp->sem_det_flag = nt > 1;
    if (type && vt && vt != type) {
      ssprintf("Type Redefinition of T%03d: ", tl[i]);
      atkn(tl[i]);
      log_error();
    }
    if (type) {
      tp->value_type = type;
    }
    ok_ptr(tl);
    LOGV(type);
    for (j = 0; j < nf; j++) {
      at(bnf_table, tl[i], fl[j]);
    }
  }
  LOGS("Ready to free tl");
  ok_ptr(tl);
  LOGV((int) tl);
  DEALLOCATE(tl);
  LOGS("Ready to free fl");
  if (fl != NULL) {
    DEALLOCATE(fl);
  }
  LOGS("Production analysis complete");
}

CharSetExpression *ss2(void) {
  LOGSECTION("ss2");
  Symbol name = Symbol::create();

  LOGV(name->token_number) LCV(name->string);
  if (name->string == "error") {
    Token token = name->token_number;
    LOGV(token);
    if (error_token || token.isNotNull() || name->parse_tree.isNotNull()) {
      return new NamedCharSet(name);
    }
    token = Token::create();
    token->token_name = name;
    name->token_number = token;
    token->value_type = default_input_type;
    error_token = token;
    LOGV(error_token);
    checkParams();
  }
  return new NamedCharSet(name);
}

void token_name(void) {
  LOGSECTION("token_name");

  unsigned symbolCount = Symbol::count();
  Symbol n = Symbol::create();
  int flag = Symbol::count() > symbolCount;  //true if new symbol

  LOGV(n) LCV(ntkns);
  Token tn = n->token_number;
  LOGV(tn) LCV(ntkns);
  if (tn.isNotNull()) {
    sis(tn);
    return;
  }
  tn = n->token_number = Token::create();
  tn->token_name = n;
  tn->value_type = 0;
  if (!flag && n->parse_tree.isNotNull()) {
    n->parse_tree = ParseTree();
    warning_here("Redefinition of %s", n->string.pointer());
  }
  sis(tn);                 /* push token on stack */
  return;
}

//int idsx(string_dict *);

/* -> keyword string                                        =vp_s(); */

int vp_s(void) {
  LOGSECTION("vp_s");
  int n;
  int i;

  n = tis();
  if (n > max_key_length) max_key_length = n;
  tss();
  LOGV(string_base);
  if (!case_sensitive) {
    for (i = n; i--; ) {
      string_base[i] = agToUpper(string_base[i]);
    }
  }
  if (n == 0) {
    log_error("Empty keyword string");
  }
  Keyword keyword(string_base);
  LOGV(keyword->string);
  rcs();
  LOGV((int) keyword->token_number);
  if (keyword->token_number.isNull()) {
    Token token = keyword->token_number = Token::create();
    LOGV((int) token);
    token->key = keyword;
    token->value_type = void_token_type;
    token->operatorCandidate = 1;
  }
  return keyword->token_number;
/*
  if (!idsx(key_dict)) {
    key = fis();
    assert(key == (int) keyword);
    LOGV(key) LCV(keyword);
    check_size(map_key_word, key, key + key/2);
    LOGV(key) LCV(map_key_word[key].token_number) LCV(ntkns);
    return map_key_word[key].token_number;
  }
  if (n > max_key_length) {
    max_key_length = n;
  }
  key = fis();
  LOGV(key) LCV(keyword);
  assert(key == (int) keyword);
  check_size(map_key_word, key,key + key/2 );
  map_key_word[key].token_number = Token::create();
  map_token_number[ntkns].key = key;
  LOGV(key) LCV(map_key_word[key].token_number) LCV(ntkns);
  return ntkns;
*/
}

/* -> left bracket, proper vp rule specs, right bracket     =vp_3(); */

int vp_3(void) {
  LOGSECTION("vp_3");
  int tn;
  int flag,vptn;

  aws(3);
  flag = idl(vp_prod_dict);
  vptn = fis();
  check_size(map_vp_prod_number,vptn,vptn + vptn/2);
  if (flag == 0) {
    tn = map_vp_prod_number[vptn].token_number;
    LOGV(tn) LCV(ntkns);
    return tn;
  }
  sws(form1());
  fdl(vp_prod_dict,vptn);
  fws();
  vp_forms();
  concat_list();
  map_vp_prod_number[vptn].token_number = Token::create();
  gen_vp_prods(ntkns,1,vptn);
  LOGV(ntkns);
  return ntkns;
}

/*
 -> keyword string, '?', blank?...             =vp_5(vp_s());
 -> union:n, '?', blank?...                    =vp_5(form_element_1(n));
*/

int vp_5(int tn) {
  LOGSECTION("vp_5");
  int flag, vptn;

  sws(tn); aws(5);
  flag = idl(vp_prod_dict);
  vptn = fis();
  check_size(map_vp_prod_number,vptn,vptn + vptn/2);
  if (flag == 0) {
    tn = map_vp_prod_number[vptn].token_number;
    return tn;
  }
  map_vp_prod_number[vptn].token_number = Token::create();
  sws(form1());
  aws(makeRule(tn));
  gen_vp_prods(ntkns,0,vptn);
  return ntkns;
}

int vp_8a(int fn) {
  LOGSECTION("vp_8a");
  token_number_map *tp;

  Token::create();
  tp = &map_token_number[ntkns];
  tp->non_terminal_flag = 1;
  map_form_number[fn].prim_tkn = ntkns;
  tp->zero_length_flag = 1;
  tp->fine_structure = 1;
  tp->immediate_action = 1;
  at(bnf_table, ntkns, fn);
  LOGV(ntkns) LCV(tp->immediate_action);
  return ntkns;
}

//static void build_choice(int tn)   {
static void build_choice(Token token)   {
  LOGSECTION("build_choice");
  int *fl, nf, j;
  int i, zl;
  //token_number_map *tp;


  zl = 0;
  vp_forms();
  fl = list_base;
  nf = rws();
  //tp = &map_token_number[tn];
  //if (nf) tp->non_terminal_flag = 1;
  if (nf) {
    token->non_terminal_flag = 1;
  }
  for (i = 0; i < nf; i++) {
    Rule rule(fl[i]);
    //rule->prim_tkn = tn;
    rule->prim_tkn = token;
    if (rule->length() == 0) {
      zl = 1;
    }
  }
  //tp->zero_length_flag = zl;
  token->zero_length_flag = zl;
  for (j = 0; j < nf; j++) {
    //at(bnf_table,tn,fl[j]);
    at(bnf_table,(int) token,fl[j]);
  }
}

//static void alter_prod(int tb, int nt, int tn, int vf) {
static void alter_prod(Token tb, int nt, Token token, VpRule vpRule) {
  LOGSECTION("alter_prod");

  LOGV(vpRule) LCV(token) LCV(tb) LCV(nt) LCV(Token::count());

  int i,j;
  iws();
  for (i = tb, j = nt; j--; i++) {
    //if (i == tn) {
    if (i == (int) token) {
      //aws(vf);
      aws(vpRule);
      continue;
    }
    AgStack<RuleElement> elementStack;
    elementStack.push(RuleElement(i,0));
    //VpRule vpRule(vf);
    for (unsigned k = 0; k < vpRule->elementList.size(); k++) {
      elementStack.push(vpRule->elementList[k]);
    }
    VpRule newRule(elementStack, vpRule->procedureName);
    aws(newRule);
  }
  build_choice(token);
}

static void alternate(void) {
  LOGSECTION("alternate");
  //int tb = ntkns+1;
  Token tb = Token::create();
  int *vfl = build_list();
  int nt = fis();
  //int tn  = tb, k;
  Token tn;
  int k;

  for (k = 1; k < nt; k++) tn = Token::create();
  iws();
  for (k = 0; k < nt; k++)  {
    tn = tb + k;
    alter_prod(tb,nt,tn,vfl[k]);
    ruleElementStack.push(AgStack<RuleElement>()).top()
      .push(RuleElement(tn,0));
    aws(vp_form3(0));
  }
  DEALLOCATE(vfl);
}

int vp_9(void){
  LOGSECTION("vp_9");
  alternate();
  return vp_1();
}

int vp_10(void){
  LOGSECTION("vp_10");
  alternate();
  return vp_3();
}