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