Better Objective-QC keyword detection.

Use a flag in the keyword struct rather than checking for "@" in the
keyword. This catches such keywords as "id" and "Protocol" as well.
This commit is contained in:
Bill Currie 2011-02-04 08:38:58 +09:00
parent 993bee4f59
commit 7b22bfba63

View file

@ -261,65 +261,66 @@ typedef struct {
type_t *type; type_t *type;
unsigned int traditional; unsigned int traditional;
unsigned int version; unsigned int version;
int objc;
} keyword_t; } keyword_t;
static keyword_t keywords[] = { static keyword_t keywords[] = {
{"void", TYPE, &type_void, 1, PROG_ID_VERSION}, {"void", TYPE, &type_void, 1, PROG_ID_VERSION, 0},
{"float", TYPE, &type_float, 1, PROG_ID_VERSION}, {"float", TYPE, &type_float, 1, PROG_ID_VERSION, 0},
{"string", TYPE, &type_string, 1, PROG_ID_VERSION}, {"string", TYPE, &type_string, 1, PROG_ID_VERSION, 0},
{"vector", TYPE, &type_vector, 1, PROG_ID_VERSION}, {"vector", TYPE, &type_vector, 1, PROG_ID_VERSION, 0},
{"entity", TYPE, &type_entity, 1, PROG_ID_VERSION}, {"entity", TYPE, &type_entity, 1, PROG_ID_VERSION, 0},
{"quaternion", TYPE, &type_quaternion, 0, PROG_VERSION}, {"quaternion", TYPE, &type_quaternion, 0, PROG_VERSION, 0},
{"integer", TYPE, &type_integer, 0, PROG_VERSION}, {"integer", TYPE, &type_integer, 0, PROG_VERSION, 0},
{"unsigned", TYPE, &type_integer, 0, PROG_VERSION},//FIXME {"unsigned", TYPE, &type_integer, 0, PROG_VERSION, 0},//FIXME
{"function", TYPE, &type_function, 0, PROG_VERSION}, {"function", TYPE, &type_function, 0, PROG_VERSION, 0},
{"id", TYPE, &type_id, 0, PROG_VERSION}, {"id", TYPE, &type_id, 0, PROG_VERSION, 1},
{"Class", TYPE, &type_Class, 0, PROG_VERSION}, {"Class", TYPE, &type_Class, 0, PROG_VERSION, 1},
// {"Protocol", TYPE, &type_Protocol, 0, PROG_VERSION}, // {"Protocol", TYPE, &type_Protocol, 0, PROG_VERSION, 0},
{"Method", TYPE, &type_Method, 0, PROG_VERSION}, {"Method", TYPE, &type_Method, 0, PROG_VERSION, 1},
{"Super", TYPE, &type_Super, 0, PROG_VERSION}, {"Super", TYPE, &type_Super, 0, PROG_VERSION, 1},
{"SEL", TYPE, &type_SEL, 0, PROG_VERSION}, {"SEL", TYPE, &type_SEL, 0, PROG_VERSION, 1},
{"IMP", TYPE, &type_IMP, 0, PROG_VERSION}, {"IMP", TYPE, &type_IMP, 0, PROG_VERSION, 1},
{"local", LOCAL, 0, 1, PROG_ID_VERSION}, {"local", LOCAL, 0, 1, PROG_ID_VERSION, 0},
{"return", RETURN, 0, 1, PROG_ID_VERSION}, {"return", RETURN, 0, 1, PROG_ID_VERSION, 0},
{"while", WHILE, 0, 1, PROG_ID_VERSION}, {"while", WHILE, 0, 1, PROG_ID_VERSION, 0},
{"do", DO, 0, 1, PROG_ID_VERSION}, {"do", DO, 0, 1, PROG_ID_VERSION, 0},
{"if", IF, 0, 1, PROG_ID_VERSION}, {"if", IF, 0, 1, PROG_ID_VERSION, 0},
{"else", ELSE, 0, 1, PROG_ID_VERSION}, {"else", ELSE, 0, 1, PROG_ID_VERSION, 0},
{"for", FOR, 0, 0, PROG_ID_VERSION}, {"for", FOR, 0, 0, PROG_ID_VERSION, 0},
{"break", BREAK, 0, 1, PROG_ID_VERSION}, {"break", BREAK, 0, 1, PROG_ID_VERSION, 0},
{"continue", CONTINUE, 0, 0, PROG_ID_VERSION}, {"continue", CONTINUE, 0, 0, PROG_ID_VERSION, 0},
{"switch", SWITCH, 0, 0, PROG_ID_VERSION}, {"switch", SWITCH, 0, 0, PROG_ID_VERSION, 0},
{"case", CASE, 0, 0, PROG_ID_VERSION}, {"case", CASE, 0, 0, PROG_ID_VERSION, 0},
{"default", DEFAULT, 0, 0, PROG_ID_VERSION}, {"default", DEFAULT, 0, 0, PROG_ID_VERSION, 0},
{"nil", NIL, 0, 0, PROG_ID_VERSION}, {"nil", NIL, 0, 0, PROG_ID_VERSION, 0},
{"struct", STRUCT, 0, 0, PROG_VERSION}, {"struct", STRUCT, 0, 0, PROG_VERSION, 0},
{"union", STRUCT, 0, 0, PROG_VERSION}, {"union", STRUCT, 0, 0, PROG_VERSION, 0},
{"enum", ENUM, 0, 0, PROG_ID_VERSION}, {"enum", ENUM, 0, 0, PROG_ID_VERSION, 0},
{"typedef", TYPEDEF, 0, 0, PROG_ID_VERSION}, {"typedef", TYPEDEF, 0, 0, PROG_ID_VERSION, 0},
{"@class", CLASS, 0, 0, PROG_VERSION}, {"@class", CLASS, 0, 0, PROG_VERSION, 1},
{"@defs", DEFS, 0, 0, PROG_VERSION}, {"@defs", DEFS, 0, 0, PROG_VERSION, 1},
{"@encode", ENCODE, 0, 0, PROG_VERSION}, {"@encode", ENCODE, 0, 0, PROG_VERSION, 1},
{"@end", END, 0, 0, PROG_VERSION}, {"@end", END, 0, 0, PROG_VERSION, 1},
{"@implementation", IMPLEMENTATION, 0, 0, PROG_VERSION}, {"@implementation", IMPLEMENTATION, 0, 0, PROG_VERSION, 1},
{"@interface", INTERFACE, 0, 0, PROG_VERSION}, {"@interface", INTERFACE, 0, 0, PROG_VERSION, 1},
{"@private", PRIVATE, 0, 0, PROG_VERSION}, {"@private", PRIVATE, 0, 0, PROG_VERSION, 1},
{"@protected", PROTECTED, 0, 0, PROG_VERSION}, {"@protected", PROTECTED, 0, 0, PROG_VERSION, 1},
{"@protocol", PROTOCOL, 0, 0, PROG_VERSION}, {"@protocol", PROTOCOL, 0, 0, PROG_VERSION, 1},
{"@public", PUBLIC, 0, 0, PROG_VERSION}, {"@public", PUBLIC, 0, 0, PROG_VERSION, 1},
{"@reference", REFERENCE, 0, 0, PROG_VERSION}, {"@reference", REFERENCE, 0, 0, PROG_VERSION, 1},
{"@selector", SELECTOR, 0, 0, PROG_VERSION}, {"@selector", SELECTOR, 0, 0, PROG_VERSION, 1},
{"@self", SELF, 0, 0, PROG_VERSION}, {"@self", SELF, 0, 0, PROG_VERSION, 1},
{"@this", THIS, 0, 0, PROG_VERSION}, {"@this", THIS, 0, 0, PROG_VERSION, 1},
{"@args", ARGS, 0, 0, PROG_VERSION}, {"@args", ARGS, 0, 0, PROG_VERSION, 0},
{"@va_list", TYPE, &type_va_list, 0, PROG_VERSION}, {"@va_list", TYPE, &type_va_list, 0, PROG_VERSION, 0},
{"@param", TYPE, &type_param, 0, PROG_VERSION}, {"@param", TYPE, &type_param, 0, PROG_VERSION, 0},
{"@extern", EXTERN, 0, 1, PROG_ID_VERSION}, {"@extern", EXTERN, 0, 1, PROG_ID_VERSION, 0},
{"@static", STATIC, 0, 1, PROG_ID_VERSION}, {"@static", STATIC, 0, 1, PROG_ID_VERSION, 0},
{"@system", SYSTEM, 0, 1, PROG_ID_VERSION}, {"@system", SYSTEM, 0, 1, PROG_ID_VERSION, 0},
{"@sizeof", SIZEOF, 0, 0, PROG_VERSION}, {"@sizeof", SIZEOF, 0, 0, PROG_VERSION, 0},
{"@overload", OVERLOAD, 0, 0, PROG_VERSION}, {"@overload", OVERLOAD, 0, 0, PROG_VERSION, 0},
}; };
static const char * static const char *
@ -345,8 +346,7 @@ keyword_or_id (char *token)
} }
keyword = Hash_Find (keyword_tab, token); keyword = Hash_Find (keyword_tab, token);
if (keyword) { if (keyword) {
if (!options.traditional && token[0] == '@' if (!options.traditional && keyword->objc && !class_Class.super_class)
&& !class_Class.super_class)
class_init (); class_init ();
if (keyword->value == STRUCT) { if (keyword->value == STRUCT) {
yylval.op = token[0]; yylval.op = token[0];