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