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