PICodeParser optimizations and improvements with PIMETA()

This commit is contained in:
2021-04-29 17:17:27 +03:00
parent 5304b21838
commit 438b4a6bce
2 changed files with 118 additions and 64 deletions

View File

@@ -194,6 +194,16 @@ void PICodeParser::clear() {
bool PICodeParser::parseFileContent(PIString & fc, bool main) {
static const PIString s_bo = PIStringAscii("{\n");
static const PIString s_bc = PIStringAscii("\n}\n");
static const PIString s_class = PIStringAscii("class");
static const PIString s_struct = PIStringAscii("struct");
static const PIString s_union = PIStringAscii("union");
static const PIString s_enum = PIStringAscii("enum");
static const PIString s_typedef = PIStringAscii("typedef");
static const PIString s_namespace = PIStringAscii("namespace");
static const PIString s_template = PIStringAscii("template");
bool mlc = false, cc = false;
int mls = 0, ole = -1, /*ccs = 0,*/ end = 0;
char c = 0, pc = 0;
@@ -277,11 +287,11 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
int nl = pfc.size_s();
if (pl == nl) break;
pl = nl;
if (pfc.left(9) == PIStringAscii("namespace")) {
if (pfc.left(9) == s_namespace) {
pfc.cutLeft(pfc.find('{') + 1);
continue;
}
if (pfc.left(8) == PIStringAscii("template")) {
if (pfc.left(8) == s_template) {
pfc.cutLeft(8);
pfc.takeRange('<', '>');
bool def = !isDeclaration(pfc, 0, &end);
@@ -290,16 +300,16 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
else pfc.takeSymbol();
continue;
}
if (pfc.left(5) == PIStringAscii("class") || pfc.left(6) == PIStringAscii("struct") || pfc.left(5) == PIStringAscii("union")) {
if (pfc.left(5) == s_class || pfc.left(6) == s_struct || pfc.left(5) == s_union) {
int dind = pfc.find('{', 0), find = pfc.find(';', 0);
if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;}
if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;}
ccmn = pfc.left(dind) + PIStringAscii("{\n") + pfc.mid(dind).takeRange('{', '}') + PIStringAscii("\n}\n");
ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc;
pfc.remove(0, ccmn.size());
parseClass(0, ccmn);
continue;
}
if (pfc.left(4) == PIStringAscii("enum")) {
if (pfc.left(4) == s_enum) {
pfc.cutLeft(4);
tmp = pfc.takeCWord();
pfc.trim();
@@ -308,7 +318,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
pfc.takeSymbol();
continue;
}
if (pfc.left(7) == PIStringAscii("typedef")) {
if (pfc.left(7) == s_typedef) {
pfc.cutLeft(7);
typedefs << parseTypedef(pfc.takeLeft(pfc.find(';')));
if (typedefs.back().first.isEmpty()) typedefs.pop_back();
@@ -336,12 +346,15 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) {
PIString cd = fc.trimmed().removeAll('\n').replaceAll('\t', ' ').replaceAll(PIStringAscii(" "), ' '), pn;
static const PIString s_ss = PIStringAscii(" ");
static const PIString s_M = PIStringAscii("$M");
static const PIString s_class = PIStringAscii("class");
PIString cd = fc.trimmed().removeAll('\n').replaceAll('\t', ' ').replaceAll(s_ss, ' '), pn;
MetaMap meta;
int ind = cd.find(PIStringAscii("$M"));
int ind = cd.find(s_M);
if (ind >= 0) {
meta = tmp_meta.value(cd.takeMid(ind, 5));
cd.replaceAll(PIStringAscii(" "), ' ');
cd.replaceAll(s_ss, ' ');
}
//piCout << "found class <****\n" << cd << "\n****>";
ind = cd.find(':');
@@ -359,7 +372,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
}
}
PIString typename_ = cd.left(6).trim();
bool is_class = typename_ == PIStringAscii("class");
bool is_class = typename_ == s_class;
cur_def_vis = (is_class ? Private : Public);
PIString cn = cd.mid(6).trim();
bool has_name = !cn.isEmpty();
@@ -379,6 +392,17 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
static const PIString s_ns = PIStringAscii("::");
static const PIString s_public = PIStringAscii("public");
static const PIString s_protected = PIStringAscii("protected");
static const PIString s_private = PIStringAscii("private");
static const PIString s_class = PIStringAscii("class");
static const PIString s_struct = PIStringAscii("struct");
static const PIString s_union = PIStringAscii("union");
static const PIString s_enum = PIStringAscii("enum");
static const PIString s_friend = PIStringAscii("friend");
static const PIString s_typedef = PIStringAscii("typedef");
static const PIString s_template = PIStringAscii("template");
Visibility prev_vis = cur_def_vis;
int dind = fc.find('{'), find = fc.find(';'), end = 0;
if (dind < 0 && find < 0) return PIString();
@@ -393,16 +417,16 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
int ps = -1;
bool def = false;
PIString prev_namespace = cur_namespace, stmp;
cur_namespace = ce->name + PIStringAscii("::");
cur_namespace = ce->name + s_ns;
//piCout << "parse class" << ce->name << "namespace" << cur_namespace;
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
while (!fc.isEmpty()) {
PIString cw = fc.takeCWord(), tmp;
//piCout << "\ntaked word" << cw;
if (cw == PIStringAscii("public" )) {cur_def_vis = Public; fc.cutLeft(1); continue;}
if (cw == PIStringAscii("protected")) {cur_def_vis = Protected; fc.cutLeft(1); continue;}
if (cw == PIStringAscii("private" )) {cur_def_vis = Private; fc.cutLeft(1); continue;}
if (cw == PIStringAscii("class") || cw == PIStringAscii("struct") || cw == PIStringAscii("union")) {
if (cw == s_public ) {cur_def_vis = Public; fc.cutLeft(1); continue;}
if (cw == s_protected) {cur_def_vis = Protected; fc.cutLeft(1); continue;}
if (cw == s_private ) {cur_def_vis = Private; fc.cutLeft(1); continue;}
if (cw == s_class || cw == s_struct || cw == s_union) {
if (isDeclaration(fc, 0, &end)) {
fc.cutLeft(end);
fc.takeSymbol();
@@ -415,7 +439,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
parseClass(ce, stmp);
continue;
}
if (cw == PIStringAscii("enum")) {
if (cw == s_enum) {
tmp = fc.takeCWord();
fc.trim();
MetaMap meta = maybeMeta(fc);
@@ -423,9 +447,17 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
fc.takeSymbol();
continue;
}
if (cw == PIStringAscii("friend")) {fc.cutLeft(fc.find(';') + 1); continue;}
if (cw == PIStringAscii("typedef")) {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';'))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;}
if (cw == PIStringAscii("template")) {
if (cw == s_friend) {fc.cutLeft(fc.find(';') + 1); continue;}
if (cw == s_typedef) {
ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';')));
typedefs << ce->typedefs.back();
typedefs.back().first.insert(0, cur_namespace);
if (ce->typedefs.back().first.isEmpty())
ce->typedefs.pop_back();
fc.takeSymbol();
continue;
}
if (cw == s_template) {
fc.takeRange('<', '>');
def = !isDeclaration(fc, 0, &end);
fc.cutLeft(end);
@@ -522,24 +554,24 @@ void removeAssignment(PIString & s) {
}
bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
static const PIString s_operator = PIStringAscii("operator");
static const PIString s_ss = PIStringAscii(" ");
static const PIString s_cs = PIStringAscii(", ");
static const PIString s_sb = PIStringAscii(" (");
static const PIString s_sM = PIStringAscii(" $M");
static const PIString s_M = PIStringAscii("$M");
static const PIString s_T = PIStringAscii("$T");
static const PIString s_inline_s = PIStringAscii("inline ");
static const PIString s_static_s = PIStringAscii("static ");
static const PIString s_virtual_s = PIStringAscii("virtual ");
static const PIString s_void = PIStringAscii("void");
static const PIString s_using = PIStringAscii("using");
static const PIString s_s5 = PIStringAscii(" ");
static const PIString s_s_const_s = PIStringAscii(" const ");
static const PIString s_s_static_s = PIStringAscii(" static ");
static const PIString s_s_mutable_s = PIStringAscii(" mutable ");
static const PIString s_operator = PIStringAscii("operator");
static const PIString s_ss = PIStringAscii(" ");
static const PIString s_cs = PIStringAscii(", ");
static const PIString s_sb = PIStringAscii(" (");
static const PIString s_sM = PIStringAscii(" $M");
static const PIString s_M = PIStringAscii("$M");
static const PIString s_T = PIStringAscii("$T");
static const PIString s_inline_s = PIStringAscii("inline ");
static const PIString s_static_s = PIStringAscii("static ");
static const PIString s_virtual_s = PIStringAscii("virtual ");
static const PIString s_void = PIStringAscii("void");
static const PIString s_using = PIStringAscii("using");
static const PIString s_s5 = PIStringAscii(" ");
static const PIString s_s_const_s = PIStringAscii(" const ");
static const PIString s_s_static_s = PIStringAscii(" static ");
static const PIString s_s_mutable_s = PIStringAscii(" mutable ");
static const PIString s_s_volatile_s = PIStringAscii(" volatile ");
static const PIString s_s_extern_s = PIStringAscii(" extern ");
static const PIString s_s_extern_s = PIStringAscii(" extern ");
if (fc.trim().isEmpty()) return true;
if (fc.find(s_operator) >= 0) return true;
@@ -631,8 +663,10 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
bool vn = true;
ctemp = tl.front().trim();
PIString meta_t;
if (ctemp.contains(s_M))
meta_t = ctemp.takeMid(ctemp.find(s_M));
if (ctemp.contains(s_M)) {
meta_t = ctemp.takeMid(ctemp.find(s_M), 5);
ctemp.trim();
}
for (ts = ctemp.size_s() - 1; ts > 0; --ts) {
if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;}
else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;}
@@ -710,10 +744,10 @@ int PICodeParser::extractMemberBits(PIString & fc) {
void PICodeParser::normalizeEntityNamespace(PIString & n) {
static const PIString s_const_s = PIStringAscii("const ");
static const PIString s_static_s = PIStringAscii("static ");
static const PIString s_mutable_s = PIStringAscii("mutable ");
static const PIString s_volatile_s = PIStringAscii("volatile ");
static const PIString s_const_s = PIStringAscii("const ");
static const PIString s_static_s = PIStringAscii("static ");
static const PIString s_mutable_s = PIStringAscii("mutable ");
static const PIString s_volatile_s = PIStringAscii("volatile ");
static const PIString s_s_const_s = PIStringAscii(" const ");
static const PIString s_s_static_s = PIStringAscii(" static ");
static const PIString s_s_mutable_s = PIStringAscii(" mutable ");
@@ -767,30 +801,33 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
void PICodeParser::restoreTmpTemp(Member * e) {
static const PIString s_T = PIStringAscii("$T");
int i = 0;
piForeach (PIString & a, e->arguments_full) {
while ((i = a.find(PIStringAscii("$T"))) >= 0)
while ((i = a.find(s_T)) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
}
piForeach (PIString & a, e->arguments_type) {
while ((i = a.find(PIStringAscii("$T"))) >= 0)
while ((i = a.find(s_T)) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
}
while ((i = e->type.find(PIStringAscii("$T"))) >= 0)
while ((i = e->type.find(s_T)) >= 0)
e->type.replace(i, 5, tmp_temp[e->type.mid(i, 5)]);
}
void PICodeParser::restoreTmpMeta(PICodeParser::Member * e) {
int i = e->name.find(PIStringAscii("$M"));
static const PIString s_M = PIStringAscii("$M");
int i = e->name.find(s_M);
if (i < 0) return;
e->meta = tmp_meta[e->name.takeMid(i, 5)];
}
PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) {
static const PIString s_M = PIStringAscii("$M");
PICodeParser::MetaMap ret;
if (fc.left(2) == PIStringAscii("$M")) {
if (fc.left(2) == s_M) {
ret = tmp_meta.value(fc.takeLeft(5));
fc.trim();
}
@@ -799,10 +836,14 @@ PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) {
bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) {
static const PIString s_ifdef = PIStringAscii("ifdef");
static const PIString s_ifndef = PIStringAscii("ifndef");
static const PIString s_if = PIStringAscii("if");
static const PIString s_elif = PIStringAscii("elif");
//piCout << "macroCondition" << mif << mifcond;
if (mif == PIStringAscii("ifdef")) return isDefineExists(mifcond);
if (mif == PIStringAscii("ifndef")) return !isDefineExists(mifcond);
if (mif == PIStringAscii("if") || mif == PIStringAscii("elif")) {
if (mif == s_ifdef) return isDefineExists(mifcond);
if (mif == s_ifndef) return !isDefineExists(mifcond);
if (mif == s_if || mif == s_elif) {
mifcond.removeAll(' ').removeAll('\t');
return procMacrosCond(mifcond) > 0.;
}
@@ -811,12 +852,13 @@ bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) {
double PICodeParser::procMacrosCond(PIString fc) {
static const PIString s_defined = PIStringAscii("defined");
bool neg = false, first = true, br = false;
double ret = 0., brv = 0.;
int oper = 0, ps = -1;
char cc, nc;
PIString ce;
fc.removeAll(PIStringAscii("defined"));
fc.removeAll(s_defined);
//piCout << "procMacrosCond" << fc;
while (!fc.isEmpty()) {
cc = fc[0].toAscii();
@@ -869,19 +911,21 @@ double PICodeParser::defineValue(const PIString & dn) {
void PICodeParser::replaceMeta(PIString & dn) {
static const PIString s_PIMETA = PIStringAscii("PIMETA");
static const PIString s_M = PIStringAscii("$M");
tmp_meta.clear();
if (dn.isEmpty()) return;
int s = dn.find(PIStringAscii("PIMETA"));
int s = dn.find(s_PIMETA);
while (s >= 0) {
int ms = 0, ml = 0;
ms = dn.findRange('(', ')', '\\', s + 6, &ml);
if (ms < 0) return;
PIString meta = dn.mid(ms, ml).trim();
PIString rm = PIStringAscii("$M") + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, '0');
PIString rm = s_M + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, '0');
dn.replace(s, ms + ml + 1 - s, rm);
//piCout << "FOUND META \"" << meta << '\"';
tmp_meta[rm] = parseMeta(meta);
s = dn.find(PIStringAscii("PIMETA"));
s = dn.find(s_PIMETA);
}
}
@@ -926,6 +970,12 @@ bool PICodeParser::isMainFile(const PIString & fc) {
PIString PICodeParser::procMacros(PIString fc) {
static const PIString s_ifdef = PIStringAscii("ifdef");
static const PIString s_ifndef = PIStringAscii("ifndef");
static const PIString s_if = PIStringAscii("if");
static const PIString s_elif = PIStringAscii("elif");
static const PIString s_else = PIStringAscii("else");
static const PIString s_endif = PIStringAscii("endif");
if (fc.isEmpty()) return PIString();
int ifcnt = 0;
bool grab = false, skip = false, cond_ok = false;
@@ -940,8 +990,8 @@ PIString PICodeParser::procMacros(PIString fc) {
//piCout << mif;
//piCout << "mif mifcond" << mif << mifcond << ifcnt;
if (skip || grab) {
if (mif.left(2) == PIStringAscii("if")) ifcnt++;
if (mif.left(5) == PIStringAscii("endif")) {
if (mif.left(2) == s_if) ifcnt++;
if (mif.left(5) == s_endif) {
if (ifcnt > 0) ifcnt--;
else {
//piCout << "main endif" << skip << grab;
@@ -950,7 +1000,7 @@ PIString PICodeParser::procMacros(PIString fc) {
continue;
}
}
if (mif.left(4) == PIStringAscii("elif") && ifcnt == 0) {
if (mif.left(4) == s_elif && ifcnt == 0) {
//piCout << "main elif" << skip << grab << cond_ok;
if (cond_ok) {
if (grab) {
@@ -968,7 +1018,7 @@ PIString PICodeParser::procMacros(PIString fc) {
}
continue;
}
if (mif.left(4) == PIStringAscii("else") && ifcnt == 0) {
if (mif.left(4) == s_else && ifcnt == 0) {
//piCout << "main else" << skip << grab;
if (grab) pfc << procMacros(nfc);
if (skip && !cond_ok) {skip = false; grab = true;}
@@ -978,7 +1028,7 @@ PIString PICodeParser::procMacros(PIString fc) {
if (grab) nfc << line << '\n';
continue;
}
if (mif.left(2) == PIStringAscii("if")) {
if (mif.left(2) == s_if) {
//piCout << "main if";
skip = grab = cond_ok = false;
if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true;
@@ -999,10 +1049,14 @@ PIString PICodeParser::procMacros(PIString fc) {
bool PICodeParser::parseDirective(PIString d) {
static const PIString s_include = PIStringAscii("include");
static const PIString s_define = PIStringAscii("define");
static const PIString s_undef = PIStringAscii("undef");
static const PIString s_PIMETA = PIStringAscii("PIMETA");
if (d.isEmpty()) return true;
PIString dname = d.takeCWord();
//piCout << "parseDirective" << d;
if (dname == PIStringAscii("include")) {
if (dname == s_include) {
d.replaceAll('<', '\"').replaceAll('>', '\"');
PIString cf = cur_file, ifc = d.takeRange('\"', '\"');
if (with_includes) {
@@ -1011,10 +1065,10 @@ bool PICodeParser::parseDirective(PIString d) {
return ret;
}
}
if (dname == PIStringAscii("define")) {
if (dname == s_define) {
PIString mname = d.takeCWord();
//piCout << mname;
if (mname == PIStringAscii("PIMETA")) return true;
if (mname == s_PIMETA) return true;
if (d.left(1) == PIChar('(')) { // macro
PIStringList args = d.takeRange('(', ')').split(',').trim();
macros << Macro(mname, d.trim(), args);
@@ -1025,7 +1079,7 @@ bool PICodeParser::parseDirective(PIString d) {
}
return true;
}
if (dname == PIStringAscii("undef")) {
if (dname == s_undef) {
PIString mname = d.takeCWord();
for (int i = 0; i < defines.size_s(); ++i)
if (defines[i].first == mname) {defines.remove(i); --i;}