written by AT&T, but I have never seen it. */
ifobjc
-%expect 20
+%expect 22
end ifobjc
ifc
-%expect 8
+%expect 10
-/* These are the 8 conflicts you should get in parse.output;
+/* These are the 10 conflicts you should get in parse.output;
the state numbers may vary if minor changes in the grammar are made.
State 41 contains 1 shift/reduce conflict. (Two ways to recover from error.)
-State 92 contains 1 shift/reduce conflict. (Two ways to recover from error.)
-State 99 contains 1 shift/reduce conflict. (Two ways to recover from error.)
-State 103 contains 1 shift/reduce conflict. (Two ways to recover from error.)
-State 119 contains 1 shift/reduce conflict. (See comment at component_decl.)
-State 183 contains 1 shift/reduce conflict. (Two ways to recover from error.)
-State 193 contains 1 shift/reduce conflict. (Two ways to recover from error.)
-State 199 contains 1 shift/reduce conflict. (Two ways to recover from error.)
+State 97 contains 1 shift/reduce conflict. (Two ways to recover from error.)
+State 104 contains 1 shift/reduce conflict. (Two ways to recover from error.)
+State 108 contains 1 shift/reduce conflict. (Two ways to recover from error.)
+State 124 contains 1 shift/reduce conflict. (See comment at component_decl.)
+State 191 contains 1 shift/reduce conflict. (Two ways to recover from error.)
+State 204 contains 1 shift/reduce conflict. (Two ways to recover from error.)
+State 210 contains 1 shift/reduce conflict. (Two ways to recover from error.)
+State 449 contains 2 shift/reduce conflicts. (Four ways to parse this.)
*/
end ifc
%type <ttype> initdecls notype_initdecls initdcl notype_initdcl
%type <ttype> init maybeasm
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
-%type <ttype> maybe_attribute attribute_list attrib
+%type <ttype> maybe_attribute attributes attribute attribute_list attrib
+%type <ttype> any_word
%type <ttype> compstmt
/* the * rules are dummies to accept the Apollo extended syntax
so that the header files compile. */
maybe_attribute:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | attributes
+ { $$ = $1; }
+ ;
+
+attributes:
+ attribute
+ { $$ = $1; }
+ | attributes attribute
+ { $$ = chainon ($1, $2); }
+ ;
+
+attribute:
+ ATTRIBUTE '(' '(' attribute_list ')' ')'
+ { $$ = $4; }
+ ;
+
+attribute_list:
+ attrib
+ { $$ = build_tree_list (NULL_TREE, $1); }
+ | attribute_list ',' attrib
+ { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ ;
+
+attrib:
/* empty */
{ $$ = NULL_TREE; }
- | maybe_attribute ATTRIBUTE '(' '(' attribute_list ')' ')'
- { $$ = chainon ($5, $1); }
- ;
-
-attribute_list
- : attrib
- { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
- | attribute_list ',' attrib
- { $$ = tree_cons (NULL_TREE, $3, $1); }
- ;
-
-attrib
- : identifier
- { if (strcmp (IDENTIFIER_POINTER ($1), "packed")
- && strcmp (IDENTIFIER_POINTER ($1), "noreturn"))
- warning ("`%s' attribute directive ignored",
- IDENTIFIER_POINTER ($1));
- $$ = $1; }
- | TYPE_QUAL
- | identifier '(' expr_no_commas ')'
- { /* If not aligned(n) or section(name), then issue warning */
- if (strcmp (IDENTIFIER_POINTER ($1), "section") == 0
- || strcmp (IDENTIFIER_POINTER ($1), "mode") == 0)
- {
- if (TREE_CODE ($3) != STRING_CST)
- {
- error ("invalid argument in `%s' attribute",
- IDENTIFIER_POINTER ($1));
- $$ = $1;
- }
- $$ = tree_cons ($1, $3, NULL_TREE);
- }
- else if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0)
- {
- warning ("`%s' attribute directive ignored",
- IDENTIFIER_POINTER ($1));
- $$ = $1;
- }
- else
- $$ = tree_cons ($1, $3, NULL_TREE); }
- | identifier '(' IDENTIFIER ',' expr_no_commas ',' expr_no_commas ')'
- { /* if not "format(...)", then issue warning */
- if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0)
- {
- warning ("`%s' attribute directive ignored",
- IDENTIFIER_POINTER ($1));
- $$ = $1;
- }
- else
- $$ = tree_cons ($1,
- tree_cons ($3,
- tree_cons ($5, $7, NULL_TREE),
- NULL_TREE),
- NULL_TREE); }
- ;
+ | any_word
+ { $$ = $1; }
+ | any_word '(' IDENTIFIER ')'
+ { $$ = tree_cons ($1, NULL_TREE,
+ build_tree_list (NULL_TREE, $3)); }
+ | any_word '(' IDENTIFIER ',' nonnull_exprlist ')'
+ { $$ = tree_cons ($1, NULL_TREE,
+ tree_cons (NULL_TREE, $3, $5)); }
+ | any_word '(' nonnull_exprlist ')'
+ { $$ = tree_cons ($1, NULL_TREE, $3); }
+ ;
+
+/* This still leaves out most reserved keywords,
+ shouldn't we include them? */
+
+any_word:
+ identifier
+ | SCSPEC
+ | TYPESPEC
+ | TYPE_QUAL
+ ;
\f
/* Initializers. `init' is the entry point. */