PR debug/46799
[official-gcc.git] / gcc / gengtype-parse.c
blob8f0b0c532334183912b6e64388263c0ce6ed704a
1 /* Process source files and output type information.
2 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "bconfig.h"
21 #include "system.h"
22 #include "gengtype.h"
24 /* This is a simple recursive-descent parser which understands a subset of
25 the C type grammar.
27 Rule functions are suffixed _seq if they scan a sequence of items;
28 _opt if they may consume zero tokens; _seqopt if both are true. The
29 "consume_" prefix indicates that a sequence of tokens is parsed for
30 syntactic correctness and then thrown away. */
32 /* Simple one-token lookahead mechanism. */
34 struct token
36 const char *value;
37 int code;
38 bool valid;
40 static struct token T;
42 /* Retrieve the code of the current token; if there is no current token,
43 get the next one from the lexer. */
44 static inline int
45 token (void)
47 if (!T.valid)
49 T.code = yylex (&T.value);
50 T.valid = true;
52 return T.code;
55 /* Retrieve the value of the current token (if any) and mark it consumed.
56 The next call to token() will get another token from the lexer. */
57 static inline const char *
58 advance (void)
60 T.valid = false;
61 return T.value;
64 /* Diagnostics. */
66 /* This array is indexed by the token code minus CHAR_TOKEN_OFFSET. */
67 static const char *const token_names[] = {
68 "GTY",
69 "typedef",
70 "extern",
71 "static",
72 "union",
73 "struct",
74 "enum",
75 "VEC",
76 "DEF_VEC_[OP]",
77 "DEF_VEC_I",
78 "DEF_VEC_ALLOC_[IOP]",
79 "...",
80 "ptr_alias",
81 "nested_ptr",
82 "a param<N>_is option",
83 "a number",
84 "a scalar type",
85 "an identifier",
86 "a string constant",
87 "a character constant",
88 "an array declarator",
91 /* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */
92 static const char *const token_value_format[] = {
93 "%s",
94 "'%s'",
95 "'%s'",
96 "'%s'",
97 "'\"%s\"'",
98 "\"'%s'\"",
99 "'[%s]'",
102 /* Produce a printable representation for a token defined by CODE and
103 VALUE. This sometimes returns pointers into malloc memory and
104 sometimes not, therefore it is unsafe to free the pointer it
105 returns, so that memory is leaked. This does not matter, as this
106 function is only used for diagnostics, and in a successful run of
107 the program there will be none. */
108 static const char *
109 print_token (int code, const char *value)
111 if (code < CHAR_TOKEN_OFFSET)
112 return xasprintf ("'%c'", code);
113 else if (code < FIRST_TOKEN_WITH_VALUE)
114 return xasprintf ("'%s'", token_names[code - CHAR_TOKEN_OFFSET]);
115 else if (!value)
116 return token_names[code - CHAR_TOKEN_OFFSET]; /* don't quote these */
117 else
118 return xasprintf (token_value_format[code - FIRST_TOKEN_WITH_VALUE],
119 value);
122 /* Convenience wrapper around print_token which produces the printable
123 representation of the current token. */
124 static inline const char *
125 print_cur_token (void)
127 return print_token (T.code, T.value);
130 /* Report a parse error on the current line, with diagnostic MSG.
131 Behaves as standard printf with respect to additional arguments and
132 format escapes. */
133 static void ATTRIBUTE_PRINTF_1
134 parse_error (const char *msg, ...)
136 va_list ap;
138 fprintf (stderr, "%s:%d: parse error: ",
139 get_input_file_name (lexer_line.file), lexer_line.line);
141 va_start (ap, msg);
142 vfprintf (stderr, msg, ap);
143 va_end (ap);
145 fputc ('\n', stderr);
147 hit_error = true;
150 /* If the next token does not have code T, report a parse error; otherwise
151 return the token's value. */
152 static const char *
153 require (int t)
155 int u = token ();
156 const char *v = advance ();
157 if (u != t)
159 parse_error ("expected %s, have %s",
160 print_token (t, 0), print_token (u, v));
161 return 0;
163 return v;
166 /* If the next token does not have one of the codes T1 or T2, report a
167 parse error; otherwise return the token's value. */
168 static const char *
169 require2 (int t1, int t2)
171 int u = token ();
172 const char *v = advance ();
173 if (u != t1 && u != t2)
175 parse_error ("expected %s or %s, have %s",
176 print_token (t1, 0), print_token (t2, 0),
177 print_token (u, v));
178 return 0;
180 return v;
183 /* Near-terminals. */
185 /* C-style string constant concatenation: STRING+
186 Bare STRING should appear nowhere else in this file. */
187 static const char *
188 string_seq (void)
190 const char *s1, *s2;
191 size_t l1, l2;
192 char *buf;
194 s1 = require (STRING);
195 if (s1 == 0)
196 return "";
197 while (token () == STRING)
199 s2 = advance ();
201 l1 = strlen (s1);
202 l2 = strlen (s2);
203 buf = XRESIZEVEC (char, CONST_CAST (char *, s1), l1 + l2 + 1);
204 memcpy (buf + l1, s2, l2 + 1);
205 XDELETE (CONST_CAST (char *, s2));
206 s1 = buf;
208 return s1;
211 /* typedef_name: either an ID, or VEC(x,y) which is translated to VEC_x_y.
212 Use only where VEC(x,y) is legitimate, i.e. in positions where a
213 typedef name may appear. */
214 static const char *
215 typedef_name (void)
217 if (token () == VEC_TOKEN)
219 const char *c1, *c2, *r;
220 advance ();
221 require ('(');
222 c1 = require2 (ID, SCALAR);
223 require (',');
224 c2 = require (ID);
225 require (')');
226 r = concat ("VEC_", c1, "_", c2, (char *) 0);
227 free (CONST_CAST (char *, c1));
228 free (CONST_CAST (char *, c2));
229 return r;
231 else
232 return require (ID);
235 /* Absorb a sequence of tokens delimited by balanced ()[]{}. */
236 static void
237 consume_balanced (int opener, int closer)
239 require (opener);
240 for (;;)
241 switch (token ())
243 default:
244 advance ();
245 break;
246 case '(':
247 consume_balanced ('(', ')');
248 break;
249 case '[':
250 consume_balanced ('[', ']');
251 break;
252 case '{':
253 consume_balanced ('{', '}');
254 break;
256 case '}':
257 case ']':
258 case ')':
259 if (token () != closer)
260 parse_error ("unbalanced delimiters - expected '%c', have '%c'",
261 closer, token ());
262 advance ();
263 return;
265 case EOF_TOKEN:
266 parse_error ("unexpected end of file within %c%c-delimited construct",
267 opener, closer);
268 return;
272 /* Absorb a sequence of tokens, possibly including ()[]{}-delimited
273 expressions, until we encounter a semicolon outside any such
274 delimiters; absorb that too. If IMMEDIATE is true, it is an error
275 if the semicolon is not the first token encountered. */
276 static void
277 consume_until_semi (bool immediate)
279 if (immediate && token () != ';')
280 require (';');
281 for (;;)
282 switch (token ())
284 case ';':
285 advance ();
286 return;
287 default:
288 advance ();
289 break;
291 case '(':
292 consume_balanced ('(', ')');
293 break;
294 case '[':
295 consume_balanced ('[', ']');
296 break;
297 case '{':
298 consume_balanced ('{', '}');
299 break;
301 case '}':
302 case ']':
303 case ')':
304 parse_error ("unmatched '%c' while scanning for ';'", token ());
305 return;
307 case EOF_TOKEN:
308 parse_error ("unexpected end of file while scanning for ';'");
309 return;
313 /* Absorb a sequence of tokens, possibly including ()[]{}-delimited
314 expressions, until we encounter a comma or semicolon outside any
315 such delimiters; absorb that too. If IMMEDIATE is true, it is an
316 error if the comma or semicolon is not the first token encountered.
317 Returns true if the loop ended with a comma. */
318 static bool
319 consume_until_comma_or_semi (bool immediate)
321 if (immediate && token () != ',' && token () != ';')
322 require2 (',', ';');
323 for (;;)
324 switch (token ())
326 case ',':
327 advance ();
328 return true;
329 case ';':
330 advance ();
331 return false;
332 default:
333 advance ();
334 break;
336 case '(':
337 consume_balanced ('(', ')');
338 break;
339 case '[':
340 consume_balanced ('[', ']');
341 break;
342 case '{':
343 consume_balanced ('{', '}');
344 break;
346 case '}':
347 case ']':
348 case ')':
349 parse_error ("unmatched '%s' while scanning for ',' or ';'",
350 print_cur_token ());
351 return false;
353 case EOF_TOKEN:
354 parse_error ("unexpected end of file while scanning for ',' or ';'");
355 return false;
360 /* GTY(()) option handling. */
361 static type_p type (options_p *optsp, bool nested);
363 /* Optional parenthesized string: ('(' string_seq ')')? */
364 static options_p
365 str_optvalue_opt (options_p prev)
367 const char *name = advance ();
368 const char *value = "";
369 if (token () == '(')
371 advance ();
372 value = string_seq ();
373 require (')');
375 return create_string_option (prev, name, value);
378 /* absdecl: type '*'*
379 -- a vague approximation to what the C standard calls an abstract
380 declarator. The only kinds that are actually used are those that
381 are just a bare type and those that have trailing pointer-stars.
382 Further kinds should be implemented if and when they become
383 necessary. Used only within GTY(()) option values, therefore
384 further GTY(()) tags within the type are invalid. Note that the
385 return value has already been run through adjust_field_type. */
386 static type_p
387 absdecl (void)
389 type_p ty;
390 options_p opts;
392 ty = type (&opts, true);
393 while (token () == '*')
395 ty = create_pointer (ty);
396 advance ();
399 if (opts)
400 parse_error ("nested GTY(()) options are invalid");
402 return adjust_field_type (ty, 0);
405 /* Type-option: '(' absdecl ')' */
406 static options_p
407 type_optvalue (options_p prev, const char *name)
409 type_p ty;
410 require ('(');
411 ty = absdecl ();
412 require (')');
413 return create_type_option (prev, name, ty);
416 /* Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' */
417 static options_p
418 nestedptr_optvalue (options_p prev)
420 type_p ty;
421 const char *from, *to;
423 require ('(');
424 ty = absdecl ();
425 require (',');
426 to = string_seq ();
427 require (',');
428 from = string_seq ();
429 require (')');
431 return create_nested_ptr_option (prev, ty, to, from);
434 /* One GTY(()) option:
435 ID str_optvalue_opt
436 | PTR_ALIAS type_optvalue
437 | PARAM_IS type_optvalue
438 | NESTED_PTR nestedptr_optvalue
440 static options_p
441 option (options_p prev)
443 switch (token ())
445 case ID:
446 return str_optvalue_opt (prev);
448 case PTR_ALIAS:
449 advance ();
450 return type_optvalue (prev, "ptr_alias");
452 case PARAM_IS:
453 return type_optvalue (prev, advance ());
455 case NESTED_PTR:
456 advance ();
457 return nestedptr_optvalue (prev);
459 default:
460 parse_error ("expected an option keyword, have %s", print_cur_token ());
461 advance ();
462 return create_string_option (prev, "", "");
466 /* One comma-separated list of options. */
467 static options_p
468 option_seq (void)
470 options_p o;
472 o = option (0);
473 while (token () == ',')
475 advance ();
476 o = option (o);
478 return o;
481 /* GTY marker: 'GTY' '(' '(' option_seq? ')' ')' */
482 static options_p
483 gtymarker (void)
485 options_p result = 0;
486 require (GTY_TOKEN);
487 require ('(');
488 require ('(');
489 if (token () != ')')
490 result = option_seq ();
491 require (')');
492 require (')');
493 return result;
496 /* Optional GTY marker. */
497 static options_p
498 gtymarker_opt (void)
500 if (token () != GTY_TOKEN)
501 return 0;
502 return gtymarker ();
505 /* Declarators. The logic here is largely lifted from c-parser.c.
506 Note that we do not have to process abstract declarators, which can
507 appear only in parameter type lists or casts (but see absdecl,
508 above). Also, type qualifiers are thrown out in gengtype-lex.l so
509 we don't have to do it. */
511 /* array_and_function_declarators_opt:
512 \epsilon
513 array_and_function_declarators_opt ARRAY
514 array_and_function_declarators_opt '(' ... ')'
516 where '...' indicates stuff we ignore except insofar as grouping
517 symbols ()[]{} must balance.
519 Subroutine of direct_declarator - do not use elsewhere. */
521 static type_p
522 array_and_function_declarators_opt (type_p ty)
524 if (token () == ARRAY)
526 const char *array = advance ();
527 return create_array (array_and_function_declarators_opt (ty), array);
529 else if (token () == '(')
531 /* We don't need exact types for functions. */
532 consume_balanced ('(', ')');
533 array_and_function_declarators_opt (ty);
534 return create_scalar_type ("function type");
536 else
537 return ty;
540 static type_p inner_declarator (type_p, const char **, options_p *);
542 /* direct_declarator:
543 '(' inner_declarator ')'
544 gtymarker_opt ID array_and_function_declarators_opt
546 Subroutine of declarator, mutually recursive with inner_declarator;
547 do not use elsewhere. */
548 static type_p
549 direct_declarator (type_p ty, const char **namep, options_p *optsp)
551 /* The first token in a direct-declarator must be an ID, a
552 GTY marker, or an open parenthesis. */
553 switch (token ())
555 case GTY_TOKEN:
556 *optsp = gtymarker ();
557 /* fall through */
558 case ID:
559 *namep = require (ID);
560 break;
562 case '(':
563 advance ();
564 ty = inner_declarator (ty, namep, optsp);
565 require (')');
566 break;
568 default:
569 parse_error ("expected '(', 'GTY', or an identifier, have %s",
570 print_cur_token ());
571 /* Do _not_ advance if what we have is a close squiggle brace, as
572 we will get much better error recovery that way. */
573 if (token () != '}')
574 advance ();
575 return 0;
577 return array_and_function_declarators_opt (ty);
580 /* The difference between inner_declarator and declarator is in the
581 handling of stars. Consider this declaration:
583 char * (*pfc) (void)
585 It declares a pointer to a function that takes no arguments and
586 returns a char*. To construct the correct type for this
587 declaration, the star outside the parentheses must be processed
588 _before_ the function type, the star inside the parentheses must
589 be processed _after_ the function type. To accomplish this,
590 declarator() creates pointers before recursing (it is actually
591 coded as a while loop), whereas inner_declarator() recurses before
592 creating pointers. */
594 /* inner_declarator:
595 '*' inner_declarator
596 direct_declarator
598 Mutually recursive subroutine of direct_declarator; do not use
599 elsewhere. */
601 static type_p
602 inner_declarator (type_p ty, const char **namep, options_p *optsp)
604 if (token () == '*')
606 type_p inner;
607 advance ();
608 inner = inner_declarator (ty, namep, optsp);
609 if (inner == 0)
610 return 0;
611 else
612 return create_pointer (ty);
614 else
615 return direct_declarator (ty, namep, optsp);
618 /* declarator: '*'+ direct_declarator
620 This is the sole public interface to this part of the grammar.
621 Arguments are the type known so far, a pointer to where the name
622 may be stored, and a pointer to where GTY options may be stored.
623 Returns the final type. */
625 static type_p
626 declarator (type_p ty, const char **namep, options_p *optsp)
628 *namep = 0;
629 *optsp = 0;
630 while (token () == '*')
632 advance ();
633 ty = create_pointer (ty);
635 return direct_declarator (ty, namep, optsp);
638 /* Types and declarations. */
640 /* Structure field(s) declaration:
642 type bitfield ';'
643 | type declarator bitfield? ( ',' declarator bitfield? )+ ';'
646 Knows that such declarations must end with a close brace (or,
647 erroneously, at EOF).
649 static pair_p
650 struct_field_seq (void)
652 pair_p f = 0;
653 type_p ty, dty;
654 options_p opts, dopts;
655 const char *name;
656 bool another;
660 ty = type (&opts, true);
661 /* Another piece of the IFCVT_EXTRA_FIELDS special case, see type(). */
662 if (!ty && token () == '}')
663 break;
665 if (!ty || token () == ':')
667 consume_until_semi (false);
668 continue;
673 dty = declarator (ty, &name, &dopts);
674 /* There could be any number of weird things after the declarator,
675 notably bitfield declarations and __attribute__s. If this
676 function returns true, the last thing was a comma, so we have
677 more than one declarator paired with the current type. */
678 another = consume_until_comma_or_semi (false);
680 if (!dty)
681 continue;
683 if (opts && dopts)
684 parse_error ("two GTY(()) options for field %s", name);
685 if (opts && !dopts)
686 dopts = opts;
688 f = create_field_at (f, dty, name, dopts, &lexer_line);
690 while (another);
692 while (token () != '}' && token () != EOF_TOKEN);
693 return nreverse_pairs (f);
696 /* This is called type(), but what it parses (sort of) is what C calls
697 declaration-specifiers and specifier-qualifier-list:
699 SCALAR
700 | ID // typedef
701 | (STRUCT|UNION) ID? gtymarker? ( '{' gtymarker? struct_field_seq '}' )?
702 | ENUM ID ( '{' ... '}' )?
704 Returns a partial type; under some conditions (notably
705 "struct foo GTY((...)) thing;") it may write an options
706 structure to *OPTSP.
708 static type_p
709 type (options_p *optsp, bool nested)
711 const char *s;
712 *optsp = 0;
713 switch (token ())
715 case SCALAR:
716 s = advance ();
717 return create_scalar_type (s);
719 case ID:
720 case VEC_TOKEN:
721 s = typedef_name ();
722 return resolve_typedef (s, &lexer_line);
724 case STRUCT:
725 case UNION:
727 options_p opts = 0;
728 /* GTY annotations follow attribute syntax
729 GTY_BEFORE_ID is for union/struct declarations
730 GTY_AFTER_ID is for variable declarations. */
731 enum
733 NO_GTY,
734 GTY_BEFORE_ID,
735 GTY_AFTER_ID
736 } is_gty = NO_GTY;
737 bool is_union = (token () == UNION);
738 advance ();
740 /* Top-level structures that are not explicitly tagged GTY(())
741 are treated as mere forward declarations. This is because
742 there are a lot of structures that we don't need to know
743 about, and some of those have weird macro stuff in them
744 that we can't handle. */
745 if (nested || token () == GTY_TOKEN)
747 is_gty = GTY_BEFORE_ID;
748 opts = gtymarker_opt ();
751 if (token () == ID)
752 s = advance ();
753 else
754 s = xasprintf ("anonymous:%s:%d",
755 get_input_file_name (lexer_line.file),
756 lexer_line.line);
758 /* Unfortunately above GTY_TOKEN check does not capture the
759 typedef struct_type GTY case. */
760 if (token () == GTY_TOKEN)
762 is_gty = GTY_AFTER_ID;
763 opts = gtymarker_opt ();
766 if (is_gty)
768 if (token () == '{')
770 pair_p fields;
772 if (is_gty == GTY_AFTER_ID)
773 parse_error ("GTY must be specified before identifier");
775 advance ();
776 fields = struct_field_seq ();
777 require ('}');
778 return new_structure (s, is_union, &lexer_line, fields, opts);
781 else if (token () == '{')
782 consume_balanced ('{', '}');
783 if (opts)
784 *optsp = opts;
785 return find_structure (s, is_union);
788 case ENUM:
789 advance ();
790 if (token () == ID)
791 s = advance ();
792 else
793 s = xasprintf ("anonymous:%s:%d",
794 get_input_file_name (lexer_line.file),
795 lexer_line.line);
797 if (token () == '{')
798 consume_balanced ('{', '}');
799 return create_scalar_type (s);
801 default:
802 parse_error ("expected a type specifier, have %s", print_cur_token ());
803 advance ();
804 return create_scalar_type ("erroneous type");
808 /* Top level constructs. */
810 /* Dispatch declarations beginning with 'typedef'. */
812 static void
813 typedef_decl (void)
815 type_p ty, dty;
816 const char *name;
817 options_p opts;
818 bool another;
820 gcc_assert (token () == TYPEDEF);
821 advance ();
823 ty = type (&opts, false);
824 if (!ty)
825 return;
826 if (opts)
827 parse_error ("GTY((...)) cannot be applied to a typedef");
830 dty = declarator (ty, &name, &opts);
831 if (opts)
832 parse_error ("GTY((...)) cannot be applied to a typedef");
834 /* Yet another place where we could have junk (notably attributes)
835 after the declarator. */
836 another = consume_until_comma_or_semi (false);
837 if (dty)
838 do_typedef (name, dty, &lexer_line);
840 while (another);
843 /* Structure definition: type() does all the work. */
845 static void
846 struct_or_union (void)
848 options_p dummy;
849 type (&dummy, false);
850 /* There may be junk after the type: notably, we cannot currently
851 distinguish 'struct foo *function(prototype);' from 'struct foo;'
852 ... we could call declarator(), but it's a waste of time at
853 present. Instead, just eat whatever token is currently lookahead
854 and go back to lexical skipping mode. */
855 advance ();
858 /* GC root declaration:
859 (extern|static) gtymarker? type ID array_declarators_opt (';'|'=')
860 If the gtymarker is not present, we ignore the rest of the declaration. */
861 static void
862 extern_or_static (void)
864 options_p opts, opts2, dopts;
865 type_p ty, dty;
866 const char *name;
867 require2 (EXTERN, STATIC);
869 if (token () != GTY_TOKEN)
871 advance ();
872 return;
875 opts = gtymarker ();
876 ty = type (&opts2, true); /* if we get here, it's got a GTY(()) */
877 dty = declarator (ty, &name, &dopts);
879 if ((opts && dopts) || (opts && opts2) || (opts2 && dopts))
880 parse_error ("GTY((...)) specified more than once for %s", name);
881 else if (opts2)
882 opts = opts2;
883 else if (dopts)
884 opts = dopts;
886 if (dty)
888 note_variable (name, adjust_field_type (dty, opts), opts, &lexer_line);
889 require2 (';', '=');
893 /* Definition of a generic VEC structure:
895 'DEF_VEC_[IPO]' '(' id ')' ';'
897 Scalar VECs require slightly different treatment than otherwise -
898 that's handled in note_def_vec, we just pass it along.*/
899 static void
900 def_vec (void)
902 bool is_scalar = (token () == DEFVEC_I);
903 const char *type;
905 require2 (DEFVEC_OP, DEFVEC_I);
906 require ('(');
907 type = require2 (ID, SCALAR);
908 require (')');
909 require (';');
911 if (!type)
912 return;
914 note_def_vec (type, is_scalar, &lexer_line);
915 note_def_vec_alloc (type, "none", &lexer_line);
918 /* Definition of an allocation strategy for a VEC structure:
920 'DEF_VEC_ALLOC_[IPO]' '(' id ',' id ')' ';'
922 For purposes of gengtype, this just declares a wrapper structure. */
923 static void
924 def_vec_alloc (void)
926 const char *type, *astrat;
928 require (DEFVEC_ALLOC);
929 require ('(');
930 type = require2 (ID, SCALAR);
931 require (',');
932 astrat = require (ID);
933 require (')');
934 require (';');
936 if (!type || !astrat)
937 return;
939 note_def_vec_alloc (type, astrat, &lexer_line);
942 /* Parse the file FNAME for GC-relevant declarations and definitions.
943 This is the only entry point to this file. */
944 void
945 parse_file (const char *fname)
947 yybegin (fname);
948 for (;;)
950 switch (token ())
952 case EXTERN:
953 case STATIC:
954 extern_or_static ();
955 break;
957 case STRUCT:
958 case UNION:
959 struct_or_union ();
960 break;
962 case TYPEDEF:
963 typedef_decl ();
964 break;
966 case DEFVEC_OP:
967 case DEFVEC_I:
968 def_vec ();
969 break;
971 case DEFVEC_ALLOC:
972 def_vec_alloc ();
973 break;
975 case EOF_TOKEN:
976 goto eof;
978 default:
979 parse_error ("unexpected top level token, %s", print_cur_token ());
980 goto eof;
982 lexer_toplevel_done = 1;
985 eof:
986 advance ();
987 yyend ();