diff anagram/agcore/cd.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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/anagram/agcore/cd.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,433 @@
+/*
+ * AnaGram, A System for Syntax Directed Programming
+ * Copyright 1993-1999 Parsifal Software. All Rights Reserved.
+ * See the file COPYING for license and usage terms.
+ *
+ * cd.cpp - Conflict Derivation module
+ */
+
+#include "arrays.h"
+#include "cd.h"
+#include "data.h"
+#include "dict.h"
+#include "q1glbl.h"
+#include "rule.h"
+#include "stacks.h"
+#include "tsd.h"
+#include "token.h"
+
+//#define INCLUDE_LOGGING
+#include "log.h"
+
+
+int conflict_token = 0;
+tsd *token_derivation = NULL;
+
+char *tried;
+
+int find_gotos(int s, const unsigned **p) {
+  state_number_map *sp = &map_state_number[s];
+  int n = sp->n_chain_gotos;
+  if (n == 0) {
+    *p = lstptr(*sp, gotos);
+    n = sp->n_gotos;
+  }
+  else {
+    *p = lstptr(*sp, chain_gotos);
+  }
+  return n;
+}
+
+/*
+ * x2 returns true if llt is an expansion token of hlt, false otherwise
+ */
+
+/*
+int x2(unsigned hlt, unsigned llt) {
+  //LOGSECTION("x2");
+  //token_number_map *tp;
+  unsigned *fl;
+  int nf;
+
+  Token token = hlt;
+  Token candidate = llt;
+  if (token == candidate) return 1;
+  //LOGV(hlt);
+  //LOGV(llt);
+  //assert(hlt <= ntkns);
+  //tp = &map_token_number[hlt];
+  //fl = lstptr(*tp, expansion_forms);
+  //nf = tp->n_expansion_forms;
+  nf = token->n_expansion_forms;
+  while (nf--) {
+    //form_number_map *fp = &map_form_number[*fl++];
+    Rule rule = *fl++;
+    int k = rule->length();
+    if (k == 0) {
+      continue;
+    }
+    //if (llt == lstptr(*fp,tokens)[0]) return 1;
+    if (candidate == rule->token(0)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+*/
+
+/*
+static int x2x(unsigned hlt, unsigned llt) {
+  //token_number_map *tp;
+  //unsigned *tl;
+  int nt;
+
+  Token highLevel(hlt);
+  Token lowLevel(llt);
+  if (highLevel == lowLevel) return 1;
+  //tp = &map_token_number[hlt];
+  //tl = lstptr(*tp,leading_tokens);
+  //nt = tp->n_leading_tokens;
+  //while (nt--) if (llt == *tl++) return 1;
+  while (nt--) if (lowLevel == highLevel->leadingToken(nt)) return 1;
+  return 0;
+}
+*/
+
+/*
+ * x2d checks the characteristic rules in state sn, and returns true if
+ * tn is next token for some characteristic rule. Otherwise, return 0
+ */
+
+int x2d(int sn, int tn) {
+  int *items = dict_str(isht_dict,sn);
+  int nitems = (*items++ -1)/2 ;
+  while (nitems--) {
+    Rule rule = *items++;
+    unsigned fx = *items++;
+    if (rule->length() <= fx) {
+      continue;
+    }
+    //if (x2x(lstptr(map_form_number[fn],tokens)[fx],tn)) return 1;
+    //if (x2x(Rule(fn)->token(fx),tn)) return 1;
+    if (rule.token(fx).isLeadingToken(tn)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+/*
+ * x4 returns true if fn is a left expansion rule of hlt, false otherwise
+ */
+
+/*
+int x4(unsigned hlt, unsigned fn) {
+  assert(hlt <= ntkns);
+  token_number_map *tp = &map_token_number[hlt];
+  unsigned *fl = lstptr(*tp, expansion_forms);
+  unsigned nf =  tp->n_expansion_forms;
+
+  assert(nf <= nforms);
+  while (nf--) if (*fl++ == fn) return 1;
+  return 0;
+}
+*/
+
+#ifndef COMMAND_LINE
+int x3(tsd *isl, int sx, int fn, int fx) {
+  unsigned k;
+
+  check_tsd(isl);
+  assert((unsigned)fn <= nforms);
+  sx++;
+  for (k = 0; k < isl->nt; k++) {
+    int fsx, fsn, ffn, ffx;
+    xtxf(isl, k, &fsx, &fsn, &ffn, &ffx);
+    if (fsx < sx) {
+      return 0;
+    }
+    if (fsx > sx) {
+      continue;
+    }
+    if (ffn == fn && ffx == fx + 1) {
+      return 1;
+    }
+    if (ffx != 1) {
+      continue;
+    }
+    //if (x4(lstptr(map_form_number[fn],tokens)[fx],ffn)) return 1;
+    //if (x4(Rule(fn)->token(fx),ffn)) return 1;
+    if (Rule(fn).token(fx).isExpansionRule(ffn)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int x3a(tsd *isl, int sx, int fn, int fx) {
+  unsigned k;
+
+  check_tsd(isl);
+  assert((unsigned)fn <= nforms);
+  for (k = 0; k < isl->nt; k++) {
+    int fsx, fsn, ffn, ffx;
+    xtxf(isl, k, &fsx, &fsn, &ffn, &ffx);
+    if (fsx < sx) {
+      return 0;
+    }
+    if (fsx > sx) {
+      continue;
+    }
+    if (ffn == fn && ffx == fx) {
+      return 0;
+    }
+    //if (x4(lstptr(map_form_number[fn],tokens)[fx],ffn)) return 1;
+    //if (x4(Rule(fn)->token(fx),ffn)) return 1;
+    if (Rule(fn).token(fx).isExpansionRule(ffn)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+/* x1 builds a rule stack from a token stack */
+
+tuple_dict *xis(unsigned sn) {
+  tuple_dict *d = null_tuple_dict(2);
+  int *items, nitems, length;
+  unsigned k;
+
+  assert(sn < isht_dict->nsx);
+  items = dict_str(isht_dict, sn);
+  length = *items++ - 1;
+  nitems = length/2;
+  while (nitems--) {
+    int fn = *items++;
+    int fx = *items++;
+    insert_tuple_dict(d, fn, fx);
+  }
+  for (k = 0; k < d->nsx; k++) {
+    int *t = d->text+2*k;
+    int fn = *t++;
+    unsigned fx = *t;
+    if (fx < Rule(fn)->length()) {
+      //unsigned tn = lstptr(map_form_number[fn],tokens)[fx];
+      Token token(Rule(fn).token(fx));
+      //token_number_map *tp = &map_token_number[tn];
+      //int nf =  token->n_forms;
+      int nf = token->ruleList.size();
+      //unsigned *fl = lstptr(*tp,forms);
+      //unsigned *fl = token->forms();
+      iws();
+      //while (nf--) {
+      for (int i = 0; i < nf; i++) {
+        //form_number_map *fp = &map_form_number[*fl];
+        //Rule rule(*fl);
+        Rule rule = token.rule(i);
+        //if (fp->length && lstptr(*fp, tokens)[0] == tn)
+        if (rule->length() && rule.token(0) == token) {
+	  //insert_tuple_dict(d,*fl, 0);
+	  insert_tuple_dict(d, (int) rule, 0);
+	}
+        else {
+	  aws(rule);
+	}
+      }
+      unsigned *fl = (unsigned *) list_base;
+      nf = rws();
+      while (nf--) {
+	insert_tuple_dict(d, *fl++, 0);
+      }
+    }
+  }
+  return d;
+}
+
+#endif
+
+/*
+tsd *x1x(tsd *sl) {
+  int n = sl->nt;
+  int sx,sn,tn;
+  unsigned fx;
+  int *items;
+  int nitems;
+  tsd *isl = init_tsd(4);
+
+  check_tsd(sl);
+  sx = n-1;
+  xtxf(sl,sx,&sn,&tn);
+  if (!shift_token(tn,sn)) {
+    tn = 0;
+  }
+
+  {
+    tuple_dict *d;
+    d = xis(sn);
+    items = d->text;
+    nitems = d->nsx;
+    items += 2*nitems;
+    while (nitems--) {
+      fx = *--items;
+      Rule rule = *--items;
+      if (tn == 0 ||
+          fx >= rule->non_vanishing_length ||
+          rule.token(fx).isExpansionToken(tn)) {
+        at(isl,sx,sn,(int) rule,fx);
+      }
+    }
+    delete_tuple_dict(d);
+  }
+  while (sx-- > 0) {
+    tuple_dict *d;
+    unsigned psn = sn;
+    const unsigned *p;
+    int n;
+    xtxf(sl,sx,&sn,&tn);
+    n = find_gotos(sn, &p);
+    p += 2*n;
+    while (n-- && *--p != psn) {
+      p--;
+    }
+    assert(*p == psn && n >= 0);
+    d = xis(sn);
+    items = d->text;
+    nitems = d->nsx;
+    items += 2*nitems;
+    while (nitems--) {
+      fx = *--items;
+      Rule rule = *--items;
+      if (fx >= rule->length()) {
+        continue;
+      }
+      if (x3(isl, sx,rule,fx)) {
+        at(isl, sx, sn, (int)rule, fx);
+      }
+    }
+    delete_tuple_dict(d);
+  }
+  return isl;
+}
+*/
+
+int x9x(int tn) {
+  Token token = tn;
+  //token_number_map *tp = &map_token_number[tn];
+  //unsigned *fl = lstptr(*tp,forms);
+  //int nf = token->n_forms;
+  int nf = token->ruleList.size();
+
+  if (tn == conflict_token) {
+    return 1;
+  }
+  if (tried[tn]) {
+    return 0;
+  }
+  tried[tn] = 1;
+  //while (nf--) {
+  for (int i = 0; i < nf; i++) {
+    //int fn = *fl++;
+    Rule rule = token.rule(i);
+    //form_number_map *fp = &map_form_number[fn];
+    int length = rule->length();
+    int fx = 0;
+    while (fx < length) {
+      //int t = lstptr(*fp,tokens)[fx];
+      Token ruleToken = rule.token(fx);
+      if ((int) ruleToken == conflict_token || x9x(ruleToken)) {
+        at(token_derivation, (int) rule, fx);
+        return 1;
+      }
+      //if (!map_token_number[t].zero_length_flag) break;
+      if (!token->zero_length_flag) {
+	break;
+      }
+      fx++;
+    }
+  }
+  return 0;
+}
+
+int new_next_state(int s, unsigned t) {
+  LOGSECTION("new_next_state");
+  LOGV(s) LCV(t);
+  Token token = t;
+  //token_number_map *tp;
+  int ts;
+  int np;
+  const unsigned *gl;
+  int ng = find_gotos(s, &gl);
+  const unsigned *glx = gl;
+  int ngx = ng;
+
+  //check_stack;
+  while (ng--) {
+    LOGV(gl[0]) LCV(gl[1]);
+    Token token = *gl;
+    if (*gl == t ||
+	(token->junky && (unsigned) token.rule(0).token(0) == t)) {
+      return gl[1]; 
+    }
+    else {
+      gl += 2;
+    }
+  }
+  LOGS("Didn't find a goto");
+  //tp = &map_token_number[t];
+  //ts = tp->token_set_id;
+  ts = token->token_set_id;
+  Token pureToken;
+  LOGV(pureToken) LCV(ts);
+  if (token->junky) {
+    pureToken = token.rule(0).token(0);
+  }
+  if (ts == 0 && pureToken.isNotNull()) {
+    ts = pureToken->token_set_id;
+  }
+  LOGV(pureToken) LCV(ts);
+  np = map_char_set[ts].nparts;
+  LOGV(np);
+  if (ts && np > 1) {
+    unsigned *fl = lstptr(map_char_set[ts], part);
+    while (np--) {
+      const unsigned *g = glx;
+      int n = ngx;
+      unsigned pn = fl[np];
+      unsigned pt = map_part_number[pn].token_number;
+      while (n--) {
+        if (*g++ == pt) {
+	  return *g;
+	}
+	else {
+	  g++;
+	}
+      }
+    }
+  }
+  LOGS("Didn't find a partition set either");
+  return 0;
+}
+
+Token transitionToken(unsigned fromState, unsigned toState) {
+  LOGSECTION("transitionToken");
+  LOGV(fromState) LCV(toState);
+  const unsigned *gl;
+  int nGotos = find_gotos(fromState,&gl);
+  //const unsigned *glx = gl;
+  int ngx = nGotos;
+
+  //check_stack;
+  while (ngx--) {
+    LOGV(gl[0]) LCV(gl[1]);
+    Token token = *gl;
+    if (gl[1] == toState) {
+      return gl[0];
+    }
+    gl += 2;
+  }
+  LOGS("Didn't find a goto");
+  return Token();
+}
+