[Uml-devel] KDE/kdesdk/umbrello/umbrello/codeimport/kdevcppparser
Jean Vittor
jean.vittor at free.fr
Tue Apr 1 13:55:07 UTC 2008
SVN commit 792532 by jvittor:
Isolate skipping management
M +44 -117 lexer.cpp
M +46 -11 lexer.h
--- trunk/KDE/kdesdk/umbrello/umbrello/codeimport/kdevcppparser/lexer.cpp #792531:792532
@@ -312,15 +312,16 @@
void Lexer::reset()
{
- m_tokens.clear();
+ m_tokens.clear();
m_source.reset();
- m_ifLevel = 0;
- m_skipping.resize( 200 );
- m_skipping.fill( 0 );
- m_trueTest.resize( 200 );
- m_trueTest.fill( 0 );
+ m_preprocessor.reset();
}
+void Lexer::Preprocessor::reset() {
+ m_skipping.clear();
+ m_trueTest.clear();
+}
+
// ### should all be done with a "long" type IMO
int Lexer::toInt( const Token& token )
{
@@ -381,7 +382,7 @@
m_source.parse( identifier_g[ assign(directive)]); // read the directive
handleDirective( directive );
- } else if( m_source.get_startLine() && m_skipping[ m_ifLevel ] ) {
+ } else if( m_source.get_startLine() && m_preprocessor.inSkip()) {
// skip line and continue
m_source.set_startLine( false);
bool ppe = m_preprocessorEnabled;
@@ -661,7 +662,7 @@
void Lexer::handleDirective( const QString& directive )
{
- m_inPreproc = true;
+ m_inPreproc = true;
bool skip = m_skipWordsEnabled;
bool preproc = m_preprocessorEnabled;
@@ -669,54 +670,48 @@
m_skipWordsEnabled = false;
m_preprocessorEnabled = false;
- if( directive == "define" ){
- if( !m_skipping[ m_ifLevel ] ){
- Macro m;
- processDefine( m );
- }
- } else if( directive == "else" ){
- processElse();
- } else if( directive == "elif" ){
- processElif();
- } else if( directive == "endif" ){
- processEndif();
- } else if( directive == "if" ){
- processIf();
- } else if( directive == "ifdef" ){
- processIfdef();
- } else if( directive == "ifndef" ){
- processIfndef();
- } else if( directive == "include" ){
- if( !m_skipping[ m_ifLevel ] ){
- processInclude();
- }
- } else if( directive == "undef" ){
- if( !m_skipping[ m_ifLevel ] ){
- processUndef();
- }
+ if( directive == "define" ){
+ if( !m_preprocessor.inSkip()) {
+ Macro m;
+ processDefine( m );
}
+ } else if( directive == "else" ){
+ if( !m_preprocessor.empty())
+ m_preprocessor.processElse();
+ } else if( directive == "elif" ){
+ if( !m_preprocessor.empty())
+ m_preprocessor.processElif( macroExpression());
+ } else if( directive == "endif" ){
+ if( !m_preprocessor.empty())
+ m_preprocessor.decrement();
+ } else if( directive == "if") {
+ m_preprocessor.processIf( macroExpression());
+ } else if( directive == "ifdef") {
+ m_preprocessor.processIf( macroDefined());
+ } else if( directive == "ifndef" ){
+ m_preprocessor.processIf( !macroDefined());
+ } else if( directive == "include" ){
+ if( !m_preprocessor.inSkip())
+ processInclude();
+ } else if( directive == "undef" ){
+ if( !m_preprocessor.inSkip())
+ processUndef();
+ }
- // skip line
- while( !m_source.currentChar().isNull()
- && m_source.currentChar() != '\n'
- && m_source.currentChar() != '\r') {
- Token tk;
- nextToken( tk);
- }
+ // skip line
+ while( !m_source.currentChar().isNull()
+ && m_source.currentChar() != '\n'
+ && m_source.currentChar() != '\r') {
+ Token tk;
+ nextToken( tk);
+ }
m_skipWordsEnabled = skip;
m_preprocessorEnabled = preproc;
- m_inPreproc = false;
+ m_inPreproc = false;
}
-int Lexer::testIfLevel()
-{
- int rtn = !m_skipping[ m_ifLevel++ ];
- m_skipping[ m_ifLevel ] = m_skipping[ m_ifLevel - 1 ];
- return rtn;
-}
-
int Lexer::macroDefined()
{
QString word;
@@ -779,74 +774,6 @@
m_driver->addMacro( m );
}
-void Lexer::processElse()
-{
- if( m_ifLevel == 0 )
- /// @todo report error
- return;
-
- if( m_ifLevel > 0 && m_skipping[m_ifLevel-1] )
- m_skipping[ m_ifLevel ] = m_skipping[ m_ifLevel - 1 ];
- else
- m_skipping[ m_ifLevel ] = m_trueTest[ m_ifLevel ];
-}
-
-void Lexer::processElif()
-{
- if( m_ifLevel == 0 )
- /// @todo report error
- return;
-
- if( !m_trueTest[m_ifLevel] ){
- /// @todo implement the correct semantic for elif!!
- bool inSkip = m_ifLevel > 0 && m_skipping[ m_ifLevel-1 ];
- m_trueTest[ m_ifLevel ] = macroExpression() != 0;
- m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ];
- }
- else
- m_skipping[ m_ifLevel ] = true;
-}
-
-void Lexer::processEndif()
-{
- if( m_ifLevel == 0 )
- /// @todo report error
- return;
-
- m_skipping[ m_ifLevel ] = 0;
- m_trueTest[ m_ifLevel-- ] = 0;
-}
-
-void Lexer::processIf()
-{
- bool inSkip = m_skipping[ m_ifLevel ];
-
- if( testIfLevel() ) {
- m_trueTest[ m_ifLevel ] = macroExpression() != 0;
- m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ];
- }
-}
-
-void Lexer::processIfdef()
-{
- bool inSkip = m_skipping[ m_ifLevel ];
-
- if( testIfLevel() ){
- m_trueTest[ m_ifLevel ] = macroDefined();
- m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ];
- }
-}
-
-void Lexer::processIfndef()
-{
- bool inSkip = m_skipping[ m_ifLevel ];
-
- if( testIfLevel() ){
- m_trueTest[ m_ifLevel ] = !macroDefined();
- m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ];
- }
-}
-
typedef std::pair<QString, int> Dependency;
struct DependencyClosure
@@ -883,7 +810,7 @@
} header_g;
void Lexer::processInclude() {
- if( !m_skipping[m_ifLevel] )
+ if( !m_preprocessor.inSkip())
m_source.parse( gr_whiteSpaces >>
header_g
[boost::bind( &Lexer::addDependence, this, _1)]
--- trunk/KDE/kdesdk/umbrello/umbrello/codeimport/kdevcppparser/lexer.h #792531:792532
@@ -236,7 +236,6 @@
void reset();
// preprocessor (based on an article of Al Stevens on Dr.Dobb's journal)
- int testIfLevel();
int macroDefined();
QString readArgument();
@@ -254,12 +253,6 @@
void handleDirective( const QString& directive );
void processDefine( Macro& macro );
- void processElse();
- void processElif();
- void processEndif();
- void processIf();
- void processIfdef();
- void processIfndef();
void processInclude();
void processUndef();
@@ -340,10 +333,52 @@
bool m_skipWordsEnabled;
- // preprocessor
- Q3MemArray<bool> m_skipping;
- Q3MemArray<bool> m_trueTest;
- int m_ifLevel;
+ /** Manages skipping. */
+ class Preprocessor {
+ public:
+ void decrement() {
+ m_skipping.pop_back();
+ m_trueTest.pop_back();
+ }
+ bool empty() const {return m_skipping.empty();}
+ bool inSkip() const {return (!empty() && m_skipping.back());}
+ void processElse()
+ {m_skipping.back() = previousInSkip() || m_trueTest.back();}
+ void processElif( bool p_test) {
+ if( m_trueTest.back())
+ m_skipping.back() = true;
+ else {
+ /// @todo implement the correct semantic for elif!!
+ m_trueTest.back() = p_test;
+ m_skipping.back() = previousInSkip() || !p_test;
+ }
+ }
+ void processIf( bool p_test) {
+ if( increment()) {
+ m_trueTest.back() = p_test;
+ m_skipping.back() = inSkip() ? true : !m_trueTest.back();
+ }
+ }
+
+ void reset();
+ private:
+ bool increment() {
+ bool l_return = false;
+ if( empty())
+ l_return = true;
+ else
+ l_return = !m_skipping.back();
+ m_skipping.push_back( !l_return);
+ m_trueTest.push_back( false);
+ return l_return;
+ }
+ bool previousInSkip() const
+ {return ((m_skipping.size() > 1) && *(++m_skipping.rbegin()));}
+
+ std::vector<bool> m_skipping;
+ std::vector<bool> m_trueTest;
+ };
+ Preprocessor m_preprocessor;
bool m_preprocessorEnabled;
bool m_inPreproc;
private:
More information about the umbrello-devel
mailing list