view anagram/agcore/rpk.cpp @ 14:a02e9434072e

Fix friend declaration for gcc10. XXX: did not check it against the IBM compiler, might end up needing XXX: to be conditional.
author David A. Holland
date Tue, 31 May 2022 00:59:42 -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.
 *
 * rpk.cpp
 */

#include <stdarg.h>
#include "port.h"

#include "arrays.h"
#include "config.h"
#include "csexp.h"
#include "error.h"
#include "p.h"
#include "pgg24-defs.h"
#include "pgg24.h"
#include "q1glbl.h"
#include "rpk.h"
#include "rproc.h"
#include "rpz.h"
#include "rule.h"
#include "stacks.h"
#include "symbol.h"
#include "token.h"
#include "tree.h"
#include "tsd.h"

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


#define PCB pgcb


AgStack< AgStack<RuleElement> > ruleElementStack;

int makeRule(const AgIndexedContainer<RuleElement> &elementList) {
  LOGSECTION("makeRule(elementList)");
  LOGV(elementList.size());
  int j, n;

  Rule rule = Rule::create();
  rule->line = PRULE_CONTEXT(PCB)->y;
  rule->col = PRULE_CONTEXT(PCB)->x;
  rule->elementList = AgArray<RuleElement>(elementList);
  LOGV(rule) LCV(elementList.size());
  n = elementList.size();
  for (j = 0; j < n; j++) {
    RuleElement element = elementList[j];
#ifdef INCLUDE_LOGGING
    int cVariable = element.cVariable;
    LOGV(cVariable) LCV(cVariableList[cVariable]);
#endif
    if (element.cVariable) {
      valueToken.insert(element.token);
    }
  }
  LOGV(n) LCV(j);
  return rule;
}

int makeRule(void) {
  LOGSECTION("makeRule");
  Rule rule = Rule::create();
  rule->line = PRULE_CONTEXT(PCB)->y;
  rule->col = PRULE_CONTEXT(PCB)->x;
  return rule;
}

int makeRule(Token token) {
  LOGSECTION("makeRule(token)");
  LOGV(token);
  Rule rule = Rule::create();
  rule->elementList = AgArray<RuleElement>(1);
  rule->line = PRULE_CONTEXT(PCB)->y;
  rule->col = PRULE_CONTEXT(PCB)->x;
  rule->elementList[0] = RuleElement(token, 0);
  LOGV(rule) LCV(rule->elementList.size());
  return rule;
}

int makeRule(Token token1, Token token2) {
  LOGSECTION("makeRule(token1, token2)");
  LOGV(token1) LCV(token2);

  Rule rule = Rule::create();
  rule->elementList = AgArray<RuleElement>(2);
  rule->line = PRULE_CONTEXT(PCB)->y;
  rule->col = PRULE_CONTEXT(PCB)->x;
  rule->elementList[0] = RuleElement(token1, 0);
  rule->elementList[1] = RuleElement(token2, 0);
  LOGV(rule) LCV(rule->elementList.size());
  return rule;
}

int id_token(int name) {
  LOGSECTION("id_token");
  LOGV(name) LCV(map_token_name[name].token_number);
  Symbol symbol(name);
  Token token = symbol->token_number;
  LOGV(symbol) LCV(token);
  if (token.isNull()){
    token = Token::create();
    token->token_name = symbol;
    symbol->token_number = token;
  }
  return token;
}

int form_element_1(CharSetExpression *x) {
  LOGSECTION("form_element_1");
  LOGV((int) x);

  if (x->nameNode()) {
    int name = ((NamedCharSet *)x)->name;
    delete x;
    //LOGV(netAllocations());
    int returnValue = id_token(name);
    LOGV(returnValue) LCV(ntkns);
    return returnValue;
  }
  ParseTree tree(x);
  Token token = tree->token_number;
  if (token.isNotNull()) return token;

  token = Token::create();
  LOGV(token) LCV(kits);
  token->parse_tree = tree;
  token->operatorCandidate = 1;

  tree->token_number = token;
  LOGV((int) tree->expression);
  token->value_type = default_input_type;
  return token;
}

void shell_production(int t, int tn) {
  LOGSECTION("shell_production");
  Token token(t);

  Rule rule = makeRule(tn);
  rule->prim_tkn = t;
  rule->fast_loop = 1;
  at(bnf_table,t,(int) rule);
  token->non_terminal_flag = 1;
  token->value_type = Token(t)->value_type;
}

void defineImmediateProc(Procedure p) {
  LOGSECTION("defineImmediateProc");
  token_name();
  Token token(fis());
  Rule rule = makeRule();
  rule->proc_name = p;
  LOGV(rule) LCV(rule->proc_name);
  p->form_number = rule;
  token->non_terminal_flag = 1;
  token->zero_length_flag = 1;
  rule->prim_tkn = token;
  at(bnf_table, (int) token, (int) rule);
}

void gen_vp_prods(int tn, int zl, int vptn) {
  LOGV("get_vp_prods");
  int nf = tis();
  int j;
  token_number_map *tp = &map_token_number[tn];

  tp->vp_prod_number = vptn;
  tp->value_type = default_token_type;
  if (nf) {
    tp->non_terminal_flag = 1;
  }
  tp->fine_structure = 1;
  tp->zero_length_flag = zl;
  for (j = 0; j < nf; j++) {
    map_form_number[list_base[j]].prim_tkn = tn;
    at(bnf_table,tn,list_base[j]);
  }
  rws();
}

/*
 form1 creates an empty grammar rule. Attach it to a token in the bnf and
 you have a null production.
*/

int form1(void) {
  LOGSECTION("form1");
  Rule rule = Rule::create();
  LOGV(rule) LCV(kits);
  rule->line = PRULE_CONTEXT(PCB)->y;
  rule->col = PRULE_CONTEXT(PCB)->x;
  return rule;
}


void vp_forms(void) {
  LOGSECTION("vp_forms");
  int *lb, nl, k;

  nl = tis();
  list_space(2*nl);
  lb = list_base;
  for (k = 0; k < nl; k++) {
    VpRule vpRule = lb[k];
    LOGV(vpRule) LCV(vpRule->procedureName);
    Rule rule = makeRule(vpRule->elementList);
    Procedure proc(vpRule->procedureName);
    proc->form_number = rule;
    rule->proc_name = vpRule->procedureName;
    LOGV(rule) LCV(rule->proc_name);
    lb[k] = rule;
  }
}

/* -> left brace, vp rules, right brace                     =vp_1(); */

int vp_1(void)   {
  LOGSECTION("vp_1");
  int nf, j;
  int i, zl;
  int tn;
  int flag, vptn;
  token_number_map *tp;

  aws(1);
  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;
  }

  zl = 0;
  fdl(vp_prod_dict,vptn);
  fws();          /* get rid of type word that was appended above */
  Token::create();
  vp_forms();
  nf = tis();
  map_vp_prod_number[vptn].token_number = ntkns;
  tp = &map_token_number[ntkns];
  tp->vp_prod_number = vptn;
  tp->value_type = default_token_type;
  if (nf) tp->non_terminal_flag = 1;
  tp->fine_structure = 1;
  for (i = 0; i < nf; i++) {
    Rule rule(list_base[i]);
    rule->prim_tkn = ntkns;
    if (rule->length() == 0) {
      zl = 1;
    }
  }
  tp->zero_length_flag = zl;
  for (j = 0; j < nf; j++) {
    at(bnf_table, ntkns, list_base[j]);
  }
  rws();
  LOGV(ntkns);
  return ntkns;
}

/* -> left brace, vp rules, "}...", blank?...               =vp_2(); */

int vp_2(void) {
  LOGSECTION("vp_2");
  int nf, j, rt;
  int i, zl = 0;
  int tn;
  int flag, vptn;

  aws(2);
  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;
  }
  fdl(vp_prod_dict,vptn);
  fws();
  rt = vp_1();
  Token token = Token::create();
  map_vp_prod_number[vptn].token_number = token;
  token->vp_prod_number = vptn;
  token->value_type = default_token_type;

  sws(makeRule(rt));
  aws(makeRule(ntkns, rt));

  nf = tis();
  if (nf) {
    token->non_terminal_flag = 1;
  }
  token->fine_structure = 1;
  for (i = 0; i < nf; i++) {
    Rule rule(list_base[i]);
    rule->prim_tkn = ntkns;
    if (rule->length() == 0) {
      zl = 1;
    }
    rule->fast_loop = 1;
  }
  //fp->fast_loop = 1;                   //must be an error
  token->zero_length_flag = zl;
  for (j = 0; j < nf; j++) {
    at(bnf_table, (int) token, list_base[j]);
  }
  rws();
  LOGV(ntkns);
  return token;
}

/* -> left bracket, proper vp rule specs, "]...", blank?... =vp_4(); */
Token vpRepeatToken;

int vp_4(void) {
  LOGSECTION("vp_4");
  int rt;
  int tn;
  int flag, vptn;
  extern int vp_2(void);
  extern int form1(void);

  aws(4);
  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;
  }
  fdl(vp_prod_dict, vptn);
  fws();
  rt = vp_2();
  vpRepeatToken = rt;
  map_vp_prod_number[vptn].token_number = Token::create();
  sws(form1());
  aws(makeRule(rt));
  gen_vp_prods(ntkns,1,vptn);
  map_form_number[nforms].fast_loop = 1;
  LOGV(ntkns);
  return ntkns;
}

int vp_form3(int pn) {
  LOGSECTION("vp_form3");
  int vpfn;

  AgStack<RuleElement> elementList = ruleElementStack.pop();
  vpfn = VpRule(elementList, pn);
  return vpfn;
}

void warning_here(const char *fs, ...) {
  LOGSECTION("warning_here");
  LOGV(fs);
  va_list ap;
  va_start(ap,fs);
  char buf[500];
  vsprintf(buf,fs,ap);
  log_error(buf);
  va_end(ap);
  LOGS("warning_here complete");
}

/* -> union:n, "?...", blank?...            =vp_6(form_element_1(n)); */

int vp_6(int tn) {
  LOGSECTION("vp_6");
  int flag, vptn;
  int rt;

  sws(tn); aws(6);
  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;
  }
  rt = vp_7(tn);
  vpRepeatToken = rt;
  map_vp_prod_number[vptn].token_number = Token::create();
  sws(form1());
  aws(makeRule(rt));
  gen_vp_prods(ntkns,0,vptn);
  map_form_number[nforms].fast_loop = 1;
  return ntkns;
}

/* -> union:n, ellipsis                       =vp_7(form_element_1(n)); */

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

  sws(tn); aws(7);
  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(makeRule(tn));
  aws(makeRule(ntkns, tn));
  gen_vp_prods(ntkns,0,vptn);
  map_form_number[nforms].fast_loop = 1;
  return ntkns;
}