New heurestics singificantly improves C++ parser in theide

git-svn-id: svn://ultimatepp.org/upp/trunk@427 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2008-09-11 20:46:49 +00:00
parent dcd4cfa666
commit a041d64a11
5 changed files with 61 additions and 8 deletions

View file

@ -107,21 +107,25 @@ class Lex {
int code;
String text;
double number;
bool grounding;
};
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; }
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);
@ -141,6 +145,13 @@ public:
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); }

View file

@ -869,6 +869,7 @@ void Parser::Statement()
bool Parser::EatBody()
{
if(lex != '{') return false;
lex.BeginBody();
maxScopeDepth = currentScopeDepth = dobody ? 0 : 1;
if(dobody) {
inbody = true;
@ -888,6 +889,7 @@ bool Parser::EatBody()
maxScopeDepth = max(level, maxScopeDepth);
}
}
lex.EndBody();
return true;
}
@ -1398,9 +1400,20 @@ void Parser::Do(Stream& in, const Vector<String>& ignore, CppBase& _base, const
try {
Do();
}
catch(Lex::Grounding) {
lex.ClearBracesLevel();
lex.ClearBody();
}
catch(Error) {
Resume(lex.GetBracesLevel());
Key(';');
if(lex.IsBody()) {
Resume(lex.GetBracesLevel());
Key(';');
}
else {
++lex;
lex.SkipToGrounding();
lex.ClearBracesLevel();
}
}
}

View file

@ -73,6 +73,8 @@ SrcFile PreProcess(Stream& in)
SLPos(res);
}
const char *rm = ln;
if(IsAlNum(*rm))
res.text << '\1';
while(*rm == ' ' || *rm == '\t') rm++;
if(*rm == '\0')
res.blankLinesRemoved++;

View file

@ -86,7 +86,7 @@ Lex::Lex()
for(int i = 0; cppk[i]; i++)
id.Add(cppk[i]);
endkey = id.GetCount();
braceslevel = ignore_low = ignore_high = 0;
braceslevel = ignore_low = ignore_high = body = 0;
}
void Lex::Init(const char *s, const Vector<String>& ig)
@ -104,13 +104,12 @@ void Lex::StartStatCollection()
statsCollected = true;
}
const LexSymbolStat & Lex::FinishStatCollection()
const LexSymbolStat& Lex::FinishStatCollection()
{
statsCollected = false;
return symbolStat;
}
int Lex::GetCharacter()
{
if(*ptr == '\0') return t_eof;
@ -151,7 +150,10 @@ int Lex::GetCharacter()
void Lex::Next()
{
grounding = false;
while((byte)*ptr <= ' ') {
if(*ptr == '\1')
grounding = true;
if(*ptr == '\0') return;
ptr++;
}
@ -369,6 +371,8 @@ void Lex::Get(int n)
{
while(n--) {
if(term.GetCount()) {
if(body && term.Head().grounding)
throw Grounding();
int chr = term.Head().code;
if(statsCollected)
symbolStat.IncStat(chr);
@ -381,6 +385,29 @@ void Lex::Get(int n)
}
if(term.GetCount() == 0)
Next();
if(term.GetCount() == 0)
break;
}
}
void Lex::SkipToGrounding()
{
for(;;) {
if(term.GetCount() == 0)
Next();
if(term.GetCount() == 0)
break;
int chr = term.Head().code;
if(chr == t_eof)
return;
if(term.Head().grounding)
return;
if(chr == '{')
braceslevel++;
else
if(chr == '}')
braceslevel--;
term.DropHead();
}
}

View file

@ -3,7 +3,7 @@
#include "CtrlCore/init"
#include "RichText/init"
#include "PdfDraw/init"
#define BLITZ_INDEX__ FF3059E544238824EE029458E30F1FEC9
#define BLITZ_INDEX__ F9FBD74A341BB7E4C8A3BC288CE65AF08
#include "CtrlLib.icpp"
#undef BLITZ_INDEX__
#endif