From a041d64a113c864bfe4c8776e670090d9ee0d75f Mon Sep 17 00:00:00 2001 From: cxl Date: Thu, 11 Sep 2008 20:46:49 +0000 Subject: [PATCH] New heurestics singificantly improves C++ parser in theide git-svn-id: svn://ultimatepp.org/upp/trunk@427 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CppBase/CppBase.h | 15 +++++++++++++-- uppsrc/CppBase/Parser.cpp | 17 +++++++++++++++-- uppsrc/CppBase/Pre.cpp | 2 ++ uppsrc/CppBase/cpplex.cpp | 33 ++++++++++++++++++++++++++++++--- uppsrc/CtrlLib/init | 2 +- 5 files changed, 61 insertions(+), 8 deletions(-) diff --git a/uppsrc/CppBase/CppBase.h b/uppsrc/CppBase/CppBase.h index aa2f9f3ac..3d23c5d17 100644 --- a/uppsrc/CppBase/CppBase.h +++ b/uppsrc/CppBase/CppBase.h @@ -107,21 +107,25 @@ class Lex { int code; String text; double number; + bool grounding; }; bool statsCollected; LexSymbolStat symbolStat; BiVector 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); } diff --git a/uppsrc/CppBase/Parser.cpp b/uppsrc/CppBase/Parser.cpp index d7b64a83d..4221426f0 100644 --- a/uppsrc/CppBase/Parser.cpp +++ b/uppsrc/CppBase/Parser.cpp @@ -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& 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(); + } } } diff --git a/uppsrc/CppBase/Pre.cpp b/uppsrc/CppBase/Pre.cpp index 0d6efe265..41ce66780 100644 --- a/uppsrc/CppBase/Pre.cpp +++ b/uppsrc/CppBase/Pre.cpp @@ -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++; diff --git a/uppsrc/CppBase/cpplex.cpp b/uppsrc/CppBase/cpplex.cpp index ad0ce0e47..e8286d3ce 100644 --- a/uppsrc/CppBase/cpplex.cpp +++ b/uppsrc/CppBase/cpplex.cpp @@ -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& 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(); } } diff --git a/uppsrc/CtrlLib/init b/uppsrc/CtrlLib/init index eb04e0781..58fc8e6f3 100644 --- a/uppsrc/CtrlLib/init +++ b/uppsrc/CtrlLib/init @@ -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