diff anagram/agcore/q8.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/q8.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,309 @@
+/*
+ * AnaGram, A System for Syntax Directed Programming
+ * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
+ * See the file COPYING for license and usage terms.
+ *
+ * q8.cpp
+ */
+
+#include "agbaltree.h"
+#include "arrays.h"
+#include "assert.h"
+#include "bitmap.h"
+#include "dict.h"
+#include "q1glbl.h"
+#include "q8.h"
+#include "rule.h"
+#include "stacks.h"
+#include "token.h"
+
+//#define INCLUDE_LOGGING
+#include "log.h"
+
+
+int external_reduction;
+
+static void find_free_states(int s) {
+  LOGSECTION("find_free_states");
+  LOGV(s);
+  state_number_map *msn = &map_state_number[s];
+  unsigned *p = lstptr(*msn, gotos);
+  int n = msn->n_gotos;
+  while (n--) {
+    int t = *p++;
+    int ns = *p++;
+    if (map_token_number[t].zero_length_flag) {
+      //if (distinguish_lexemes && t == disregard_token) continue;
+      if (isws(ns)) {
+	continue;
+      }
+      LOGV(t) LCV(disregard_token);
+      find_free_states(ns);
+    }
+  }
+}
+
+static void frss13(int sn, int f) {
+  LOGSECTION("frss13");
+  LOGV(sn) LCV(f);
+  int flag, kn, g, s, nf, n, *sp, m;
+  unsigned t;
+  unsigned *p;
+  unsigned *px;
+  state_number_map *msn = &map_state_number[sn];
+
+  if (f == 0) {
+    isws(0);
+    return;
+  }
+  sp = ibnfs + ibnfb[f];
+  m = ibnfn[f];
+  while (m--) {
+    int i;
+
+    t = sp[m];
+    if (map_token_number[t].subgrammar) {
+      external_reduction = 1;
+      continue;
+    }
+    flag = 0;
+    px = lstptr(*msn,completions);
+    i = 2*msn->n_completions;
+    while (i) {
+      i-=2;
+      if (px[i] != t) {
+	continue;
+      }
+      //g = px[i+1];
+      Rule rule(px[i+1]);
+      add_tuple_dict_new(frss_dict, sn, (int) rule, rule->length()-1);
+      flag++;
+      break;
+    }
+    if (flag) {
+      continue;
+    }
+    px = lstptr(*msn, gotos);
+    for (kn = msn->n_gotos; kn--; px +=2) {
+      if (t == *px) {
+	break;
+      }
+    }
+    if (kn < 0) continue;
+    s = px[1];
+    isws(s);
+    p = (unsigned *) dict_str(isht_dict,s);
+    nf = *p++ - 1;
+    p += nf;
+    nf /= 2;
+    while (nf--) {
+      n = *--p;
+      g = *--p;
+      Rule rule = g;
+      if ((unsigned) n < rule->non_vanishing_length) {
+	continue;
+      }
+      //if (distinguish_lexemes && n < rule->length() && 
+      //    (int) rule.token(n) == disregard_token) {
+      //  continue;
+      //}
+      LOGV(sn) LCV(g) LCV(n);
+      add_tuple_dict_new(frss_dict, sn, g, n-1);
+    }
+    find_free_states(s);
+  }
+}
+
+void frss12(int sn, int f, int n) {
+  unsigned k, ps;
+  unsigned *p, nt;
+  unsigned kk;
+
+  LOGSECTION("frss12");
+  LOGV(sn) LCV(f) LCV(n);
+  add_tuple_dict_new(frss_dict,sn,f,n);
+  external_reduction = 0;
+  iws();
+  k = 0;
+  while (k < frss_dict->nsx) {
+    completed_form_map *mcf;
+    extract_tuple_dict(frss_dict, k, &sn, &f, &n);
+    LOGV(k) LCV(frss_dict->nsx) LCV(sn) LCV(f) LCV(n) ;
+    k++;
+    if (f == 0) {
+      continue;
+    }
+    int length = Rule(f)->length();
+    assert(n <= length);
+    LOGV(f) LCV(length) LCV(n);
+    if (n == length) {
+      kk = add_tuple_dict_new(completed_form_dict, sn, f);
+      check_size(map_completed_form, kk, kk);
+      mcf = &map_completed_form[kk];
+      external_reduction |= mcf->external_reduction;
+      if (mcf->reduction_states_index) {
+        p = lstptr(*mcf, reduction_states);
+        nt = mcf->n_reduction_states;
+        while (nt--) {
+	  isws(*p++);
+	}
+        continue;
+      }
+    }
+    if (n) {
+      LOGSECTION("Previous states");
+      state_number_map *msn = &map_state_number[sn];
+      unsigned *p = lstptr(*msn,previous_states);
+      int nt = msn->n_previous_states;
+      while (nt--) {
+        ps = *p++;
+        add_tuple_dict_new(frss_dict, ps, f, n-1);
+        LOGV(ps) LCV(f) LCV(n-1);
+      }
+      continue;
+    }
+    frss13(sn, f);
+  }
+  reset_tuple_dict(frss_dict);
+}
+
+static AgArray< AgBalancedTree<int> > digraphList;
+
+//static void grstt3(unsigned t, unsigned ft) {
+static void grstt3(Token token, Token follower) {
+  LOGSECTION("grstt3");
+  LOGV((int) token) LCV((int) follower);
+  unsigned nt;
+  unsigned n;
+  //Token token = t;
+  //Token follower = ft;
+
+  if (digraphList[token].insert(follower)) return;
+  n = token->ruleList.size();
+  while (n--) {
+    Rule rule = token.rule(n);
+    RuleDescriptor &ruleDescriptor(rule);
+
+    if ((nt = ruleDescriptor.length()) == 0) {
+      continue;
+    }
+    Token ruleToken;
+    do {
+      //token = rule.token(--nt);
+      ruleToken = ruleDescriptor.token(--nt);
+      if (!ruleToken->non_terminal_flag) {
+	break;
+      }
+      grstt3(ruleToken, follower);
+    } while (nt && ruleToken->zero_length_flag);
+  }
+}
+
+void bfst3(void) {
+  LOGSECTION("bfst3");
+  unsigned n, k, kk;
+  Rule ruleZero(0);
+
+  int last = ruleZero->length() - 1;
+  if (last < 0) {
+    return;
+  }
+  LOGV(last) LCV(ruleZero->length()) LCV(ruleZero->elementList.size());
+  if (ruleZero.token(last).isNull()) {
+    return;
+  }
+  digraphList = AgArray< AgBalancedTree<int> >(Token::count());
+  grstt3(ruleZero.token(last), Token());
+
+  for (Each<Rule> rule; rule.loopNotFinished(); rule.getNext()) {
+    RuleDescriptor &ruleDescriptor(rule);
+    //n = rule->length();
+    n = ruleDescriptor.length();
+    if (n < 2) {
+      continue;
+    }
+    k = 0;
+    while (1) {
+      LOGV(rule) LCV(rule->length()) LCV(k);
+      //Token token = rule.token(k);
+
+      //k++;
+      if (++k >= n) {
+	break;
+      }
+      Token token = ruleDescriptor.token(k-1);
+      token_number_map &tokenDescriptor(token);
+      //if (!token->non_terminal_flag &&
+      //    !token->zero_length_flag) continue;
+      if (!tokenDescriptor.non_terminal_flag &&
+          !tokenDescriptor.zero_length_flag) {
+	continue;
+      }
+      kk = k;
+      while (kk < n) {
+        LOGV(rule) LCV(rule->length()) LCV(kk);
+        //Token followingToken = rule.token(kk);
+        Token followingToken = ruleDescriptor.token(kk);
+        grstt3(token, followingToken);
+        if (followingToken->zero_length_flag == 0) {
+	  break;
+	}
+	kk++;
+      }
+    }
+  }
+  for (Each<Token> t; t.loopNotFinished(); t.getNext()) {
+    AgBalancedTree<int> &list = digraphList[t];
+    Bitmap map(Token::count());
+    AgStack<Token> followers;
+    for (unsigned i = 0; i < list.size(); i++) {
+      if (map.setBit(list[i])) {
+	continue;
+      }
+      followers.push(list[i]);
+    }
+    t->followerList = followers;
+  }
+  digraphList.reset();
+}
+
+void ivgtt(void) {
+  LOGSECTION("ivgtt");
+  unsigned ns, i;
+
+  if (nits == 0) {
+    return;
+  }
+  LOGV(n_gotos);
+
+  AgArray< AgBalancedTree< int > > predecessor(nits);
+  for (i = 0; i < nits; i++){
+    state_number_map *sp = &map_state_number[i];
+    unsigned *p = lstptr(*sp, gotos);
+    int nt = sp->n_gotos;
+    LOGV(i) LCV(nt);
+    while (nt--) {
+      p++;
+      ns = *p++;
+      assert(ns < nits);
+      predecessor[ns].insert(i);
+    }
+  }
+  for (i = 0; i < nits; i++) {
+    state_number_map *sp = &map_state_number[i];
+    AgBalancedTree<int> &list = predecessor[i];
+    int n = list.size();
+    iws();
+    LOGS("State") LS(i);
+    for (int j = 0; j < n; j++) {
+#ifdef INCLUDE_LOGGING
+      LOGX() LS(list[j]);
+#endif
+      aws(list[j]);
+    }
+    sp->previous_states_index = store_list(previous_states_list);
+    int nps = rws();
+    sp->n_previous_states = nps;
+  }
+  LOGV(n_gotos);
+}