diff anagram/agcore/rpz.cpp @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children 607e3be6bad8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/anagram/agcore/rpz.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,549 @@
+/*
+ * 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();
+}
+