adopt PICodeParser for C-style typedefs and some other

This commit is contained in:
2025-09-17 19:42:00 +03:00
parent 2806086558
commit af02684dc5
2 changed files with 83 additions and 19 deletions

View File

@@ -19,6 +19,8 @@
#include "picodeparser.h"
#include "piliterals_string.h"
PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
PIStringList arg_vals;
@@ -454,7 +456,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
cur_namespace += pfc.takeCWord() + s_ns;
ccmn = pfc.takeRange('{', '}');
// piCout << "namespace" << cur_namespace;
parseClass(0, ccmn, true);
parseClass(nullptr, ccmn, true);
cur_namespace = prev_namespace;
continue;
}
@@ -483,8 +485,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
continue;
}
ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc;
pfc.remove(0, ccmn.size());
parseClass(0, ccmn, false);
pfc.remove(0, ccmn.size() - 2);
parseClass(nullptr, ccmn, false);
continue;
}
if (pfc.left(4) == s_enum) {
@@ -499,17 +501,59 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
meta << smeta;
}
// piCout << "pfc E" << cur_namespace << "," << tmp;
parseEnum(0, cur_namespace + tmp, pfc.takeRange('{', '}'), meta);
parseEnum(nullptr, cur_namespace + tmp, pfc.takeRange('{', '}'), meta);
pfc.takeSymbol();
continue;
}
if (pfc.left(7) == s_typedef) {
pfc.cutLeft(7);
typedefs << parseTypedef(pfc.takeLeft(pfc.find(';')));
if (typedefs.back().first.isEmpty())
typedefs.pop_back();
else
root_.typedefs << typedefs.back();
PIString typedef_type = pfc.takeCWord();
if (typedef_type == s_class || typedef_type == s_struct || typedef_type == 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(find + 1);
continue;
}
PIString cname = pfc.left(dind);
ccmn = cname + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc;
pfc.remove(0, ccmn.size() - 3);
if (cname.trimmed().isEmpty()) {
cname = pfc.takeCWord();
ccmn.prepend(cname);
}
ccmn.prepend(typedef_type + " "_a);
parseClass(nullptr, ccmn, false);
} else if (typedef_type == s_enum) {
tmp = pfc.takeCWord();
pfc.trim();
MetaMap meta = maybeMeta(pfc);
if (tmp == s_class || tmp == s_struct) {
tmp = pfc.takeCWord();
pfc.trim();
MetaMap smeta = maybeMeta(pfc);
meta << smeta;
}
ccmn = pfc.takeRange('{', '}');
if (tmp.isEmpty()) {
tmp = pfc.takeCWord();
}
// piCout << "pfc E" << cur_namespace << "," << tmp;
parseEnum(nullptr, cur_namespace + tmp, ccmn, meta);
} else {
pfc.prepend(typedef_type);
}
PIString last = pfc.takeLeft(pfc.find(';')).trim();
if (last.isNotEmpty()) {
typedefs << parseTypedef(last);
if (typedefs.back().first.isEmpty())
typedefs.pop_back();
else
root_.typedefs << typedefs.back();
}
pfc.takeSymbol();
continue;
}
@@ -570,7 +614,6 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
bool has_name = !cn.isEmpty();
if (cn.isEmpty()) cn = PIStringAscii("<unnamed_") + PIString::fromNumber(anon_num++) + '>';
// piCout << "found " << typename_ << cn;
if (cn.isEmpty()) return nullptr;
Entity * e = new Entity();
e->meta = meta;
e->name = cur_namespace + cn;
@@ -584,7 +627,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
}
void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) {
PICodeParser::Entity * PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) {
static const PIString s_ns = PIStringAscii("::");
static const PIString s_public = PIStringAscii("public");
static const PIString s_protected = PIStringAscii("protected");
@@ -599,7 +642,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
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;
if (dind < 0 && find < 0) return nullptr;
// piCout << "parse class <****\n" << fc << "\n****>";
Entity * ce = parent;
if (!is_namespace) {
@@ -650,11 +693,31 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
fc.takeSymbol();
continue;
}
tmp = fc.takeLeft(fc.find('{'));
stmp = fc.takeRange('{', '}');
fc.takeSymbol();
stmp = cw + ' ' + tmp + '{' + stmp + '}';
parseClass(ce, stmp, false);
tmp = fc.takeLeft(fc.find('{'));
stmp = fc.takeRange('{', '}');
stmp = cw + ' ' + tmp + '{' + stmp + '}';
auto new_entity = parseClass(ce, stmp, false);
// piCout << "!!! > \"" << fc << "\"";
PIStringList vars;
PIString var;
do {
var = fc.takeCWord();
if (var.isNotEmpty()) vars << var;
if (fc.takeSymbol() == ";") break;
} while (var.isNotEmpty());
if (new_entity) {
if (vars.isNotEmpty()) {
ce->children.removeAll(new_entity);
Member me;
me.visibility = cur_def_vis;
me.type = new_entity->name;
for (const auto & v: vars) {
me.name = v;
ce->members << me;
}
}
}
// piCout << "!!! <" << vars;
continue;
}
if (cw == s_enum) {
@@ -710,6 +773,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
}
cur_def_vis = prev_vis;
cur_namespace = prev_namespace;
return ce;
}
@@ -766,7 +830,7 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc
PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
// piCout << "parse typedef" << fc;
// piCout << "parse typedef \"" << fc << "\"";
Typedef td;
fc.replaceAll('\t', ' ');

View File

@@ -164,7 +164,7 @@ private:
bool parseFileContent(PIString & fc, bool main);
bool parseDirective(PIString d);
Entity * parseClassDeclaration(const PIString & fc);
void parseClass(Entity * parent, PIString & fc, bool is_namespace);
Entity * parseClass(Entity * parent, PIString & fc, bool is_namespace);
MetaMap parseMeta(PIString & fc);
bool parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta);
Typedef parseTypedef(PIString fc);