From 2a59d2ae0c889fe6e4ac50a3f110b0103f880c15 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Sun, 14 Feb 2010 14:41:51 +0100 Subject: Split Objective-C keyword parsing to handle the '@' separately. Because apparently, while designing the Objective-C language, somebody thought it was a world-class idea to allow any white-space between the '@' character and the subsequent keyword. With this fix, we now correctly parse: @ dynamic and: @ selector and: @"foo" "bar" @"mooze" (This last one is 1 single string split over multiple lines.) Wonderful, isn't it? What we (and Clang) do not support, but what GCC supports is something like: @"foo"@@ "bar" @"mooze" @@ which is equivalent to @"foobarmooze". --- src/shared/cplusplus/Lexer.cpp | 62 ++++++++++-------------------------------- 1 file changed, 14 insertions(+), 48 deletions(-) (limited to 'src/shared/cplusplus/Lexer.cpp') diff --git a/src/shared/cplusplus/Lexer.cpp b/src/shared/cplusplus/Lexer.cpp index 9a71ccfa7e..f8cc188238 100644 --- a/src/shared/cplusplus/Lexer.cpp +++ b/src/shared/cplusplus/Lexer.cpp @@ -596,52 +596,11 @@ void Lexer::scan_helper(Token *tok) tok->f.kind = T_COMMA; break; - default: { - if (f._objCEnabled) { - if (ch == '@' && _yychar >= 'a' && _yychar <= 'z') { - const char *yytext = _currentChar; - - do { - yyinp(); - if (! (isalnum(_yychar) || _yychar == '_' || _yychar == '$')) - break; - } while (_yychar); - - const int yylen = _currentChar - yytext; - tok->f.kind = classifyObjCAtKeyword(yytext, yylen); - break; - } else if (ch == '@' && _yychar == '"') { - // objc @string literals - ch = _yychar; - yyinp(); - tok->f.kind = T_AT_STRING_LITERAL; - - const char *yytext = _currentChar; - - while (_yychar && _yychar != '"') { - if (_yychar != '\\') - yyinp(); - else { - yyinp(); // skip `\\' - - if (_yychar) - yyinp(); - } - } - // assert(_yychar == '"'); - - int yylen = _currentChar - yytext; - - if (_yychar == '"') - yyinp(); - - if (control()) - tok->string = control()->findOrInsertStringLiteral(yytext, yylen); - - break; - } - } + case '@': + tok->f.kind = T_AT; + break; + default: { if (ch == 'L' && (_yychar == '"' || _yychar == '\'')) { // wide char/string literals ch = _yychar; @@ -679,11 +638,18 @@ void Lexer::scan_helper(Token *tok) while (std::isalnum(_yychar) || _yychar == '_' || _yychar == '$') yyinp(); int yylen = _currentChar - yytext; - if (f._scanKeywords) + if (f._scanKeywords) { tok->f.kind = classify(yytext, yylen, f._qtMocRunEnabled); - else + } else { tok->f.kind = T_IDENTIFIER; - + } + // ### is this correct w.r.t. the _scanKeywords? + if (f._objCEnabled && tok->f.kind == T_IDENTIFIER) { + tok->f.kind = classifyObjCAtKeyword(yytext, yylen); + if (tok->f.kind == T_ERROR) + tok->f.kind = T_IDENTIFIER; + } + // ### is this correct w.r.t. the _scanKeywords? if (tok->f.kind == T_IDENTIFIER) { tok->f.kind = classifyOperator(yytext, yylen); -- cgit v1.2.1