mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-30 22:03:46 -06:00
uppsrc: docs & cosmetics
git-svn-id: svn://ultimatepp.org/upp/trunk@15254 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
263382f30b
commit
33ff83e72a
57 changed files with 4617 additions and 4544 deletions
|
|
@ -1,825 +0,0 @@
|
|||
#include "docpp.h"
|
||||
|
||||
String Purify(const char *s) {
|
||||
String res;
|
||||
while(*s) {
|
||||
if(*s >= 'a' && *s <= 'z') {
|
||||
String q;
|
||||
while(*s >= 'a' && *s <= 'z')
|
||||
q.Cat(*s++);
|
||||
if(q != "virtual" && q != "inline")
|
||||
res.Cat(q);
|
||||
else
|
||||
while((byte)*s <= ' ' && *s) s++;
|
||||
}
|
||||
else
|
||||
if((byte)*s <= ' ') {
|
||||
res.Cat(' ');
|
||||
while(*s <= ' ' && *s)
|
||||
s++;
|
||||
}
|
||||
else
|
||||
res.Cat(*s++);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void ScAdd(String& s, const String& a)
|
||||
{
|
||||
if(a.IsEmpty()) return;
|
||||
if(!s.IsEmpty())
|
||||
s << ';';
|
||||
s << a;
|
||||
}
|
||||
|
||||
String Parser::Context::Dump() const
|
||||
{
|
||||
return "Namespace: " + nameing + " Struct: " + nesting;
|
||||
}
|
||||
|
||||
void Parser::Context::operator<<=(const Context& t)
|
||||
{
|
||||
nameing = t.nameing;
|
||||
nesting = t.nesting;
|
||||
typenames <<= t.typenames;
|
||||
access = t.access;
|
||||
}
|
||||
|
||||
|
||||
Parser::Decla::Decla()
|
||||
{
|
||||
function = type_def = false;
|
||||
s_static = s_auto = s_register = s_extern = s_mutable = s_explicit = s_virtual = false;
|
||||
isfriend = istemplate = istructor = isptr = nofn = false;
|
||||
}
|
||||
|
||||
bool Parser::Key(int code)
|
||||
{
|
||||
if(lex == code) {
|
||||
++lex;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int Parser::GetLine(const char *p)
|
||||
{
|
||||
int pos = p - ~file.text;
|
||||
int l = 0;
|
||||
int h = file.linepos.GetCount();
|
||||
while(l < h) {
|
||||
int q = (l + h) / 2;
|
||||
if(file.linepos[q] < pos)
|
||||
l = q + 1;
|
||||
else
|
||||
h = q;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void Parser::Line()
|
||||
{
|
||||
int pos = lex.Pos() - ~file.text;
|
||||
while(line + 1 < file.linepos.GetCount() && file.linepos[line + 1] <= pos)
|
||||
line++;
|
||||
}
|
||||
|
||||
void Parser::ThrowError(const String& e)
|
||||
{
|
||||
throw Error(Format("(%d) : %s", GetLine(lex.Pos()), ~e));
|
||||
}
|
||||
|
||||
void Parser::Check(bool b, const char *err)
|
||||
{
|
||||
if(!b) ThrowError(err);
|
||||
}
|
||||
|
||||
void Parser::CheckKey(int c)
|
||||
{
|
||||
if(!Key(c)) ThrowError(Format("Missing %c", c));
|
||||
}
|
||||
|
||||
String Parser::TemplateParams(String& param)
|
||||
{
|
||||
const char *pos = lex.Pos();
|
||||
CheckKey('<');
|
||||
int level = 1;
|
||||
String id;
|
||||
bool gp = true;
|
||||
for(;;) {
|
||||
if(lex.IsId() && gp)
|
||||
id = lex.GetId();
|
||||
else
|
||||
if(Key(',')) {
|
||||
ScAdd(param, id);
|
||||
id.Clear();
|
||||
gp = true;
|
||||
}
|
||||
else
|
||||
if(Key('=')) {
|
||||
if(!id.IsEmpty()) {
|
||||
ScAdd(param, id);
|
||||
id.Clear();
|
||||
}
|
||||
gp = false;
|
||||
}
|
||||
else
|
||||
if(Key('>')) {
|
||||
level--;
|
||||
if(level <= 0) {
|
||||
ScAdd(param, id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(Key('<'))
|
||||
level++;
|
||||
else
|
||||
++lex;
|
||||
}
|
||||
return String(pos, lex.Pos());
|
||||
}
|
||||
|
||||
String Parser::TemplateParams()
|
||||
{
|
||||
String dummy;
|
||||
return TemplateParams(dummy);
|
||||
}
|
||||
|
||||
String Parser::TemplatePnames()
|
||||
{
|
||||
String pnames;
|
||||
TemplateParams(pnames);
|
||||
return pnames;
|
||||
}
|
||||
|
||||
String Parser::Name()
|
||||
{
|
||||
String s;
|
||||
if(Key(t_dblcolon))
|
||||
s << "::";
|
||||
Check(lex.IsId(), "Name expected");
|
||||
while(lex.IsId()) {
|
||||
s << lex.GetId();
|
||||
if(lex == '<')
|
||||
s << TemplateParams();
|
||||
if(Key(t_dblcolon)) {
|
||||
s << "::";
|
||||
if(Key('~'))
|
||||
s << "~";
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
String Parser::Constant()
|
||||
{
|
||||
const char *p = lex.Pos();
|
||||
const char *p1 = p;
|
||||
int level = 0;
|
||||
for(;;) {
|
||||
p1 = lex.Pos();
|
||||
if(lex == t_eof) break;
|
||||
if(level <= 0 && (lex == ',' || lex == ';' || lex == ')' || lex == '}' || lex == ']'))
|
||||
break;
|
||||
if(Key('(') || Key('[') || Key('{')) level++;
|
||||
else
|
||||
if(Key(')') || Key(']') || Key('}')) level--;
|
||||
else
|
||||
++lex;
|
||||
}
|
||||
return String(p, p1);
|
||||
}
|
||||
|
||||
String Parser::SimpleType()
|
||||
{
|
||||
if(Key(tk_struct) || Key(tk_class) || Key(tk_union) || Key(tk_enum) || Key(tk_typename)) {
|
||||
if(lex.IsId() || lex == t_dblcolon) Name();
|
||||
if(lex == '{') EatBody();
|
||||
return Null;
|
||||
}
|
||||
if(Key(tk_bool) || Key(tk_float) || Key(tk_double) || Key(tk_void))
|
||||
return Null;
|
||||
bool sgn = Key(tk_signed) || Key(tk_unsigned);
|
||||
if(Key(tk_long)) {
|
||||
Key(tk_int);
|
||||
return Null;
|
||||
}
|
||||
if(Key(tk_short)) {
|
||||
Key(tk_int);
|
||||
return Null;
|
||||
}
|
||||
if(Key(tk_int) || Key(tk_char) ||
|
||||
Key(tk___int8) || Key(tk___int16) || Key(tk___int32) || Key(tk___int64)) return Null;
|
||||
if(sgn) return Null;
|
||||
const char *p = lex.Pos();
|
||||
int cs = 0;
|
||||
Index<int> cix;
|
||||
Key(t_dblcolon);
|
||||
Check(lex.IsId(), "Name expected");
|
||||
while(lex.IsId()) {
|
||||
if(cix.Find(lex) >= 0)
|
||||
cs++;
|
||||
else
|
||||
cix.Add(lex);
|
||||
++lex;
|
||||
if(lex == '<')
|
||||
TemplateParams();
|
||||
if(Key(t_dblcolon))
|
||||
Key('~');
|
||||
else
|
||||
break;
|
||||
}
|
||||
return cs ? String(p, lex.Pos()) : String();
|
||||
}
|
||||
|
||||
void Parser::Qualifier()
|
||||
{
|
||||
Key(tk_const);
|
||||
Key(tk_volatile);
|
||||
if(Key(tk_throw)) {
|
||||
while(lex != t_eof && !Key(')'))
|
||||
++lex;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::Elipsis(Decl& d)
|
||||
{
|
||||
Decl& q = d.param.Add();
|
||||
q.name = "...";
|
||||
CheckKey(')');
|
||||
}
|
||||
|
||||
void Parser::ParamList(Decl& d) {
|
||||
if(!Key(')'))
|
||||
for(;;) {
|
||||
if(Key(t_elipsis)) {
|
||||
Elipsis(d);
|
||||
break;
|
||||
}
|
||||
else
|
||||
d.param.Add() = Declaration().Top();
|
||||
if(Key(t_elipsis)) {
|
||||
Elipsis(d);
|
||||
break;
|
||||
}
|
||||
if(Key(')')) break;
|
||||
CheckKey(',');
|
||||
}
|
||||
}
|
||||
|
||||
int Parser::RPtr()
|
||||
{
|
||||
int n = 0;
|
||||
int q = 0;
|
||||
int tlevel = 0;
|
||||
for(;;) {
|
||||
int t = lex[n];
|
||||
if(t == '*') return n + 1;
|
||||
if(t == '<') {
|
||||
tlevel++;
|
||||
n++;
|
||||
}
|
||||
else
|
||||
if(t == '>') {
|
||||
tlevel--;
|
||||
n++;
|
||||
}
|
||||
else
|
||||
if(t == t_dblcolon || lex.IsId(n) || t == ',' && tlevel > 0)
|
||||
n++;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::EatInitializers()
|
||||
{
|
||||
if(Key(':')) {
|
||||
while(lex != '{' && lex != t_eof) ++lex;
|
||||
}
|
||||
}
|
||||
|
||||
String Parser::ReadOper() {
|
||||
const char *p = lex.Pos();
|
||||
const char *p1 = p;
|
||||
Key(tk_operator);
|
||||
int level = 0;
|
||||
if(Key('('))
|
||||
level++;
|
||||
for(;;) {
|
||||
p1 = lex.Pos();
|
||||
if(lex == t_eof) break;
|
||||
if(level <= 0 && lex == '(') break;
|
||||
if(Key('(') || Key('[')) level++;
|
||||
else
|
||||
if(Key(')') || Key(']')) level--;
|
||||
else
|
||||
++lex;
|
||||
}
|
||||
return TrimRight(Purify(String(p, p1)));
|
||||
}
|
||||
|
||||
void Parser::Declarator(Decl& d, const char *p)
|
||||
{
|
||||
int n = RPtr();
|
||||
if(n) {
|
||||
while(n--) lex.Get();
|
||||
Declarator(d, p);
|
||||
d.isptr = true;
|
||||
return;
|
||||
}
|
||||
if(Key('&')) {
|
||||
Declarator(d, p);
|
||||
return;
|
||||
}
|
||||
if(Key(tk_const)) {
|
||||
Declarator(d, p);
|
||||
return;
|
||||
}
|
||||
if(Key('(')) {
|
||||
Declarator(d, p);
|
||||
if(d.isptr)
|
||||
d.nofn = true;
|
||||
CheckKey(')');
|
||||
}
|
||||
if(lex == tk_operator)
|
||||
d.name = ReadOper();
|
||||
else
|
||||
if(lex.IsId() || lex == t_dblcolon) {
|
||||
d.name = Name();
|
||||
if(Key(':'))
|
||||
if(!Key(t_integer))
|
||||
Name();
|
||||
}
|
||||
if(Key('(')) {
|
||||
if((lex < 256 || lex == tk_true || lex == tk_false) && lex != ')') {
|
||||
int level = 0;
|
||||
for(;;) {
|
||||
if(lex == t_eof) break;
|
||||
if(Key('(')) level++;
|
||||
else
|
||||
if(Key(')')) {
|
||||
if(--level < 0) break;
|
||||
}
|
||||
else
|
||||
++lex;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
d.header = String(p, lex.Pos() - 1);
|
||||
d.function = !d.nofn;
|
||||
ParamList(d);
|
||||
p = lex.Pos();
|
||||
Qualifier();
|
||||
d.ender = String(p, lex.Pos());
|
||||
}
|
||||
}
|
||||
EatInitializers();
|
||||
while(Key('[')) {
|
||||
const char *p = lex.Pos();
|
||||
int level = 1;
|
||||
while(level && lex != t_eof) {
|
||||
if(Key('[')) level++;
|
||||
else
|
||||
if(Key(']')) level--;
|
||||
else
|
||||
++lex;
|
||||
}
|
||||
}
|
||||
if(Key('=')) {
|
||||
Constant();
|
||||
}
|
||||
}
|
||||
|
||||
Parser::Decl& Parser::Finish(Decl& d, const char *s)
|
||||
{
|
||||
d.natural = String(s, lex.Pos());
|
||||
return d;
|
||||
}
|
||||
|
||||
Parser::Decl Parser::Type() {
|
||||
Decl d;
|
||||
const char *p = lex.Pos();
|
||||
Qualifier();
|
||||
SimpleType();
|
||||
Declarator(d, p);
|
||||
return Finish(d, p);
|
||||
}
|
||||
|
||||
Array<Parser::Decl> Parser::Declaration(bool l0, bool more)
|
||||
{
|
||||
Array<Decl> r;
|
||||
Decla d;
|
||||
const char *p = lex.Pos();
|
||||
if(Key(tk_typedef)) {
|
||||
r = Declaration();
|
||||
r.Top().type_def = true;
|
||||
r.Top().natural = String(p, lex.Pos());
|
||||
return r;
|
||||
}
|
||||
if(Key(tk_friend))
|
||||
d.isfriend = true;
|
||||
// if(Key(tk_template)) {
|
||||
// d.istemplate = true;
|
||||
// d.template_params = TemplateParams(d.tnames);
|
||||
// }
|
||||
for(;;) {
|
||||
if(Key(tk_static))
|
||||
d.s_static = true;
|
||||
else
|
||||
if(Key(tk_extern))
|
||||
d.s_extern = true;
|
||||
else
|
||||
if(Key(tk_auto))
|
||||
d.s_auto = true;
|
||||
else
|
||||
if(Key(tk_register))
|
||||
d.s_register = true;
|
||||
else
|
||||
if(Key(tk_mutable))
|
||||
d.s_mutable = true;
|
||||
else
|
||||
if(Key(tk_explicit))
|
||||
d.s_explicit = true;
|
||||
else
|
||||
if(Key(tk_virtual))
|
||||
d.s_virtual = true;
|
||||
else
|
||||
if(!Key(tk_inline))
|
||||
break;
|
||||
}
|
||||
Qualifier();
|
||||
bool isdestructor = Key('~');
|
||||
if(l0 && context.typenames.Find(lex) >= 0 && lex[1] == '(') {
|
||||
Decl& a = r.Add();
|
||||
a.name = lex.GetId();
|
||||
a.isdestructor = isdestructor;
|
||||
a.function = true;
|
||||
a.istructor = true;
|
||||
a.header = String(p, lex.Pos());
|
||||
++lex;
|
||||
ParamList(a);
|
||||
const char *p1 = lex.Pos();
|
||||
Qualifier();
|
||||
a.ender = String(p1, lex.Pos());
|
||||
a.natural = String(p, lex.Pos());
|
||||
EatInitializers();
|
||||
return r;
|
||||
}
|
||||
if(lex == tk_operator) {
|
||||
Decl& a = r.Add();
|
||||
(Decla&)a = d;
|
||||
a.name = ReadOper();
|
||||
a.header = String(p, lex.Pos());
|
||||
Key('(');
|
||||
ParamList(a);
|
||||
const char *p1 = lex.Pos();
|
||||
Qualifier();
|
||||
a.ender = String(p1, lex.Pos());
|
||||
a.function = true;
|
||||
a.natural = String(p, lex.Pos());
|
||||
return r;
|
||||
}
|
||||
String st = SimpleType();
|
||||
if(!st.IsEmpty()) {
|
||||
Decl& a = r.Add();
|
||||
a.name = st;
|
||||
a.isdestructor = st.Find('~') > 0;
|
||||
a.function = true;
|
||||
a.istructor = true;
|
||||
a.header = String(p, lex.Pos());
|
||||
if(Key('('))
|
||||
ParamList(a);
|
||||
const char *p1 = lex.Pos();
|
||||
Qualifier();
|
||||
a.ender = String(p1, lex.Pos());
|
||||
a.natural = String(p, lex.Pos());
|
||||
EatInitializers();
|
||||
return r;
|
||||
}
|
||||
String natural1 = String(p, lex.Pos());
|
||||
do {
|
||||
const char *p1 = lex.Pos();
|
||||
Decl& a = r.Add();
|
||||
(Decla&)a = d;
|
||||
Declarator(a, p);
|
||||
a.natural = natural1 + String(p1, lex.Pos());
|
||||
p = lex.Pos();
|
||||
}
|
||||
while(more && Key(','));
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Parser::EatBody()
|
||||
{
|
||||
if(!Key('{')) return false;
|
||||
int level = 1;
|
||||
while(level && lex != t_eof) {
|
||||
if(Key('{')) level++;
|
||||
else
|
||||
if(Key('}')) level--;
|
||||
else
|
||||
++lex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
String CleanTp(const String& tp)
|
||||
{
|
||||
int q = tp.Find('<');
|
||||
int w = tp.ReverseFind('>');
|
||||
if(q < 0 || w < 0) return tp;
|
||||
String a = TrimLeft(TrimRight(tp.Mid(q + 1, w - q - 1)));
|
||||
const char *s = a;
|
||||
String r;
|
||||
while(*s) {
|
||||
if(*s == ',') {
|
||||
r.Cat(';');
|
||||
s++;
|
||||
while(*s == ' ')
|
||||
s++;
|
||||
}
|
||||
else
|
||||
r.Cat(*s++);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Parser::Nest(const String& tp, const String& tn) {
|
||||
if(Key(tk_namespace)) {
|
||||
Check(lex.IsId(), "Expected name of namespace");
|
||||
String name = lex.GetId();
|
||||
if(Key('{')) {
|
||||
Context cc;
|
||||
cc <<= context;
|
||||
context.nameing << name << "::";
|
||||
Do();
|
||||
context <<= cc;
|
||||
Key('}');
|
||||
}
|
||||
Key(';');
|
||||
return true;
|
||||
}
|
||||
if((lex == tk_class || lex == tk_struct || lex == tk_union) &&
|
||||
lex.IsId(1) &&
|
||||
(lex[2] == ':' || lex[2] == ';' || lex[2] == '{')) {
|
||||
int t = lex.GetCode();
|
||||
context.typenames.FindAdd(lex);
|
||||
String name = lex.GetId();
|
||||
Context cc;
|
||||
cc <<= context;
|
||||
if(context.nesting.IsEmpty())
|
||||
context.nesting = name + TrimRight(tp);
|
||||
else
|
||||
context.nesting = context.nesting + "::" + name + TrimRight(tp);
|
||||
context.access = t == tk_class ? PRIVATE : PUBLIC;
|
||||
String nn;
|
||||
if(!tp.IsEmpty())
|
||||
nn = "template " + tp + " ";
|
||||
nn << (t == tk_class ? "class " : t == tk_union ? "union " : "struct ") + name;
|
||||
CppItem& im = Item(context.nameing, context.nesting, nn);
|
||||
im.kind = tp.IsEmpty() ? STRUCT : STRUCTTEMPLATE;
|
||||
im.name = name;
|
||||
im.access = cc.access;
|
||||
im.tname = tn;
|
||||
im.tparam = CleanTp(tp);
|
||||
if(Key(':')) {
|
||||
do {
|
||||
String access = t == tk_class ? "private" : "public";
|
||||
if(Key(tk_public)) access = "public";
|
||||
else
|
||||
if(Key(tk_protected)) access = "protected";
|
||||
else
|
||||
if(Key(tk_private)) access = "private";
|
||||
if(Key(tk_virtual)) access << " virtual";
|
||||
String n = Name();
|
||||
ScAdd(im.pname, n);
|
||||
ScAdd(im.param, access + ' ' + n);
|
||||
}
|
||||
while(Key(','));
|
||||
}
|
||||
if(Key('{')) {
|
||||
Do();
|
||||
CheckKey('}');
|
||||
}
|
||||
CheckKey(';');
|
||||
context = cc;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CppItem& Parser::Item(const String& nameing, const String& nesting, const String& item)
|
||||
{
|
||||
CppItem& im = base->GetAdd(nameing).GetAdd(nesting).GetAdd(TrimRight(Purify(item)));
|
||||
im.pname.Clear();
|
||||
im.param.Clear();
|
||||
im.package = package;
|
||||
im.file = filename;
|
||||
im.line = line + 1;
|
||||
im.name.Clear();
|
||||
return im;
|
||||
}
|
||||
|
||||
void Parser::Do()
|
||||
{
|
||||
while(lex != t_eof && lex != '}') {
|
||||
Line();
|
||||
if(Key(tk_using)) {
|
||||
while(!Key(';'))
|
||||
++lex;
|
||||
}
|
||||
else
|
||||
if(Key(tk_extern) && lex == t_string) {
|
||||
++lex;
|
||||
++lex;
|
||||
if(Key('{')) {
|
||||
Do();
|
||||
Key('}');
|
||||
}
|
||||
Key(';');
|
||||
}
|
||||
else
|
||||
if(Key(tk_template)) {
|
||||
if(lex.IsId() || lex == tk_class && lex.IsId(1)) {
|
||||
Key(tk_class);
|
||||
for(;;) {
|
||||
if(lex.IsId())
|
||||
lex.GetId();
|
||||
else
|
||||
if(!Key(t_dblcolon))
|
||||
break;
|
||||
}
|
||||
TemplateParams();
|
||||
Key(';');
|
||||
}
|
||||
else {
|
||||
String tnames;
|
||||
String tparam = TemplateParams(tnames);
|
||||
if(!Nest(tparam, tnames)) {
|
||||
Array<Decl> r = Declaration(true, true);
|
||||
for(int i = 0; i < r.GetCount(); i++) {
|
||||
Decl& d = r[i];
|
||||
d.natural = "template" + tparam + ' ' + d.natural;
|
||||
if(context.access != PRIVATE && !d.isfriend && d.function) {
|
||||
CppItem& im = Item(context.nameing, context.nesting, d.natural);
|
||||
im.name = d.name;
|
||||
im.access = context.access;
|
||||
im.header = Purify(d.header);
|
||||
im.ender = Purify(d.ender);
|
||||
im.kind = context.nesting.IsEmpty() ? FUNCTIONTEMPLATE :
|
||||
d.s_static ? CLASSFUNCTIONTEMPLATE
|
||||
: INSTANCEFUNCTIONTEMPLATE;
|
||||
for(int i = 0; i < d.param.GetCount(); i++) {
|
||||
ScAdd(im.param, d.param[i].natural);
|
||||
ScAdd(im.pname, d.param[i].name);
|
||||
}
|
||||
im.tname = tnames;
|
||||
im.tparam = CleanTp(tparam);
|
||||
}
|
||||
}
|
||||
EatBody();
|
||||
Key(';');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(lex == tk_enum && (lex[1] == '{' || lex[2] == '{')) {
|
||||
++lex;
|
||||
String name;
|
||||
if(lex.IsId())
|
||||
name = lex.GetId();
|
||||
String param;
|
||||
String pname;
|
||||
String n = "enum " + name + " { ";
|
||||
Key('{');
|
||||
for(;;) {
|
||||
String val;
|
||||
Check(lex.IsId(), "Expected identifier");
|
||||
String nm = lex.GetId();
|
||||
if(Key('='))
|
||||
val = Constant();
|
||||
if(!param.IsEmpty())
|
||||
n << ", ";
|
||||
n << nm;
|
||||
ScAdd(param, nm + " = " + val);
|
||||
ScAdd(pname, nm);
|
||||
Key(',');
|
||||
if(Key('}')) break;
|
||||
}
|
||||
n << " }";
|
||||
CppItem& im = Item(context.nameing, context.nesting, n);
|
||||
im.kind = ENUM;
|
||||
im.name = name;
|
||||
im.access = context.access;
|
||||
im.param = param;
|
||||
im.pname = pname;
|
||||
if(lex.IsId())
|
||||
im.name = lex.GetId();
|
||||
CheckKey(';');
|
||||
}
|
||||
else
|
||||
if(Key('#')) {
|
||||
String n = lex.GetText();
|
||||
CppItem& im = Item(context.nameing, context.nesting, n);
|
||||
im.kind = MACRO;
|
||||
im.name.Clear();
|
||||
const char *s = n;
|
||||
while(*s && iscid(*s))
|
||||
im.name.Cat(*s++);
|
||||
s = strchr(n, '(');
|
||||
if(s) {
|
||||
s++;
|
||||
String p;
|
||||
for(;;) {
|
||||
if(iscid(*s))
|
||||
p.Cat(*s++);
|
||||
else {
|
||||
ScAdd(im.pname, p);
|
||||
p.Clear();
|
||||
if(*s == ')' || *s == '\0') break;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
im.access = context.access;
|
||||
}
|
||||
else
|
||||
if(!Nest(String(), String())) {
|
||||
if(Key(tk_public)) {
|
||||
context.access = PUBLIC;
|
||||
Key(':');
|
||||
}
|
||||
else
|
||||
if(Key(tk_private)) {
|
||||
context.access = PRIVATE;
|
||||
Key(':');
|
||||
}
|
||||
else
|
||||
if(Key(tk_protected)) {
|
||||
context.access = PROTECTED;
|
||||
Key(':');
|
||||
}
|
||||
else {
|
||||
const char *p = lex.Pos();
|
||||
Array<Decl> r = Declaration(true, true);
|
||||
bool body = EatBody();
|
||||
for(int i = 0; i < r.GetCount(); i++) {
|
||||
Decl& d = r[i];
|
||||
if(context.access != PRIVATE && !d.isfriend || d.isfriend && body) {
|
||||
CppItem& im = Item(context.nameing, context.nesting, d.natural);
|
||||
im.name = d.name;
|
||||
im.header = Purify(d.header);
|
||||
im.ender = Purify(d.ender);
|
||||
im.access = context.access;
|
||||
if(d.function) {
|
||||
im.kind = d.istructor ? (d.isdestructor ? DESTRUCTOR : CONSTRUCTOR) :
|
||||
d.isfriend ? INLINEFRIEND :
|
||||
context.nesting.IsEmpty() ? FUNCTION :
|
||||
d.s_static ? CLASSFUNCTION : INSTANCEFUNCTION;
|
||||
for(int i = 0; i < d.param.GetCount(); i++) {
|
||||
ScAdd(im.param, d.param[i].natural);
|
||||
ScAdd(im.pname, d.param[i].name);
|
||||
}
|
||||
}
|
||||
else
|
||||
im.kind = d.type_def ? TYPEDEF :
|
||||
context.nesting.IsEmpty() ? VARIABLE :
|
||||
d.s_static ? CLASSVARIABLE : INSTANCEVARIABLE;
|
||||
}
|
||||
}
|
||||
EatBody();
|
||||
Key(';');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::Do(Stream& in, const Vector<String>& ignore, CppBase& _base,
|
||||
const String& p, const String& f) throw(Parser::Error)
|
||||
{
|
||||
base = &_base;
|
||||
file = PreProcess(in);
|
||||
lex = ~file.text;
|
||||
lex.Ignore(ignore);
|
||||
context.nesting.Clear();
|
||||
context.nameing = "::";
|
||||
context.access = PUBLIC;
|
||||
context.typenames.Clear();
|
||||
package = p;
|
||||
filename = f;
|
||||
lpos = 0;
|
||||
line = 0;
|
||||
Do();
|
||||
}
|
||||
|
||||
void Parse(Stream& s, const Vector<String>& ignore, CppBase& base,
|
||||
const String& package, const String& file) throw(Parser::Error)
|
||||
{
|
||||
Parser p;
|
||||
p.Do(s, ignore, base, package, file);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue