1 /* $Id: grammar.y,v 1.7 2020/03/30 23:55:49 tom Exp $
3 * yacc grammar for C function prototype generator
4 * This was derived from the grammar in Appendix A of
5 * "The C Programming Language" by Kernighan and Ritchie.
11 #define YYSTYPE_IS_DECLARED
12 #define yyerror yaccError
15 #if defined(YYBISON) || !defined(YYBYACC)
16 static void yyerror(const char *s);
20 %token <text> '(' '*' '&'
21 /* identifiers that are not reserved words */
22 T_IDENTIFIER T_TYPEDEF_NAME T_DEFINE_NAME
25 T_AUTO T_EXTERN T_REGISTER T_STATIC T_TYPEDEF
26 /* This keyword included for compatibility with C++. */
28 /* This keyword included for compatibility with GCC */
32 T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID
33 T_LONG T_SHORT T_SIGNED T_UNSIGNED
34 T_ENUM T_STRUCT T_UNION
36 T_Bool T_Complex T_Imaginary
41 /* paired square brackets and everything between them: [ ... ] */
47 /* all input to the matching right brace */
53 /* constant expression or paired braces following an equal sign */
61 /* ( "string literal" ) following asm keyword */
64 /* va_dcl from <varargs.h> */
67 %type <decl_spec> decl_specifiers decl_specifier
68 %type <decl_spec> storage_class type_specifier type_qualifier
69 %type <decl_spec> struct_or_union_specifier enum_specifier
70 %type <decl_list> init_declarator_list
71 %type <declarator> init_declarator declarator direct_declarator
72 %type <declarator> abs_declarator direct_abs_declarator
73 %type <param_list> parameter_type_list parameter_list
74 %type <parameter> parameter_declaration
75 %type <param_list> opt_identifier_list identifier_list
76 %type <text> struct_or_union pointer opt_type_qualifiers type_qualifier_list
77 any_id identifier_or_ref
78 %type <text> enumeration
85 #define OPT_LINTLIBRARY 1
95 /* #include "cproto.h" */
96 #define MAX_TEXT_SIZE 1024
97 #define TEXT_LEN (MAX_TEXT_SIZE / 2 - 3)
99 /* Prototype styles */
101 #define PROTO_ANSI_LLIB -2 /* form ANSI lint-library source */
102 #define PROTO_LINTLIBRARY -1 /* form lint-library source */
104 #define PROTO_NONE 0 /* do not output any prototypes */
105 #define PROTO_TRADITIONAL 1 /* comment out parameters */
106 #define PROTO_ABSTRACT 2 /* comment out parameter names */
107 #define PROTO_ANSI 3 /* ANSI C prototype */
109 typedef int PrototypeStyle;
111 typedef char boolean;
113 extern boolean types_out;
114 extern PrototypeStyle proto_style;
116 #define ansiLintLibrary() (proto_style == PROTO_ANSI_LLIB)
117 #define knrLintLibrary() (proto_style == PROTO_LINTLIBRARY)
118 #define lintLibrary() (knrLintLibrary() || ansiLintLibrary())
121 #define FUNC_UNKNOWN -1 /* unspecified */
123 #define FUNC_UNKNOWN 0 /* unspecified (same as FUNC_NONE) */
125 #define FUNC_NONE 0 /* not a function definition */
126 #define FUNC_TRADITIONAL 1 /* traditional style */
127 #define FUNC_ANSI 2 /* ANSI style */
128 #define FUNC_BOTH 3 /* both styles */
130 typedef int FuncDefStyle;
132 /* Source file text */
133 typedef struct text {
134 char text[MAX_TEXT_SIZE]; /* source text */
135 long begin; /* offset in temporary file */
138 /* Declaration specifier flags */
139 #define DS_NONE 0 /* default */
140 #define DS_EXTERN 1 /* contains "extern" specifier */
141 #define DS_STATIC 2 /* contains "static" specifier */
142 #define DS_CHAR 4 /* contains "char" type specifier */
143 #define DS_SHORT 8 /* contains "short" type specifier */
144 #define DS_FLOAT 16 /* contains "float" type specifier */
145 #define DS_INLINE 32 /* contains "inline" specifier */
146 #define DS_JUNK 64 /* we're not interested in this declaration */
148 /* This structure stores information about a declaration specifier. */
149 typedef struct decl_spec {
150 unsigned short flags; /* flags defined above */
151 char *text; /* source text */
152 long begin; /* offset in temporary file */
155 /* This is a list of function parameters. */
156 typedef struct _ParameterList {
157 struct parameter *first; /* pointer to first parameter in list */
158 struct parameter *last; /* pointer to last parameter in list */
159 long begin_comment; /* begin offset of comment */
160 long end_comment; /* end offset of comment */
161 char *comment; /* comment at start of parameter list */
164 /* This structure stores information about a declarator. */
165 typedef struct _Declarator {
166 char *name; /* name of variable or function */
167 char *text; /* source text */
168 long begin; /* offset in temporary file */
169 long begin_comment; /* begin offset of comment */
170 long end_comment; /* end offset of comment */
171 FuncDefStyle func_def; /* style of function definition */
172 ParameterList params; /* function parameters */
173 boolean pointer; /* TRUE if it declares a pointer */
174 struct _Declarator *head; /* head function declarator */
175 struct _Declarator *func_stack; /* stack of function declarators */
176 struct _Declarator *next; /* next declarator in list */
179 /* This structure stores information about a function parameter. */
180 typedef struct parameter {
181 struct parameter *next; /* next parameter in list */
183 Declarator *declarator;
184 char *comment; /* comment following the parameter */
187 /* This is a list of declarators. */
188 typedef struct declarator_list {
189 Declarator *first; /* pointer to first declarator in list */
190 Declarator *last; /* pointer to last declarator in list */
193 /* #include "symbol.h" */
194 typedef struct symbol {
195 struct symbol *next; /* next symbol in list */
196 char *name; /* name of symbol */
197 char *value; /* value of symbol (for defines) */
198 short flags; /* symbol attributes */
201 /* parser stack entry type */
205 Parameter *parameter;
206 ParameterList param_list;
207 Declarator *declarator;
208 DeclaratorList decl_list;
211 /* The hash table length should be a prime number. */
212 #define SYM_MAX_HASH 251
214 typedef struct symbol_table {
215 Symbol *bucket[SYM_MAX_HASH]; /* hash buckets */
218 extern SymbolTable *new_symbol_table /* Create symbol table */
220 extern void free_symbol_table /* Destroy symbol table */
222 extern Symbol *find_symbol /* Lookup symbol name */
223 (SymbolTable *s, const char *n);
224 extern Symbol *new_symbol /* Define new symbol */
225 (SymbolTable *s, const char *n, const char *v, int f);
227 /* #include "semantic.h" */
228 extern void new_decl_spec (DeclSpec *, const char *, long, int);
229 extern void free_decl_spec (DeclSpec *);
230 extern void join_decl_specs (DeclSpec *, DeclSpec *, DeclSpec *);
231 extern void check_untagged (DeclSpec *);
232 extern Declarator *new_declarator (const char *, const char *, long);
233 extern void free_declarator (Declarator *);
234 extern void new_decl_list (DeclaratorList *, Declarator *);
235 extern void free_decl_list (DeclaratorList *);
236 extern void add_decl_list (DeclaratorList *, DeclaratorList *, Declarator *);
237 extern Parameter *new_parameter (DeclSpec *, Declarator *);
238 extern void free_parameter (Parameter *);
239 extern void new_param_list (ParameterList *, Parameter *);
240 extern void free_param_list (ParameterList *);
241 extern void add_param_list (ParameterList *, ParameterList *, Parameter *);
242 extern void new_ident_list (ParameterList *);
243 extern void add_ident_list (ParameterList *, ParameterList *, const char *);
244 extern void set_param_types (ParameterList *, DeclSpec *, DeclaratorList *);
245 extern void gen_declarations (DeclSpec *, DeclaratorList *);
246 extern void gen_prototype (DeclSpec *, Declarator *);
247 extern void gen_func_declarator (Declarator *);
248 extern void gen_func_definition (DeclSpec *, Declarator *);
250 extern void init_parser (void);
251 extern void process_file (FILE *infile, char *name);
252 extern char *cur_text (void);
253 extern char *cur_file_name (void);
254 extern char *implied_typedef (void);
255 extern void include_file (char *name, int convert);
256 extern char *supply_parm (int count);
257 extern char *xstrdup (const char *);
258 extern int already_declared (char *name);
259 extern int is_actual_func (Declarator *d);
260 extern int lint_ellipsis (Parameter *p);
261 extern int want_typedef (void);
262 extern void begin_tracking (void);
263 extern void begin_typedef (void);
264 extern void copy_typedef (char *s);
265 extern void ellipsis_varargs (Declarator *d);
266 extern void end_typedef (void);
267 extern void flush_varargs (void);
268 extern void fmt_library (int code);
269 extern void imply_typedef (const char *s);
270 extern void indent (FILE *outf);
271 extern void put_blankline (FILE *outf);
272 extern void put_body (FILE *outf, DeclSpec *decl_spec, Declarator *declarator);
273 extern void put_char (FILE *outf, int c);
274 extern void put_error (void);
275 extern void put_newline (FILE *outf);
276 extern void put_padded (FILE *outf, const char *s);
277 extern void put_string (FILE *outf, const char *s);
278 extern void track_in (void);
280 extern boolean file_comments;
281 extern FuncDefStyle func_style;
282 extern char base_file[];
284 extern int yylex (void);
286 /* declaration specifier attributes for the typedef statement currently being
289 static int cur_decl_spec_flags;
291 /* pointer to parameter list for the current function definition */
292 static ParameterList *func_params;
294 /* A parser semantic action sets this pointer to the current declarator in
295 * a function parameter declaration in order to catch any comments following
296 * the parameter declaration on the same line. If the lexer scans a comment
297 * and <cur_declarator> is not NULL, then the comment is attached to the
298 * declarator. To ignore subsequent comments, the lexer sets this to NULL
299 * after scanning a comment or end of line.
301 static Declarator *cur_declarator;
303 /* temporary string buffer */
304 static char buf[MAX_TEXT_SIZE];
306 /* table of typedef names */
307 static SymbolTable *typedef_names;
309 /* table of define names */
310 static SymbolTable *define_names;
312 /* table of type qualifiers */
313 static SymbolTable *type_qualifiers;
315 /* information about the current input file */
317 char *base_name; /* base input file name */
318 char *file_name; /* current file name */
319 FILE *file; /* input file */
320 unsigned line_num; /* current line number in input file */
321 FILE *tmp_file; /* temporary file */
322 long begin_comment; /* tmp file offset after last written ) or ; */
323 long end_comment; /* tmp file offset after last comment */
324 boolean convert; /* if TRUE, convert function definitions */
325 boolean changed; /* TRUE if conversion done in this file */
328 static IncludeStack *cur_file; /* current input file */
330 /* #include "yyerror.c" */
332 static int haveAnsiParam (void);
335 /* Flags to enable us to find if a procedure returns a value.
337 static int return_val; /* nonzero on BRACES iff return-expression found */
342 return (lintLibrary() && !return_val) ? "void" : "int";
349 if (func_params != 0) {
350 for (p = func_params->first; p != 0; p = p->next) {
351 if (p->declarator->func_def == FUNC_ANSI) {
367 : external_declaration
368 | translation_unit external_declaration
373 | function_definition
375 | linkage_specification
377 | error T_MATCHRBRACE
388 : T_LBRACE T_MATCHRBRACE
391 linkage_specification
392 : T_EXTERN T_STRING_LITERAL braces
394 /* Provide an empty action here so bison will not complain about
395 * incompatible types in the default action it normally would
399 | T_EXTERN T_STRING_LITERAL declaration
406 : decl_specifiers ';'
409 if (types_out && want_typedef()) {
410 gen_declarations(&$1, (DeclaratorList *)0);
417 | decl_specifiers init_declarator_list ';'
419 if (func_params != NULL) {
420 set_param_types(func_params, &$1, &$2);
422 gen_declarations(&$1, &$2);
431 | any_typedef decl_specifiers
433 cur_decl_spec_flags = $2.flags;
436 opt_declarator_list ';'
443 : T_EXTENSION T_TYPEDEF
461 int flags = cur_decl_spec_flags;
463 /* If the typedef is a pointer type, then reset the short type
464 * flags so it does not get promoted.
466 if (strcmp($1->text, $1->name) != 0)
467 flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
468 new_symbol(typedef_names, $1->name, NULL, flags);
471 | declarator_list ',' declarator
473 int flags = cur_decl_spec_flags;
475 if (strcmp($3->text, $3->name) != 0)
476 flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
477 new_symbol(typedef_names, $3->name, NULL, flags);
483 : decl_specifiers declarator
486 if ($2->func_def == FUNC_NONE) {
487 yyerror("syntax error");
490 func_params = &($2->head->params);
491 func_params->begin_comment = cur_file->begin_comment;
492 func_params->end_comment = cur_file->end_comment;
494 opt_declaration_list T_LBRACE
496 /* If we're converting to K&R and we've got a nominally K&R
497 * function which has a parameter which is ANSI (i.e., a prototyped
498 * function pointer), then we must override the deciphered value of
499 * 'func_def' so that the parameter will be converted.
501 if (func_style == FUNC_TRADITIONAL
503 && $2->head->func_def == func_style) {
504 $2->head->func_def = FUNC_BOTH;
509 if (cur_file->convert)
510 gen_func_definition(&$1, $2);
511 gen_prototype(&$1, $2);
521 if ($1->func_def == FUNC_NONE) {
522 yyerror("syntax error");
525 func_params = &($1->head->params);
526 func_params->begin_comment = cur_file->begin_comment;
527 func_params->end_comment = cur_file->end_comment;
529 opt_declaration_list T_LBRACE T_MATCHRBRACE
535 new_decl_spec(&decl_spec, dft_decl_spec(), $1->begin, DS_NONE);
536 if (cur_file->convert)
537 gen_func_definition(&decl_spec, $1);
538 gen_prototype(&decl_spec, $1);
542 free_decl_spec(&decl_spec);
555 | declaration_list declaration
560 | decl_specifiers decl_specifier
562 join_decl_specs(&$$, &$1, &$2);
577 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
581 new_decl_spec(&$$, $1.text, $1.begin, DS_EXTERN);
585 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
589 new_decl_spec(&$$, $1.text, $1.begin, DS_STATIC);
593 new_decl_spec(&$$, $1.text, $1.begin, DS_INLINE);
597 new_decl_spec(&$$, $1.text, $1.begin, DS_JUNK);
604 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
608 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
612 new_decl_spec(&$$, $1.text, $1.begin, DS_FLOAT);
616 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
620 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
624 new_decl_spec(&$$, $1.text, $1.begin, DS_SHORT);
628 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
632 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
636 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
640 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
644 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
648 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
653 s = find_symbol(typedef_names, $1.text);
655 new_decl_spec(&$$, $1.text, $1.begin, s->flags);
657 | struct_or_union_specifier
664 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
668 /* This rule allows the <pointer> nonterminal to scan #define
669 * names as if they were type modifiers.
672 s = find_symbol(define_names, $1.text);
674 new_decl_spec(&$$, $1.text, $1.begin, s->flags);
678 struct_or_union_specifier
679 : struct_or_union any_id braces
682 if ((s = implied_typedef()) == 0)
683 (void)sprintf(s = buf, "%.*s %.*s", TEXT_LEN, $1.text, TEXT_LEN, $2.text);
684 new_decl_spec(&$$, s, $1.begin, DS_NONE);
686 | struct_or_union braces
689 if ((s = implied_typedef()) == 0)
690 (void)sprintf(s = buf, "%.*s {}", TEXT_LEN, $1.text);
691 new_decl_spec(&$$, s, $1.begin, DS_NONE);
693 | struct_or_union any_id
695 (void)sprintf(buf, "%.*s %.*s", TEXT_LEN, $1.text, TEXT_LEN, $2.text);
696 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
703 imply_typedef($$.text);
707 imply_typedef($$.text);
714 new_decl_list(&$$, $1);
716 | init_declarator_list ',' init_declarator
718 add_decl_list(&$$, &$1, $3);
725 if ($1->func_def != FUNC_NONE && func_params == NULL &&
726 func_style == FUNC_TRADITIONAL && cur_file->convert) {
727 gen_func_declarator($1);
728 fputs(cur_text(), cur_file->tmp_file);
734 if ($1->func_def != FUNC_NONE && func_params == NULL &&
735 func_style == FUNC_TRADITIONAL && cur_file->convert) {
736 gen_func_declarator($1);
737 fputs(" =", cur_file->tmp_file);
744 : enumeration any_id braces
747 if ((s = implied_typedef()) == 0)
748 (void)sprintf(s = buf, "enum %.*s", TEXT_LEN, $2.text);
749 new_decl_spec(&$$, s, $1.begin, DS_NONE);
754 if ((s = implied_typedef()) == 0)
755 (void)sprintf(s = buf, "%.*s {}", TEXT_LEN, $1.text);
756 new_decl_spec(&$$, s, $1.begin, DS_NONE);
760 (void)sprintf(buf, "enum %.*s", TEXT_LEN, $2.text);
761 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
768 imply_typedef("enum");
779 : pointer direct_declarator
782 (void)sprintf(buf, "%.*s%.*s", TEXT_LEN, $1.text, TEXT_LEN, $$->text);
784 $$->text = xstrdup(buf);
785 $$->begin = $1.begin;
794 $$ = new_declarator($1.text, $1.text, $1.begin);
799 (void)sprintf(buf, "(%.*s)", TEXT_LEN, $$->text);
801 $$->text = xstrdup(buf);
802 $$->begin = $1.begin;
804 | direct_declarator T_BRACKETS
807 (void)sprintf(buf, "%.*s%.*s", TEXT_LEN, $$->text, TEXT_LEN, $2.text);
809 $$->text = xstrdup(buf);
811 | direct_declarator '(' parameter_type_list ')'
813 $$ = new_declarator("%s()", $1->name, $1->begin);
816 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
817 $$->func_def = FUNC_ANSI;
819 | direct_declarator '(' opt_identifier_list ')'
821 $$ = new_declarator("%s()", $1->name, $1->begin);
824 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
825 $$->func_def = FUNC_TRADITIONAL;
830 : '*' opt_type_qualifiers
832 (void)sprintf($$.text, "*%.*s", TEXT_LEN, $2.text);
835 | '*' opt_type_qualifiers pointer
837 (void)sprintf($$.text, "*%.*s%.*s", TEXT_LEN, $2.text, TEXT_LEN, $3.text);
848 | type_qualifier_list
854 (void)sprintf($$.text, "%s ", $1.text);
858 | type_qualifier_list type_qualifier
860 (void)sprintf($$.text, "%.*s%.*s ", TEXT_LEN, $1.text, TEXT_LEN, $2.text);
868 | parameter_list ',' T_ELLIPSIS
870 add_ident_list(&$$, &$1, "...");
875 : parameter_declaration
877 new_param_list(&$$, $1);
879 | parameter_list ',' parameter_declaration
881 add_param_list(&$$, &$1, $3);
885 parameter_declaration
886 : decl_specifiers declarator
889 $$ = new_parameter(&$1, $2);
891 | decl_specifiers abs_declarator
894 $$ = new_parameter(&$1, $2);
899 $$ = new_parameter(&$1, (Declarator *)0);
915 add_ident_list(&$$, &$$, $1.text);
917 | identifier_list ',' any_id
919 add_ident_list(&$$, &$1, $3.text);
931 if (lintLibrary()) { /* Lint doesn't grok C++ ref variables */
935 (void)sprintf($$.text, "&%.*s", TEXT_LEN, $2.text);
943 $$ = new_declarator($1.text, "", $1.begin);
945 | pointer direct_abs_declarator
948 (void)sprintf(buf, "%.*s%.*s", TEXT_LEN, $1.text, TEXT_LEN, $$->text);
950 $$->text = xstrdup(buf);
951 $$->begin = $1.begin;
953 | direct_abs_declarator
956 direct_abs_declarator
957 : '(' abs_declarator ')'
960 (void)sprintf(buf, "(%.*s)", TEXT_LEN, $$->text);
962 $$->text = xstrdup(buf);
963 $$->begin = $1.begin;
965 | direct_abs_declarator T_BRACKETS
968 (void)sprintf(buf, "%.*s%.*s", TEXT_LEN, $$->text, TEXT_LEN, $2.text);
970 $$->text = xstrdup(buf);
974 $$ = new_declarator($1.text, "", $1.begin);
976 | direct_abs_declarator '(' parameter_type_list ')'
978 $$ = new_declarator("%s()", "", $1->begin);
981 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
982 $$->func_def = FUNC_ANSI;
984 | direct_abs_declarator '(' ')'
986 $$ = new_declarator("%s()", "", $1->begin);
988 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
989 $$->func_def = FUNC_ANSI;
991 | '(' parameter_type_list ')'
995 d = new_declarator("", "", $1.begin);
996 $$ = new_declarator("%s()", "", $1.begin);
1000 $$->func_def = FUNC_ANSI;
1006 d = new_declarator("", "", $1.begin);
1007 $$ = new_declarator("%s()", "", $1.begin);
1010 $$->func_def = FUNC_ANSI;
1017 #define BEGIN yy_start = 1 + 2 *
1025 #define CPP_INLINE 7
1027 extern char *yytext;
1028 extern FILE *yyin, *yyout;
1030 static int curly; /* number of curly brace nesting levels */
1031 static int ly_count; /* number of occurrences of %% */
1032 static int inc_depth; /* include nesting level */
1033 static SymbolTable *included_files; /* files already included */
1034 static int yy_start = 0; /* start state number */
1036 #define grammar_error(s) yaccError(s)
1039 yaccError (const char *msg)
1042 put_error(); /* tell what line we're on, and what file */
1043 fprintf(stderr, "%s at token '%s'\n", msg, yytext);
1046 /* Initialize the table of type qualifier keywords recognized by the lexical
1052 static const char *keywords[] = {
1061 #if defined(MSDOS) || defined(OS2)
1106 "__builtin_va_list",
1119 /* Initialize type qualifier table. */
1120 type_qualifiers = new_symbol_table();
1121 for (i = 0; i < sizeof(keywords)/sizeof(keywords[0]); ++i) {
1122 new_symbol(type_qualifiers, keywords[i], NULL, DS_NONE);
1126 /* Process the C source file. Write function prototypes to the standard
1127 * output. Convert function definitions and write the converted source
1128 * code to a temporary file.
1131 process_file (FILE *infile, char *name)
1135 if (strlen(name) > 2) {
1136 s = name + strlen(name) - 2;
1139 if (*s == 'l' || *s == 'y')
1141 #if defined(MSDOS) || defined(OS2)
1142 if (*s == 'L' || *s == 'Y')
1148 included_files = new_symbol_table();
1149 typedef_names = new_symbol_table();
1150 define_names = new_symbol_table();
1156 include_file(strcpy(base_file, name), func_style != FUNC_NONE);
1157 if (file_comments) {
1159 if (lintLibrary()) {
1160 put_blankline(stdout);
1164 put_string(stdout, "/* ");
1165 put_string(stdout, cur_file_name());
1166 put_string(stdout, " */\n");
1169 free_symbol_table(define_names);
1170 free_symbol_table(typedef_names);
1171 free_symbol_table(included_files);
1178 free_symbol_table (type_qualifiers);
1180 if (yy_current_buffer != 0)
1181 yy_delete_buffer(yy_current_buffer);