[Uml-devel] KDE/kdesdk/umbrello/umbrello/codeimport/kdevcppparser
Jean Vittor
jean.vittor at free.fr
Mon Mar 31 19:40:00 UTC 2008
SVN commit 792295 by jvittor:
Use rules inside macro processing
M +67 -76 lexer.cpp
--- trunk/KDE/kdesdk/umbrello/umbrello/codeimport/kdevcppparser/lexer.cpp #792294:792295
@@ -29,15 +29,23 @@
#include <q3valuelist.h>
#include <boost/bind.hpp>
+#include <boost/function.hpp>
#include <boost/spirit/dynamic/if.hpp>
#include <boost/spirit/phoenix/functions.hpp>
+#include "assignFunctor.hpp"
+
namespace boost { namespace spirit { namespace impl {
bool isalnum_( QChar const& c) {return isalnum_( c.toAscii());}
bool isblank_( QChar const& c) {return isblank_( c.toAscii());}
bool isdigit_( QChar const& c) {return isdigit_( c.toAscii());}
}}}
+template <class _Tp>
+struct tilde : public std::unary_function<_Tp,_Tp> {
+ _Tp operator()(_Tp& __x) const { return ~__x; }
+};
+
using namespace boost::spirit;
using phoenix::arg1;
using phoenix::arg2;
@@ -178,7 +186,7 @@
definition( numberLiteral const& self) {
main =
- (digit_p >> *(alnum_p | '.'))
+ (+digit_p)
[ self.result_ = construct_<Token>( Token_number_literal, arg1, arg2)];
}
};
@@ -711,12 +719,9 @@
int Lexer::macroDefined()
{
- m_source.parse( gr_whiteSpaces);
QString word;
- m_source.parse( identifier_g[assign(word)]);
- bool r = m_driver->hasMacro( word );
-
- return r;
+ m_source.parse( gr_whiteSpaces >> identifier_g[assign(word)]);
+ return m_driver->hasMacro( word );
}
void Lexer::processDefine( Macro& m )
@@ -817,13 +822,6 @@
bool inSkip = m_skipping[ m_ifLevel ];
if( testIfLevel() ) {
-#if 0
- int n;
- if( (n = testDefined()) != 0 ) {
- int isdef = macroDefined();
- m_trueTest[ m_ifLevel ] = (n == 1 && isdef) || (n == -1 && !isdef);
- } else
-#endif
m_trueTest[ m_ifLevel ] = macroExpression() != 0;
m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ];
}
@@ -904,61 +902,48 @@
{
m_source.parse( gr_whiteSpaces);
int result = 0;
- switch( m_source.currentChar().unicode() ) {
- case '(':
- m_source.nextChar();
+ if( m_source.parse( ch_p('(')).hit) {
result = macroExpression();
- if( m_source.currentChar() != ')' ){
- /// @todo report error
- return 0;
+ bool l_hit = m_source.parse( ch_p(')')).hit;
+ /** \todo hit must be true */
+ if( !l_hit)
+ result = 0;
+ } else {
+#warning use locals
+ boost::function<int (int)> l_op = _Identity<int>();
+ if( m_source.parse( ch_p('+')
+ | ch_p('-')[var(l_op) = std::negate<int>()]
+ | ch_p('!')[var(l_op) = std::logical_not<int>()]
+ | ch_p('~')[var(l_op) = tilde<int>()]
+ ).hit) {
+ result = l_op( macroPrimary());
+ } else if( m_source.parse( str_p("defined")).hit) {
+ /** \todo Strange : should result in an identifier (after
+ preprocessor variable substitution) ! */
+ result = macroPrimary();
+ } else {
+ m_source.parse(
+ identifier_g[assignFunctorResult<1>
+ ( result,
+ boost::bind( &Driver::hasMacro, m_driver,
+ _1))]
+ | numberLiteral_g[assignFunctorResult<1>
+ ( result,
+ boost::bind( &Lexer::toInt, _1))]
+ | charLiteral_g[assignFunctorResult<1>
+ ( result,
+ boost::bind( &Lexer::toInt, _1))]
+ );
}
- m_source.nextChar();
- return result;
-
- case '+':
- case '-':
- case '!':
- case '~':
- {
- QChar tk = m_source.currentChar();
- m_source.nextChar();
- int result = macroPrimary();
- if( tk == '-' ) return -result;
- else if( tk == '!' ) return !result;
- else if( tk == '~' ) return ~result;
- }
- break;
-
- default:
- {
- Token tk;
- nextToken( tk);
- switch( tk.type() ){
- case Token_identifier:
- if( tk.text() == "defined" ){
- return macroPrimary();
- }
- /// @todo implement
- return m_driver->hasMacro( tk.text() );
- case Token_number_literal:
- case Token_char_literal:
- return toInt( tk );
- default:
- break;
- } // end switch
-
- } // end default
-
- } // end switch
-
- return 0;
+ }
+ return result;
}
int Lexer::macroMultiplyDivide()
{
int result = macroPrimary();
int iresult, op;
- for (;;) {
+ for (;;) {
m_source.parse( gr_whiteSpaces);
if( m_source.parse(
ch_p('*')[var(op) = 0]
@@ -967,12 +952,19 @@
[var(op) = 1]
| ch_p('%')[var(op) = 2]
).hit) {
+ iresult = macroPrimary();
+ switch( op) {
+ case 0:
+ result = (result * iresult);
+ break;
+ case 1:
+ result = (iresult == 0 ? 0 : (result / iresult));
+ break;
+ case 2:
+ result = (iresult == 0) ? 0 : (result % iresult);
+ }
} else
break;
- iresult = macroPrimary();
- result = op == 0 ? (result * iresult) :
- op == 1 ? (iresult == 0 ? 0 : (result / iresult)) :
- (iresult == 0 ? 0 : (result % iresult)) ;
}
return result;
}
@@ -995,17 +987,16 @@
int Lexer::macroRelational() {
int result = macroAddSubtract();
m_source.parse( gr_whiteSpaces);
- bool lt;
+ boost::function<bool (int, int)> l_op;
while( m_source.parse(
- ch_p('<')[var(lt) = true] | ch_p('>')[var(lt) = false]
+ str_p("<=")[var(l_op) = less_equal<int>()]
+ | ch_p('<')[var(l_op) = less<int>()]
+ | str_p(">=")[var(l_op) = greater_equal<int>()]
+ | ch_p('>')[var(l_op) = greater<int>()]
).hit
) {
int iresult = macroAddSubtract();
- if( m_source.parse( ch_p('=')).hit) {
- result = lt ? (result <= iresult) : (result >= iresult);
- } else {
- result = lt ? (result < iresult) : (result > iresult);
- }
+ result = l_op( result, iresult);
}
return result;
}
@@ -1013,12 +1004,12 @@
int Lexer::macroEquality()
{
int result = macroRelational();
- int iresult;
- bool eq = false;
m_source.parse( gr_whiteSpaces);
- while( m_source.parse( (ch_p('=')[var(eq) = true] | '!') >> '=').hit) {
- iresult = macroRelational();
- result = eq ? (result==iresult) : (result!=iresult);
+ boost::function<bool( int, int)> l_op;
+ while( m_source.parse( str_p("==")[var(l_op) = equal_to<int>()]
+ | str_p("!=")[var(l_op) = not_equal_to<int>()]
+ ).hit) {
+ result = l_op( result, macroRelational());
}
return result;
}
More information about the umbrello-devel
mailing list