Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/agcore/rpz.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 | 607e3be6bad8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anagram/agcore/rpz.cpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,549 @@ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1993-2002 Parsifal Software. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * rpz.cpp + */ + +#include "arrays.h" +#include "assert.h" +#include "bpe3.h" +#include "config.h" +#include "csexp.h" +#include "dict.h" +#include "error.h" +#include "keyword.h" +#include "myalloc.h" +#include "pgg24-defs.h" +#include "pgg24.h" +#include "q1glbl.h" +#include "rpk.h" +#include "rpz.h" +#include "rproc.h" +#include "rule.h" +#include "symbol.h" +#include "stacks.h" +#include "token.h" +#include "tree.h" +#include "tsd.h" +#include "ut.h" + +//#define INCLUDE_LOGGING +#include "log.h" + + +#define PCB pgcb + + +void definition_1(CharSetExpression *x) { + LOGSECTION("definition_1"); + int k; + Symbol id = Symbol::create(); + LOGV(id); + if (x->recursive(id)) { + LOGS("Recursive definition"); + warning_here("Recursive definition of character set %s", + id->string.pointer()); + delete x; + return; + } + if (id->parse_tree.isNotNull()) { + warning_here("Redefinition of %s", id->string.pointer()); + delete x; + return; + } + if ((k = id->token_number) != 0) { + if (Token(k)->non_terminal_flag) { + warning_here("Redefinition of token T%03d: %s", k, id->string.pointer()); + delete x; + return; + } + } + LOGS("Ready to identify parse tree"); + ParseTree tree(x); + LOGV((int) tree) LCV((int) tree->expression); + id->parse_tree = tree; + tree->token_name = id; +} + + +void definition_3(int cn) { + LOGSECTION("definition_3"); + definition_1(new IndividualCode(cn)); +} + +void definition_2(int tn) { + LOGSECTION("definition_2"); + LOGV(tn); + int t; + token_number_map *mtn; + unsigned name; + + Symbol id = Symbol::create(); + LOGV(id); + if (id->parse_tree.isNotNull()) { + warning_here("Redefinition of %s", id->string.pointer()); + return; + } + if ((t = id->token_number) != 0) { + mtn = &map_token_number[t]; + if (mtn->non_terminal_flag || mtn->key) { + warning_here("Redefinition of token T%03d: %s",t, id->string.pointer()); + return; + } + shell_production(t,tn); + return; + } + name = map_token_number[tn].token_name; + if (name == (unsigned) id) { + return; + } + if (name) { + LOGS("call shell_production") LV(t) LCV(tn); + shell_production(t,tn); + return; + } + map_token_number[tn].token_name = id; + id->token_number = tn; + LOGV(tn) LCV(id); +} + +int form_spec_2(int fn, int pn) { + LOGSECTION("form_spec_2"); + LOGV(fn) LCV(pn); + Procedure reductionProc(pn); + Rule rule(fn); + + rule->proc_name = pn; + LOGV(rule) LCV(rule->proc_name); + reductionProc->form_number = rule; + return fn; +} + +int head_list_2(int flag) { + LOGSECTION("head_list_2"); + unsigned tn; + token_name(); + tn = fis(); + LOGV(tn) LCV(ntkns); + assert(tn <= ntkns); + if (flag) { + if (grammar_token) { + log_error("Redefinition of grammar token"); + } + grammar_token = tn; + } + return tn; +} + +int mid_line(int pn) { + LOGSECTION("mid_line"); + Rule rule = form1(); + Procedure proc(pn); + LOGV(rule); + LOGV(ruleElementStack.size()); + int bias = ruleElementStack.top().size(); + LOGV(bias); + rule->immediate_proc = 1; + rule->proc_name = pn; + proc->form_number = rule; + LOGV(rule) LCV(rule->proc_name); + rule->hostElementList = AgArray<RuleElement>(ruleElementStack.top()); + rule->op_bias = bias; + return rule; +} + +int proc_spec_4(int flag) { + LOGSECTION("proc_spec_4"); + + CSegment cSegment = cSegmentStack.pop(); + Procedure proc(cSegment); + LOGV(proc); + proc->value_flag = flag; + proc->line = PRULE_CONTEXT(PCB)->y; + proc->col = PRULE_CONTEXT(PCB)->x; + return proc; +} + +static int proc_spec_6(int, int fn) { + LOGSECTION("proc_spec_6"); + + CSegment segment; + segment.end = segment.begin; + Procedure proc(segment); + proc->value_flag = 1; + proc->form_number = fn; + return proc; +} + + +int semantic_productions = 0; + + +void production(int type) { + LOGSECTION("production"); + unsigned *fl, *tl, nf, nt,i,j, zl; + + zl = 0; + fl = (unsigned *) build_list(); + nf = fis(); + tl = (unsigned *) build_list(); + ok_ptr(tl); + LOGV((int) tl); + nt = fis(); + LOGV(nt) LCV(nf); + if (nt > 1) { + semantic_productions = 1; + } + for (j = 0; j < nf; j++) { + ok_ptr(tl); + LOGV(fl[j]); + Rule rule(fl[j]); + //int pn = rule->proc_name; + //const unsigned *rp = rule->tokens(); + int rl = rule->length(), i = rl; + + ok_ptr(tl); + LOGV(fl[j]); + iws(); + int tokenIndex = 0; + //while (i--) aws(*rp++); + while (i--) { + aws(rule.token(tokenIndex++)); + } + i = nt; + rl++; + while (i--) { + aws(tl[i]); + if (list_in_dict(list_base, rl, prod_dict)) { + log_error("Duplicate production"); + } + fws(); + } + rws(); + //check_size(map_proc_name,pn, pn + pn/2); + rule->prim_tkn = tl[0]; + rule->fast_loop = nt == 1 && + rule->length() == 2 && + tl[0] == (unsigned) rule.token(0); + //tl[0] == lstptr(*mfn,tokens)[0]; + if (rule->length() == 0) zl = 1; + if (rule-> length() == 1) { + int i = nt; + unsigned t = rule.token(0); + while (i--) { + if (t != tl[i]) { + continue; + } + warning_here("Suspicious production for %s", + Token(t)->token_name->string.pointer()); + } + } + if (nt > 1) { + rule->not_unique_reduction = 1; + if (rule->proc_name == 0) { + rule->proc_name = proc_spec_6(rule->line, fl[j]); + } + } + } + for (i = 0; i < nt; i++) { + token_number_map *tp = &map_token_number[tl[i]]; + int vt = tp->value_type; + ok_ptr(tl); + LOGV((int) tl); + LOGV(tl[i]) LCV(vt); + if (nf) { + tp->non_terminal_flag = 1; + } + tp->zero_length_flag = zl; + tp->sem_det_flag = nt > 1; + if (type && vt && vt != type) { + ssprintf("Type Redefinition of T%03d: ", tl[i]); + atkn(tl[i]); + log_error(); + } + if (type) { + tp->value_type = type; + } + ok_ptr(tl); + LOGV(type); + for (j = 0; j < nf; j++) { + at(bnf_table, tl[i], fl[j]); + } + } + LOGS("Ready to free tl"); + ok_ptr(tl); + LOGV((int) tl); + DEALLOCATE(tl); + LOGS("Ready to free fl"); + if (fl != NULL) { + DEALLOCATE(fl); + } + LOGS("Production analysis complete"); +} + +CharSetExpression *ss2(void) { + LOGSECTION("ss2"); + Symbol name = Symbol::create(); + + LOGV(name->token_number) LCV(name->string); + if (name->string == "error") { + Token token = name->token_number; + LOGV(token); + if (error_token || token.isNotNull() || name->parse_tree.isNotNull()) { + return new NamedCharSet(name); + } + token = Token::create(); + token->token_name = name; + name->token_number = token; + token->value_type = default_input_type; + error_token = token; + LOGV(error_token); + checkParams(); + } + return new NamedCharSet(name); +} + +void token_name(void) { + LOGSECTION("token_name"); + + unsigned symbolCount = Symbol::count(); + Symbol n = Symbol::create(); + int flag = Symbol::count() > symbolCount; //true if new symbol + + LOGV(n) LCV(ntkns); + Token tn = n->token_number; + LOGV(tn) LCV(ntkns); + if (tn.isNotNull()) { + sis(tn); + return; + } + tn = n->token_number = Token::create(); + tn->token_name = n; + tn->value_type = 0; + if (!flag && n->parse_tree.isNotNull()) { + n->parse_tree = ParseTree(); + warning_here("Redefinition of %s", n->string.pointer()); + } + sis(tn); /* push token on stack */ + return; +} + +//int idsx(string_dict *); + +/* -> keyword string =vp_s(); */ + +int vp_s(void) { + LOGSECTION("vp_s"); + int n; + int i; + + n = tis(); + if (n > max_key_length) max_key_length = n; + tss(); + LOGV(string_base); + if (!case_sensitive) { + for (i = n; i--; ) { + string_base[i] = agToUpper(string_base[i]); + } + } + if (n == 0) { + log_error("Empty keyword string"); + } + Keyword keyword(string_base); + LOGV(keyword->string); + rcs(); + LOGV((int) keyword->token_number); + if (keyword->token_number.isNull()) { + Token token = keyword->token_number = Token::create(); + LOGV((int) token); + token->key = keyword; + token->value_type = void_token_type; + token->operatorCandidate = 1; + } + return keyword->token_number; +/* + if (!idsx(key_dict)) { + key = fis(); + assert(key == (int) keyword); + LOGV(key) LCV(keyword); + check_size(map_key_word, key, key + key/2); + LOGV(key) LCV(map_key_word[key].token_number) LCV(ntkns); + return map_key_word[key].token_number; + } + if (n > max_key_length) { + max_key_length = n; + } + key = fis(); + LOGV(key) LCV(keyword); + assert(key == (int) keyword); + check_size(map_key_word, key,key + key/2 ); + map_key_word[key].token_number = Token::create(); + map_token_number[ntkns].key = key; + LOGV(key) LCV(map_key_word[key].token_number) LCV(ntkns); + return ntkns; +*/ +} + +/* -> left bracket, proper vp rule specs, right bracket =vp_3(); */ + +int vp_3(void) { + LOGSECTION("vp_3"); + int tn; + int flag,vptn; + + aws(3); + flag = idl(vp_prod_dict); + vptn = fis(); + check_size(map_vp_prod_number,vptn,vptn + vptn/2); + if (flag == 0) { + tn = map_vp_prod_number[vptn].token_number; + LOGV(tn) LCV(ntkns); + return tn; + } + sws(form1()); + fdl(vp_prod_dict,vptn); + fws(); + vp_forms(); + concat_list(); + map_vp_prod_number[vptn].token_number = Token::create(); + gen_vp_prods(ntkns,1,vptn); + LOGV(ntkns); + return ntkns; +} + +/* + -> keyword string, '?', blank?... =vp_5(vp_s()); + -> union:n, '?', blank?... =vp_5(form_element_1(n)); +*/ + +int vp_5(int tn) { + LOGSECTION("vp_5"); + int flag, vptn; + + sws(tn); aws(5); + flag = idl(vp_prod_dict); + vptn = fis(); + check_size(map_vp_prod_number,vptn,vptn + vptn/2); + if (flag == 0) { + tn = map_vp_prod_number[vptn].token_number; + return tn; + } + map_vp_prod_number[vptn].token_number = Token::create(); + sws(form1()); + aws(makeRule(tn)); + gen_vp_prods(ntkns,0,vptn); + return ntkns; +} + +int vp_8a(int fn) { + LOGSECTION("vp_8a"); + token_number_map *tp; + + Token::create(); + tp = &map_token_number[ntkns]; + tp->non_terminal_flag = 1; + map_form_number[fn].prim_tkn = ntkns; + tp->zero_length_flag = 1; + tp->fine_structure = 1; + tp->immediate_action = 1; + at(bnf_table, ntkns, fn); + LOGV(ntkns) LCV(tp->immediate_action); + return ntkns; +} + +//static void build_choice(int tn) { +static void build_choice(Token token) { + LOGSECTION("build_choice"); + int *fl, nf, j; + int i, zl; + //token_number_map *tp; + + + zl = 0; + vp_forms(); + fl = list_base; + nf = rws(); + //tp = &map_token_number[tn]; + //if (nf) tp->non_terminal_flag = 1; + if (nf) { + token->non_terminal_flag = 1; + } + for (i = 0; i < nf; i++) { + Rule rule(fl[i]); + //rule->prim_tkn = tn; + rule->prim_tkn = token; + if (rule->length() == 0) { + zl = 1; + } + } + //tp->zero_length_flag = zl; + token->zero_length_flag = zl; + for (j = 0; j < nf; j++) { + //at(bnf_table,tn,fl[j]); + at(bnf_table,(int) token,fl[j]); + } +} + +//static void alter_prod(int tb, int nt, int tn, int vf) { +static void alter_prod(Token tb, int nt, Token token, VpRule vpRule) { + LOGSECTION("alter_prod"); + + LOGV(vpRule) LCV(token) LCV(tb) LCV(nt) LCV(Token::count()); + + int i,j; + iws(); + for (i = tb, j = nt; j--; i++) { + //if (i == tn) { + if (i == (int) token) { + //aws(vf); + aws(vpRule); + continue; + } + AgStack<RuleElement> elementStack; + elementStack.push(RuleElement(i,0)); + //VpRule vpRule(vf); + for (unsigned k = 0; k < vpRule->elementList.size(); k++) { + elementStack.push(vpRule->elementList[k]); + } + VpRule newRule(elementStack, vpRule->procedureName); + aws(newRule); + } + build_choice(token); +} + +static void alternate(void) { + LOGSECTION("alternate"); + //int tb = ntkns+1; + Token tb = Token::create(); + int *vfl = build_list(); + int nt = fis(); + //int tn = tb, k; + Token tn; + int k; + + for (k = 1; k < nt; k++) tn = Token::create(); + iws(); + for (k = 0; k < nt; k++) { + tn = tb + k; + alter_prod(tb,nt,tn,vfl[k]); + ruleElementStack.push(AgStack<RuleElement>()).top() + .push(RuleElement(tn,0)); + aws(vp_form3(0)); + } + DEALLOCATE(vfl); +} + +int vp_9(void){ + LOGSECTION("vp_9"); + alternate(); + return vp_1(); +} + +int vp_10(void){ + LOGSECTION("vp_10"); + alternate(); + return vp_3(); +} +