diff anagram/agcore/bpu.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/bpu.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,394 @@
+/*
+ * AnaGram, A System for Syntax Directed Programming
+ * Copyright 1993-1999 Parsifal Software. All Rights Reserved.
+ * See the file COPYING for license and usage terms.
+ *
+ * bpu.cpp - Utility routines for bpe3
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include "port.h"
+
+#include "arrays.h"
+#include "bpe3.h"
+#include "bpu.h"
+#include "cd.h"
+#include "data.h"
+#include "dict.h"
+#include "engdef.h"
+#include "keyword.h"
+#include "myalloc.h"
+#include "q1glbl.h"
+#include "rule.h"
+#include "stacks.h"
+#include "symbol.h"
+#include "token.h"
+
+//#define INCLUDE_LOGGING
+#include "log.h"
+
+
+void template_string(const char *name, const char *tp, const char tc) {
+  ics();
+  while (*tp) {
+    char c = *tp++;
+    if (c == tc) {
+      ass(name);
+      continue;
+    }
+    acs(c);
+  }
+  tss();
+}
+
+AgString subs_template(const char *name, const char *tp, const char tc) {
+  template_string(name, tp, tc);
+  return buildAgString();
+}
+
+unsigned find_token_number(const char *name) {
+  return Symbol(name)->token_number;
+  //return map_token_name[identify_string(name,tkn_dict)].token_number;
+}
+
+int find_completions(int s, const unsigned **q) {
+  state_number_map *sp = &map_state_number[s];
+  const unsigned *p = lstptr(*sp, chain_completions);
+  int n = sp->n_chain_completions;
+  if (n == 0 && sp->chain_gotos_index == 0) {
+    p = lstptr(*sp, completions);
+    n = sp->n_completions;
+  }
+  *q = p;
+  return n;
+}
+
+void select_actions(int k) {
+  int n = tis()/3;
+  int *lb;
+
+  list_space(n+1);
+  lb = list_base;
+  iws();
+  while (n--) {
+    aws(lb[k]);
+    k += 3;
+  }
+}
+
+void find_key_tokens(const int *pl, int n, int tw /*, int ct */) {
+  LOGSECTION("find_key_tokens");
+  LOGV(n);
+  for (; n--; pl += tw) {
+    //int tn = *pl;
+    Token token = *pl;
+    LOGV(token);
+    //if (map_token_number[tn].key == 0) continue;
+    //if (token->key == 0) continue;
+    if (token->key.isNull()) {
+      continue;
+    }
+    isws(token);
+  }
+}
+
+
+/*
+ * Note that the text of the defined format must not contain a newline.
+ * Failure to abide by this rule will cause the line count to be
+ * incorrect.
+ */
+
+void define_macro(const char *n, const char *fmt, ...) {
+  va_list ap;
+  fprintf(pe_file, "#define %s ", n);
+  va_start(ap, fmt);
+  vfprintf(pe_file, fmt, ap);
+  va_end(ap);
+  fputc('\n', pe_file);
+  pe_line_count++;
+}
+
+void define_macro_default(const char *n, const char *fmt, ...) {
+  va_list ap;
+  char name_only[80];
+  char *ptr;
+
+  strcpy(name_only, n);
+  ptr = strchr(name_only, '(');
+
+  if (ptr != NULL) {
+    *ptr = 0;
+  }
+
+  fprintf(pe_file, "#ifndef %s\n#define %s ", name_only, n);
+  va_start(ap, fmt);
+  vfprintf(pe_file, fmt, ap);
+  va_end(ap);
+  fprintf(pe_file, "\n#endif\n");
+  pe_line_count += 3;
+}
+
+unsigned char *key_string(int tn) {
+  LOGSECTION("key_string");
+  Keyword key = map_token_number[tn].key;
+  LOGV(tn) LCV(key) LCV(Keyword::count());
+
+  if (key.isNull()) {
+    return NULL;
+  }
+  LOGV(key->string);
+  return (unsigned char *) key->string.pointer();
+}
+
+/*
+ * Function:  reducing_token
+ * Arguments:
+ *   token number, tn
+ *   state number, sn
+ * Returns: 0 if tn is _not_ a reducing token in the given state
+ * Otherwise, returns the number of the rule it reduces.
+ */
+
+#if 0 /* no longer used */
+unsigned reducing_token(unsigned tn, unsigned sn) {
+  state_number_map *sp = &map_state_number[sn];
+  const unsigned *p;
+  unsigned n = sp->n_reductions;     /* number of reductions in this state */
+
+  if (n) {
+    p = lstptr(*sp, reductions);
+    while (n--) {
+      if (*p++ == tn) {
+        return *p;
+      }
+      p++;
+    }
+    return 0;
+  }
+  if (sp->n_completed_forms != 1) {
+    return 0;
+  }
+  if (shift_token(tn, sn)) {
+    return 0;
+  }
+  return *(lstptr(*sp,completed_forms));
+}
+#endif /* 0 - no longer used */
+
+Rule ruleReducedBy(Token token, unsigned sn) {
+  state_number_map *sp = &map_state_number[sn];
+  const unsigned *p;
+  unsigned n = sp->n_reductions;     /* number of reductions in this state */
+
+  if (n) {
+    p = lstptr(*sp, reductions);
+    while (n--) {
+      if (*p++ == (unsigned) token) {
+        return *p;
+      }
+      p++;
+    }
+    return 0;
+  }
+  if (sp->n_completed_forms != 1) {
+    // Exit if more than one completed rule
+    return 0;
+  }
+  if (shift_token(token, sn)) {
+    // Exit if there's a shift
+    return 0;
+  }
+  // Default reduction, return rule #
+  return *(lstptr(*sp, completed_forms));
+}
+
+void select_write_fragment(const char *name, const char *modes,
+			   const char *suffix) {
+  char fragment[80];
+
+  strcpy(fragment, name);
+  strcat(fragment, modes);
+  strcat(fragment, suffix);
+  write_code_segment(fragment);
+}
+
+int shift_token(unsigned tn, unsigned sn) {
+  const unsigned *p;
+  unsigned n;
+
+  n = find_gotos(sn, &p);
+  while (n--) {
+    if (*p == tn) {
+      return 1; 
+    }
+    else {
+      p += 2;
+    }
+  }
+
+  n = find_completions(sn, &p);
+  while (n--) {
+    if (*p == tn) {
+      return 1;
+    }
+    else {
+      p += 2;
+    }
+  }
+
+  return 0;
+}
+
+void count_pe_line(const char *s, int k) {
+  LOGSECTION("count_pe_line");
+
+  while (k--) {
+    if (s[k] == '\n') {
+      pe_line_count++;
+    }
+  }
+  LOGV(pe_line_count);
+}
+
+int wps(const char *s) {
+  LOGSECTION("wps");
+  int k = strlen(s);
+
+  fputs(s, pe_file);
+  count_pe_line(s, k);
+  return k;
+}
+
+int wss(void) {
+  count_pe_line(string_base, tis());
+  fputs(string_base, pe_file);
+  return rcs();
+}
+
+int wpe(const char *fs, ...) {
+  LOGSECTION("wpe");
+  va_list ap;
+  char buf[2000];
+
+  va_start(ap, fs);
+  vsprintf(buf, fs, ap);
+  va_end(ap);
+  return wps(buf);
+}
+
+void write_code_segment(const char *name) {
+  LOGSECTION("write_code_segment");
+  LOGV(name);
+  if (name == NULL) {
+    return;
+  }
+  AgString text = code_segment(name);
+  if (!text.exists()) {
+    return;
+  }
+  char *buf = text.pointer();
+  wps(buf);
+  wps("\n\n");
+}
+
+static AgString expand_my_macros(const char *s) {
+  LOGSECTION("expand_my_macros");
+  char *p;
+  int col_no = 0, lb = 0, k;
+
+  LOGV(s);
+  if (my_macros == NULL) {
+    return AgString(s);
+  }
+  ics();
+  while (*s) {
+    char *word;
+    int index;
+
+    while (*s && !isalpha(*s) && *s != '_') {
+      if (*s == '\n') {
+        acs(*s++);
+        col_no = 0;
+        while (*s && *s == ' ') {
+	  col_no++, s++;
+	}
+        lb = col_no;
+        continue;
+      }
+      if (lb == col_no) {
+	for (k = lb; k--; ) {
+	  acs(' ');
+	}
+      }
+      col_no++;
+      acs(*s++);
+    }
+    if (*s == 0) {
+      break;
+    }
+    ics();
+    while (*s && (isalpha(*s) || *s == '_')) {
+      acs(*s++);
+    }
+    word = build_string();
+    index = identify_string(word, my_macros);
+    if (index == 0) {
+      if (lb == col_no) {
+	for (k = lb; k--; ) {
+	  acs(' ');
+	}
+      }
+      col_no += strlen(word);
+      ass(word);
+      DEALLOCATE(word);
+      continue;
+    }
+    DEALLOCATE(word);
+    p = my_macros_subs[index];
+    if (*p == 0 && lb == col_no && (*s == '\n' || strncmp(s,"\\\n",2) == 0)) {
+      if (*s == '\\') {
+	s++;
+      }
+      s++;
+      col_no = 0;
+      while (*s && *s == ' ') {
+	col_no++;
+	s++;
+      }
+      lb = col_no;
+      continue;
+    }
+    if (lb == col_no) for (k = lb; k--;) acs(' ');
+    for (; *p; p++ ) {
+      acs(*p);
+      col_no++;
+      if (*p == '\n') {
+        for (k = lb; k--; ) {
+	  acs(' ');
+	}
+        col_no = lb;
+        continue;
+      }
+    }
+    if (*s == '#') {
+      s++;
+    }
+  }
+  LOGV(string_base);
+  return buildAgString();
+}
+
+
+AgString code_segment(const char *name) {
+  LOGSECTION("code_segment");
+
+  const char *rawtext = engdef_get(name);
+  LOGV(rawtext);
+
+  AgString mx = expand_my_macros(rawtext);
+  LOGV(mx);
+
+  return mx;
+}