#include "output.h"
#include "reader.h"
#include "conflicts.h"
-
-extern char *printable_version PARAMS ((int));
-
-#define LTYPESTR "\
-\n\
-#ifndef YYLTYPE\n\
-typedef\n\
- struct yyltype\n\
-\
- {\n\
- int timestamp;\n\
- int first_line;\n\
- int first_column;\
-\n\
- int last_line;\n\
- int last_column;\n\
- char *text;\n\
- }\n\
-\
- yyltype;\n\
-\n\
-#define YYLTYPE yyltype\n\
-#endif\n\
-\n"
+#include "quote.h"
/* Number of slots allocated (but not necessarily used yet) in `rline' */
static int rline_allocated;
they must be unions. */
static int value_components_used;
-static int typed; /* nonzero if %union has been seen. */
+/* Nonzero if %union has been seen. */
+static int typed;
-static int lastprec; /* incremented for each %left, %right or %nonassoc seen */
+/* Incremented for each %left, %right or %nonassoc seen */
+static int lastprec;
-static int gensym_count; /* incremented for each generated symbol */
+/* Incremented for each generated symbol */
+static int gensym_count;
static bucket *errtoken;
static bucket *undeftoken;
-
-/* Nonzero if any action or guard uses the @n construct. */
-static int yylsp_needed;
\f
/*===================\
return sign * n;
}
\f
+/*--------------------------------------------------------------.
+| Get the data type (alternative in the union) of the value for |
+| symbol N in rule RULE. |
+`--------------------------------------------------------------*/
+
+static char *
+get_type_name (int n, symbol_list * rule)
+{
+ int i;
+ symbol_list *rp;
+
+ if (n < 0)
+ {
+ complain (_("invalid $ value"));
+ return NULL;
+ }
+
+ rp = rule;
+ i = 0;
+
+ while (i < n)
+ {
+ rp = rp->next;
+ if (rp == NULL || rp->sym == NULL)
+ {
+ complain (_("invalid $ value"));
+ return NULL;
+ }
+ i++;
+ }
+
+ return rp->sym->type_name;
+}
+\f
/*-------------------------------------------------------------------.
| Dump the string from FINPUT to FOUTPUT. MATCH is the delimiter of |
| the string (either ' or "). |
if (c == '$')
{
fprintf (fout, "yyloc");
- yylsp_needed = 1;
+ locations_flag = 1;
}
else if (isdigit (c) || c == '-')
{
n = read_signed_integer (fin);
fprintf (fout, "yylsp[%d]", n - stack_offset);
- yylsp_needed = 1;
+ locations_flag = 1;
+ }
+ else
+ {
+ char buf[] = "@c";
+ buf[1] = c;
+ complain (_("%s is invalid"), quote (buf));
+ }
+}
+
+
+/*-------------------------------------------------------------------.
+| FIN is pointing to a wannabee semantic value (i.e., a `$'). |
+| |
+| Possible inputs: $[<TYPENAME>]($|integer) |
+| |
+| Output to FOUT a reference to this semantic value. STACK_OFFSET is |
+| the number of values in the current rule so far, which says where |
+| to find `$0' with respect to the top of the stack. |
+`-------------------------------------------------------------------*/
+
+static inline void
+copy_dollar (FILE *fin, FILE *fout,
+ symbol_list *rule, int stack_offset)
+{
+ int c = getc (fin);
+ char *type_name = NULL;
+
+ /* Get the typename if explicit. */
+ if (c == '<')
+ {
+ char *cp = token_buffer;
+
+ while ((c = getc (fin)) != '>' && c > 0)
+ {
+ if (cp == token_buffer + maxtoken)
+ cp = grow_token_buffer (cp);
+
+ *cp++ = c;
+ }
+ *cp = 0;
+ type_name = token_buffer;
+ value_components_used = 1;
+
+ c = getc (fin);
+ }
+
+ if (c == '$')
+ {
+ fprintf (fout, "yyval");
+ if (!type_name)
+ type_name = get_type_name (0, rule);
+ if (type_name)
+ fprintf (fout, ".%s", type_name);
+ if (!type_name && typed)
+ complain (_("$$ of `%s' has no declared type"),
+ rule->sym->tag);
+ }
+ else if (isdigit (c) || c == '-')
+ {
+ int n;
+ ungetc (c, fin);
+ n = read_signed_integer (fin);
+
+ if (!type_name && n > 0)
+ type_name = get_type_name (n, rule);
+
+ fprintf (fout, "yyvsp[%d]", n - stack_offset);
+ if (type_name)
+ fprintf (fout, ".%s", type_name);
+ if (!type_name && typed)
+ complain (_("$%d of `%s' has no declared type"),
+ n, rule->sym->tag);
}
else
- complain (_("@%s is invalid"), printable_version (c));
+ {
+ char buf[] = "$c";
+ buf[1] = c;
+ complain (_("%s is invalid"), quote (buf));
+ }
}
\f
/*-------------------------------------------------------------------.
/* -1 while reading a character if prev char was %. */
int after_percent;
- if (!nolinesflag)
+ if (!no_lines_flag)
fprintf (fattrs, "#line %d \"%s\"\n", lineno, infile);
after_percent = 0;
}
-/*-----------------------------------------------------------------.
-| Parse what comes after %token or %nterm. For %token, what_is is |
-| STOKEN and what_is_not is SNTERM. For %nterm, the arguments are |
-| reversed. |
-`-----------------------------------------------------------------*/
+/*-------------------------------------------------------------------.
+| Parse what comes after %token or %nterm. For %token, WHAT_IS is |
+| token_sym and WHAT_IS_NOT is nterm_sym. For %nterm, the arguments |
+| are reversed. |
+`-------------------------------------------------------------------*/
static void
-parse_token_decl (int what_is, int what_is_not)
+parse_token_decl (symbol_class what_is, symbol_class what_is_not)
{
int token = 0;
char *typename = 0;
struct bucket *symbol = NULL; /* pts to symbol being defined */
- int k;
for (;;)
{
}
if (token == TYPENAME)
{
- k = strlen (token_buffer);
- typename = XCALLOC (char, k + 1);
- strcpy (typename, token_buffer);
+ typename = xstrdup (token_buffer);
value_components_used = 1;
symbol = NULL;
}
else if (token == IDENTIFIER && *symval->tag == '\"' && symbol)
{
+ if (symval->alias)
+ warn (_("symbol `%s' used more than once as a literal string"),
+ symval->tag);
+ else if (symbol->alias)
+ warn (_("symbol `%s' given more than one literal string"),
+ symbol->tag);
+ else
+ {
+ symval->class = token_sym;
+ symval->type_name = typename;
+ symval->user_token_number = symbol->user_token_number;
+ symbol->user_token_number = SALIAS;
+ symval->alias = symbol;
+ symbol->alias = symval;
+ /* symbol and symval combined are only one symbol */
+ nsyms--;
+ }
translations = 1;
- symval->class = STOKEN;
- symval->type_name = typename;
- symval->user_token_number = symbol->user_token_number;
- symbol->user_token_number = SALIAS;
-
- symval->alias = symbol;
- symbol->alias = symval;
- symbol = NULL;
-
- nsyms--; /* symbol and symval combined are only one symbol */
+ symbol = NULL;
}
else if (token == IDENTIFIER)
{
if (symbol->class == what_is_not)
complain (_("symbol %s redefined"), symbol->tag);
symbol->class = what_is;
- if (what_is == SNTERM && oldclass != SNTERM)
+ if (what_is == nterm_sym && oldclass != nterm_sym)
symbol->value = nvars++;
if (typename)
else
{
complain (_("`%s' is invalid in %s"),
- token_buffer, (what_is == STOKEN) ? "%token" : "%nterm");
+ token_buffer, (what_is == token_sym) ? "%token" : "%nterm");
skip_to_char ('%');
}
}
}
-/* Parse what comes after %start */
+/*------------------------------.
+| Parse what comes after %start |
+`------------------------------*/
static void
parse_start_decl (void)
}
}
-
-
-/*--------------------------------------------------------------.
-| Get the data type (alternative in the union) of the value for |
-| symbol n in rule rule. |
-`--------------------------------------------------------------*/
-
-static char *
-get_type_name (int n, symbol_list * rule)
-{
- int i;
- symbol_list *rp;
-
- if (n < 0)
- {
- complain (_("invalid $ value"));
- return NULL;
- }
-
- rp = rule;
- i = 0;
-
- while (i < n)
- {
- rp = rp->next;
- if (rp == NULL || rp->sym == NULL)
- {
- complain (_("invalid $ value"));
- return NULL;
- }
- i++;
- }
-
- return rp->sym->type_name;
-}
-
-
/*-----------------------------------------------------------.
| read in a %type declaration and record its information for |
| get_type_name to access |
static void
parse_type_decl (void)
{
- int k;
char *name;
if (lex () != TYPENAME)
return;
}
- k = strlen (token_buffer);
- name = XCALLOC (char, k + 1);
- strcpy (name, token_buffer);
+ name = xstrdup (token_buffer);
for (;;)
{
-/* read in a %left, %right or %nonassoc declaration and record its information. */
-/* assoc is either LEFT_ASSOC, RIGHT_ASSOC or NON_ASSOC. */
+/*----------------------------------------------------------------.
+| Read in a %left, %right or %nonassoc declaration and record its |
+| information. |
+`----------------------------------------------------------------*/
static void
-parse_assoc_decl (int assoc)
+parse_assoc_decl (associativity assoc)
{
- int k;
char *name = NULL;
int prev = 0;
switch (t)
{
-
case TYPENAME:
- k = strlen (token_buffer);
- name = XCALLOC (char, k + 1);
- strcpy (name, token_buffer);
+ name = xstrdup (token_buffer);
break;
case COMMA:
complain (_("redefining precedence of %s"), symval->tag);
symval->prec = lastprec;
symval->assoc = assoc;
- if (symval->class == SNTERM)
+ if (symval->class == nterm_sym)
complain (_("symbol %s redefined"), symval->tag);
- symval->class = STOKEN;
+ symval->class = token_sym;
if (name)
{ /* record the type, if one is specified */
if (symval->type_name == NULL)
-/* copy the union declaration into fattrs (and fdefines),
- where it is made into the
- definition of YYSTYPE, the type of elements of the parser value stack. */
+/*-------------------------------------------------------------------.
+| Copy the union declaration into fattrs (and fdefines), where it is |
+| made into the definition of YYSTYPE, the type of elements of the |
+| parser value stack. |
+`-------------------------------------------------------------------*/
static void
parse_union_decl (void)
typed = 1;
- if (!nolinesflag)
+ if (!no_lines_flag)
fprintf (fattrs, "\n#line %d \"%s\"\n", lineno, infile);
else
fprintf (fattrs, "\n");
}
}
-/* parse the declaration %expect N which says to expect N
- shift-reduce conflicts. */
+
+/*-------------------------------------------------------.
+| Parse the declaration %expect N which says to expect N |
+| shift-reduce conflicts. |
+`-------------------------------------------------------*/
static void
parse_expect_decl (void)
{
- int c;
- int count;
- char buffer[20];
-
- c = getc (finput);
- while (c == ' ' || c == '\t')
- c = getc (finput);
-
- count = 0;
- while (c >= '0' && c <= '9')
- {
- if (count < 20)
- buffer[count++] = c;
- c = getc (finput);
- }
- buffer[count] = 0;
-
+ int c = skip_white_space ();
ungetc (c, finput);
- if (count <= 0 || count > 10)
- complain ("%s", _("argument of %expect is not an integer"));
- expected_conflicts = atoi (buffer);
+ if (!isdigit (c))
+ complain (_("argument of %%expect is not an integer"));
+ else
+ expected_conflicts = read_signed_integer (finput);
}
int token;
struct bucket *symbol;
char *typename = 0;
- int k, usrtoknum;
+ int usrtoknum;
translations = 1;
token = lex (); /* fetch typename or first token */
if (token == TYPENAME)
{
- k = strlen (token_buffer);
- typename = XCALLOC (char, k + 1);
- strcpy (typename, token_buffer);
+ typename = xstrdup (token_buffer);
value_components_used = 1;
token = lex (); /* fetch first token */
}
skip_to_char ('%');
return;
}
- symval->class = STOKEN;
+ symval->class = token_sym;
symval->type_name = typename;
symval->user_token_number = SALIAS;
symbol = symval;
skip_to_char ('%');
return;
}
- symval->class = STOKEN;
+ symval->class = token_sym;
symval->type_name = typename;
symval->user_token_number = usrtoknum;
symval->alias = symbol;
symbol->alias = symval;
- nsyms--; /* symbol and symval combined are only one symbol */
+ /* symbol and symval combined are only one symbol. */
+ nsyms--;
}
+
/*----------------------------------------------------------------.
| Read from finput until `%%' is seen. Discard the `%%'. Handle |
| any `%' declarations, and copy the contents of any `%{ ... %}' |
break;
case TOKEN:
- parse_token_decl (STOKEN, SNTERM);
+ parse_token_decl (token_sym, nterm_sym);
break;
case NTERM:
- parse_token_decl (SNTERM, STOKEN);
+ parse_token_decl (nterm_sym, token_sym);
break;
case TYPE:
case THONG:
parse_thong_decl ();
break;
+
case LEFT:
- parse_assoc_decl (LEFT_ASSOC);
+ parse_assoc_decl (left_assoc);
break;
case RIGHT:
- parse_assoc_decl (RIGHT_ASSOC);
+ parse_assoc_decl (right_assoc);
break;
case NONASSOC:
- parse_assoc_decl (NON_ASSOC);
+ parse_assoc_decl (non_assoc);
break;
case SEMANTIC_PARSER:
fatal (_("no input grammar"));
else
{
- complain (_("unknown character: %s"), printable_version (c));
+ char buf[] = "c";
+ buf[0] = c;
+ complain (_("unknown character: %s"), quote (buf));
skip_to_char ('%');
}
}
`-------------------------------------------------------------------*/
static void
-copy_action (symbol_list * rule, int stack_offset)
+copy_action (symbol_list *rule, int stack_offset)
{
int c;
- int n;
int count;
- char *type_name;
/* offset is always 0 if parser has already popped the stack pointer */
if (semantic_parser)
stack_offset = 0;
fprintf (faction, "\ncase %d:\n", nrules);
- if (!nolinesflag)
+ if (!no_lines_flag)
fprintf (faction, "#line %d \"%s\"\n", lineno, infile);
putc ('{', faction);
break;
case '$':
- c = getc (finput);
- type_name = NULL;
-
- if (c == '<')
- {
- char *cp = token_buffer;
-
- while ((c = getc (finput)) != '>' && c > 0)
- {
- if (cp == token_buffer + maxtoken)
- cp = grow_token_buffer (cp);
-
- *cp++ = c;
- }
- *cp = 0;
- type_name = token_buffer;
- value_components_used = 1;
-
- c = getc (finput);
- }
- if (c == '$')
- {
- fprintf (faction, "yyval");
- if (!type_name)
- type_name = get_type_name (0, rule);
- if (type_name)
- fprintf (faction, ".%s", type_name);
- if (!type_name && typed)
- complain (_("$$ of `%s' has no declared type"),
- rule->sym->tag);
- }
- else if (isdigit (c) || c == '-')
- {
- ungetc (c, finput);
- n = read_signed_integer (finput);
- c = getc (finput);
-
- if (!type_name && n > 0)
- type_name = get_type_name (n, rule);
-
- fprintf (faction, "yyvsp[%d]", n - stack_offset);
- if (type_name)
- fprintf (faction, ".%s", type_name);
- if (!type_name && typed)
- complain (_("$%d of `%s' has no declared type"),
- n, rule->sym->tag);
- continue;
- }
- else
- complain (_("$%s is invalid"), printable_version (c));
-
+ copy_dollar (finput, faction, rule, stack_offset);
break;
case '@':
`-------------------------------------------------------------------*/
static void
-copy_guard (symbol_list * rule, int stack_offset)
+copy_guard (symbol_list *rule, int stack_offset)
{
int c;
- int n;
int count;
- char *type_name;
int brace_flag = 0;
/* offset is always 0 if parser has already popped the stack pointer */
stack_offset = 0;
fprintf (fguard, "\ncase %d:\n", nrules);
- if (!nolinesflag)
+ if (!no_lines_flag)
fprintf (fguard, "#line %d \"%s\"\n", lineno, infile);
putc ('{', fguard);
break;
case '$':
- c = getc (finput);
- type_name = NULL;
-
- if (c == '<')
- {
- char *cp = token_buffer;
-
- while ((c = getc (finput)) != '>' && c > 0)
- {
- if (cp == token_buffer + maxtoken)
- cp = grow_token_buffer (cp);
-
- *cp++ = c;
- }
- *cp = 0;
- type_name = token_buffer;
-
- c = getc (finput);
- }
-
- if (c == '$')
- {
- fprintf (fguard, "yyval");
- if (!type_name)
- type_name = rule->sym->type_name;
- if (type_name)
- fprintf (fguard, ".%s", type_name);
- if (!type_name && typed)
- complain (_("$$ of `%s' has no declared type"),
- rule->sym->tag);
- }
- else if (isdigit (c) || c == '-')
- {
- ungetc (c, finput);
- n = read_signed_integer (finput);
- c = getc (finput);
-
- if (!type_name && n > 0)
- type_name = get_type_name (n, rule);
-
- fprintf (fguard, "yyvsp[%d]", n - stack_offset);
- if (type_name)
- fprintf (fguard, ".%s", type_name);
- if (!type_name && typed)
- complain (_("$%d of `%s' has no declared type"),
- n, rule->sym->tag);
- continue;
- }
- else
- complain (_("$%s is invalid"), printable_version (c));
+ copy_dollar (finput, fguard, rule, stack_offset);
break;
case '@':
sprintf (token_buffer, "@%d", ++gensym_count);
sym = getsym (token_buffer);
- sym->class = SNTERM;
+ sym->class = nterm_sym;
sym->value = nvars++;
return sym;
}
return t;
}
- k = strlen (token_buffer);
- name = XCALLOC (char, k + 1);
- strcpy (name, token_buffer);
+ name = xstrdup (token_buffer);
for (;;)
{
symbol_list *p1;
bucket *bp;
- symbol_list *crule; /* points to first symbol_list of current rule. */
- /* its symbol is the lhs of the rule. */
- symbol_list *crule1; /* points to the symbol_list preceding crule. */
+ /* Points to first symbol_list of current rule. its symbol is the
+ lhs of the rule. */
+ symbol_list *crule;
+ /* Points to the symbol_list preceding crule. */
+ symbol_list *crule1;
p1 = NULL;
{
if (t == IDENTIFIER || t == BAR)
{
- int actionflag = 0;
- int rulelength = 0; /* number of symbols in rhs of this rule so far */
+ int action_flag = 0;
+ /* Number of symbols in rhs of this rule so far */
+ int rulelength = 0;
int xactions = 0; /* JF for error checking */
bucket *first_rhs = 0;
/* mark the rule's lhs as a nonterminal if not already so. */
- if (lhs->class == SUNKNOWN)
+ if (lhs->class == unknown_sym)
{
- lhs->class = SNTERM;
+ lhs->class = nterm_sym;
lhs->value = nvars;
nvars++;
}
- else if (lhs->class == STOKEN)
+ else if (lhs->class == token_sym)
complain (_("rule given for %s, which is a token"), lhs->tag);
/* read the rhs of the rule. */
/* If we just passed an action, that action was in the middle
of a rule, so make a dummy rule to reduce it to a
non-terminal. */
- if (actionflag)
+ if (action_flag)
{
bucket *sdummy;
p1->next = p;
p1 = p;
- actionflag = 0;
+ action_flag = 0;
}
if (t == IDENTIFIER)
else /* handle an action. */
{
copy_action (crule, rulelength);
- actionflag = 1;
+ action_flag = 1;
xactions++; /* JF */
}
rulelength++;
if (t == GUARD)
{
if (!semantic_parser)
- complain ("%s",
- _
- ("%guard present but %semantic_parser not specified"));
+ complain (_("%%guard present but %%semantic_parser not specified"));
copy_guard (crule, rulelength);
t = lex ();
else if (t == LEFT_CURLY)
{
/* This case never occurs -wjh */
- if (actionflag)
+ if (action_flag)
complain (_("two actions at end of one rule"));
copy_action (crule, rulelength);
- actionflag = 1;
+ action_flag = 1;
xactions++; /* -wjh */
t = lex ();
}
*/
else if (t == TOKEN)
{
- parse_token_decl (STOKEN, SNTERM);
+ parse_token_decl (token_sym, nterm_sym);
t = lex ();
}
else if (t == NTERM)
{
- parse_token_decl (SNTERM, STOKEN);
+ parse_token_decl (nterm_sym, token_sym);
t = lex ();
}
else if (t == TYPE)
if (nrules == 0)
fatal (_("no rules in the input grammar"));
- if (typed == 0 /* JF put out same default YYSTYPE as YACC does */
+ /* JF put out same default YYSTYPE as YACC does */
+ if (typed == 0
&& !value_components_used)
{
/* We used to use `unsigned long' as YYSTYPE on MSDOS,
/* Report any undefined symbols and consider them nonterminals. */
for (bp = firstsymbol; bp; bp = bp->next)
- if (bp->class == SUNKNOWN)
+ if (bp->class == unknown_sym)
{
complain (_
("symbol %s is used, but is not defined as a token and has no rules"),
-bp->tag);
- bp->class = SNTERM;
+ bp->tag);
+ bp->class = nterm_sym;
bp->value = nvars++;
}
continue;
fprintf (file, "#define\t%s\t%d\n", symbol,
- ((translations && !rawtoknumflag)
+ ((translations && !raw_flag)
? bp->user_token_number : bp->value));
if (semantic_parser)
fprintf (file, "#define\tT%s\t%d\n", symbol, bp->value);
for (bp = firstsymbol; bp; bp = bp->next)
{
- if (bp->class == SNTERM)
+ if (bp->class == nterm_sym)
{
bp->value += ntokens;
}
continue; /* do not do processing below for SALIASs */
}
- else /* bp->class == STOKEN */
+ else /* bp->class == token_sym */
{
bp->value = tokno++;
}
- if (bp->class == STOKEN)
+ if (bp->class == token_sym)
{
if (translations && !(bp->user_token_number))
bp->user_token_number = ++last_user_token_number;
error_token_number = errtoken->value;
- if (!noparserflag)
+ if (!no_parser_flag)
output_token_defines (ftable);
- if (startval->class == SUNKNOWN)
+ if (startval->class == unknown_sym)
fatal (_("the start symbol %s is undefined"), startval->tag);
- else if (startval->class == STOKEN)
+ else if (startval->class == token_sym)
fatal (_("the start symbol %s is a token"), startval->tag);
start_symbol = startval->value;
- if (definesflag)
+ if (defines_flag)
{
output_token_defines (fdefines);
ritem[itemno++] = p->sym->value;
/* A rule gets by default the precedence and associativity
of the last token in it. */
- if (p->sym->class == STOKEN)
+ if (p->sym->class == token_sym)
{
rprec[ruleno] = p->sym->prec;
rassoc[ruleno] = p->sym->assoc;
semantic_parser = 0;
pure_parser = 0;
- yylsp_needed = 0;
grammar = NULL;
tabinit ();
/* Construct the error token */
errtoken = getsym ("error");
- errtoken->class = STOKEN;
+ errtoken->class = token_sym;
errtoken->user_token_number = 256; /* Value specified by POSIX. */
/* Construct a token that represents all undefined literal tokens.
It is always token number 2. */
undeftoken = getsym ("$undefined.");
- undeftoken->class = STOKEN;
+ undeftoken->class = token_sym;
undeftoken->user_token_number = 2;
/* Read the declaration section. Copy %{ ... %} groups to FTABLE
fprintf (ftable, "\
/* %s, made from %s\n\
by GNU bison %s. */\n\
-\n", noparserflag ? "Bison-generated parse tables" : "A Bison parser", infile, VERSION);
+\n", no_parser_flag ? "Bison-generated parse tables" : "A Bison parser", infile, VERSION);
fputs ("#define YYBISON 1 /* Identify Bison output. */\n\n", ftable);
read_declarations ();
reader_output_yylsp (fdefines);
/* Write closing delimiters for actions and guards. */
output_trailers ();
- if (yylsp_needed)
+ if (locations_flag)
fputs ("#define YYLSP_NEEDED\n\n", ftable);
/* Assign the symbols their symbol numbers. Write #defines for the
token symbols into FDEFINES if requested. */
free_symtab ();
}
+
void
reader_output_yylsp (FILE *f)
{
- if (yylsp_needed)
- fprintf (f, LTYPESTR);
+ if (locations_flag)
+ fputs ("\
+\n\
+#ifndef YYLTYPE\n\
+typedef struct yyltype\n\
+{\n\
+ int timestamp;\n\
+ int first_line;\n\
+ int first_column;\
+\n\
+ int last_line;\n\
+ int last_column;\n\
+ char *text;\n\
+} yyltype;\n\
+\n\
+# define YYLTYPE yyltype\n\
+#endif\n\
+\n",
+ f);
}