Mercurial > ~dholland > hg > ag > index.cgi
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 = ", "; + } +}