aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-parse.in
diff options
context:
space:
mode:
authorZack Weinberg <zackw@stanford.edu>2001-03-07 01:32:01 +0000
committerZack Weinberg <zack@gcc.gnu.org>2001-03-07 01:32:01 +0000
commitcc937581390c3aebf39e5f36b61f6b6098b8a236 (patch)
tree6fd6ae80f761d7e077d853c2bbffc740946a5e0d /gcc/c-parse.in
parent8b44d68f7b41308b3ea5b66642352c6fc8946093 (diff)
downloadgcc-cc937581390c3aebf39e5f36b61f6b6098b8a236.zip
gcc-cc937581390c3aebf39e5f36b61f6b6098b8a236.tar.gz
gcc-cc937581390c3aebf39e5f36b61f6b6098b8a236.tar.bz2
c-parse.in (yylexname): New function, split out of _yylex.
* c-parse.in (yylexname): New function, split out of _yylex. (objc_rid_sans_at): New table. (init_reswords): Initialize it. (_yylex): Give labels clearer names. Handle CPP_ATSIGN by retrieving the next token and checking it for significance as an ObjC keyword or string constant. * cpplex.c (_cpp_lex_token): Just return CPP_ATSIGN for '@'. * cpplib.h (TTYPE_TABLE): Add CPP_ATSIGN, drop CPP_OSTRING. * c-lex.c, c-parse.in, cppmacro.c, cpplex.c, cp/spew.c: Remove references to CPP_OSTRING. From-SVN: r40279
Diffstat (limited to 'gcc/c-parse.in')
-rw-r--r--gcc/c-parse.in164
1 files changed, 99 insertions, 65 deletions
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index ea59e73..d187ab4 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -263,6 +263,7 @@ end ifobjc
static void yyprint PARAMS ((FILE *, int, YYSTYPE));
static void yyerror PARAMS ((const char *));
+static int yylexname PARAMS ((void));
static inline int _yylex PARAMS ((void));
static int yylex PARAMS ((void));
static void init_reswords PARAMS ((void));
@@ -3114,6 +3115,13 @@ static const short rid_to_yy[RID_MAX] =
/* RID_AT_IMPLEMENTATION */ IMPLEMENTATION
};
+ifobjc
+/* Lookup table for ObjC keywords beginning with '@'. Crude but
+ hopefully effective. */
+#define N_at_reswords ((int) RID_AT_IMPLEMENTATION - (int)RID_AT_ENCODE + 1)
+static tree objc_rid_sans_at[N_at_reswords];
+end ifobjc
+
static void
init_reswords ()
{
@@ -3139,6 +3147,16 @@ init_reswords ()
C_RID_CODE (id) = reswords[i].rid;
C_IS_RESERVED_WORD (id) = 1;
ridpointers [(int) reswords[i].rid] = id;
+
+ifobjc
+ /* Enter ObjC @-prefixed keywords into the "sans" table
+ _without_ their leading at-sign. Again, all these
+ identifiers are reachable by the get_identifer table, so it's
+ not necessary to make objc_rid_sans_at a GC root. */
+ if (reswords[i].word[0] == '@')
+ objc_rid_sans_at[(int) reswords[i].rid - (int) RID_AT_ENCODE]
+ = get_identifier (reswords[i].word + 1);
+end ifobjc
}
ifobjc
save_and_forget_protocol_qualifiers ();
@@ -3188,8 +3206,7 @@ yyerror (msgid)
error ("%s before %s'\\x%x'", string, ell, val);
}
else if (last_token == CPP_STRING
- || last_token == CPP_WSTRING
- || last_token == CPP_OSTRING)
+ || last_token == CPP_WSTRING)
error ("%s before string constant", string);
else if (last_token == CPP_NUMBER
|| last_token == CPP_INT
@@ -3201,12 +3218,65 @@ yyerror (msgid)
error ("%s before '%s' token", string, NAME(last_token));
}
+static int
+yylexname ()
+{
+ tree decl;
+
+ if (C_IS_RESERVED_WORD (yylval.ttype))
+ {
+ enum rid rid_code = C_RID_CODE (yylval.ttype);
+ /* Return the canonical spelling for this keyword. */
+ yylval.ttype = ridpointers[(int) rid_code];
+ return rid_to_yy[(int) rid_code];
+ }
+
+ decl = lookup_name (yylval.ttype);
+ if (decl)
+ {
+ if (TREE_CODE (decl) == TYPE_DECL)
+ return TYPENAME;
+ /* A user-invisible read-only initialized variable
+ should be replaced by its value.
+ We handle only strings since that's the only case used in C. */
+ else if (TREE_CODE (decl) == VAR_DECL
+ && DECL_IGNORED_P (decl)
+ && TREE_READONLY (decl)
+ && DECL_INITIAL (decl) != 0
+ && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
+ {
+ tree stringval = DECL_INITIAL (decl);
+
+ /* Copy the string value so that we won't clobber anything
+ if we put something in the TREE_CHAIN of this one. */
+ yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
+ TREE_STRING_POINTER (stringval));
+ return STRING;
+ }
+ }
+ else if (doing_objc_thang)
+ {
+ tree objc_interface_decl = is_class_name (yylval.ttype);
+
+ if (objc_interface_decl)
+ {
+ yylval.ttype = objc_interface_decl;
+ return CLASSNAME;
+ }
+ }
+
+ return IDENTIFIER;
+}
+
+
static inline int
_yylex ()
{
- retry:
+ get_next:
last_token = c_lex (&yylval.ttype);
-
+ifobjc
+ reconsider:
+end ifobjc
switch (last_token)
{
case CPP_EQ: return '=';
@@ -3263,63 +3333,10 @@ _yylex ()
case CPP_EOF:
if (cpp_pop_buffer (parse_in) == 0)
return 0;
- goto retry;
+ goto get_next;
case CPP_NAME:
- if (C_IS_RESERVED_WORD (yylval.ttype))
- {
- enum rid rid_code = C_RID_CODE (yylval.ttype);
- /* Return the canonical spelling for this keyword. */
- yylval.ttype = ridpointers[(int) rid_code];
- return rid_to_yy[(int) rid_code];
- }
-
- if (IDENTIFIER_POINTER (yylval.ttype)[0] == '@')
- {
- error ("invalid identifier `%s'", IDENTIFIER_POINTER (yylval.ttype));
- return IDENTIFIER;
- }
-
- {
- tree decl;
-
- decl = lookup_name (yylval.ttype);
-
- if (decl)
- {
- if (TREE_CODE (decl) == TYPE_DECL)
- return TYPENAME;
- /* A user-invisible read-only initialized variable
- should be replaced by its value.
- We handle only strings since that's the only case used in C. */
- else if (TREE_CODE (decl) == VAR_DECL
- && DECL_IGNORED_P (decl)
- && TREE_READONLY (decl)
- && DECL_INITIAL (decl) != 0
- && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
- {
- tree stringval = DECL_INITIAL (decl);
-
- /* Copy the string value so that we won't clobber anything
- if we put something in the TREE_CHAIN of this one. */
- yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
- TREE_STRING_POINTER (stringval));
- return STRING;
- }
- }
- else if (doing_objc_thang)
- {
- tree objc_interface_decl = is_class_name (yylval.ttype);
-
- if (objc_interface_decl)
- {
- yylval.ttype = objc_interface_decl;
- return CLASSNAME;
- }
- }
-
- return IDENTIFIER;
- }
+ return yylexname ();
case CPP_INT:
case CPP_FLOAT:
@@ -3332,9 +3349,27 @@ _yylex ()
case CPP_WSTRING:
return STRING;
- case CPP_OSTRING:
- return OBJC_STRING;
-
+ /* This token is Objective-C specific. It gives the next
+ token special significance. */
+ case CPP_ATSIGN:
+ifobjc
+ last_token = c_lex (&yylval.ttype);
+ if (last_token == CPP_STRING)
+ return OBJC_STRING;
+ else if (last_token == CPP_NAME)
+ {
+ int i;
+ for (i = 0; i < N_at_reswords; i++)
+ if (objc_rid_sans_at[i] == yylval.ttype)
+ {
+ int rid_code = i + (int) RID_AT_ENCODE;
+ yylval.ttype = ridpointers[rid_code];
+ return rid_to_yy[rid_code];
+ }
+ }
+ error ("syntax error at '@' token");
+ goto reconsider;
+end ifobjc
/* These tokens are C++ specific (and will not be generated
in C mode, but let's be cautious). */
case CPP_SCOPE:
@@ -3347,13 +3382,12 @@ _yylex ()
/* These tokens should not survive translation phase 4. */
case CPP_HASH:
case CPP_PASTE:
- error ("syntax error before '%s' token", NAME(last_token));
- goto retry;
+ error ("syntax error at '%s' token", NAME(last_token));
+ goto get_next;
default:
abort ();
}
-
/* NOTREACHED */
}