view anagram/agcore/rpk.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.
 *
 * 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;
}