Mercurial > ~dholland > hg > ag > index.cgi
view anagram/agcore/cd.cpp @ 7:57b2cc9b87f7
Use memcpy instead of strncpy when we know the length anyway.
Modern gcc seems to think it knows how to detect misuse of strncpy,
but it's wrong (in fact: very, very wrong) and the path of least
resistance is to not try to fight with it.
author | David A. Holland |
---|---|
date | Mon, 30 May 2022 23:47:52 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * AnaGram, A System for Syntax Directed Programming * Copyright 1993-1999 Parsifal Software. All Rights Reserved. * See the file COPYING for license and usage terms. * * cd.cpp - Conflict Derivation module */ #include "arrays.h" #include "cd.h" #include "data.h" #include "dict.h" #include "q1glbl.h" #include "rule.h" #include "stacks.h" #include "tsd.h" #include "token.h" //#define INCLUDE_LOGGING #include "log.h" int conflict_token = 0; tsd *token_derivation = NULL; char *tried; int find_gotos(int s, const unsigned **p) { state_number_map *sp = &map_state_number[s]; int n = sp->n_chain_gotos; if (n == 0) { *p = lstptr(*sp, gotos); n = sp->n_gotos; } else { *p = lstptr(*sp, chain_gotos); } return n; } /* * x2 returns true if llt is an expansion token of hlt, false otherwise */ /* int x2(unsigned hlt, unsigned llt) { //LOGSECTION("x2"); //token_number_map *tp; unsigned *fl; int nf; Token token = hlt; Token candidate = llt; if (token == candidate) return 1; //LOGV(hlt); //LOGV(llt); //assert(hlt <= ntkns); //tp = &map_token_number[hlt]; //fl = lstptr(*tp, expansion_forms); //nf = tp->n_expansion_forms; nf = token->n_expansion_forms; while (nf--) { //form_number_map *fp = &map_form_number[*fl++]; Rule rule = *fl++; int k = rule->length(); if (k == 0) { continue; } //if (llt == lstptr(*fp,tokens)[0]) return 1; if (candidate == rule->token(0)) { return 1; } } return 0; } */ /* static int x2x(unsigned hlt, unsigned llt) { //token_number_map *tp; //unsigned *tl; int nt; Token highLevel(hlt); Token lowLevel(llt); if (highLevel == lowLevel) return 1; //tp = &map_token_number[hlt]; //tl = lstptr(*tp,leading_tokens); //nt = tp->n_leading_tokens; //while (nt--) if (llt == *tl++) return 1; while (nt--) if (lowLevel == highLevel->leadingToken(nt)) return 1; return 0; } */ /* * x2d checks the characteristic rules in state sn, and returns true if * tn is next token for some characteristic rule. Otherwise, return 0 */ int x2d(int sn, int tn) { int *items = dict_str(isht_dict,sn); int nitems = (*items++ -1)/2 ; while (nitems--) { Rule rule = *items++; unsigned fx = *items++; if (rule->length() <= fx) { continue; } //if (x2x(lstptr(map_form_number[fn],tokens)[fx],tn)) return 1; //if (x2x(Rule(fn)->token(fx),tn)) return 1; if (rule.token(fx).isLeadingToken(tn)) { return 1; } } return 0; } /* * x4 returns true if fn is a left expansion rule of hlt, false otherwise */ /* int x4(unsigned hlt, unsigned fn) { assert(hlt <= ntkns); token_number_map *tp = &map_token_number[hlt]; unsigned *fl = lstptr(*tp, expansion_forms); unsigned nf = tp->n_expansion_forms; assert(nf <= nforms); while (nf--) if (*fl++ == fn) return 1; return 0; } */ #ifndef COMMAND_LINE int x3(tsd *isl, int sx, int fn, int fx) { unsigned k; check_tsd(isl); assert((unsigned)fn <= nforms); sx++; for (k = 0; k < isl->nt; k++) { int fsx, fsn, ffn, ffx; xtxf(isl, k, &fsx, &fsn, &ffn, &ffx); if (fsx < sx) { return 0; } if (fsx > sx) { continue; } if (ffn == fn && ffx == fx + 1) { return 1; } if (ffx != 1) { continue; } //if (x4(lstptr(map_form_number[fn],tokens)[fx],ffn)) return 1; //if (x4(Rule(fn)->token(fx),ffn)) return 1; if (Rule(fn).token(fx).isExpansionRule(ffn)) { return 1; } } return 0; } int x3a(tsd *isl, int sx, int fn, int fx) { unsigned k; check_tsd(isl); assert((unsigned)fn <= nforms); for (k = 0; k < isl->nt; k++) { int fsx, fsn, ffn, ffx; xtxf(isl, k, &fsx, &fsn, &ffn, &ffx); if (fsx < sx) { return 0; } if (fsx > sx) { continue; } if (ffn == fn && ffx == fx) { return 0; } //if (x4(lstptr(map_form_number[fn],tokens)[fx],ffn)) return 1; //if (x4(Rule(fn)->token(fx),ffn)) return 1; if (Rule(fn).token(fx).isExpansionRule(ffn)) { return 1; } } return 0; } /* x1 builds a rule stack from a token stack */ tuple_dict *xis(unsigned sn) { tuple_dict *d = null_tuple_dict(2); int *items, nitems, length; unsigned k; assert(sn < isht_dict->nsx); items = dict_str(isht_dict, sn); length = *items++ - 1; nitems = length/2; while (nitems--) { int fn = *items++; int fx = *items++; insert_tuple_dict(d, fn, fx); } for (k = 0; k < d->nsx; k++) { int *t = d->text+2*k; int fn = *t++; unsigned fx = *t; if (fx < Rule(fn)->length()) { //unsigned tn = lstptr(map_form_number[fn],tokens)[fx]; Token token(Rule(fn).token(fx)); //token_number_map *tp = &map_token_number[tn]; //int nf = token->n_forms; int nf = token->ruleList.size(); //unsigned *fl = lstptr(*tp,forms); //unsigned *fl = token->forms(); iws(); //while (nf--) { for (int i = 0; i < nf; i++) { //form_number_map *fp = &map_form_number[*fl]; //Rule rule(*fl); Rule rule = token.rule(i); //if (fp->length && lstptr(*fp, tokens)[0] == tn) if (rule->length() && rule.token(0) == token) { //insert_tuple_dict(d,*fl, 0); insert_tuple_dict(d, (int) rule, 0); } else { aws(rule); } } unsigned *fl = (unsigned *) list_base; nf = rws(); while (nf--) { insert_tuple_dict(d, *fl++, 0); } } } return d; } #endif /* tsd *x1x(tsd *sl) { int n = sl->nt; int sx,sn,tn; unsigned fx; int *items; int nitems; tsd *isl = init_tsd(4); check_tsd(sl); sx = n-1; xtxf(sl,sx,&sn,&tn); if (!shift_token(tn,sn)) { tn = 0; } { tuple_dict *d; d = xis(sn); items = d->text; nitems = d->nsx; items += 2*nitems; while (nitems--) { fx = *--items; Rule rule = *--items; if (tn == 0 || fx >= rule->non_vanishing_length || rule.token(fx).isExpansionToken(tn)) { at(isl,sx,sn,(int) rule,fx); } } delete_tuple_dict(d); } while (sx-- > 0) { tuple_dict *d; unsigned psn = sn; const unsigned *p; int n; xtxf(sl,sx,&sn,&tn); n = find_gotos(sn, &p); p += 2*n; while (n-- && *--p != psn) { p--; } assert(*p == psn && n >= 0); d = xis(sn); items = d->text; nitems = d->nsx; items += 2*nitems; while (nitems--) { fx = *--items; Rule rule = *--items; if (fx >= rule->length()) { continue; } if (x3(isl, sx,rule,fx)) { at(isl, sx, sn, (int)rule, fx); } } delete_tuple_dict(d); } return isl; } */ int x9x(int tn) { Token token = tn; //token_number_map *tp = &map_token_number[tn]; //unsigned *fl = lstptr(*tp,forms); //int nf = token->n_forms; int nf = token->ruleList.size(); if (tn == conflict_token) { return 1; } if (tried[tn]) { return 0; } tried[tn] = 1; //while (nf--) { for (int i = 0; i < nf; i++) { //int fn = *fl++; Rule rule = token.rule(i); //form_number_map *fp = &map_form_number[fn]; int length = rule->length(); int fx = 0; while (fx < length) { //int t = lstptr(*fp,tokens)[fx]; Token ruleToken = rule.token(fx); if ((int) ruleToken == conflict_token || x9x(ruleToken)) { at(token_derivation, (int) rule, fx); return 1; } //if (!map_token_number[t].zero_length_flag) break; if (!token->zero_length_flag) { break; } fx++; } } return 0; } int new_next_state(int s, unsigned t) { LOGSECTION("new_next_state"); LOGV(s) LCV(t); Token token = t; //token_number_map *tp; int ts; int np; const unsigned *gl; int ng = find_gotos(s, &gl); const unsigned *glx = gl; int ngx = ng; //check_stack; while (ng--) { LOGV(gl[0]) LCV(gl[1]); Token token = *gl; if (*gl == t || (token->junky && (unsigned) token.rule(0).token(0) == t)) { return gl[1]; } else { gl += 2; } } LOGS("Didn't find a goto"); //tp = &map_token_number[t]; //ts = tp->token_set_id; ts = token->token_set_id; Token pureToken; LOGV(pureToken) LCV(ts); if (token->junky) { pureToken = token.rule(0).token(0); } if (ts == 0 && pureToken.isNotNull()) { ts = pureToken->token_set_id; } LOGV(pureToken) LCV(ts); np = map_char_set[ts].nparts; LOGV(np); if (ts && np > 1) { unsigned *fl = lstptr(map_char_set[ts], part); while (np--) { const unsigned *g = glx; int n = ngx; unsigned pn = fl[np]; unsigned pt = map_part_number[pn].token_number; while (n--) { if (*g++ == pt) { return *g; } else { g++; } } } } LOGS("Didn't find a partition set either"); return 0; } Token transitionToken(unsigned fromState, unsigned toState) { LOGSECTION("transitionToken"); LOGV(fromState) LCV(toState); const unsigned *gl; int nGotos = find_gotos(fromState,&gl); //const unsigned *glx = gl; int ngx = nGotos; //check_stack; while (ngx--) { LOGV(gl[0]) LCV(gl[1]); Token token = *gl; if (gl[1] == toState) { return gl[0]; } gl += 2; } LOGS("Didn't find a goto"); return Token(); }