mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
472 lines
11 KiB
C++
472 lines
11 KiB
C++
#ifndef DOCPP_H
|
|
#define DOCPP_H
|
|
|
|
#include <Core/Core.h>
|
|
|
|
NAMESPACE_UPP
|
|
|
|
int GetCppFileIndex(const String& path);
|
|
const String& GetCppFile(int i);
|
|
|
|
enum {
|
|
Tmarker_before_first = 255,
|
|
#define CPPID(x) tk_##x,
|
|
#include "keyword.i"
|
|
#undef CPPID
|
|
};
|
|
|
|
class CppWordsHash {
|
|
dword w[4];
|
|
|
|
public:
|
|
void Clear() { w[0] = w[1] = w[2] = w[3] = 0; }
|
|
void SetAll() { w[0] = w[1] = w[2] = w[3] = ~0; }
|
|
void AddWord(const String& s);
|
|
void AddWords(const char *s);
|
|
|
|
bool operator&(const CppWordsHash& b) const {
|
|
return (w[0] & b.w[0]) | (w[1] & b.w[1]) | (w[2] & b.w[2]) | (w[3] & b.w[3]);
|
|
}
|
|
|
|
bool IsAll() const { return (w[0] & w[1] & w[2] & w[3]) == (dword)~0; }
|
|
|
|
CppWordsHash() { Clear(); }
|
|
};
|
|
|
|
CppWordsHash AllCppWords();
|
|
|
|
enum {
|
|
t_eof,
|
|
t_string = -200,
|
|
t_integer,
|
|
t_double,
|
|
t_character,
|
|
t_dblcolon,
|
|
t_mulass,
|
|
t_divass,
|
|
t_modass,
|
|
t_xorass,
|
|
t_neq,
|
|
t_dot_asteriks,
|
|
t_elipsis,
|
|
t_inc,
|
|
t_addass,
|
|
t_dec,
|
|
t_arrow_asteriks,
|
|
t_arrow,
|
|
t_subass,
|
|
t_and,
|
|
t_andass,
|
|
t_or,
|
|
t_orass,
|
|
t_eq,
|
|
t_shl,
|
|
t_shlass,
|
|
t_le,
|
|
t_shr,
|
|
t_shrass,
|
|
t_ge,
|
|
te_integeroverflow,
|
|
te_badcharacter,
|
|
te_badstring,
|
|
};
|
|
|
|
const char **CppKeyword();
|
|
|
|
class LexSymbolStat
|
|
{
|
|
public:
|
|
LexSymbolStat();
|
|
void Reset(int minSymbol, int maxSymbol);
|
|
void IncStat(int symbol);
|
|
int GetStat(int symbol) const;
|
|
int SumStat(const Vector<int> & symbols) const;
|
|
void Merge(const LexSymbolStat & other);
|
|
|
|
private:
|
|
Vector<int> v;
|
|
int minSymbol;
|
|
};
|
|
|
|
|
|
class Lex {
|
|
#ifdef _DEBUG
|
|
const char *pp;
|
|
#endif
|
|
const char *ptr;
|
|
const char *pos;
|
|
|
|
Index<String> id;
|
|
Index<int> ignore;
|
|
int endkey;
|
|
int braceslevel;
|
|
int ignore_low, ignore_high;
|
|
|
|
struct Term : Moveable<Term>{
|
|
const char *ptr;
|
|
int code;
|
|
String text;
|
|
double number;
|
|
bool grounding;
|
|
|
|
Term() { grounding = false; }
|
|
};
|
|
|
|
bool statsCollected;
|
|
LexSymbolStat symbolStat;
|
|
BiVector<Term> term;
|
|
int body;
|
|
bool grounding;
|
|
|
|
bool Char(int c) { if(*ptr == c) { ptr++; return true; } else return false; }
|
|
void AddCode(int code) { Term& tm = term.AddTail(); tm.code = code; tm.ptr = pos; tm.grounding = grounding; }
|
|
void AssOp(int noass, int ass) { AddCode(Char('=') ? ass : noass); }
|
|
void Next();
|
|
bool Prepare(int pos);
|
|
int GetCharacter();
|
|
|
|
public:
|
|
struct Grounding {};
|
|
|
|
int Code(int pos = 0);
|
|
bool IsId(int pos = 0);
|
|
String Id(int pos = 0);
|
|
int Int(int pos = 0);
|
|
double Double(int pos = 0);
|
|
int Chr(int pos = 0);
|
|
String Text(int pos = 0);
|
|
|
|
void Get(int n = 1);
|
|
int GetCode() { int q = Code(); Get(); return q; }
|
|
String GetId() { String q = Id(); Get(); return q; }
|
|
int GetInt() { int q = Int(); Get(); return q; }
|
|
double GetDouble() { double q = Double(); Get(); return q; }
|
|
int GetChr() { int q = Chr(); Get(); return q; }
|
|
String GetText() { String q = Text(); Get(); return q; }
|
|
|
|
int Id(const String& s) { return id.FindAdd(s) + 256; }
|
|
|
|
int GetBracesLevel() const { return braceslevel; }
|
|
void ClearBracesLevel() { braceslevel = 0; }
|
|
|
|
void BeginBody() { body++; }
|
|
void EndBody() { body--; }
|
|
void ClearBody() { body = 0; }
|
|
bool IsBody() const { return body; }
|
|
void SkipToGrounding();
|
|
|
|
const char *Pos(int pos = 0);
|
|
int operator[](int pos) { return Code(pos); }
|
|
operator int() { return Code(0); }
|
|
void operator++() { Get(); }
|
|
|
|
void Init(const char *s, const Vector<String>& ignore);
|
|
void StartStatCollection();
|
|
const LexSymbolStat & FinishStatCollection();
|
|
|
|
Lex();
|
|
};
|
|
|
|
struct SrcFile {
|
|
SrcFile();
|
|
String text;
|
|
Vector<int> linepos;
|
|
int preprocessorLinesRemoved;
|
|
int blankLinesRemoved;
|
|
int commentLinesRemoved;
|
|
};
|
|
|
|
SrcFile PreProcess(Stream& in);
|
|
|
|
enum Kind {
|
|
STRUCT,
|
|
STRUCTTEMPLATE,
|
|
TYPEDEF,
|
|
CONSTRUCTOR,
|
|
DESTRUCTOR,
|
|
FUNCTION,
|
|
INSTANCEFUNCTION,
|
|
CLASSFUNCTION,
|
|
FUNCTIONTEMPLATE,
|
|
INSTANCEFUNCTIONTEMPLATE,
|
|
CLASSFUNCTIONTEMPLATE,
|
|
INLINEFRIEND,
|
|
VARIABLE,
|
|
INSTANCEVARIABLE,
|
|
CLASSVARIABLE,
|
|
ENUM,
|
|
MACRO,
|
|
};
|
|
|
|
inline bool IsCppType(int i)
|
|
{
|
|
return i >= STRUCT && i <= TYPEDEF;
|
|
}
|
|
|
|
inline bool IsCppCode(int i) {
|
|
return i >= CONSTRUCTOR && i <= INLINEFRIEND;
|
|
};
|
|
|
|
inline bool IsCppData(int i) {
|
|
return i >= VARIABLE && i <= ENUM;
|
|
}
|
|
|
|
inline bool IsCppMacro(int i) {
|
|
return i == MACRO;
|
|
}
|
|
|
|
inline bool IsCppTemplate(int i) {
|
|
return i == STRUCTTEMPLATE || i >= FUNCTIONTEMPLATE && i <= CLASSFUNCTIONTEMPLATE;
|
|
}
|
|
|
|
enum {
|
|
PUBLIC,
|
|
PROTECTED,
|
|
PRIVATE,
|
|
};
|
|
|
|
struct CppPos : Moveable<CppPos> {
|
|
bool impl;
|
|
int line;
|
|
int file;
|
|
|
|
String GetFile() const { return GetCppFile(file); }
|
|
|
|
CppPos() { line = 0; impl = false; }
|
|
};
|
|
|
|
struct CppSimpleItem {
|
|
String natural;
|
|
|
|
String type;
|
|
String qtype;
|
|
String tparam;
|
|
String param;
|
|
String pname;
|
|
String ptype;
|
|
String qptype;
|
|
String tname;
|
|
String ctname;
|
|
byte access;
|
|
byte kind;
|
|
int16 at;
|
|
bool virt;
|
|
bool decla;
|
|
|
|
bool IsType() const { return IsCppType(kind); }
|
|
bool IsCode() const { return IsCppCode(kind); }
|
|
bool IsData() const { return IsCppData(kind); }
|
|
bool IsMacro() const { return IsCppMacro(kind); }
|
|
bool IsTemplate() const { return IsCppTemplate(kind); }
|
|
|
|
CppSimpleItem() { decla = false; virt = false; at = 0; }
|
|
};
|
|
|
|
struct CppItem : CppSimpleItem {
|
|
Vector<CppPos> pos;
|
|
String key;
|
|
CppWordsHash words;
|
|
|
|
void Serialize(Stream& s);
|
|
|
|
CppItem() { words.SetAll(); }
|
|
};
|
|
|
|
struct CppNest {
|
|
int namespacel;
|
|
Index<String> key;
|
|
Index<String> name;
|
|
Array<CppItem> item;
|
|
|
|
void Remove(const Vector<int>& rm) { key.Remove(rm); name.Remove(rm); item.Remove(rm); }
|
|
int GetCount() const { return item.GetCount(); }
|
|
const CppItem& operator[](int i) const { return item[i]; }
|
|
CppItem& GetAdd(const String& key, const String& name);
|
|
|
|
CppNest() { namespacel = 0; }
|
|
};
|
|
|
|
struct CppBase {
|
|
ArrayMap<String, CppNest> nest;
|
|
|
|
CppNest& operator[](int i) { return nest[i]; }
|
|
int GetCount() const { return nest.GetCount(); }
|
|
const String& GetKey(int i) const { return nest.GetKey(i); }
|
|
void Clear() { nest.Clear(); }
|
|
int Find(const String& s) const { return nest.Find(s); }
|
|
CppNest& GetAdd(const String& s) { return nest.GetAdd(s); }
|
|
|
|
bool IsType(int i) const;
|
|
};
|
|
|
|
class Parser {
|
|
struct Context {
|
|
int namespacel;
|
|
String nesting;
|
|
String ctname;
|
|
Vector<int> tparam;
|
|
Index<int> typenames;
|
|
int access;
|
|
bool noclass;
|
|
|
|
void operator<<=(const Context& t);
|
|
|
|
String Dump() const;
|
|
};
|
|
|
|
struct Decla {
|
|
bool s_static:1;
|
|
bool s_extern:1;
|
|
bool s_register:1;
|
|
bool s_auto:1;
|
|
bool s_mutable:1;
|
|
bool s_explicit:1;
|
|
bool s_virtual:1;
|
|
String name;
|
|
bool function:1;
|
|
bool type_def:1;
|
|
bool isfriend:1;
|
|
bool istemplate:1;
|
|
bool istructor:1;
|
|
bool isdestructor:1;
|
|
bool isptr:1;
|
|
bool nofn:1;
|
|
|
|
String tnames;
|
|
String type;
|
|
String natural;
|
|
|
|
Decla();
|
|
};
|
|
|
|
struct Decl : Decla {
|
|
Array<Decl> param;
|
|
};
|
|
|
|
struct RecursionCounter
|
|
{
|
|
int change;
|
|
int &count;
|
|
RecursionCounter(int &count_i, int change_i = 1) :
|
|
change(change_i), count(count_i)
|
|
{
|
|
count += change;
|
|
}
|
|
~RecursionCounter() { count -= change; }
|
|
};
|
|
|
|
Context context;
|
|
SrcFile file;
|
|
Lex lex;
|
|
int filei;
|
|
bool inbody;
|
|
|
|
Callback2<int, const String&> err;
|
|
|
|
int lpos, line;
|
|
|
|
CppBase *base;
|
|
|
|
int RPtr();
|
|
|
|
bool Key(int code);
|
|
bool EatBody();
|
|
|
|
void Cv();
|
|
String SimpleType(Decla& d);
|
|
void Qualifier();
|
|
void ParamList(Decl& d);
|
|
void Declarator(Decl& d, const char *p);
|
|
void EatInitializers();
|
|
Decl Type();
|
|
void Vars(Array<Decl>& r, const char *p, bool type_def, bool more);
|
|
Array<Decl> Declaration(bool l0 = false, bool more = false);
|
|
bool IsParamList(int q);
|
|
void Elipsis(Decl& d);
|
|
Decl& Finish(Decl& d, const char *p);
|
|
bool Nest(const String& tp, const String& tn);
|
|
|
|
String TemplateParams(String& pnames);
|
|
String TemplateParams();
|
|
String TemplatePnames();
|
|
String Name(String& h);
|
|
String Name();
|
|
String Constant();
|
|
String ReadOper();
|
|
|
|
int GetLine(const char *pos);
|
|
void Line();
|
|
void Check(bool b, const char *err);
|
|
void CheckKey(int c);
|
|
|
|
void SetNestCurrent();
|
|
void NestBody();
|
|
void Do();
|
|
|
|
CppItem& Item(const String& nesting, const String& item, const String& name, bool impl);
|
|
CppItem& Item(const String& nesting, const String& item, const String& name);
|
|
|
|
CppItem& Fn(const Decl& d, const String& templ, bool body, int kind, const String& tname, const String& tparam);
|
|
|
|
struct Error {};
|
|
|
|
void ThrowError(const String& e);
|
|
void Resume(int bl);
|
|
|
|
void MatchPars();
|
|
bool TryDecl();
|
|
void Statement();
|
|
void Locals(const String& type);
|
|
String Tparam(int& q);
|
|
|
|
public:
|
|
struct FunctionStat
|
|
{
|
|
FunctionStat(const String & nesting,
|
|
const CppItem & cppItem,
|
|
const LexSymbolStat &symbolStat,
|
|
int maxScopeDepth);
|
|
String nesting;
|
|
const CppItem & cppItem;
|
|
const LexSymbolStat &symbolStat;
|
|
int maxScopeDepth;
|
|
};
|
|
|
|
bool IsInBody() const { return inbody; }
|
|
|
|
typedef Callback1<const FunctionStat &> FnEndCallback;
|
|
|
|
bool dobody;
|
|
String current_nest;
|
|
int current_namespacel;
|
|
String current_key;
|
|
CppItem current;
|
|
int currentScopeDepth;
|
|
int maxScopeDepth;
|
|
VectorMap<String, String> local;
|
|
FnEndCallback whenFnEnd;
|
|
LexSymbolStat symbolsOutsideFunctions;
|
|
|
|
const SrcFile &getPreprocessedFile() { return file; }
|
|
|
|
void Do(Stream& s, const Vector<String>& ignore, CppBase& base, const String& fn,
|
|
Callback2<int, const String&> err, const Vector<String>& typenames = Vector<String>());
|
|
|
|
Parser() : dobody(false) {}
|
|
};
|
|
|
|
String NoTemplatePars(const String& type);
|
|
|
|
String Qualify(const CppBase& base, const String& nest, const String& type);
|
|
void QualifyTypes(CppBase& base, const String& nest, CppItem& m);
|
|
String QualifyKey(const CppBase& base, const String& nest, const String& type);
|
|
|
|
void Qualify(CppBase& base, const CppWordsHash& words);
|
|
|
|
void Parse(Stream& s, const Vector<String>& ignore, CppBase& base, const String& fn,
|
|
Callback2<int, const String&> err);
|
|
void Remove(CppBase& base, const Vector<String>& fn);
|
|
|
|
END_UPP_NAMESPACE
|
|
|
|
#endif
|