Third iteration of QMake parser, looking for a parser generator
Roberto Raggi
roberto.raggi at gmail.com
Thu Jul 5 14:50:19 UTC 2007
Hi Andreas,
Il giorno 05/lug/07, alle ore 13:55, Andreas Pakulat ha scritto:
> So to conclude: kdev-pg will get another use-case :)
This is a very good news for KDevelop. You can help the kdev
developers working on kdev-pg to improve it ;-) I really think it
should be easy to change kdev-pg to generate the code you need for
the qmake parser and I'm sure that those changes will be very helpful
for the other programming language plug-ins.
>
> That would be cool, I've already got an idea how to write it, but that
You can find in attachment a little example of an incremental lexer
for a dummy language. The example is small (about 200 loc), but it
shows how to recognize common tokens like whitespaces, C++ comments,
string literals, identifiers, and operators with 1 or 2 characters.
It also has 2 states, so you have an example of how to handle multi-
state lexers.
The signature of the Lexer is very simple, so you have two methods to
get and set the active state, a method that returns the type of the
current token and a method(it is a function call operator actually)
that advance the scanner.
class Lexer: Constants {
public:
Lexer(int state = State_default);
inline int state() const { return _state; }
inline void setState(int state) { _state = state; }
inline int token() const { return _token; }
const QChar *operator()(const QChar *it, const QChar *last);
..
};
how do you use it? well, if you need to scan a file you do
void tokenize(const QString &filename) {
QFile file(filename);
if (file.open(QFile::ReadOnly)) {
QTextStream stream(&file);
QString contents = stream.readAll();
const QChar *begin = contents.unicode();
const QChar *it = begin, *end = begin + contents.length();
Lexer yylex;
while (it != end) {
int start = it - begin;
it = yylex(it, end);
int stop = it - begin;
qDebug() << "*** token:" << yylex.token() << "location:" <<
start << stop;
}
}
}
or if you want to use it as syntax highlighter..
class SyntaxHighlighter: public QSyntaxHighlighter, Constants {
public:
SyntaxHighlighter(QTextEdit *editor):
QSyntaxHighlighter(editor) {}
protected:
virtual void highlightBlock(const QString &text) {
int state = previousBlockState();
yylex.setState(state != -1 ? state : State_default);
const QChar *begin = text.unicode();
const QChar *it = begin, *end = begin + text.length();
while (it != end) {
int start = it - begin;
it = yylex(it, end);
int stop = it - begin;
switch (yylex.token()) {
case Token_comment:
setFormat(start, stop - start, Qt::darkRed);
break;
/// more ...
default:
break;
}
}
setCurrentBlockState(yylex.state());
}
private:
Lexer yylex;
};
as you can see it is very simple to use. You can generate the code to
recognize the keywords with kwgen.cpp the little tool I posted 2-3
days ago. I think you should be able to change the example to
recognize tokens for qmake or any other other(real?) language.
ciao robe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: lex.cpp
Type: application/octet-stream
Size: 4130 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kdevelop-devel/attachments/20070705/482c1abd/attachment.obj>
-------------- next part --------------
More information about the KDevelop-devel
mailing list