diff anagram/agcore/ut.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 5b21f127e957
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/anagram/agcore/ut.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,414 @@
+/*
+ * AnaGram, A System for Syntax Directed Programming
+ * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
+ * See the file COPYING for license and usage terms.
+ *
+ * ut.cpp
+ */
+
+#include <stdio.h>
+#include "port.h"
+
+#include "csexp.h"
+#include "dict.h"
+#include "keyword.h"
+#include "q1glbl.h"
+#include "rule.h"
+#include "stacks.h"
+#include "symbol.h"
+#include "token.h"
+#include "tree.h"
+#include "ut.h"
+
+//#define INCLUDE_LOGGING
+#include "log.h"
+
+
+#define PUREMARK '%'
+
+
+
+void append_ascii_char(unsigned int j) {
+  switch (j) {
+    case '\a':
+      ass("\\a");
+      break;
+    case '\b':
+      ass("\\b");
+      break;
+    case '\f':
+      ass("\\f");
+      break;
+    case '\n':
+      ass("\\n");
+      break;
+    case '\r':
+      ass("\\r");
+      break;
+    case '\t':
+      ass("\\t");
+      break;
+    case '\v':
+      ass("\\v");
+      break;
+    case '\'':
+    case '\\':
+    case '\"':
+      apprintf("\\%c",j);
+      break;
+    default:
+      if (j >= 32 && j < 127) {
+	acs(j);
+      }
+      else {
+	apprintf("\\%o",j);
+      }
+      break;
+  }
+}
+
+void append_char_range(int i, int j) {
+  const char *fmt;
+  if (i == j) {
+    append_char_rep(i);
+    return;
+  }
+  if (j <= 32 || i >= 127) {
+    fmt = "%d..%d";
+  }
+  else if (i > 32 && j < 127) {
+    fmt = "'%c-%c'";
+  }
+  else if (i > 32) {
+    fmt = "'%c'..%d";
+  }
+  else if (j < 127) {
+    fmt = "%d..'%c'";
+  }
+  else {
+    fmt = "%d..%d";
+  }
+  apprintf(fmt, i,j);
+}
+
+void append_char_rep(int j) {
+  switch (j) {
+    case '\a':
+      ass("'\\a'");
+      break;
+    case '\b':
+      ass("'\\b'");
+      break;
+    case '\f':
+      ass("'\\f'");
+      break;
+    case '\n':
+      ass("'\\n'");
+      break;
+    case '\r':
+      ass("'\\r'");
+      break;
+    case '\t':
+      ass("'\\t'");
+      break;
+    case '\v':
+      ass("'\\v'");
+      break;
+    case '\'':
+    case '\\':
+    case '\"':
+      apprintf("'\\%c'", j);
+      break;
+    default:
+      if (j > 0 && j <= 26) {
+	apprintf("^%c", j+64);
+      }
+      else if (j >=32 && j < 127) {
+	apprintf("'%c'", j);
+      }
+      else {
+	apprintf("%d", j);
+      }
+  }
+}
+
+void append_string_char(int j) {
+  switch (j) {
+    case '\a':
+      ass("\\a");
+      break;
+    case '\b':
+      ass("\\b");
+      break;
+    case '\f':
+      ass("\\f");
+      break;
+    case '\n':
+      ass("\\n");
+      break;
+    case '\r':
+      ass("\\r");
+      break;
+    case '\t':
+      ass("\\t");
+      break;
+    case '\v':
+      ass("\\v");
+      break;
+    case '\\':
+    case '\"':
+      apprintf("\\%c",j);
+      break;
+    default:
+      if (j >= 32 && j < 127) {
+	acs(j);
+      }
+      else {
+	apprintf("\\%o",j);
+      }
+      break;
+  }
+}
+
+static void append_vp_form(VpRule vpRule) {
+  int n, i;
+  AgArray<RuleElement> elementList = vpRule->elementList;
+  n = elementList.size();
+  const char *cs = "";
+  for (i = 0; i < n; i++) {
+    ass(cs);
+    atkn(elementList[i].token);
+    cs = ", ";
+  }
+}
+
+static void append_vp_forms(int *lb, int n) {
+  const char *cs;
+  int i;
+
+  cs = "";
+  for (i = 0; i < n; i++) {
+    ass(cs);
+    append_vp_form(*lb++);
+    cs = " | ";
+  }
+}
+
+AgString proc_name_string(int pn) {
+  LOGSECTION("proc_name_string");
+  LOGV(pn);
+  char buf[100];
+  sprintf(buf, "ag_rp_%d", pn);
+  LOGV(buf);
+  return AgString(buf);
+}
+
+void avptkn(int tn) {
+  int vpt, *lb, n, pn;
+
+  lb = dict_str(vp_prod_dict,tn);
+  n = *lb++ - 1;
+  vpt = lb[--n];
+  switch (vpt) {
+    case 1:        /* {forms} */
+      acs('{');
+      append_vp_forms(lb,n);
+      acs('}');
+      break;
+    case 2:        /* {forms}... */
+      acs('{');
+      append_vp_forms(lb,n);
+      ass("}...");
+      break;
+    case 3:        /* [forms] */
+      acs('[');
+      append_vp_forms(lb,n);
+      acs(']');
+      break;
+    case 4:        /* [forms]... */
+      acs('[');
+      append_vp_forms(lb,n);
+      ass("]...");
+      break;
+    case 5:        /* name? */
+      atkn(*lb);
+      acs('?');
+      break;
+    case 6:        /* name?... */
+      atkn(*lb);
+      ass("?...");
+      break;
+    case 7:        /* name... */
+      atkn(*lb);
+      ass("...");
+      break;
+    case 8:        /* !proc */
+      acs('!');
+      pn = Rule(*lb)->proc_name;
+      ass(proc_name_string(pn).pointer());
+      break;
+  }
+}
+
+void atkn(Token token) {
+  Keyword key;
+  int pn;
+  int vptn;
+
+  LOGSECTION("atkn");
+  LOGV(token);
+
+  //Does token have an explicit name, if so, use that.
+  Symbol tokenName = token->token_name;
+  if (tokenName.isNotNull()) {
+    LOGV(tokenName) LCV(tokenName->string.pointer());
+    ass(tokenName->string.pointer());
+    if (token->pure) acs(PUREMARK); return;
+  }
+  // token does not have an explicit name. Is it a keyword?
+  LOGV(token);
+  key = token->key;
+  //if (key) {
+  if (key.isNotNull()) {
+    acs('"');
+    append_key(key);
+    acs('"');
+    if (token->pure) acs(PUREMARK);
+    return;
+  }
+
+  // token isn't a keyword. Does it have a parse tree?
+  LOGV(token);
+  LOGV(token->parse_tree) LCV(ParseTree::count());
+  ParseTree tokenParseTree = token->parse_tree;
+  LOGV(tokenParseTree);
+  LOGV(token);
+  if (tokenParseTree.isNotNull()) {
+    Symbol parseTreeName = tokenParseTree->token_name;
+    LOGV(parseTreeName);
+    if (parseTreeName.isNotNull() && parseTreeName->token_number == token) {
+      LOGV(tokenParseTree) LCV(parseTreeName->string.pointer());
+      tokenName = parseTreeName;
+      ass(tokenName->string.pointer());
+      if (token->pure) acs(PUREMARK);
+      return;
+    }
+    // Parse tree has no name, so use the expression
+    LOGV(token);
+    LOGV(tokenParseTree->expression->asString().pointer());
+    ass(tokenParseTree->expression->asString().pointer());
+    if (token->pure) acs(PUREMARK);
+    return;
+  }
+  // No parse tree. Try virtual production
+  LOGV(token);
+  LOGV(token->vp_prod_number);
+  if ((vptn = token->vp_prod_number) != 0){
+    LOGV(vptn);
+    avptkn(vptn);
+    if (token->pure) acs(PUREMARK);
+    return;
+  }
+  // No virtual production. Is this a partition token?
+  LOGV(token);
+  LOGV(token->part_number);
+  if ((pn = token->part_number) != 0) {
+    LOGV(pn);
+    apprintf("P%03d", pn);
+    if (token->pure) acs(PUREMARK);
+    return;
+  }
+  // Try for immediate action
+  LOGV(token);
+  //LOGV(token->n_expansion_forms);
+  //if (token->n_expansion_forms == 1) {
+  if (token->expansionRuleList.size() == 1) {
+    //unsigned *fl = lstptr(*tp, expansion_forms);
+    //unsigned *fl = token->expansion_forms();
+    LOGV(token);
+    LOGV(token.expansionRule(0));
+    Rule rule = token.expansionRule(0);
+    LOGV(rule);
+    if (rule->immediate_proc) {
+      apprintf("!ag_rp_%d", rule->proc_name);
+      if (token->pure) acs(PUREMARK);
+      return;
+    }
+  }
+  // none of those things. Be satisfied with token number
+  apprintf("T%03d",(int) token);
+  if (token->pure) acs(PUREMARK);
+}
+
+AgString token_string(unsigned tn) {
+  ics();
+  atkn(tn);
+  return buildAgString();
+}
+
+static void append_item_only(int f, int x) {
+  int n, i;
+  const char *cs;
+
+  Rule rule = f;
+  n = rule->length();
+  cs = "";
+  for (i = 0; i < n; i++) {
+    ass(cs);
+    if (i == x) {
+      ass("< ");
+    }
+    atkn(rule.token(i));
+    //if (i == x) {
+    //  acs('þ');
+    //}
+    if (i == x) {
+      acs('>');
+    }
+    cs = ", ";
+  }
+  if (i == x) {
+    if (i > 0) {
+      acs(' ');
+    }
+#ifdef OLDUI
+    acs('þ');
+#endif
+  }
+}
+
+void append_item(int f, int x) {
+  if (nforms < 1000) {
+    apprintf("R%03d:  ", f);
+  }
+  else {
+    apprintf("R%04d: ", f);
+  }
+  append_item_only(f, x);
+}
+
+void append_item_brkt(int f, int brkt) {
+  int n, i;
+  const char *cs;
+
+  Rule rule = f;
+  n = rule->length();
+  if (nforms < 1000) {
+    apprintf("R%03d:  ", f);
+  }
+  else {
+    apprintf("R%04d: ", f);
+  }
+  cs = "";
+  for (i = 0; i < n; i++) {
+    ass(cs);
+    if (i == brkt) {
+      ass("< ");
+    }
+    atkn(rule.token(i));
+    if (i == brkt) {
+      acs('>');
+    }
+    cs = ", ";
+  }
+}