Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/agcore/q5.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/q5.cpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,1194 @@ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1993-2002 Parsifal Software. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * q5.cpp + */ + +#include "arrays.h" +#include "assert.h" +#include "config.h" +#include "bpu.h" +#include "cra.h" +#include "data.h" +#include "dict.h" +#include "error.h" +#include "keyword.h" +#include "lexeme.h" +#include "minmax.h" +#include "myalloc.h" +#include "q1a.h" +#include "q1glbl.h" +#include "q5.h" +#include "q8.h" +#include "rule.h" +#include "stacks.h" +#include "token.h" +#include "tsd.h" +#include "ut.h" + +//#define INCLUDE_LOGGING +#include "log.h" + + +static unsigned items_length; + +unsigned n_gotos; +unsigned n_completions; +unsigned n_conflicts; +unsigned n_reductions; +unsigned n_default_reductions; +static int reduce_proc_flag; + + +tsd *lcft = NULL; +tsd *lcftp = NULL; +tsd *lgt = NULL; + +int nInputRules = 0; + +//extern tsd *items_table; + +tsd *expand_state(int sn) { + int *list = dict_str(isht_dict, sn); + int n = (*list++ - 1)/2; + int fn, fx, k = n; + tsd *sx = init_tsd(2); + while (k--) { + fn = *list++; + fx = *list++; + at(sx, fn, fx); + } + list -= 2*n; + k = n; + iws(); + while (k--) { + int nx; + + fn = *list++; + fx = *list++; + if (fx >= (int) map_form_number[fn].length()) { + continue; + } + //tn = lstptr(map_form_number[fn],tokens)[fx]; + Token token = Rule(fn).token(fx); + if (!token->non_terminal_flag) { + continue; + } + //xl = lstptr(map_token_number[tn], expansion_forms); + //nx = map_token_number[tn].n_expansion_forms; + //while (nx--) xws(*xl++); + nx = token->expansionRuleList.size(); + for (int i = 0; i < nx; i++) { + xws(token.expansionRule(i)); + } + } + k = tis(); + list = list_base; + while (k--) { + at(sx, *list++, 0); + } + rws(); + return sx; +} + +static AgBalancedTree<OrderedPair<int> > pairs; +static AgBalancedTree<int> frameTokens; +static AgStack<int> frameRules; +static AgBalancedTree<int> frameStates; +int frameIndex; + +static void findFrameStates(int sn, int rx) { + LOGSECTION("findFrameStates"); + LOGV(sn) LCV(rx); + if (pairs.insert(OrderedPair<int>(sn, rx))) { + return; + } + LOGV(sn) LCV(rx); + if (rx) { + unsigned *p = lstptr(map_state_number[sn],previous_states); + int nt = map_state_number[sn].n_previous_states; + LOGV(nt); + while (nt--) { + LOGV(*p); + findFrameStates(*p++, rx - 1); + } + return; + } + frameStates.insert(sn); +} + +static void findFrameTokens(void) { + LOGSECTION("findFrameTokens"); + frameTokens.reset(); + int n = frameStates.size(); + LOGV(n); + if (n == 0) { + return; + } + + int state = frameStates[0]; + tsd *expansion = expand_state(state); + int k = expansion->nt; + LOGV(state) LCV(k); + + { LOGSECTION("Scan expansion rules"); } + + while (k--) { + int r, index; + xtx(expansion, k, &r, &index); + Rule rule(r); + RuleDescriptor &ruleDescriptor(rule); + if (index >= (int) ruleDescriptor.length()) { + continue; + } + Token token = ruleDescriptor.token(index); + token_number_map &tokenDescriptor(token); + if (tokenDescriptor.key || tokenDescriptor.fine_structure || + tokenDescriptor.junky) { + continue; + } + if ((int) token == grammar_token) { + continue; + } + LOGV(rule) LCV(index) LCV(token); + int nFrameRules = frameRules.size(); + // Does there exist a frameRule which is an expansion rule of token? + while (nFrameRules--) { + if (token.isExpansionRule(frameRules[nFrameRules])) { + break; + } + } + if (nFrameRules < 0) { + continue; + } + // Yes, at least one + nFrameRules = frameRules.size(); + // Is there a frameRule which is not an expansion rule of token? + while (nFrameRules--) { + if (!token.isExpansionRule(frameRules[nFrameRules])) { + break; + } + } + if (nFrameRules >= 0 && index == 0) { + continue; + } + LOGV(token); + frameTokens.insert(token); + } + delete_tsd(expansion); + + { LOGSECTION("Scan frameStates"); } + + int i = 1; + while (i < n) { + AgBalancedTree<int> tokens; + state = frameStates[i++]; + LOGV(state); + expansion = expand_state(state); + k = expansion->nt; + while (k--) { + int r, index; + xtx(expansion, k, &r, &index); + Rule rule(r); + RuleDescriptor &ruleDescriptor(rule); + if (index >= (int) ruleDescriptor.length()) { + continue; + } + Token token = rule.token(index); + if (!frameTokens.includes(token)) { + continue; + } + token_number_map &tokenDescriptor(token); + if (tokenDescriptor.key || tokenDescriptor.fine_structure || + tokenDescriptor.junky) { + continue; + } + if ((int) token == grammar_token) { + continue; + } + LOGV(rule) LCV(index) LCV(token); + int nFrameRules = frameRules.size(); + while (nFrameRules--) { + if (token.isExpansionRule(frameRules[nFrameRules])) { + break; + } + } + if (nFrameRules < 0) { + continue; + } + nFrameRules = frameRules.size(); + while (nFrameRules--) { + if (!token.isExpansionRule(frameRules[nFrameRules])) { + break; + } + } + LOGV(nFrameRules); + if (nFrameRules >= 0 && index == 0) continue; + LOGV(token); + tokens.insert(token); + } + delete_tsd(expansion); + LOGS("Expansion deleted"); + frameTokens *= tokens; + LOGS("Intersection complete"); + } +} + +int find_ctn(int state) { + LOGSECTION("find_ctn"); + int *items, nitems; + int *p; + + frameRules.reset(); + items = dict_str(isht_dict,state); + nitems = (*items++ -1)/2; + p = items; + frameIndex = 0; + LOGV(state) LCV(nitems); + // Scan the items that define this state + // The goal is to identify the rule, or rules, that have the fewest tokens + // on the parse stack, that is the rules for which the rule index + // is at a minimum + while (nitems--) { + Rule rule(*p++); + RuleDescriptor &ruleDescriptor(rule); + int index = *p++; + if (index >= (int) ruleDescriptor.length()) { + continue; + } + Token token(ruleDescriptor.prim_tkn); + if (frameRules.size() == 0 || index < frameIndex) { + frameRules.reset().push(rule); + frameIndex = index; + LOGV(rule) LCV(frameIndex); + continue; + } + else if (index == frameIndex) { + frameRules.push(rule); + LOGV(rule); + } + } + if (frameRules.size() == 0) { + frameIndex = 0; + return 0; + } + frameStates.reset(); + pairs.reset(); + + { LOGSECTION("frame states"); } + + // identify states where frame rules originated + findFrameStates(state, frameIndex); + pairs.reset(); + + { LOGSECTION("frame tokens"); } + findFrameTokens(); + { LOGSECTION("frame tokens complete"); } + + int n = frameTokens.size(); + if (n == 0) { + frameIndex = 0; + return 0; + } + Token token = frameTokens[0]; + LOGV(n) LCV(token); + if (n == 1) { + return token; + } + int i = 1; + for (i = 1; i < n; i++) { + LOGV(token) LCV(frameTokens[i]); + if (token.isExpansionToken(frameTokens[i])) { + token = frameTokens[i]; + } + } + LOGV(token); + frameTokens.reset(); + frameRules.reset(); + return (int) token; +} + +static int zeros[] = {0,0,0}; + +//int *token_list; + + +static void cmpits3a(unsigned t) { + LOGSECTION("cmpits3a"); + LOGV(t) LCV(tis()); + unsigned lis_id; + + if ((lits = tis()) == 1) { // if single rule on stack + Rule rule = list_base[0]; + if (rule->length() == (unsigned) list_base[1]) { + if (!traditional_engine || rule.isNull() || (int) t == eof_token) { + LOGV(rule) LCV(list_base[1]); + at(lcft, t, (int) rule); + n_completions++; + return; + } + } + } + Rule rule(list_base[0]); + int index = list_base[1] - 1; + LOGV(rule) LCV(index); + int charToken = rule.token(index); + LOGV(charToken); + lis_id = add_list_dict(list_base, 2*lits, isht_dict); + check_size(map_state_number, lis_id, lis_id); + at(lgt, t, lis_id); + map_state_number[lis_id].char_token = charToken; + LOGV(lis_id) LCV(t); + n_gotos++; +} + +void *size_prop(unsigned *list, unsigned n) { + unsigned m = nits + 1; + unsigned k = kits + 1; + n += list[0]; + if (m > 3*k) m = 3*k; + return check_array_size(list, n, n*m/k); +} + +#define resize(list, n) list = (unsigned *) size_prop(list, n) + +void lalr(void) { + LOGSECTION("lalr"); + int f, n, s, g; + int nt; + item_map item; + //int *chain_tokens = local_array(ntkns+1, int); + LocalArray<int> chain_tokens(ntkns+1); + + nits = n_conflicts = 0; + + check_size(map_state_number, n_states_est, n_states_est); + n = 4*n_states_est; + check_size(completions_list,n, n); + check_size(completed_forms_list, n_states_est, n_states_est); + check_size(gotos_list, n_gotos, n_gotos); + check_size(reductions_list, n_states_est, n_states_est); + check_size(chain_completions_list, n, n); + check_size(chain_gotos_list, n_gotos, n_gotos); + MAP(item, 100); + n_gotos = n_completions = 0; + n_reductions = n_default_reductions = 0; + //token_list = local_array(ntkns+1, int); + AgStack<int> tokenStack; + lcftp = spec_tsd(300, 2); + lcft = spec_tsd(300, 2); + lgt = spec_tsd(300, 2); + nitems = 1; + add_list_dict(zeros, 2, isht_dict); + + nits = 1; + + kits = 0; + while (kits < nits) { + LOGV(kits) LCV(nits); + state_number_map *sp; + //int *tnl; + + memset(chain_tokens, 0, (ntkns+1)*sizeof(*chain_tokens)); + sp = &map_state_number[nstates = kits]; + nitems = 1; + + items = (unsigned *) dict_str(isht_dict,kits); + items_length = (*items++ - 1)/2; + n = nitems + items_length + 1; + check_size(map_item, n, n); + + ncssa = 0; + tokenStack.reset(); + iws(); + while (items_length--) { + Rule rule(item.form_number = f = *items++); + item.form_index = n = *items++; + LOGS("item") LS(f) LCS(n); + if (n > 0 && Token(rule.token(n-1))->sticky) { + sp->sticky = 1; + } + if ((unsigned) n >= rule->length()) { + aws(f); + continue; + } + Token t(rule.token(n)); + //token_list[ncssa++] = t; + tokenStack.push(t); + LOGS("token") LS(t); + item.chain_item = chain_tokens[t]; + map_item[nitems] = item; + chain_tokens[t] = nitems++; + + nt = t->expansionRuleList.size(); + check_size(map_item, nitems+nt, nitems+nt); + if (nt == 0) { + continue; + } + for (int i = 0; i < nt; i++) { + Rule expansionRule(item.form_number = g = t.expansionRule(i)); + if (expansionRule->length() == 0) { + xws(expansionRule); + continue; + } + item.form_index = 0; + s = expansionRule.token(0); + LOGV(expansionRule)LCS("token is") LS(s); + item.chain_item = chain_tokens[s]; + //if (item.chain_item == 0) token_list[ncssa++] = s; + if (item.chain_item == 0) { + tokenStack.push(s); + } + map_item[nitems] = item; + chain_tokens[s] = nitems++; + } + } + resize(completed_forms_list, tis()); + sp->completed_forms_index = store_list(completed_forms_list); + sp->n_completed_forms = rws(); + + reset_tsd(lgt); + reset_tsd(lcft); +/* + iws(); + n = 0; + while (n<ncssa) { + LOGV(n) LCV(token_list[n]); + xws(token_list[n++]); + } + tnl = list_base; + ncssa = tis(); +*/ + AgStack<int> tnl; + n = 0; + ncssa = tokenStack.size(); + LOGV(ncssa); + while (n < ncssa) { + //int tokenNumber = token_list[n++]; + int tokenNumber = tokenStack[n++]; + int i = tnl.size(); + LOGV(tokenNumber); + while (i--) { + LOGV(i) LCV(tnl[i]); + if (tokenNumber == tnl[i]) { + break; + } + } + if (i >= 0) { + continue; + } + tnl.push(tokenNumber); + LOGV(i) LCV(tokenNumber) LCV(tnl.size()); + LOGV(tnl.top()) LCV(tnl[tnl.size()-1]); + } + ncssa = tnl.size(); + LOGS("Create") LS(ncssa) LS("proto-states"); +#ifdef INCLUDE_LOGGING + n = ncssa; + if (n) { + LOGV(tnl.top()) LCV(tnl[tnl.size()-1]); + } + while (n--) { + LOGV(n) LCV(tnl[n]); + } +#endif + while (ncssa--) { + LOGV(ncssa) LCV(tnl[ncssa]); + Token token(tnl[ncssa]); + if (token->non_terminal_flag && token->token_set_id && !token->junky) { + continue; + } + iws(); + n = chain_tokens[token]; + LOGV(token) LCV(n); + while (n) { + item = map_item[n]; + Token pt(Rule(item.form_number)->prim_tkn); + LOGV(item.form_number) LCV(pt) LCV(pt->token_set_id); + LOGV(pt->junky) LCV(pt->pure); + + if (pt->non_terminal_flag && pt->token_set_id && !pt->junky) { + LOGV(n); + int n = chain_tokens[pt]; + while (n) { + item_map item = map_item[n]; + xps(item.form_number, item.form_index + 1); + LOGV(item.form_number) LCV(item.form_index + 1); + n = item.chain_item; + LOGV(n); + } + } + else { + xps(item.form_number, item.form_index + 1); + } + nitems--; + n = item.chain_item; + } + cmpits3a(token); + sp = &map_state_number[kits]; + rps(); + } + //rws(); + resize(completions_list, lcft->nt); + sp->completions_index = store_tuples(lcft, completions_list); + sp->n_completions = lcft->nt; + resize(gotos_list, lgt->nt); + sp->gotos_index = store_tuples(lgt,gotos_list); + sp->n_gotos = lgt->nt; + nits = isht_dict->nsx; + check_size(map_state_number, nits, nits + nits/2); + if (!traditional_engine && !rule_coverage) { + cra(); + } + kits++; + } + delete_tsd(lgt); + delete_tsd(lcft); + delete_tsd(lcftp); + delete_array(map_item); + map_state_number = (state_number_map *) + set_array_size(map_state_number, nits); + //close_list_dict(isht_dict); + n_states_est = nits - 1; + nstates = nits; +} + +static void find_followers(int f) { + LOGSECTION("find_followers"); + int nt, nq; + unsigned *p; + + if (f == 0) { + sws(0); + return; + } + iws(); + p = (unsigned *) ibnfs + ibnfb[f]; + nt = ibnfn[f]; + LOGV(nt); + while (nt--) { + Token token = *p++; + nq = token->followerList.size(); + LOGV(nq); + if (nq == 0 || (nq == 1 && token.follower(0).isNull())) { + int errorNumber = errorList.size(); + ssprintf("Nothing reduces T%03d -> ",(int)token); + append_item(f, 1+map_form_number[f].length()); + log_error(map_form_number[f].line, map_form_number[f].col); + + for (int k = 0; k < errorNumber; k++) { + if (errorList[k].message != errorList[errorNumber].message) { + continue; + } + errorList.pop(); + break; + } + } + for (int k = 0; k < nq; k++) { + int nlt; + Token follower = token.follower(k); + LOGV(follower); + if(!follower->non_terminal_flag) { + isws(follower); + continue; + } + if ((nlt = follower->leadingTokenList.size()) == 0) { + continue; + } + for (int i = 0; i < nlt; i++) { + isws(follower.leadingToken(i)); + } + } + } +} + +static void bsgt(void) { + LOGSECTION("bsgt"); + int kn, rtk, s, n, g, k; + int *p; + unsigned *px; + state_number_map *sp = &map_state_number[kits]; + + px = lstptr(*sp,gotos); + kn = sp->n_gotos; + while (kn--) { + rtk = *px++; + s = *px++; + if (map_token_number[rtk].non_terminal_flag) { + continue; + } + p = dict_str(isht_dict, s); + n = (*p++ - 1)/2; + while (n--) { + g = *p++; + k = *p++; + at(sgt, rtk, g, k-1); + tut[rtk]++; + LOGV(tut[rtk]) LCV(rtk) LCV(k); + } + } + px = lstptr(*sp,completions); + kn = sp->n_completions; + while (kn--) { + rtk = *px++; + g = *px++; + if (map_token_number[rtk].non_terminal_flag) { + continue; + } + at(sgt, rtk, g, map_form_number[g].length() - 1); + tut[rtk]++; + LOGV(tut[rtk]) LCV(rtk); + } +} + +static void logcon(tsd *rrc, int *p, int nt) { + LOGSECTION("logcon"); + LOGV(kits) LCV(nits); + int n; + int t, f; + int *q, nq,qt; + + while (nt--) { + if (rrc != res_con) { + if (n_conflicts >= (unsigned) max_conflicts) { + return; + } + n_conflicts++; + } + t = *p++; + q = sgt->sb; + nq = sgt->nt; + while (nq--) { + if (*q++ != t) { + q += 2; + continue; + } + f = *q++; + n = *q++; + at(rrc, kits, t, f, n); + } + q = srt->sb; nq = srt->nt; + while (nq--) { + qt = *q++; + f = *q++; + if (qt != t) { + continue; + } + at(rrc, kits, t, f, map_form_number[f].length()); + } + } +} + +static void log_prr(tsd *s, tsd *r) { + int *p, n; + + p = s->sb; + n = s->nt; + while (n--) { + int t = *p++; + int f = *p++; + + at(prr, kits, 0, t, f); + } + p = r->sb; + n = r->nt; + while (n--) { + int t = *p++; + int f = *p++; + + at(prr, kits, 1, t, f); + } +} + +static tsd *purge_ts = NULL; + +static void purge_gotos(tsd *st) { + tsd *t = purge_ts; + int kn; + state_number_map *sp = &map_state_number[kits]; + + t->tw = 2; + if ((kn = sp->n_gotos) != 0) { + t->nt = t->na = kn; + t->sb = (int *) lstptr(*sp,gotos); + p1_tsd(t, 0, st, 0); + sp->n_gotos = t->nt; + } + if ((kn = sp->n_chain_gotos) != 0) { + t->nt = t->na = kn; + t->sb = (int *) lstptr(*sp,chain_gotos); + p1_tsd(t, 0, st, 0); + sp->n_chain_gotos = t->nt; + } + if ((kn = sp->n_completions) != 0) { + t->nt = t->na = kn; + t->sb = (int *)lstptr(*sp,completions); + p1_tsd(t, 0, st, 0); + sp->n_completions = t->nt; + } + if ((kn = sp->n_chain_completions) != 0) { + t->nt = t-> na = kn; + t->sb = (int *) lstptr(*sp,chain_completions); + p1_tsd(t, 0, st, 0); + sp->n_chain_completions = t->nt; + } +} + +static void find_terminals(state_number_map *msn) { + unsigned *p = lstptr(*msn, gotos); + int n = msn->n_gotos; + + while (n--) { + int t = *p++; + p++; + if (!map_token_number[t].non_terminal_flag) { + xws(t); + } + } + p = lstptr(*msn, completions); + n = msn->n_completions; + while (n--) { + int t = *p++; + p++; + if (!map_token_number[t].non_terminal_flag) { + xws(t); + } + } +} + +static int disregardToken(const Token &t) { + int k = disregardList.size(); + while (k--) { + Token disregardToken = disregardList[k]; + if (t == disregardToken) { + return 1; + } + AgArray<Token> &list = disregardToken->leadingTokenList; + int n = list.size(); + while (n--) { + if (t == list[n]) { + return 1; + } + } + } + return 0; +} + +void rlalr(void) { + LOGSECTION("rlalr"); + unsigned f, k, n, s; + int flag; + int nf; + unsigned nt; + int *q, nq; + unsigned *p, *px; + int no_default; + tsd *spr = init_tsd(2); + tsd *sps = init_tsd(2); + tsd *discardedReductions = init_tsd(2); + int crc; /* conflict resolution count */ + tsd *resolved_tokens = init_tsd(1); + unsigned char *stf = (unsigned char *) alloca(ntkns+1); + + + purge_ts = local_array(1,tsd); + no_default = error_token != 0 || + !default_reductions || + traditional_engine; + check_size(previous_states_list, n_gotos, n_gotos); + ivgtt(); + + if (key_list_dict != NULL) { + reset_list_dict(key_list_dict); + } + else { + key_list_dict = null_list_dict(); + } + add_list_dict(zeros, 0, key_list_dict); + + for (kits = 0; kits < nits; kits++) { + LOGV(kits) LCV(nits); + state_number_map *sp = &map_state_number[kits]; + int sticky = sp->sticky; + int error_state = 0; + + items = (unsigned *) dict_str(isht_dict, kits); + f = items[1]; + n = items[2]; + if (n > 0 && Rule(f).token(n-1) == Token(error_token)) { + error_state = 1; + } + crc = 0; + reset_tsd(sgt); + memset(tut, 0, sizeof(*tut) * (ntkns+1)); + LOGS("tut zeroed"); + bsgt(); + if (tut[error_token]) { + error_state = 1; + } + if ((nf = sp->n_completed_forms) == 0) { + { + int n1, n2; + n1 = sp->n_gotos; + n2 = sp->n_chain_gotos; + nt = max(n1,n2); + n1 = sp->n_completions; + n2 = sp->n_chain_completions; + nt += max(n1,n2) + 1; + } + iws(); + find_key_tokens(sgt->sb, sgt->nt,3); + k = tis(); + if (k) { + k = add_list_dict(list_base, k, key_list_dict); + } + rws(); + sp->key_list = k; + continue; + } + reset_tsd(srt); + kfrs = nf; + n = nf; + px = lstptr(*sp, completed_forms); + flag = 0; + int noDefaultOnNullProduction = 0; + while (n-- && (flag == 0)) { + Rule rule(frs = f = *px++); + RuleDescriptor &ruleDescriptor(rule); + + flag = traditional_engine || error_state || !default_reductions; + if (flag) break; + //flag = noDefaultOnNullProduction = (nf == 1) && rule->length() == 0; + flag = noDefaultOnNullProduction = + (nf == 1) && ruleDescriptor.length() == 0; + if (flag) { + break; + } + //reduce_proc_flag = flag = rule->proc_name && !rule->immediate_proc; + reduce_proc_flag = flag = + ruleDescriptor.proc_name && !ruleDescriptor.immediate_proc; + /*|| noise_token; */ + if ((no_default && reduce_proc_flag)) { + break; + } + + find_followers(f); + p = (unsigned *) list_base; + nt = rws(); + while (nt--) { + s = *p++; + if ((int) s == error_token) { + continue; + } + at(srt, s, f); + if (map_token_number[s].key || tut[s]) { + flag++; + break; + } + else { + tut[s] = (char) -1; + LOGV(tut[s]) LCV(s); + } + } + } + if (flag) { + LOGSECTION("Detailed resolution"); + LOGV(noDefaultOnNullProduction); + flag = crc = 0; + memset(stf, 0, sizeof(*stf) * (ntkns+1)); + memset(tut,0,sizeof(*tut) * (ntkns+1)); + LOGS("tut zeroed") LCV(ntkns); + LOGV(tut[16]); + p = (unsigned *) sgt->sb; + nt = sgt->nt; + while (nt--){ + s = *p; + assert(s <= ntkns); + tut[s]++; + LOGV(tut[s]) LCV(s); + stf[s]++; + p += 3; + } + LOGV(tut[16]); + reset_tsd(srt); + iws(); /* for list of tokens which have conflicts */ + unsigned *unsortedForms = lstptr(*sp, completed_forms); + unsigned *sortedForms = local_array(nf, unsigned); + memcpy(sortedForms, unsortedForms, nf*sizeof(unsigned)); + int i, j; + for (i = 0; i < nf; i++) { + for (j = i+1; j < nf; j++) { + if (sortedForms[i] > sortedForms[j]) { + unsigned temp = sortedForms[i]; + sortedForms[i] = sortedForms[j]; + sortedForms[j] = temp; + } + } + } + LOGV(tut[16]); + px = sortedForms; + while (nf--) { + int fpl; + int fra; + Rule rule(frs = f = *px++); + RuleDescriptor &ruleDescriptor(rule); + completed_form_map *mcf; + + fpl = ruleDescriptor.precedence_level; + fra = ruleDescriptor.right_associative; + + k = add_tuple_dict_new(completed_form_dict, kits, f); + check_size(map_completed_form, k, k*(nits+1)/(kits+1)); + mcf = &map_completed_form[k]; + if (mcf->reduction_states_index == 0) { + unsigned nrs; + extern int external_reduction; + + frss12(kits, f, ruleDescriptor.length()); + mcf = &map_completed_form[k]; + mcf->external_reduction = external_reduction; + resize(reduction_states_list, tis()); + mcf->reduction_states_index = store_list(reduction_states_list); + nrs = rws(); + mcf->n_reduction_states = nrs; + } + LOGV(mcf->reduction_states_index); + if (mcf->reduction_states_index == 0) { + if(sit(srt, 0, f)) { + continue; + } + s = 0; + if (tut[s] > 0) { + tut[s] = - tut[s]; + LOGV(s) LCV(tut[s]); + xws(s); + flag++; + continue; + } + else if (tut[s] < 0) { + continue; + } + tut[s]++; + LOGV(s) LCV(tut[s]); + continue; + } + p = lstptr(*mcf,reduction_states); + nt = mcf->n_reduction_states; + LOGV(f) LCV(nt); + iws(); + while (nt--) { + int sn = *p++; + state_number_map *msn = &map_state_number[sn]; + LOGV(sn); + if (sn == 0) { + xws(0); + } + else { + find_terminals(msn); + if (tis() == 0 && mcf->external_reduction) { + xws(0); + } + } + } +#ifdef INCLUDE_LOGGING + LOGS("terminals"); + for (int i = 0; i < tis(); i++) { + LOGV(i) LCV(list_base[i]) LCV(tut[list_base[i]]); + } +#endif + { + int *terminals; + q = terminals = build_list(); + nq = fis(); + if (nq == 0) { + continue; + } + while (nq--) { + int sk; + + s = *q++; + LOGV(s) LCV(tut[s]); + if ((int) s == error_token) { + continue; + } + sk = map_token_number[s].key; + LOGV(sk) LCV(sticky) LCV(distinguish_lexemes) + LCV(disregard_skip_rule); + LOGV(f) LCV(map_form_number[f].lexical); + if (sk && !map_token_number[s].lexical && ( + sticky || ( + //!map_token_number[s].lexical && + distinguish_lexemes && (f == disregard_skip_rule + || map_form_number[f].lexical) + //) // || map_form_number[f].lexical) + ) + ) + ) + { + int c = *(unsigned char *) Keyword(sk)->string.pointer(); + assert(c >= min_char_number); + int t = map_char_number[c - min_char_number].token_number; + LOGV(c) LCV(t) LCV(stf[t]); + if (stf[t]) continue; + } + if (sit(srt,s,f)) continue; + LOGV(s) LCV(tut[s]); + if (tut[s] > 0) { + int spl = map_token_number[s].precedence_level; + //int sla = map_token_number[s].left_associative; + //int sra = map_token_number[s].right_associative; + if (sticky || (fpl && spl)) { + if (sticky || spl > fpl || (fra && spl == fpl)) { + /* shift */ + LOGS("Shift") LCV(s) LCV(f); + at(sps, s, f); + } + else { + LOGS("Reduce") LCV(s) LCV(f); + /* reduce */ + at(spr,s,f); + } + at(resolved_tokens, s); + crc++; + continue; + } +/* + // not clear whether this should be done + else if (sla) { + LOGS("Shift -- left associative") LCV(s) LCV(f); + at(sps, s, f); + at(resolved_tokens, s); + crc++; + continue; + } + else if (sra) { + LOGS("Reduce -- right associative") LCV(s) LCV(f); + // reduce + at(spr, s, f); + at(resolved_tokens, s); + crc++; + continue; + } +*/ + else if (disregardToken(s)) { + if (f == disregard_skip_rule) { + //LOGS("Reduce") LCV(s) LCV(f); + //at(spr, s, f); /* reduce */ + LOGS("Shift") LCV(s) LCV(f); + at(sps, s, f); /*shift */ + at(resolved_tokens, s); + crc++; + continue; + } + else if (f == disregard_cont_rule + || map_form_number[f].lexical) { + LOGS("Shift") LCV(s) LCV(f); + at(sps, s, f); /*shift */ + at(resolved_tokens, s); + crc++; + continue; + } + } + + else if (distinguish_lexemes && //!map_token_number[s].lexical && + (f == disregard_skip_rule + || map_form_number[f].lexical)) + { + LOGV(s) LCV(f); + LOGS("Shift") LCV(s) LCV(f); + at(sps, s, f); /* shift */ + continue; + } + xws(s); + at(discardedReductions, s, f); + LOGS("Discarding reduction") LCV(s) LCV(f); + flag++; + continue; + } + else if (tut[s] < 0) { + xws(s); + at(discardedReductions, s, f); + LOGS("Discarding reduction") LCV(s) LCV(f); + flag++; + continue; + } + else { + tut[s] = -1; // Assert this is a reducing token + LOGV(s) LCV(tut[s]); + } + } + DEALLOCATE(terminals); + } + } + if (flag) { + logcon(unres_con, list_base, tis()); + } + rws(); + } + if (crc) { + logcon(res_con, resolved_tokens->sb, resolved_tokens->nt); + purge_tsd(srt, sps); + purge_gotos(spr); + log_prr(sps, spr); + reset_tsd(spr); + reset_tsd(sps); + } + if (sps->nt) { + purge_tsd(srt, sps); + reset_tsd(sps); + } + if (discardedReductions->nt) { + purge_tsd(srt, discardedReductions); + reset_tsd(discardedReductions); + } + reset_tsd(resolved_tokens); + iws(); + find_key_tokens(sgt->sb, sgt->nt, 3); + find_key_tokens(srt->sb, srt->nt, 2); + k = tis(); + if (k) { + k = add_list_dict(list_base, k, key_list_dict); + } + sp->key_list = k; + rws(); + if (error_state || (no_default && reduce_proc_flag) || + !default_reductions || + noDefaultOnNullProduction || + traditional_engine || + kfrs != 1) { + p = (unsigned *) srt->sb; + nt = srt->nt; + resize(reductions_list, nt); + sp->reductions_index = store_tuples(srt,reductions_list); + sp->n_reductions = nt; + n_reductions += nt; + } + else { + n_default_reductions++; + } + { + int n1, n2; + n1 = sp->n_gotos; + n2 = sp->n_chain_gotos; + nt = max(n1, n2); + n1 = sp->n_completions; + n2 = sp->n_chain_completions; + nt += max(n1, n2) + 1; + } + nt += sp->n_reductions; + } + LOGS("rlalr state loop complete"); + LOGV(previous_states_list[0]); + previous_states_list = reset_list(previous_states_list, + previous_states_list[0]); + ivgtt(); + delete_tsd(resolved_tokens); + delete_tsd(spr); + delete_tsd(sps); + delete_tsd(discardedReductions); + //close_list_dict(key_list_dict); + //LOGS("list dict closed"); +} +