33 #include <boost/bind.hpp>
34 #include <boost/function.hpp>
35 #include <boost/spirit/include/classic_if.hpp>
36 #include <boost/spirit/include/phoenix1_functions.hpp>
55 struct tilde :
public std::unary_function<_Tp, _Tp> {
56 _Tp operator()(_Tp& __x)
const {
61 using namespace boost::spirit::classic;
65 using phoenix::construct_;
66 using phoenix::function;
69 SkipRule Lexer::m_SkipRule = nothing_p;
71 #if defined(KDEVELOP_BGPARSER)
77 static void yield() { msleep(0); }
80 inline void qthread_yield()
90 template <
typename ResultT >
91 struct result_closure : closure<result_closure<ResultT>, ResultT> {
92 typedef closure<result_closure<ResultT>, ResultT> base_t;
93 typename base_t::member1 result_;
97 struct constructQString_impl {
98 template <
typename _Arg1,
typename _Arg2>
100 typedef QString type;
103 template <
typename _Arg1,
typename _Arg2>
104 QString operator()(_Arg1
const& first, _Arg2
const& last) {
105 return QString(&*first, &*last - &*first);
110 constructQString_impl();
113 grammar<identifier, result_closure<QString>::context_t> {
114 template <
typename ScannerT >
116 typedef rule<ScannerT> rule_t;
119 rule_t
const& start()
const {
123 definition(identifier
const&
self) {
125 ((alpha_p |
'_') >> *(alnum_p |
'_'))
133 grammar<operator_, result_closure<Token>::context_t> {
134 template <
typename ScannerT >
136 typedef rule<ScannerT, result_closure<int>::context_t> rule_t;
139 rule_t
const& start()
const {
143 definition(operator_
const&
self) {
147 | (str_p(
"<<=") |
">>=" |
"+=" |
"-=" |
"*=" |
"/=" |
"%=" |
"^=" |
"&=" |
"|=")[
main.result_ =
Token_assign]
160 [
self.result_ = construct_<Token>(
main.result_, arg1, arg2)];
166 grammar<charLiteral, result_closure<Token>::context_t> {
167 template <
typename ScannerT >
169 typedef rule<ScannerT, result_closure<int>::context_t> rule_t;
172 rule_t
const& start()
const {
176 definition(charLiteral
const&
self) {
178 (!ch_p(
'L') >> ch_p(
'\'')
186 struct numberLiteral :
187 grammar<numberLiteral, result_closure<Token>::context_t> {
188 template <
typename ScannerT >
190 typedef rule<ScannerT, result_closure<int>::context_t> rule_t;
193 rule_t
const& start()
const {
197 definition(numberLiteral
const&
self) {
199 (ch_p(
'0') >> ch_p(
'x') >> + xdigit_p | + digit_p)
207 struct DependencyClosure
208 : boost::spirit::classic::closure<DependencyClosure, QString, int> {
232 m_start(start.get_position()),
233 m_end(end.get_position()),
234 m_text(&*start, &*end - &*start)
252 <<
"type:" << t.
type()
253 <<
"text:" << t.
text()
263 return Token(type, start, end);
269 typedef QMap<QString, QString> Scope;
272 StaticChain staticChain;
276 staticChain.push_front(scope);
280 staticChain.pop_front();
283 void bind(
const QString& name,
const QString& value) {
284 Q_ASSERT(staticChain.size() > 0);
285 staticChain.front().insert(name, value);
288 bool hasBind(
const QString& name)
const {
289 StaticChain::ConstIterator it = staticChain.begin();
290 while (it != staticChain.end()) {
291 const Scope& scope = *it;
294 if (scope.contains(name))
301 QString apply(
const QString& name)
const {
302 StaticChain::ConstIterator it = staticChain.begin();
303 while (it != staticChain.end()) {
304 const Scope& scope = *it;
307 if (scope.contains(name))
308 return scope[ name ];
318 m_recordComments(false),
319 m_preprocessLexer(m_driver)
329 const QString& p_filename)
332 m_preprocessLexer.
setSource(source, p_filename);
333 m_source.set_filename(p_filename);
349 void Lexer::nextToken(
Token& tk)
355 QChar ch = m_source.currentChar();
356 if (ch.isNull() || ch.isSpace()) {
358 }
else if (m_source.get_startLine()
360 m_source.set_startLine(
false);
365 handleDirective(directive);
366 }
else if (m_source.parse
368 if_p(var(m_recordComments))
378 }
else if (ch.isLetter() || ch ==
'_') {
384 tk = m_source.createToken(k, start);
394 tk = m_source.createToken(ch.unicode(), l_ptr);
396 if (m_source.parse(eol_p).hit)
397 m_source.set_startLine(
true);
399 m_source.set_startLine(
false);
402 bool Lexer::tokenize()
408 for (
int i = 0; i < l_tmp.size(); ++i)
409 std::cout << l_tmp.at(i);
410 std::cout << std::endl;
413 m_source.set_startLine(
true);
419 m_tokens.push_back(tk);
421 if (m_source.currentChar().isNull())
426 m_tokens.push_back(tk);
430 void Lexer::handleDirective(
const QString& directive)
433 assert(directive !=
"define");
434 assert(directive !=
"else");
435 assert(directive !=
"elif");
436 assert(directive !=
"endif");
437 assert(directive !=
"if");
438 assert(directive !=
"ifdef");
439 assert(directive !=
"ifndef");
440 assert(directive !=
"include");
441 assert(directive !=
"undef");
Position currentPosition() const
bool isalnum_(QChar const &c)
std::pair< QString, int > Dependency
QString const & preprocessedString() const
int main(int argc, char *argv[])
PreprocessLexer::CharRule gr_escapeSequence
void setSource(const QString &source, const QString &p_filename)
Lexer::CharRule gr_skipTillEol
QDebug operator<<(QDebug out, const Token &t)
Lexer::CharRule gr_lineComment
bool isxdigit_(QChar const &c)
Lexer::CharRule gr_whiteSpace
Lexer::CharRule gr_stringLiteral
bool isblank_(QChar const &c)
static int find(const struct HashTable *table, const QString &s)
Find an entry in the table, and return its value (i.e.
Lexer::CharRule gr_multiLineComment
rule< scanner< CharIterator, CharPolicies > > CharRule
bool isdigit_(QChar const &c)
Position const & getStartPosition() const
bool isalpha_(QChar const &c)
Position const & getTokenPosition(const Token &token) const
bool setSource(const QString &source, const QString &p_filename)
const function< constructQString_impl > constructQString
charLiteral charLiteral_g
rule< scanner< CharIterator > > SkipRule
Position const & getEndPosition() const
numberLiteral numberLiteral_g
QString const & text() const
static const struct HashTable keyword
Token & operator=(Token const &p)