syntax highlighter?

  • Thread starter Thread starter Bonj
  • Start date Start date
B

Bonj

does anybody know if there is a good SQL syntax highlighting control? Must
be freeware.
If not can anybody think of a good way of writing one in C# or C++ that
doesn't flicker?
Thanks
 
Bonj,

Here is the starting point - the rest is up to you (p.s. I have implemented
one of these for (PL/SQL))

1) You need to get a good book on writing compilers - one that has a good
coverage of token concepts, scanning, and parsing techniques.

2) Build your keyword table. Make user that you handle the complete grammar
(identify all delimiters, know the implications of keyword context - for
instance NULL is a keyword, but may appear in many contexts; as a rvalue or
in an expression, or in a literal constant such as a string or comment)...

Whether or not you have a good design starts with the design of the keyword
table.

3) For the control, use the richedit control to display the text. Here is a
link:
http://msdn.microsoft.com/library/d...it/richeditcontrols/aboutricheditcontrols.asp

The richedit control does a lot, and therefore, it quite a monster to
master, but there is a lot of documentation. As for flicker, DO NOT reload
the control all of the time. The most common mistake is to rebuild and
reload all of the time. Do all of the edits and modifications in place. If
this is a dynamic control, and if the user changes the following:
v_firstName := noll;
to this
v_firstName := null;

know that the third token on the line is now a reserved work, and set the
attributes accordingly - do not redraw the entire control...

4) This is not a novice undertaking. If you have already have a good grasp
on 1) and 2), then 3) will be but a walk in the park.

regards,

that's all i have for you on this matter...

roy fine
 
Oh I've already got the keyword list, system proc/table list and function
list off MSDN. I've compiled them into a (unmanaged) C++ dll into which
takes the current RTB text, the start and end points of the new part of that
text (wherever and however long this may be, usually the same character when
characters are sequentially typed, but the user could copy and paste text
in).
In the c++ dll, it then parses out all the possibly changed keywords from
the string between the start and end position (rounded inclusively to the
nearest whole word) and fills three int[] arrays, one for the start
positions of 'colored' words, one for the lengths of the 'colored' words,
and one for the type of 'colored' word - system, keyword or function. It
returns the number of keywords in the section that includes the changed text
(which is often just the word being typed). The C# program then applies
these to the RTB. The C++ dll is using unicode, and uses _tcs* functions to
check whether each word it parses is a keyword. Is this how you'd go about
it?

It is still a tiny little bit flickery though on odd occasions, although
mostly it is more than acceptable and turns keywords the right color
perfectly. I think this is largely due to the fact that the RTB can only set
color when the text to be colored is selected. Do you know of anyway round
this? Low-level messaging-based hack maybe?

This is the C++ code that does the parsing:

enum WORDTYPE {WT_NONE = 0, WT_RESWORD = 1, WT_FUNCTION = 2, WT_SYSTEMPROC =
3};

long GetWordType(const int maxlen, const _TCHAR* word)

{

_TCHAR* absword = new _TCHAR[maxlen];

_tcscpy(absword, _T(" "));

_tcscat(absword, word);

_tcscat(absword, _T(" "));

if(_tcsstr(sql_reserved_words, absword) != NULL) return WT_RESWORD;

if(_tcsstr(sql_functions, absword) != NULL) return WT_FUNCTION;

if(_tcsstr(sql_system_procs, absword) != NULL) return WT_SYSTEMPROC;

delete[] absword;

return WT_NONE;

}

const _TCHAR* okchars =
_T("#$0123456789@_abcdefghijklmnopqrstuvwxyzfSOZsozYªµ·ºÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ
ÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ");

inline BOOL CharIsLetter(_TCHAR testchar)

{

return _tcschr(okchars, testchar) != NULL ? TRUE : FALSE;

// BOOL retval = ( (testchar >= 'a') && (testchar <= 'z') ) ||

// (testchar = '$') ||

// (testchar = '#') ||

// (testchar = '_');

// return retval;

}

long __stdcall GetWords(//long startpos,

//long endpos,

//long& abs_startpos,

//long& abs_endpos,

_TCHAR* input,

long* startpos_array,

long* length_array,

long* type_array

) //returns array size (number of words found)

{

long abs_startpos = 0, abs_endpos = 0, startpos = 0, endpos = 0;

//get to the start of the first affected word and the end of the last one

int totallen = (int)_tcslen(input);

//if start is character, go left if not, go right. for end position, v.v.

//(caller is responsible for broadening to include possibly revalidated
word)

if(CharIsLetter(input[startpos])) //if it's a letter, go left, if not, go
right

for(abs_startpos = startpos;

(abs_startpos > 0) && (CharIsLetter(input[abs_startpos]));

abs_startpos--);

else

for(abs_startpos = startpos;

(abs_startpos < endpos) && (!CharIsLetter(input[abs_startpos]));

abs_startpos++);

if(CharIsLetter(input[endpos]))

for(abs_endpos = endpos;

(abs_endpos < totallen - 1) && CharIsLetter(input[abs_endpos]);

abs_endpos++);

else

for(abs_endpos = endpos;

(abs_endpos >= abs_startpos) && (!CharIsLetter(input[abs_endpos]));

abs_endpos--);

//eliminate any leading punctuation character

if((abs_startpos > 0) || (!CharIsLetter(input[abs_startpos])))
abs_startpos++;


//parse the words...

int wordstart = abs_startpos;

BOOL inword = TRUE;

long numwords = 0, arrayindex = 0;

for(int pos = abs_startpos; pos <= abs_endpos; pos++)

{

if(inword)

{

if((!CharIsLetter(input[pos])) || pos == abs_endpos) //just finished a word

{

if(pos != abs_endpos) input[pos] = 0;

const _TCHAR* substring = input + wordstart; //pointer offset

long wt = GetWordType(totallen, substring);

if(wt != WT_NONE)

{

startpos_array[arrayindex] = wordstart;

length_array[arrayindex] = pos - wordstart;

type_array[arrayindex++] = wt;

}

inword = FALSE;

}

}else

{

if(CharIsLetter(input[pos])) //just started a word

{

wordstart = pos;

inword = TRUE;

}

}

}

return arrayindex;

}
 
Roy
would you possibly care to have a little look at my existing code?
I've posted it at
http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=2354&lngWId=10

It should be currently in a working state - it's just it could possibly do
with
a few refinements, I'm not asking you to debug it or 'get it working' or do
it
for me, I'd just be really interested to hear any comments you can give me
on
'which direction I should be leaning in next' so to speak...
Also do you think I'm right to implement the main algorithm in an
unmanaged DLL? It seems to be functioning OK, but like I say
I'd be interested to get somebody else's opinion - there's no COM,
but I'm not sure whether the speed gains of C++ outweight the marshaling
overhead, I think they probably do but I'm not sure...

Thanks very much in advance for any suggestions
(ignore the vb folder in the URL. There's no VB of any kind in it.)
 
in said:


Ah I see you're busily winning friends and influencing people in
other groups as well now. She's a sharp cookie - too bad you
blew her off so rudely.
 
Back
Top