⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yyreg.cpp

📁 Linux下的基于X11的图形开发环境。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
static int yyTok; // the current token/*  Returns TRUE if thingy is a constructor or a destructor; otherwise  returns FALSE.*/static bool isCtorOrDtor( const QString& thingy ){    // e.g., Alpha<a>::Beta<Bar<b, c> >::~Beta    QRegExp xtor( QString(	    "(?:([A-Z_a-z][0-9A-Z_a-z]*)" // class name	       "(?:<(?:[^>]|<[^>]*>)*>)*" // template arguments	       "::)+"                     // many in a row	    "~?"                          // ctor or dtor?	    "\\1") );                     // function has same name as class    return xtor.exactMatch( thingy );}/*  Skips over any template arguments with balanced angle brackets, and  returns the skipped material as a string.  Before: QMap < QString , QValueList < QString > > @ m ;  After: QMap @ < QString , QValueList < QString > > m ;*/static QString matchTemplateAngles(){    QString t;    if ( yyTok == Tok_RightAngle ) {	int depth = 0;	do {	    if ( yyTok == Tok_RightAngle )		depth++;	    else if ( yyTok == Tok_LeftAngle )		depth--;	    t.prepend( yyLex );	    yyTok = getToken();	} while ( depth > 0 && yyTok != Tok_Boi && yyTok != Tok_LeftBrace );    }    return t;}/*  Similar to matchTemplateAngles(), but for array brackets in parameter  data types (as in "int *argv[]").*/static QString matchArrayBrackets(){    QString t;    while ( yyTok == Tok_RightBracket ) {	t.prepend( yyLex );	yyTok = getToken();	if ( yyTok == Tok_Something ) {	    t.prepend( yyLex );	    yyTok = getToken();	}	if ( yyTok != Tok_LeftBracket )	    return QString::null;	t.prepend( yyLex );	yyTok = getToken();    }    return t;}/*  Prepends prefix to *type. This operation is in theory trivial, but  for the spacing to look good, we have to do something. The original  spacing is lost as the input is tokenized.*/static void prependToType( QString *type, const QString& prefix ){    if ( !type->isEmpty() && !prefix.isEmpty() ) {	QChar left = prefix[(int) prefix.length() - 1];	QChar right = (*type)[0];	if ( left.isLetter() &&	     (right.isLetter() || right == QChar('*') || right == QChar('&')) )	    type->prepend( QChar(' ') );    }    type->prepend( prefix );}/*  Parses a data type (backwards as usual) and returns a textual  representation of it.*/static QString matchDataType(){    QString type;    while ( yyTok == Tok_Ampersand || yyTok == Tok_Aster ||	    yyTok == Tok_const ) {	prependToType( &type, yyLex );	yyTok = getToken();    }    /*      This code is really hard to follow... sorry. The loop matches      Alpha::Beta::Gamma::...::Omega.    */    for ( ;; ) {	bool virgin = TRUE;	prependToType( &type, matchTemplateAngles() );	if ( yyTok != Tok_Ident ) {	    /*	      People may write 'const unsigned short' or	      'short unsigned const' or any other permutation.	    */	    while ( yyTok == Tok_const || yyTok == Tok_signed ||		    yyTok == Tok_unsigned || yyTok == Tok_short ||		    yyTok == Tok_long ) {		prependToType( &type, yyLex );		yyTok = getToken();		if ( yyTok != Tok_const )		    virgin = FALSE;	    }	    if ( yyTok == Tok_Tilde ) {		prependToType( &type, yyLex );		yyTok = getToken();	    }	}	if ( virgin ) {	    if ( yyTok == Tok_Ellipsis || yyTok == Tok_Ident ||		 yyTok == Tok_char || yyTok == Tok_int ||		 yyTok == Tok_double ) {		prependToType( &type, yyLex );		yyTok = getToken();	    } else {		return QString::null;	    }	} else if ( yyTok == Tok_int || yyTok == Tok_char ||		    yyTok == Tok_double ) {	    prependToType( &type, yyLex );	    yyTok = getToken();	}	while ( yyTok == Tok_const ) {	    prependToType( &type, yyLex );	    yyTok = getToken();	}	if ( yyTok == Tok_Gulbrandsen ) {	    prependToType( &type, yyLex );	    yyTok = getToken();	} else {	    break;	}    }    return type;}/*  Parses a function prototype (without the semicolon) and returns an  object that stores information about this function.*/static CppFunction matchFunctionPrototype( bool stripParamNames ){    CppFunction func;#if 0    QString documentation;#endif    QString returnType;    QString scopedName;    QStringList params;    QString qualifier;    bool cnst = FALSE;    if ( yyTok == Tok_const ) {	cnst = TRUE;	yyTok = getToken();    }    if ( yyTok != Tok_RightParen )	return func;    yyTok = getToken();    if ( yyTok != Tok_LeftParen ) {	for ( ;; ) {	    QString brackets = matchArrayBrackets();	    QString name;	    if ( yyTok == Tok_Ident ) {		name = yyLex;		yyTok = getToken();	    }	    QString type = matchDataType();	    if ( type.isEmpty() ) {		if ( name.isEmpty() )		    return func;		type = name;		name = QString::null;	    }	    if ( stripParamNames )		name = QString::null;	    QString param = type + QChar( ' ' ) + name + brackets;	    params.prepend( param.stripWhiteSpace() );	    if ( yyTok != Tok_Comma )		break;	    yyTok = getToken();	}	if ( yyTok != Tok_LeftParen )	    return func;    }    yyTok = getToken();    for ( ;; ) {	scopedName.prepend( matchTemplateAngles() );	if ( yyTok != Tok_Ident ) {	    // the operator keyword should be close	    int i = 0;	    while ( i < 4 && yyTok != Tok_operator ) {		scopedName.prepend( yyLex );		i++;	    }	    if ( yyTok != Tok_operator )		return func;	}	scopedName.prepend( yyLex );	yyTok = getToken();	if ( yyTok != Tok_Gulbrandsen )	    break;	scopedName.prepend( yyLex );	yyTok = getToken();    }    if ( !isCtorOrDtor(scopedName) ) {	returnType = matchDataType();	if ( returnType.isEmpty() )	    return func;    }    /*      The documentation feature is unused so far, since we cannot      really distinguist between a normal comment between two      functions and one that relates to the following function. One      good heuristic is to assume that a comment immediately followed      by a function with no blank line in between relates to the      function, but there's no easy way to find that out with a      tokenizer.    */#if 0    if ( yyTok == Tok_Comment ) {	documentation = yyLex;	yyTok = getToken();    }    func.setDocumentation( documentation );#endif    func.setReturnType( returnType );    func.setScopedName( scopedName );    func.setParameterList( params );    func.setConst( cnst );    return func;}/*  Try to set the body. It's not sufficient to call  func->setBody(somewhatBody), as the somewhatBody might be too large.  Case in point:    void foo()    {	printf( "Hello" );    }    int n;    void bar()    {	printf( " world!\n" );    }  The parser first finds bar(). Then it finds "void foo() {" and  naively expects the body to extend up to "void bar()". This  function's job is to count braces and make sure "int n;" is not  counted as part of the body.  Cases where the closing brace of the body is missing require no  special processing.*/static void setBody( CppFunction *func, const QString& somewhatBody ){    QString body = somewhatBody;    int braceDepth = 0;    int i = 0;    while ( i < (int) body.length() ) {	if ( body[i] == QChar('{') ) {	    braceDepth++;	} else if ( body[i] == QChar('}') ) {	    braceDepth--;	    if ( braceDepth == 0 ) {		body.truncate( i + 1 );		break;	    }	}	i++;    }    func->setBody( body );}/*  Parses a whole C++ file, looking for function definitions. Case in  point:    void foo()    {	printf( "Hello" );    void bar()    {	printf( " world!\n" );    }  The parser looks for left braces and tries to parse a function  prototype backwards. First it finds "void bar() {". Then it works  up and finds "void foo() {".*/static void matchTranslationUnit( QValueList<CppFunction> *flist ){    int endBody = -1;    int startBody;    for ( ;; ) {	if ( endBody == -1 )	    endBody = yyPos;	while ( yyTok != Tok_Boi && yyTok != Tok_LeftBrace )	    yyTok = getToken();	if ( yyTok == Tok_Boi )	    break;	// found a left brace	yyTok = getToken();	startBody = yyPos;	CppFunction func = matchFunctionPrototype( FALSE );	if ( !func.scopedName().isEmpty() ) {	    QString body = yyIn->mid( startBody, endBody - startBody );	    setBody( &func, body );	    body = func.body(); // setBody() can change the body	    /*	      Compute important line numbers.	    */	    int functionStartLineNo = 1 + QConstString( yyIn->unicode(), yyPos )					  .string().contains( QChar('\n') );	    int startLineNo = functionStartLineNo +		    QConstString( yyIn->unicode() + yyPos, startBody - yyPos )		    .string().contains( QChar('\n') );	    int endLineNo = startLineNo + body.contains( QChar('\n') );	    func.setLineNums( functionStartLineNo, startLineNo, endLineNo );	    flist->prepend( func );	    endBody = -1;	}    }}/*  Extracts C++ function from source code and put them in a list.*/void extractCppFunctions( const QString& code, QValueList<CppFunction> *flist ){    startTokenizer( code );    yyTok = getToken();    matchTranslationUnit( flist );    stopTokenizer();}/*  Returns the prototype with the parameter names removed.*/QString canonicalCppProto( const QString& proto ){    startTokenizer( proto );    yyTok = getToken();    CppFunction func = matchFunctionPrototype( TRUE );    stopTokenizer();    return func.prototype();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -