Mercurial > ~dholland > hg > ag > index.cgi
view anagram/agcore/rpz.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 | 607e3be6bad8 |
children |
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. * * 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; } n->token_number = Token::create(); tn = n->token_number; 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()) { keyword->token_number = Token::create(); Token token = keyword->token_number; 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(); }