git-svn-id: svn://db.shs.com.ru/pip@592 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2018-02-09 21:44:38 +00:00
parent 9a1c5deadd
commit 9017861eb0
5 changed files with 194 additions and 30 deletions

View File

@@ -84,14 +84,18 @@ PICodeParser::PICodeParser() {
void PICodeParser::parseFile(const PIString & file, bool follow_includes) {
clear();
parseFileInternal(file, follow_includes);
/*piForeachC (Entity * c, entities) {
/*piCout << "\n\n";
piForeachC (Entity * c, entities) {
piCout << "";
piCout << c->type << c->name << c->parent_scope << c->parents << c->children;
piCout << c->type << c->name << c->parent_scope << c->parents << c->children << c->meta;
if (c->parent_scope)
piCout << "parent" << c->parent_scope->name;
piForeachC (Member & m, c->members) {
piCout << m.type << m.name;
}
piCout << "Functions:";
piForeachC (Member & m, c->functions)
piCout << m.type << m.name << m.meta;
piCout << "Members:";
piForeachC (Member & m, c->members)
piCout << m.type << m.name << m.meta;
}
piCout << "\n\nDefines:";
piForeachC (Define & m, defines)
@@ -100,11 +104,12 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) {
piForeachC (Macro & m, macros)
piCout << "Macro:" << m.name << m.args << m.value;
piCout << "\n\nClasses:";
piForeachC (Entity * c, entities)
piCout << "class" << c->name << c->parents;
piCout << "\n\nEnums:";
piForeachC (Enum & c, enums)
piCout << "enum" << c.name << c.members;
piForeachC (Enum & c, enums) {
piCout << "enum" << c.name << c.meta;
piForeachC (EnumeratorInfo & e, c.members)
piCout << " " << e.name << "=" << e.value << e.meta;
}
piCout << "\n\nTypedefs:";
piForeachC (Typedef & c, typedefs)
piCout << "typedef" << c;*/
@@ -223,6 +228,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
}
//piCout << fc;
pfc = procMacros(fc);
replaceMeta(pfc);
if (main) return true;
@@ -299,7 +306,9 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
if (pfc.left(4) == "enum") {
pfc.cutLeft(4);
tmp = pfc.takeCWord();
parseEnum(0, cur_namespace + tmp, pfc.takeRange("{", "}"));
pfc.trim();
MetaMap meta = maybeMeta(pfc);
parseEnum(0, cur_namespace + tmp, pfc.takeRange("{", "}"), meta);
pfc.takeSymbol();
continue;
}
@@ -332,8 +341,14 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) {
PIString cd = fc.trimmed().removeAll('\n').replaceAll("\t", " ").replaceAll(" ", " "), pn;
MetaMap meta;
int ind = cd.find("$M");
if (ind >= 0) {
meta = tmp_meta.value(cd.takeMid(ind, 5));
cd.replaceAll(" ", " ");
}
//piCout << "found class <****\n" << cd << "\n****>";
int ind = cd.find(":");
ind = cd.find(":");
PIVector<Entity * > parents;
if (ind > 0) {
PIStringList pl = cd.takeMid(ind + 1).trim().split(",");
@@ -356,6 +371,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
//piCout << "found " << typename_ << cn;
if (cn.isEmpty()) return 0;
Entity * e = new Entity();
e->meta = meta;
e->name = cur_namespace + cn;
e->type = typename_;//(is_class ? "class" : "struct");
e->has_name = has_name;
@@ -403,7 +419,14 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
parseClass(ce, stmp);
continue;
}
if (cw == "enum") {tmp = fc.takeCWord(); parseEnum(ce, cur_namespace + tmp, fc.takeRange("{", "}")); fc.takeSymbol(); continue;}
if (cw == "enum") {
tmp = fc.takeCWord();
fc.trim();
MetaMap meta = maybeMeta(fc);
parseEnum(ce, cur_namespace + tmp, fc.takeRange("{", "}"), meta);
fc.takeSymbol();
continue;
}
if (cw == "friend") {fc.cutLeft(fc.find(";") + 1); continue;}
if (cw == "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 == "template") {
@@ -429,17 +452,41 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
}
bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc) {
PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) {
PICodeParser::MetaMap ret;
if (fc.isEmpty()) return ret;
PIStringList ml = fc.split(",");
piForeachC (PIString & m, ml) {
int i = m.find("=");
if (i < 0) continue;
PIString mv = m.mid(i + 1).trim();
if (mv.startsWith("\"")) mv.cutLeft(1);
if (mv.endsWith("\"")) mv.cutRight(1);
ret[m.left(i).trim()] = mv;
}
//piCout << ms << ret;
return ret;
}
bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta) {
//piCout << "enum" << name << fc;
Enum e(name);
e.meta = meta;
PIStringList vl(fc.split(","));
PIString vn;
int cv = -1, ind = 0;
piForeachC (PIString & v, vl) {
piForeach (PIString & v, vl) {
MetaMap meta;
int mi = v.find("$M");
if (mi >= 0) {
meta = tmp_meta.value(v.takeMid(mi, 5));
v.replaceAll(" ", " ");
}
vn = v; ind = v.find("=");
if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);}
if (ind < 0) ++cv;
e.members << EnumeratorInfo(vn.trim(), cv);
e.members << EnumeratorInfo(vn.trim(), cv, meta);
}
if (!e.members.isEmpty())
if (e.members.back().name.isEmpty())
@@ -478,22 +525,30 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
while (ts >= 0) {
ctemp = fc.mid(ts).takeRange("<", ">");
if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find("<", te); continue;}
crepl = "$" + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, "0");
crepl = "$T" + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, "0");
fc.replace(ts, ctemp.size_s() + 2, crepl);
tmp_temp[crepl] = "<" + ctemp + ">";
ts = fc.find("<", te);
}
fc.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ").replaceAll(", ", ",");
fc.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ").replaceAll(", ", ",").replaceAll(" $M", "$M");
//piCout << "parse member" << fc;
PIStringList tl, al;
Member me;
//piCout << fc;
if (fc.contains("(")) {
MetaMap meta;
int ind = fc.find("$M");
if (ind >= 0) {
meta = tmp_meta.value(fc.takeMid(ind, 5));
fc.replaceAll(" ", " ");
}
fc.cutRight(fc.size_s() - fc.findLast(")") - 1);
te = fc.find("(");
//piCout << fc;
for (ts = te - 1; ts >= 0; --ts)
if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break;
//piCout << "takeMid" << ts + 1 << te - ts - 1;
me.meta = meta;
me.name = fc.takeMid(ts + 1, te - ts - 1);
if (me.name == parent->name) return true;
me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(",");
@@ -542,17 +597,21 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
if (fc.startsWith("using") || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true;
int bits = extractMemberBits(fc);
tl = fc.split(",");
//piCout << "member" << fc;
//piCout << "member" << fc << tl;
//piCout << "member after eb" << fc << ", bits =" << bits;
if (tl.isEmpty()) return true;
bool vn = true;
ctemp = tl.front();
ctemp = tl.front().trim();
PIString meta_t;
if (ctemp.contains("$M"))
meta_t = ctemp.takeMid(ctemp.find("$M"));
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;}
}
me.type = ctemp.takeLeft(ts + 1);
me.visibility = cur_def_vis;
ctemp += meta_t;
restoreTmpTemp(&me);
PIString type = " " + me.type;
if (type.find(" const ") >= 0) {
@@ -580,8 +639,10 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
tl[0] = ctemp.trim();
piForeachC (PIString & v, tl) {
crepl.clear();
me.name = v.trimmed();
me.type = type;
restoreTmpMeta(&me);
if (me.name.isEmpty()) continue;
if (me.name.contains("["))
crepl = me.name.takeMid(me.name.find("["), me.name.findLast("]") - me.name.find("[") + 1);
@@ -669,15 +730,32 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
void PICodeParser::restoreTmpTemp(Member * e) {
int i = 0;
piForeach (PIString & a, e->arguments_full) {
while ((i = a.find("$")) >= 0)
a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
while ((i = a.find("$T")) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
}
piForeach (PIString & a, e->arguments_type) {
while ((i = a.find("$")) >= 0)
a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
while ((i = a.find("$T")) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
}
while ((i = e->type.find("$")) >= 0)
e->type.replace(i, 4, tmp_temp[e->type.mid(i, 4)]);
while ((i = e->type.find("$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("$M");
if (i < 0) return;
e->meta = tmp_meta[e->name.takeMid(i, 5)];
}
PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) {
PICodeParser::MetaMap ret;
if (fc.left(2) == "$M") {
ret = tmp_meta.value(fc.takeLeft(5));
fc.trim();
}
return ret;
}
@@ -751,6 +829,24 @@ double PICodeParser::defineValue(const PIString & dn) {
}
void PICodeParser::replaceMeta(PIString & dn) {
tmp_meta.clear();
if (dn.isEmpty()) return;
int s = dn.find("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 = "$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("PIMETA");
}
}
PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
piForeach (Entity * e, entities)
if (e->name == en)