QString CodeEditor::identAtCursor(){ QTextDocument *doc=document(); int len=doc->characterCount(); int pos=textCursor().position(); while( pos>=0 && pos<len && !isAlpha( doc->characterAt(pos) ) ){ --pos; } if( pos<0 ) return ""; while( pos>0 && isAlpha( doc->characterAt(pos-1) ) ){ --pos; } if( pos==len ) return ""; int start=pos; while( pos<len && isIdent( doc->characterAt(pos) ) ){ ++pos; } if( pos==start ) return ""; QTextCursor cursor( doc ); cursor.setPosition( start ); cursor.setPosition( pos,QTextCursor::KeepAnchor ); QString ident=cursor.selectedText(); return ident; }
QString Highlighter::parseToke( QString &text,QColor &color ){ if( !text.length() ) return ""; int i=0,n=text.length(); QChar c=text[i++]; bool monkeyFile=_editor->isMonkey(); if( c<=' ' ){ while( i<n && text[i]<=' ' ) ++i; }else if( isAlpha(c) ){ while( i<n && isIdent(text[i]) ) ++i; color=_identifiersColor; if( monkeyFile ){ if( _keyWords.contains( text.left(i).toLower() ) ) color=_keywordsColor; } }else if( isDigit(c) || (c=='.' && i<n && isDigit(text[i])) ){ if( i<n && text[i]=='x' && !monkeyFile ){ for( ++i;i<n;++i ){ if( isDigit(text[i]) || (text[i]>='A' && text[i]<='F') || (text[i]>='a' && text[i]<='f') ) continue; break; } }else{ bool flt=(c=='.'); while( i<n && isDigit(text[i]) ) ++i; if( !flt && i<n && text[i]=='.' ){ ++i; flt=true; while( i<n && isDigit(text[i]) ) ++i; } if( i<n && (text[i]=='e' || text[i]=='E') ){ flt=true; if( i<n && (text[i]=='+' || text[i]=='-') ) ++i; while( i<n && isDigit(text[i]) ) ++i; } } color=_numbersColor; }else if( c=='\"' ){ while( i<n && text[i]!='\"' ) ++i; if( i<n ) ++i; color=_stringsColor; }else if( c=='\'' ){ if( monkeyFile || _editor->fileType()=="bmx" ){ while( i<n && text[i]!='\n' ) ++i; if( i<n ) ++i; color=_commentsColor; }else{ while( i<n && text[i]!='\'' ) ++i; if( i<n ) ++i; color=_stringsColor; } }else{ color=_defaultColor; } QString t=text.left(i); text=text.mid(i); return t; }
/* read the @something directives */ static void readIdentifierObjcDirective (lexingState * st) { const unsigned char *p; vStringClear (st->name); /* first char is a simple letter */ if (*st->cp == '@') vStringPut (st->name, (int) *st->cp); /* Go till you get identifier chars */ for (p = st->cp + 1; isIdent (*p); p++) vStringPut (st->name, (int) *p); st->cp = p; }
int Tmlex::readVar() { TstrBuf buff; int ch = Dinput.get(); Tstr posn = Dinput.posn(); unsigned long pos = 0; if ('{' == ch) { ch = Dinput.get(); while (isIdent(ch) || (SEP_S_VAR == ch)) // 009 { if (SEP_S_VAR == ch) // 009 { readVar(); // Recursivly expand the variable } else { buff[pos++] = ch; } ch = Dinput.get(); } buff[pos++] = '\0'; if ('}' != ch) { // Bad variable name Dinput.putBack((char const*)buff); Dinput.putBack('{'); return(0); } else { // Look up the variable and do a put back on its value substitute((char const*)buff); return(1); } } else { // Bad variable name Dinput.putBack(ch); return(0); } }
static void readIdentifier (lexingState * st) { const unsigned char *p; vStringClear (st->name); /* first char is a simple letter */ if (isAlpha (*st->cp) || *st->cp == '_') vStringPut (st->name, (int) *st->cp); /* Go till you get identifier chars */ for (p = st->cp + 1; isIdent (*p); p++) vStringPut (st->name, (int) *p); st->cp = p; vStringTerminate (st->name); }
Ttoken *Tmlex::getToken() { Ttoken *token = NULL; TstrBuf text = ""; unsigned long textIdx = 0; int found = 0; if (NULL != (token = popToken())) { return(token); } else { token = new Ttoken; } token->setType(TOK_ILLEGAL); while (!found) { int ch = Dinput.get(); if (EOF != ch) text[textIdx++] = ch; if (EOF == ch) { // End of file token->setType(TOK_END); token->setText(""); token->setPosn(Dinput.posn()); found = 1; } else if ('\n' == ch) { token->setType(TOK_EOL); token->setText(""); found = 1; } else if (isspace(ch)) { // Ignore white space } else if (SEP_ESC == ch) { // excape ch = Dinput.get(); if ('\n' == ch) { // ignore the end-of-line } else if (SEP_ESC == ch) { // Litteral Dinput.putBack(ch); token->setPosn(Dinput.posn()); found = readIdent(*token); } else { // Excaped charactor Dinput.putBack(ch); } } else if ('#' == ch) { // Check for comment token->setPosn(Dinput.posn()); ch = Dinput.get(); found = readComment(*token); } else if (SEP_TEXT == ch) { // Text token->setPosn(Dinput.posn()); found = readText(*token); } else if (SEP_S_VAR == ch) { // Start an evaluated variable (define) readVar(); } else if (SEP_CALL == ch) { // Call token->setPosn(Dinput.posn()); found = readCall(*token); } else if (isSymb(ch)) { // Symbol token->setPosn(Dinput.posn()); Dinput.putBack(ch); found = readSymb(*token); } else if (isIdent(ch)) { // Ident token->setPosn(Dinput.posn()); Dinput.putBack(ch); found = readIdent(*token); } else { while ((EOF != ch) && !isspace(ch)) ch = Dinput.get(); if (EOF != ch) Dinput.putBack(ch); } } return(token); }
int Tmlex::readIdent(Ttoken &token) { static TstrBuf buff; int ch = Dinput.get(); Tstr posn = Dinput.posn(); unsigned long pos = 0; int mType = 0; while (isIdent(ch) || (SEP_S_VAR == ch)) { if (SEP_S_VAR == ch) { // Posible var if (!readVar()) buff[pos++] = ch; } else if ('\\' == ch) { // Excape any special (or non-special charactors) ch = Dinput.get(); if (isIdent(ch)) { buff[pos++] = ch; } else { Dinput.putBack(ch); } } else { mType = (mType || ('+' == ch) || ('#' == ch) || ('*' == ch) || ('?' == ch) || ('[' == ch) || (']' == ch) || ('\004' == ch)); buff[pos++] = ch; } ch = Dinput.get(); } buff[pos++] = '\0'; Dinput.putBack(ch); if (mType) { token.setType(TOK_MATCH); } else { // This may be a state command if (!strcmp(buff, "echo")) { token.setType(TOK_ECHO); } else if (!strcmp(buff, "cd")) { token.setType(TOK_CHANGE_DIR); } else if (!strcmp(buff, "pwd")) { token.setType(TOK_PRINT_DIR); } else if (!strcmp(buff, "exit")) { token.setType(TOK_EXIT); } else if (!strcmp(buff, "IF")) // 012 { token.setType(TOK_IF); } else if (!strcmp(buff, "ELSE")) // 012 { token.setType(TOK_ELSE); } else if (!strcmp(buff, "ELIF")) // 012 { token.setType(TOK_ELIF); } else if (!strcmp(buff, "FI")) // 012 { token.setType(TOK_ENDIF); } else if (!strcmp(buff, "NOT")) // 012 { token.setType(TOK_NOT); } else if (!strcmp(buff, "IsFILE")) // 012 { token.setType(TOK_FILE); } else if (!strcmp(buff, "IsDIR")) // 012 { token.setType(TOK_DIR); } else if (!strcmp(buff, "IsEXE")) // 012 { token.setType(TOK_EXECUTABLE); } else if (!strcmp(buff, "EXISTS")) // 012 { token.setType(TOK_EXISTS); } else { token.setType(TOK_IDENT); } } token.setText((char const*)buff); return(1); }
void Highlighter::highlightBlock( const QString &ctext ){ QString text=ctext; int i=0,n=text.length(); while( i<n && text[i]<=' ' ) ++i; if( _editor->isMonkey() ){ // // handle monkey block comments // int st=previousBlockState(); int blkst=st; if( i<n && text[i]=='#' ){ int i0=i+1; while( i0<n && text[i0]<=' ' ) ++i0; int i1=i0; while( i1<n && isIdent(text[i1]) ) ++i1; QString t=text.mid( i0,i1-i0 ).toLower(); if( t=="rem" ){ blkst=++st; }else if( t=="if" ){ if( st>-1 ) blkst=++st; }else if( t=="end" || t=="endif" ){ if( st>-1) blkst=st-1; } } setCurrentBlockState( blkst ); if( st>-1 ){ setFormat( 0,text.length(),_commentsColor ); setCurrentBlockUserData( 0 ); return; } } if( !_editor->isCode() ){ setFormat( 0,text.length(),_defaultColor ); setCurrentBlockUserData( 0 ); return; } int indent=i; text=text.mid(i); int colst=0; QColor curcol=_defaultColor; QVector<QString> tokes; for(;;){ QColor col=curcol; QString t=parseToke( text,col ); if( t.isEmpty() ) break; if( t[0]>' ' ) tokes.push_back( t ); if( col!=curcol ){ setFormat( colst,i-colst,curcol ); curcol=col; colst=i; } i+=t.length(); } if( colst<n ) setFormat( colst,n-colst,curcol ); if( _editor->isMonkey() ){ // //Update user block data for code tree. // BlockData *data=0; QString decl=tokes.size()>0 ? tokes[0].toLower() : ""; QString ident=tokes.size()>1 ? tokes[1] : ""; if( (decl=="class" || decl=="interface" || decl=="method" || decl=="function") && !ident.isEmpty() ){ QTextBlock block=currentBlock(); data=dynamic_cast<BlockData*>( currentBlockUserData() ); if( data && data->block()==block && data->decl()==decl && data->ident()==ident && data->indent()==indent ){ }else{ data=new BlockData( this,block,decl,ident,indent ); setCurrentBlockUserData( data ); insert( data ); } }else{ setCurrentBlockUserData( 0 ); } } }
std::string Symbol::extractName(const std::string& decl) { poco_assert (!decl.empty()); // special cases: operator () and operator [] if (decl.find("operator ()") != std::string::npos) return "operator ()"; else if (decl.find("operator[]") != std::string::npos) return "operator []"; std::string::size_type pos = decl.find('('); // another special case: function pointer if (pos != std::string::npos && pos < decl.size() - 1) { std::string::size_type i = pos + 1; while (i < decl.size() && std::isspace(decl[i])) i++; if (i < decl.size() && decl[i] == '*') { i++; std::string name; while (i < decl.size() && std::isspace(decl[i])) i++; while (i < decl.size() && !std::isspace(decl[i]) && decl[i] != ')') name += decl[i++]; return name; } } if (pos == std::string::npos || (pos > 0 && decl[pos - 1] == '(')) pos = decl.size(); --pos; // check for constant; start searching after template std::string::size_type eqStart = 0; if (decl.compare(0, 8, "template") == 0) { eqStart = 8; while (std::isspace(decl[eqStart]) && eqStart < decl.size()) ++eqStart; if (eqStart < decl.size() && decl[eqStart] == '<') { ++eqStart; int tc = 1; while (tc > 0 && eqStart < decl.size()) { if (decl[eqStart] == '<') ++tc; else if (decl[eqStart] == '>') --tc; ++eqStart; } } } std::string::size_type eqPos = decl.find('=', eqStart); if (eqPos != std::string::npos) { // special case: default template parameter std::string::size_type gtPos = decl.find('>', eqPos); std::string::size_type ltPos = decl.find('<', eqPos); if ((gtPos == std::string::npos || gtPos > pos || (ltPos != std::string::npos && gtPos > ltPos)) && eqPos < pos && eqPos > 0 && decl[eqPos + 1] != '=') pos = eqPos - 1; } while (pos > 0 && std::isspace(decl[pos])) --pos; while (pos > 0 && decl[pos] == ']') { --pos; while (pos > 0 && decl[pos] != '[') --pos; if (pos > 0) --pos; while (pos > 0 && std::isspace(decl[pos])) --pos; } // iterate over template (specialization) int nestedTemplateCount = 0; if (pos > 1 && decl[pos] == '>' && decl[pos-1] != '-' && decl[pos-1] != '>') // the operators ->, >> { --pos; ++nestedTemplateCount; while (pos > 0 && nestedTemplateCount != 0) { if (decl[pos] == '<') --nestedTemplateCount; if (decl[pos] == '>') ++nestedTemplateCount; --pos; } while (pos > 0 && std::isspace(decl[pos])) --pos; } std::string::size_type end = pos; std::string::size_type op = decl.find("operator "); if (op != std::string::npos && (op == 0 || std::isspace(decl[op - 1]) || decl[op - 1] == ':')) { pos = op; } else { while (pos > 0 && !isIdent(decl[pos])) --pos; while (pos > 0 && std::isspace(decl[pos])) --pos; while (pos > 0 && isIdent(decl[pos - 1])) --pos; if (pos > 0 && decl[pos - 1] == '~') --pos; } while (pos > 2 && decl[pos - 1] == ':') { pos -= 3; while (pos > 0 && isIdent(decl[pos - 1])) --pos; } return decl.substr(pos, end - pos + 1); }
QString Highlighter::parseToke( QString &text,QColor &color ){ if( !text.length() ) return ""; int i=0,n=text.length(); QChar c=text[i++]; bool monkeyFile=_editor->isMonkey(); if( c<=' ' ){ while( i<n && text[i]<=' ' ) ++i; }else if( isAlpha(c) ){ while( i<n && isIdent(text[i]) ) ++i; color=_identifiersColor; if( monkeyFile && _keyWords.contains( text.left(i).toLower() ) ) color=_keywordsColor; }else if( c=='0' && !monkeyFile ){ if( i<n && text[i]=='x' ){ for( ++i;i<n && isHexDigit( text[i] );++i ){} }else{ for( ;i<n && isOctDigit( text[i] );++i ){} } color=_numbersColor; }else if( isDigit(c) || (c=='.' && i<n && isDigit(text[i])) ){ bool flt=(c=='.'); while( i<n && isDigit(text[i]) ) ++i; if( !flt && i<n && text[i]=='.' ){ ++i; flt=true; while( i<n && isDigit(text[i]) ) ++i; } if( i<n && (text[i]=='e' || text[i]=='E') ){ flt=true; if( i<n && (text[i]=='+' || text[i]=='-') ) ++i; while( i<n && isDigit(text[i]) ) ++i; } color=_numbersColor; }else if( c=='%' && monkeyFile && i<n && isBinDigit( text[i] ) ){ for( ++i;i<n && isBinDigit( text[i] );++i ){} color=_numbersColor; }else if( c=='$' && monkeyFile && i<n && isHexDigit( text[i] ) ){ for( ++i;i<n && isHexDigit( text[i] );++i ){} color=_numbersColor; }else if( c=='\"' ){ if( monkeyFile ){ for( ;i<n && text[i]!='\"';++i ){} }else{ for( ;i<n && text[i]!='\"';++i ){ if( text[i]=='\\' && i+1<n && text[i+1]=='\"' ) ++i; } } if( i<n ) ++i; color=_stringsColor; }else if( !monkeyFile && c=='/' && i<n && text[i]=='/' ){ for( ++i;i<n && text[i]!='\n';++i ){} if( i<n ) ++i; color=_commentsColor; }else if( c=='\'' ){ if( monkeyFile ){ for( ;i<n && text[i]!='\n';++i ){} if( i<n ) ++i; color=_commentsColor; }else{ for( ;i<n && text[i]!='\'';++i ){ if( text[i]=='\\' && i+1<n && text[i+1]=='\'' ) ++i; } if( i<n ) ++i; color=_stringsColor; } }else{ color=_defaultColor; } QString t=text.left(i); text=text.mid(i); return t; }
// whichEnd: which end of the runway are we approaching? inline Runway::WhichEnd Runway::whichEnd(const char rwEndId[]) const { Runway::WhichEnd we = Runway::HIGH_END; if ( !isIdent(rwEndId,we) ) we = Runway::LOW_END; return we; }
bool parseForNextToken() { size_t pos = getCurrentPosition(); assert( pos < codestr.size() ); // // Consume whitespace // for ( ; pos < codestr.size() && isWhitespace(codestr[pos]); ++pos ) { // do nothing, just consume space. } // // End of the line? // if ( pos == codestr.size() ) { setLastToken( "", TOK_EOF ); return false; } size_t startPos = pos; // // Search for the next token // TokenType type = TOK_UNKNOWN; bool done = false; bool error = false; for ( ; (!done) && pos < codestr.size() && (!isWhitespace(codestr[pos])) && ((pos == startPos) || !isEndOfToken(codestr[pos]) ); ++pos ) { char c = codestr[pos]; switch ( type ) { case TOK_UNKNOWN: if ( c == '(' ) { type = TOK_OPEN; done = true; } else if ( c == ')' ) { type = TOK_CLOSE; done = true; } else if ( c == ',' ) { type = TOK_SEP; done = true; } else if ( isNumeric( c ) ) { type = TOK_NUMERIC; } else if ( isIdent( c ) ) { type = TOK_IDENT; } else { error = true; } break; case TOK_NUMERIC: if ( isNumeric( c ) == false ) { error = true; } break; case TOK_IDENT: if ( isIdent( c ) == false ) { error = true; } break; default: error = true; } // // Was there an error while parsing the token? // if ( error ) { std::cerr << "Error while parsing token. " << "start=" << startPos << ", " << "pos=" << pos << ", " << "type=" << toString(type) << ", " << "value: " << codestr.substr( startPos, pos - startPos+1 ) << std::endl; return false; } } setLastToken( codestr.substr(startPos, pos - startPos), type ); setCurrentPosition( pos ); return !isEOF(); }